From 4c1bfce6c5f1102a6eac4e0ab421fa8181a38722 Mon Sep 17 00:00:00 2001 From: Sergey Zorchenko Date: Sun, 11 Sep 2022 14:34:19 +0300 Subject: [PATCH 01/77] TDD calc cache optimization --- .../ProfileFunctionImplementation.kt | 22 ++++++++++++------- .../androidaps/utils/stats/TddCalculator.kt | 14 +++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt index b851e40b22..4bbb6f8efe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt @@ -43,7 +43,7 @@ class ProfileFunctionImplementation @Inject constructor( private val deviceStatusData: DeviceStatusData ) : ProfileFunction { - val cache = LongSparseArray() + val cache = HashMap() private val disposable = CompositeDisposable() @@ -54,10 +54,10 @@ class ProfileFunctionImplementation @Inject constructor( .subscribe( { synchronized(cache) { - for (index in cache.size() - 1 downTo 0) { - if (cache.keyAt(index) > it.startDate) { - aapsLogger.debug(LTag.AUTOSENS, "Removing from profileCache: " + dateUtil.dateAndTimeAndSecondsString(cache.keyAt(index))) - cache.removeAt(index) + for (key in cache.keys) { + if (key > it.startDate) { + aapsLogger.debug(LTag.AUTOSENS, "Removing from profileCache: " + dateUtil.dateAndTimeAndSecondsString(key)) + cache.remove(key) } else { break } @@ -98,14 +98,17 @@ class ProfileFunctionImplementation @Inject constructor( val rounded = time - time % 1000 // Clear cache after longer use synchronized(cache) { - if (cache.size() > 30000) { + if (cache.keys.size > 30000) { cache.clear() aapsLogger.debug("Profile cache cleared") } - val cached = cache[rounded] - if (cached != null) return cached + if (cache.containsKey(rounded)) { + //aapsLogger.debug(LTag.PROFILE, "Profile cache HIT for $rounded") + return cache[rounded] + } } // aapsLogger.debug("getProfile called for $time") + //aapsLogger.debug(LTag.PROFILE, "Profile cache MISS for $rounded") val ps = repository.getEffectiveProfileSwitchActiveAt(time).blockingGet() if (ps is ValueWrapper.Existing) { val sealed = ProfileSealed.EPS(ps.value) @@ -130,6 +133,9 @@ class ProfileFunctionImplementation @Inject constructor( } } + synchronized(cache) { + cache.put(rounded, null) + } return null } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt b/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt index f9b7ba509a..02c505525e 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt @@ -99,7 +99,7 @@ class TddCalculator @Inject constructor( } fun calculateToday(): TotalDailyDose { - var startTime = MidnightTime.calc(dateUtil.now()) + val startTime = MidnightTime.calc(dateUtil.now()) val endTime = dateUtil.now() return calculate(startTime, endTime) } @@ -111,7 +111,9 @@ class TddCalculator @Inject constructor( } fun calculate(startTime: Long, endTime: Long): TotalDailyDose { - val tdd = TotalDailyDose(timestamp = startTime) + val startTimeAligned = startTime - startTime % (5 * 60 * 1000) + val endTimeAligned = endTime - endTime % (5 * 60 * 1000) + val tdd = TotalDailyDose(timestamp = startTimeAligned) repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() .filter { it.type != Bolus.Type.PRIMING } .forEach { t -> @@ -121,14 +123,14 @@ class TddCalculator @Inject constructor( tdd.carbs += t.amount } val calculationStep = T.mins(5).msecs() - for (t in startTime until endTime step calculationStep) { - val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) + for (t in startTimeAligned until endTimeAligned step calculationStep) { + val profile = profileFunction.getProfile(t) ?: continue - val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) + val tbr = iobCobCalculator.getBasalData(profile, t) + val absoluteRate = tbr.tempBasalAbsolute tdd.basalAmount += absoluteRate / 60.0 * 5.0 if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) { - // they are not included in TBRs val eb = iobCobCalculator.getExtendedBolus(t) val absoluteEbRate = eb?.rate ?: 0.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 From bf873e304e5332628897465119d9836ef0780232 Mon Sep 17 00:00:00 2001 From: Sergey Zorchenko Date: Mon, 12 Sep 2022 13:33:15 +0300 Subject: [PATCH 02/77] daily TDD calculation now uses unified flow to benefit from caches --- .../androidaps/utils/stats/TddCalculator.kt | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt b/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt index 02c505525e..009671e58a 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt @@ -41,6 +41,7 @@ class TddCalculator @Inject constructor( fun calculate(days: Long): LongSparseArray { var startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs()) val endTime = MidnightTime.calc(dateUtil.now()) + val stepSize = T.hours(24).msecs() val result = LongSparseArray() // Try to load cached values @@ -48,47 +49,17 @@ class TddCalculator @Inject constructor( val tdd = repository.getCalculatedTotalDailyDose(startTime).blockingGet() if (tdd is ValueWrapper.Existing) result.put(startTime, tdd.value) else break - startTime += T.hours(24).msecs() + startTime += stepSize } if (endTime > startTime) { - repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() - .filter { it.type != Bolus.Type.PRIMING } - .forEach { t -> - val midnight = MidnightTime.calc(t.timestamp) - val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) - tdd.bolusAmount += t.amount - result.put(midnight, tdd) - } - repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> - val midnight = MidnightTime.calc(t.timestamp) - val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) - tdd.carbs += t.amount - result.put(midnight, tdd) - } - - val calculationStep = T.mins(5).msecs() - val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep) - for (t in startTime until endTime step calculationStep) { - val midnight = MidnightTime.calc(t) - val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) - val tbr = tempBasals[t] - val profile = profileFunction.getProfile(t) ?: continue - val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) - tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() - - if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) { - // they are not included in TBRs - val eb = iobCobCalculator.getExtendedBolus(t) - val absoluteEbRate = eb?.rate ?: 0.0 - tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() - } + for (midnight in startTime until endTime step stepSize) { + val tdd = calculate(midnight, midnight + stepSize) result.put(midnight, tdd) } } for (i in 0 until result.size()) { val tdd = result.valueAt(i) - tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount if (tdd.interfaceIDs.pumpType != InterfaceIDs.PumpType.CACHE) { tdd.interfaceIDs.pumpType = InterfaceIDs.PumpType.CACHE aapsLogger.debug(LTag.CORE, "Storing TDD $tdd") From 0096dbe06b859319b85a88b8eda7a35b79abfdee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 08:15:26 +0000 Subject: [PATCH 03/77] chore(deps): bump kotlin_version from 1.7.10 to 1.7.20 Bumps `kotlin_version` from 1.7.10 to 1.7.20. Updates `kotlin-gradle-plugin` from 1.7.10 to 1.7.20 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.20/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.10...v1.7.20) Updates `kotlin-allopen` from 1.7.10 to 1.7.20 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.20/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.10...v1.7.20) Updates `kotlin-serialization` from 1.7.10 to 1.7.20 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.20/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.10...v1.7.20) Updates `kotlin-stdlib-jdk8` from 1.7.10 to 1.7.20 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.20/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.10...v1.7.20) Updates `kotlin-reflect` from 1.7.10 to 1.7.20 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.20/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.10...v1.7.20) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-allopen dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-serialization dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-reflect dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 584278a22e..e595300892 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlin_version = '1.7.10' + kotlin_version = '1.7.20' core_version = '1.9.0' rxjava_version = '3.1.5' rxandroid_version = '3.0.0' From 2fc85ec1c896a15cb54a4467287a20562e95c07a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 10:51:45 +0000 Subject: [PATCH 04/77] chore(deps): bump org.jetbrains.kotlin.android from 1.7.10 to 1.7.20 Bumps org.jetbrains.kotlin.android from 1.7.10 to 1.7.20. --- updated-dependencies: - dependency-name: org.jetbrains.kotlin.android dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e595300892..6e8a1a6d54 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,7 @@ plugins { id "io.gitlab.arturbosch.detekt" version "1.21.0" id "org.jlleitschuh.gradle.ktlint" version "11.0.0" id 'org.barfuin.gradle.jacocolog' version '2.0.0' - id 'org.jetbrains.kotlin.android' version '1.7.10' apply false + id 'org.jetbrains.kotlin.android' version '1.7.20' apply false } allprojects { From ca25801c629ec074ce5eec38f89af304035b328b Mon Sep 17 00:00:00 2001 From: Sergey Zorchenko Date: Fri, 30 Sep 2022 14:47:07 +0300 Subject: [PATCH 05/77] SafeParse in ValidatingEditTextPreference and FloatNumericRangeValidator --- .../textValidator/ValidatingEditTextPreference.kt | 12 +++++++----- .../validators/FloatNumericRangeValidator.kt | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt index 64a7e7d09e..5ebdd6dbfa 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt @@ -8,6 +8,7 @@ import dagger.android.HasAndroidInjector import info.nightscout.androidaps.core.R import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.shared.SafeParse import javax.inject.Inject class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : EditTextPreference(ctx, attrs, defStyleAttr, defStyleRes) { @@ -67,14 +68,15 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt override fun onSetInitialValue(defaultValue: Any?) { text = if (validatorParameters.testType == EditTextValidator.TEST_BG_RANGE) - Profile.fromMgdlToUnits(getPersistedString(defaultValue as String?).toDouble(), profileFunction.getUnits()).toString() + Profile.fromMgdlToUnits(SafeParse.stringToDouble(getPersistedString(defaultValue as String?)), profileFunction.getUnits()).toString() else getPersistedString(defaultValue as String?) } override fun persistString(value: String?): Boolean = - if (validatorParameters.testType == EditTextValidator.TEST_BG_RANGE) - super.persistString(Profile.toMgdl(value?.toDouble() ?: 0.0, profileFunction.getUnits()).toString()) - else - super.persistString(value) + when (validatorParameters.testType) { + EditTextValidator.TEST_BG_RANGE -> super.persistString(Profile.toMgdl(SafeParse.stringToDouble(value, 0.0), profileFunction.getUnits()).toString()) + EditTextValidator.TEST_FLOAT_NUMERIC_RANGE -> super.persistString(SafeParse.stringToDouble(value, 0.0).toString()) + else -> super.persistString(value) + } } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/validators/FloatNumericRangeValidator.kt b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/validators/FloatNumericRangeValidator.kt index d574233f43..889914dbdc 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/validators/FloatNumericRangeValidator.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/validators/FloatNumericRangeValidator.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.utils.textValidator.validators import android.widget.EditText +import info.nightscout.shared.SafeParse /** * A validator that returns true only if the input field contains only numbers @@ -12,7 +13,7 @@ class FloatNumericRangeValidator(_customErrorMessage: String?, private val float override fun isValid(editText: EditText): Boolean { return try { - val value = editText.text.toString().toFloat() + val value = SafeParse.stringToFloat(editText.text.toString()) value in floatMin..floatMax } catch (e: NumberFormatException) { false From d0d17216d22f12c6c04a9da9aed569d3696dc755 Mon Sep 17 00:00:00 2001 From: mushroom-dev Date: Sat, 1 Oct 2022 11:03:10 +0200 Subject: [PATCH 06/77] fix to always by default check alarm tickbox in bolus calc wizard when carb time is >0 --- .../info/nightscout/androidaps/dialogs/WizardDialog.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 8d86cb5e9e..d6788dd0ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -92,11 +92,13 @@ class WizardDialog : DaggerDialogFragment() { } private val timeTextWatcher = object : TextWatcher { - override fun afterTextChanged(s: Editable) {} + override fun afterTextChanged(s: Editable) { + binding.alarm.isChecked = binding.carbTimeInput.value > 0 + } + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { calculateInsulin() - binding.alarm.isChecked = binding.carbTimeInput.value > 0 } } @@ -367,7 +369,7 @@ class WizardDialog : DaggerDialogFragment() { // Set BG if not old binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0 - binding.ttCheckbox.isEnabled = tempTarget is ValueWrapper.Existing + binding.ttCheckbox.isEnabled = tempTarget is ValueWrapper.Existing binding.ttCheckboxIcon.visibility = binding.ttCheckbox.isEnabled.toVisibility() binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, -bolusIob.iob - basalIob.basaliob) From 3f3cdde53bcff139515cf9cdfb9bb5dbd68a4ca2 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 3 Oct 2022 16:18:15 +0200 Subject: [PATCH 07/77] Ignore active SN for VirtualPump, try to resolve Combo issue --- .../plugins/aps/loop/LoopFragment.kt | 2 +- .../plugins/pump/PumpSyncImplementation.kt | 107 +++++++++++++++--- .../plugins/pump/combo/ComboPlugin.java | 15 +-- .../androidaps/interfaces/PumpSync.kt | 28 ++++- .../androidaps/danar/AbstractDanaRPlugin.java | 2 +- .../activities/InsightPairingActivity.java | 2 +- .../eros/manager/AapsOmnipodErosManager.java | 2 +- 7 files changed, 124 insertions(+), 34 deletions(-) rename {core => app}/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt (82%) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt index 1d44fa75d0..eaaee1c41e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt @@ -66,7 +66,7 @@ class LoopFragment : DaggerFragment(), MenuProvider { setColorSchemeColors(rh.gac(context, R.attr.colorPrimaryDark), rh.gac(context, R.attr.colorPrimary), rh.gac(context, R.attr.colorSecondary)) setOnRefreshListener { binding.lastrun.text = rh.gs(R.string.executing) - handler.post { loop.invoke("Loop swiperefresh", true) } + handler.post { loop.invoke("Loop swipe refresh", true) } } } } diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt similarity index 82% rename from core/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt rename to app/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt index 9e4f9fb189..83704b9489 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/PumpSyncImplementation.kt @@ -5,20 +5,44 @@ import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.embedments.InterfaceIDs -import info.nightscout.androidaps.database.entities.* -import info.nightscout.androidaps.database.transactions.* +import info.nightscout.androidaps.database.entities.Bolus +import info.nightscout.androidaps.database.entities.Carbs +import info.nightscout.androidaps.database.entities.ExtendedBolus +import info.nightscout.androidaps.database.entities.TemporaryBasal +import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.database.entities.TotalDailyDose +import info.nightscout.androidaps.database.entities.UserEntry +import info.nightscout.androidaps.database.entities.ValueWithUnit +import info.nightscout.androidaps.database.transactions.InsertBolusWithTempIdTransaction +import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampCarbsTransaction +import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampTherapyEventTransaction +import info.nightscout.androidaps.database.transactions.InsertTemporaryBasalWithTempIdTransaction +import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction +import info.nightscout.androidaps.database.transactions.InvalidateTemporaryBasalTransaction +import info.nightscout.androidaps.database.transactions.InvalidateTemporaryBasalTransactionWithPumpId +import info.nightscout.androidaps.database.transactions.InvalidateTemporaryBasalWithTempIdTransaction +import info.nightscout.androidaps.database.transactions.SyncBolusWithTempIdTransaction +import info.nightscout.androidaps.database.transactions.SyncPumpBolusTransaction +import info.nightscout.androidaps.database.transactions.SyncPumpCancelExtendedBolusIfAnyTransaction +import info.nightscout.androidaps.database.transactions.SyncPumpCancelTemporaryBasalIfAnyTransaction +import info.nightscout.androidaps.database.transactions.SyncPumpExtendedBolusTransaction +import info.nightscout.androidaps.database.transactions.SyncPumpTemporaryBasalTransaction +import info.nightscout.androidaps.database.transactions.SyncPumpTotalDailyDoseTransaction +import info.nightscout.androidaps.database.transactions.SyncTemporaryBasalWithTempIdTransaction +import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -32,7 +56,8 @@ class PumpSyncImplementation @Inject constructor( private val rh: ResourceHelper, private val profileFunction: ProfileFunction, private val repository: AppRepository, - private val uel: UserEntryLogger + private val uel: UserEntryLogger, + private val activePlugin: ActivePlugin ) : PumpSync { private val disposable = CompositeDisposable() @@ -51,6 +76,15 @@ class PumpSyncImplementation @Inject constructor( sp.remove(R.string.key_active_pump_change_timestamp) } + override fun verifyPumpIdentification(type: PumpType, serialNumber: String): Boolean { + val storedType = sp.getString(R.string.key_active_pump_type, "") + val storedSerial = sp.getString(R.string.key_active_pump_serial_number, "") + if (activePlugin.activePump is VirtualPumpPlugin) return true + if (type.description == storedType && serialNumber == storedSerial) return true + aapsLogger.debug(LTag.PUMP, "verifyPumpIdentification failed for $type $serialNumber") + return false + } + /** * Check if data is coming from currently active pump to prevent overlapping pump histories * @@ -73,14 +107,19 @@ class PumpSyncImplementation @Inject constructor( return timestamp > dateUtil.now() - T.mins(1).msecs() // allow first record to be 1 min old } - if (type.description == storedType && serialNumber == storedSerial && timestamp >= storedTimestamp) { + if (activePlugin.activePump is VirtualPumpPlugin || (type.description == storedType && serialNumber == storedSerial && timestamp >= storedTimestamp)) { // data match return true } if (showNotification && (type.description != storedType || serialNumber != storedSerial) && timestamp >= storedTimestamp) rxBus.send(EventNewNotification(Notification(Notification.WRONG_PUMP_DATA, rh.gs(R.string.wrong_pump_data), Notification.URGENT))) - aapsLogger.error(LTag.PUMP, "Ignoring pump history record Allowed: ${dateUtil.dateAndTimeAndSecondsString(storedTimestamp)} $storedType $storedSerial Received: $timestamp ${dateUtil.dateAndTimeAndSecondsString(timestamp)} ${type.description} $serialNumber") + aapsLogger.error( + LTag.PUMP, + "Ignoring pump history record Allowed: ${dateUtil.dateAndTimeAndSecondsString(storedTimestamp)} $storedType $storedSerial Received: $timestamp ${ + dateUtil.dateAndTimeAndSecondsString(timestamp) + } ${type.description} $serialNumber" + ) return false } @@ -100,7 +139,7 @@ class PumpSyncImplementation @Inject constructor( isAbsolute = temporaryBasal.value.isAbsolute, type = PumpSync.TemporaryBasalType.fromDbType(temporaryBasal.value.type), pumpId = temporaryBasal.value.interfaceIDs.pumpId, - pumpType = temporaryBasal.value.interfaceIDs.pumpType?.let { PumpType.fromDbPumpType(it)} ?: PumpType.USER, + pumpType = temporaryBasal.value.interfaceIDs.pumpType?.let { PumpType.fromDbPumpType(it) } ?: PumpType.USER, pumpSerial = temporaryBasal.value.interfaceIDs.pumpSerial ?: "", ) else null, @@ -111,7 +150,7 @@ class PumpSyncImplementation @Inject constructor( duration = extendedBolus.value.duration, amount = extendedBolus.value.amount, rate = extendedBolus.value.rate, - pumpType = extendedBolus.value.interfaceIDs.pumpType?.let { PumpType.fromDbPumpType(it)} ?: PumpType.USER, + pumpType = extendedBolus.value.interfaceIDs.pumpType?.let { PumpType.fromDbPumpType(it) } ?: PumpType.USER, pumpSerial = extendedBolus.value.interfaceIDs.pumpSerial ?: "" ) else null, @@ -203,7 +242,8 @@ class PumpSyncImplementation @Inject constructor( interfaceIDs_backing = InterfaceIDs( pumpId = pumpId, pumpType = pumpType.toDbPumpType(), - pumpSerial = pumpSerial) + pumpSerial = pumpSerial + ) ) repository.runTransactionForResult(InsertIfNewByTimestampCarbsTransaction(carbs)) .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving Carbs", it) } @@ -228,7 +268,8 @@ class PumpSyncImplementation @Inject constructor( interfaceIDs_backing = InterfaceIDs( pumpId = pumpId, pumpType = pumpType.toDbPumpType(), - pumpSerial = pumpSerial) + pumpSerial = pumpSerial + ) ) uel.log(UserEntry.Action.CAREPORTAL, pumpType.source, note, ValueWithUnit.Timestamp(timestamp), ValueWithUnit.TherapyEventType(type.toDBbEventType())) repository.runTransactionForResult(InsertIfNewByTimestampTherapyEventTransaction(therapyEvent)) @@ -252,7 +293,16 @@ class PumpSyncImplementation @Inject constructor( * TEMPORARY BASALS */ - override fun syncTemporaryBasalWithPumpId(timestamp: Long, rate: Double, duration: Long, isAbsolute: Boolean, type: PumpSync.TemporaryBasalType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean { + override fun syncTemporaryBasalWithPumpId( + timestamp: Long, + rate: Double, + duration: Long, + isAbsolute: Boolean, + type: PumpSync.TemporaryBasalType?, + pumpId: Long, + pumpType: PumpType, + pumpSerial: String + ): Boolean { if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false val temporaryBasal = TemporaryBasal( timestamp = timestamp, @@ -289,7 +339,16 @@ class PumpSyncImplementation @Inject constructor( } } - override fun addTemporaryBasalWithTempId(timestamp: Long, rate: Double, duration: Long, isAbsolute: Boolean, tempId: Long, type: PumpSync.TemporaryBasalType, pumpType: PumpType, pumpSerial: String): Boolean { + override fun addTemporaryBasalWithTempId( + timestamp: Long, + rate: Double, + duration: Long, + isAbsolute: Boolean, + tempId: Long, + type: PumpSync.TemporaryBasalType, + pumpType: PumpType, + pumpSerial: String + ): Boolean { if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false val temporaryBasal = TemporaryBasal( timestamp = timestamp, @@ -312,7 +371,17 @@ class PumpSyncImplementation @Inject constructor( } } - override fun syncTemporaryBasalWithTempId(timestamp: Long, rate: Double, duration: Long, isAbsolute: Boolean, temporaryId: Long, type: PumpSync.TemporaryBasalType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean { + override fun syncTemporaryBasalWithTempId( + timestamp: Long, + rate: Double, + duration: Long, + isAbsolute: Boolean, + temporaryId: Long, + type: PumpSync.TemporaryBasalType?, + pumpId: Long?, + pumpType: PumpType, + pumpSerial: String + ): Boolean { if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false val bolus = TemporaryBasal( timestamp = timestamp, @@ -349,8 +418,12 @@ class PumpSyncImplementation @Inject constructor( } override fun invalidateTemporaryBasalWithPumpId(pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean { - repository.runTransactionForResult(InvalidateTemporaryBasalTransactionWithPumpId(pumpId, pumpType.toDbPumpType(), - pumpSerial)) + repository.runTransactionForResult( + InvalidateTemporaryBasalTransactionWithPumpId( + pumpId, pumpType.toDbPumpType(), + pumpSerial + ) + ) .doOnError { aapsLogger.error(LTag.DATABASE, "Error while invalidating TemporaryBasal", it) } .blockingGet() .also { result -> diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java b/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java index 0c70619feb..bc40358970 100644 --- a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java +++ b/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java @@ -38,6 +38,7 @@ import info.nightscout.androidaps.interfaces.Pump; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpPluginBase; import info.nightscout.androidaps.interfaces.PumpSync; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.common.ManufacturerType; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; @@ -61,17 +62,16 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.InstanceId; import info.nightscout.androidaps.utils.T; -import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.shared.logging.AAPSLogger; import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; /** * Driver for the Roche Accu-Chek Combo pump, using the ruffy app for BT communication. - * + *

* For boluses, the logic is to request a bolus and then read it back from the history to see what was * actually delivered. - * + *

* TBR-handling doesn't read the pump history. On the pump, TBR records are only created after a TBR has finished. * So when a TBR is started on the pump, it can't be known when it started until the TBR ends or is cancelled. * Cancelling would assume a user works against the loop, and creating a temporary TBR (AAPS-side) and updating it @@ -85,7 +85,7 @@ import info.nightscout.shared.sharedPreferences.SP; * This approach skipped implementing edge-cases that pose no real risk, in part due to limited resources to * implement every edge-case scenario. Insulin amount given via boluses are significantly higher, so the * priority was there to make that as safe as possible. - * + *

* Created by mike on 05.08.2016. */ @Singleton @@ -424,11 +424,12 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { String lastKnownSN = serialNumber(); if (!lastKnownSN.equals(fakeSerialNumber()) && !lastKnownSN.equals(macAddress)) { getAapsLogger().info(LTag.PUMP, "Pump serial number changed " + lastKnownSN + " -> " + macAddress); - pumpSync.connectNewPump(); + pumpSync.connectNewPump(true); } sp.putString(R.string.combo_pump_serial, macAddress); } - + if (!pumpSync.verifyPumpIdentification(pumpDescription.getPumpType(), serialNumber())) + pumpSync.connectNewPump(true); // ComboFragment updates state fully only after the pump has initialized, // so force an update after initialization completed rxBus.send(new EventComboPumpUpdateGUI()); @@ -566,7 +567,7 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { return new PumpEnactResult(getInjector()).success(true).enacted(false); } - EventOverviewBolusProgress.Treatment treatment = new EventOverviewBolusProgress.Treatment(0.0, 0,detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.getId()); + EventOverviewBolusProgress.Treatment treatment = new EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.getId()); EventOverviewBolusProgress.INSTANCE.setT(treatment); // start bolus delivery diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpSync.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpSync.kt index 4a6662608f..a81d3fda36 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpSync.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpSync.kt @@ -27,13 +27,19 @@ interface PumpSync { * * Call this function when new pump is paired to accept data from new pump * to prevent overlapping pump histories - * @param endRunning if true end previous running TBR and EB + * @param endRunning if true end previous running TBR and EB */ - // @JvmOverloads and default value impossible on interface - // replace by `fun connectNewPump(endRunning: Boolean = true)` after full conversion to kotlin - fun connectNewPump(endRunning: Boolean) - fun connectNewPump() = connectNewPump(true) + fun connectNewPump(endRunning: Boolean = true) + + /** + * Verify if current pump type and SN is properly registered + * @param type current PumpType + * @param serialNumber current serial number + * + * @return true if type and SN match to last call of connectNewPump + */ + fun verifyPumpIdentification(type: PumpType, serialNumber: String): Boolean /* * GENERAL STATUS @@ -355,7 +361,17 @@ interface PumpSync { * @param pumpSerial pump serial number * @return true if record is successfully updated **/ - fun syncTemporaryBasalWithTempId(timestamp: Long, rate: Double, duration: Long, isAbsolute: Boolean, temporaryId: Long, type: TemporaryBasalType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean + fun syncTemporaryBasalWithTempId( + timestamp: Long, + rate: Double, + duration: Long, + isAbsolute: Boolean, + temporaryId: Long, + type: TemporaryBasalType?, + pumpId: Long?, + pumpType: PumpType, + pumpSerial: String + ): Boolean /** * Invalidate of temporary basals that failed to start diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java b/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java index 77588a77bf..881eda371f 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java @@ -110,7 +110,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump .subscribe(event -> { if (event.isChanged(getRh(), R.string.key_danar_bt_name)) { danaPump.reset(); - pumpSync.connectNewPump(); + pumpSync.connectNewPump(true); getCommandQueue().readStatus(getRh().gs(R.string.device_changed), null); } }) diff --git a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightPairingActivity.java b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightPairingActivity.java index e88086499b..fda0450c1f 100644 --- a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightPairingActivity.java +++ b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightPairingActivity.java @@ -74,7 +74,7 @@ public class InsightPairingActivity extends NoSplashAppCompatActivity implements service.registerStateCallback(InsightPairingActivity.this); service.registerExceptionCallback(InsightPairingActivity.this); onStateChanged(service.getState()); - pumpSync.connectNewPump(); + pumpSync.connectNewPump(true); } } diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java index 26a5a3445d..d017a7e7d2 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java @@ -209,7 +209,7 @@ public class AapsOmnipodErosManager { addToHistory(System.currentTimeMillis(), PodHistoryEntryType.INSERT_CANNULA, result.getComment(), result.getSuccess()); if (result.getSuccess()) { - pumpSync.connectNewPump(); + pumpSync.connectNewPump(true); uploadCareportalEvent(System.currentTimeMillis() - 1000, DetailedBolusInfo.EventType.INSULIN_CHANGE); uploadCareportalEvent(System.currentTimeMillis(), DetailedBolusInfo.EventType.CANNULA_CHANGE); From 2e3ce68e3da991833d4ca3d01aef339b71997bcf Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 3 Oct 2022 21:44:30 +0200 Subject: [PATCH 08/77] SMS: fix displayed number on sent messages --- .../plugins/general/smsCommunicator/Sms.kt | 10 ++++++++++ .../smsCommunicator/SmsCommunicatorPlugin.kt | 3 +-- .../plugins/general/smsCommunicator/SmsTest.kt | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt index 6efac44dbb..cfbfbd163b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt @@ -26,6 +26,16 @@ class Sms { sent = true } + internal constructor(other: Sms, number: String? = null) { + phoneNumber = number ?: other.phoneNumber + text = other.text + date = other.date + received = other.received + sent = other.sent + processed = other.processed + ignored = other.ignored + } + override fun toString(): String { return "SMS from $phoneNumber: $text" } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index fecdc3b3d3..e26c0d0066 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -1095,8 +1095,7 @@ class SmsCommunicatorPlugin @Inject constructor( private fun sendSMSToAllNumbers(sms: Sms) { for (number in allowedNumbers) { - sms.phoneNumber = number - sendSMS(sms) + sendSMS(Sms(sms, number)) } } diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt index 75e2d0b602..31b315a8df 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt @@ -26,5 +26,20 @@ class SmsTest : TestBase() { Assert.assertEquals(sms.text, "U") Assert.assertTrue(sms.sent) Assert.assertEquals(sms.toString(), "SMS from aNumber: U") + + // copy constructor #1 + val sms2 = Sms(sms) + Assert.assertEquals(sms2.phoneNumber, "aNumber") + Assert.assertEquals(sms2.text, "U") + Assert.assertTrue(sms2.sent) + Assert.assertEquals(sms2.toString(), "SMS from aNumber: U") + + // copy constructor #2 + val sms3 = Sms(sms, "different") + Assert.assertEquals(sms3.phoneNumber, "different") + Assert.assertEquals(sms3.text, "U") + Assert.assertTrue(sms3.sent) + Assert.assertEquals(sms3.toString(), "SMS from different: U") + } } \ No newline at end of file From 2a93e059b1658ea0487da33eb496d02163370e26 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 4 Oct 2022 12:20:26 +0200 Subject: [PATCH 09/77] Display timeshit in overview graph --- .../graphExtensions/EffectiveProfileSwitchDataPoint.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt index 716a0fd0b7..57de803f7b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt @@ -4,6 +4,7 @@ import android.content.Context import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.utils.T class EffectiveProfileSwitchDataPoint( val data: EffectiveProfileSwitch, @@ -14,7 +15,11 @@ class EffectiveProfileSwitchDataPoint( override fun getX(): Double = data.timestamp.toDouble() override fun getY(): Double = scale.transform(data.originalPercentage.toDouble()) override fun setY(y: Double) {} - override val label get() = if (data.originalPercentage != 100) data.originalPercentage.toString() + "%" else "" + override val label + get() = "" + + (if (data.originalPercentage != 100) "${data.originalPercentage}%" else "") + + (if (data.originalPercentage != 100 && data.originalTimeshift != 0L) "," else "") + + (if (data.originalTimeshift != 0L) (T.msecs(data.originalTimeshift).hours().toString() + rh.gs(R.string.shorthour)) else "") override val duration = 0L override val shape = PointsWithLabelGraphSeries.Shape.PROFILE override val size = 2f From 3a87a95e323dd51998eae5e4d863d5d57cdd7a14 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 4 Oct 2022 12:44:17 +0200 Subject: [PATCH 10/77] VirtualPump: fix and improve bolus progress --- .idea/codeStyles/Project.xml | 5 ----- .../plugins/pump/virtual/VirtualPumpPlugin.kt | 21 +++++++++++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index c76f23799b..f9209c97b3 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -3,12 +3,7 @@

+ * This is a one time call. If you call {@link TextView#setText(CharSequence)} after this, + * you'll need to call it again. + * @param textViews The TextView(s) to enhance. + */ + public static void addIcons(TextView... textViews) { + for (TextView textView : textViews) { + if (textView == null) continue; + textView.setText(compute(textView.getContext(), textView.getText(), textView)); + } + } + + private static void addIconFontDescriptor(IconFontDescriptor iconFontDescriptor) { + + // Prevent duplicates + for (IconFontDescriptorWrapper wrapper : iconFontDescriptors) { + if (wrapper.getIconFontDescriptor().ttfFileName() + .equals(iconFontDescriptor.ttfFileName())) { + return; + } + } + + // Add to the list + iconFontDescriptors.add(new IconFontDescriptorWrapper(iconFontDescriptor)); + + } + + public static CharSequence compute(Context context, CharSequence text) { + return compute(context, text, null); + } + + public static CharSequence compute(Context context, CharSequence text, TextView target) { + return ParsingUtil.parse(context, iconFontDescriptors, text, target); + } + + /** + * Allows chain calls on {@link Iconify#with(IconFontDescriptor)}. + */ + public static class IconifyInitializer { + + public IconifyInitializer(IconFontDescriptor iconFontDescriptor) { + Iconify.addIconFontDescriptor(iconFontDescriptor); + } + + /** + * Add support for a new icon font. + * @param iconFontDescriptor The IconDescriptor holding the ttf file reference and its mappings. + * @return An initializer instance for chain calls. + */ + public IconifyInitializer with(IconFontDescriptor iconFontDescriptor) { + Iconify.addIconFontDescriptor(iconFontDescriptor); + return this; + } + } + + /** + * Finds the Typeface to apply for a given icon. + * @param icon The icon for which you need the typeface. + * @return The font descriptor which contains info about the typeface to apply, or null + * if the icon cannot be found. In that case, check that you properly added the modules + * using {@link #with(IconFontDescriptor)}} prior to calling this method. + */ + public static IconFontDescriptorWrapper findTypefaceOf(Icon icon) { + for (IconFontDescriptorWrapper iconFontDescriptor : iconFontDescriptors) { + if (iconFontDescriptor.hasIcon(icon)) { + return iconFontDescriptor; + } + } + return null; + } + + + /** + * Retrieve an icon from a key, + * @return The icon, or null if no icon matches the key. + */ + public static Icon findIconForKey(String iconKey) { + for (int i = 0, iconFontDescriptorsSize = iconFontDescriptors.size(); i < iconFontDescriptorsSize; i++) { + IconFontDescriptorWrapper iconFontDescriptor = iconFontDescriptors.get(i); + Icon icon = iconFontDescriptor.getIcon(iconKey); + if (icon != null) return icon; + } + return null; + } +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java b/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java new file mode 100644 index 0000000000..16202e243c --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java @@ -0,0 +1,716 @@ +package com.joanzapata.iconify.fonts; + +import com.joanzapata.iconify.Icon; + +public enum FontAwesomeIcons implements Icon { + fa_glass('\uf000'), + fa_music('\uf001'), + fa_search('\uf002'), + fa_envelope_o('\uf003'), + fa_heart('\uf004'), + fa_star('\uf005'), + fa_star_o('\uf006'), + fa_user('\uf007'), + fa_film('\uf008'), + fa_th_large('\uf009'), + fa_th('\uf00a'), + fa_th_list('\uf00b'), + fa_check('\uf00c'), + fa_remove('\uf00d'), + fa_close('\uf00d'), + fa_times('\uf00d'), + fa_search_plus('\uf00e'), + fa_search_minus('\uf010'), + fa_power_off('\uf011'), + fa_signal('\uf012'), + fa_gear('\uf013'), + fa_cog('\uf013'), + fa_trash_o('\uf014'), + fa_home('\uf015'), + fa_file_o('\uf016'), + fa_clock_o('\uf017'), + fa_road('\uf018'), + fa_download('\uf019'), + fa_arrow_circle_o_down('\uf01a'), + fa_arrow_circle_o_up('\uf01b'), + fa_inbox('\uf01c'), + fa_play_circle_o('\uf01d'), + fa_rotate_right('\uf01e'), + fa_repeat('\uf01e'), + fa_refresh('\uf021'), + fa_list_alt('\uf022'), + fa_lock('\uf023'), + fa_flag('\uf024'), + fa_headphones('\uf025'), + fa_volume_off('\uf026'), + fa_volume_down('\uf027'), + fa_volume_up('\uf028'), + fa_qrcode('\uf029'), + fa_barcode('\uf02a'), + fa_tag('\uf02b'), + fa_tags('\uf02c'), + fa_book('\uf02d'), + fa_bookmark('\uf02e'), + fa_print('\uf02f'), + fa_camera('\uf030'), + fa_font('\uf031'), + fa_bold('\uf032'), + fa_italic('\uf033'), + fa_text_height('\uf034'), + fa_text_width('\uf035'), + fa_align_left('\uf036'), + fa_align_center('\uf037'), + fa_align_right('\uf038'), + fa_align_justify('\uf039'), + fa_list('\uf03a'), + fa_dedent('\uf03b'), + fa_outdent('\uf03b'), + fa_indent('\uf03c'), + fa_video_camera('\uf03d'), + fa_photo('\uf03e'), + fa_image('\uf03e'), + fa_picture_o('\uf03e'), + fa_pencil('\uf040'), + fa_map_marker('\uf041'), + fa_adjust('\uf042'), + fa_tint('\uf043'), + fa_edit('\uf044'), + fa_pencil_square_o('\uf044'), + fa_share_square_o('\uf045'), + fa_check_square_o('\uf046'), + fa_arrows('\uf047'), + fa_step_backward('\uf048'), + fa_fast_backward('\uf049'), + fa_backward('\uf04a'), + fa_play('\uf04b'), + fa_pause('\uf04c'), + fa_stop('\uf04d'), + fa_forward('\uf04e'), + fa_fast_forward('\uf050'), + fa_step_forward('\uf051'), + fa_eject('\uf052'), + fa_chevron_left('\uf053'), + fa_chevron_right('\uf054'), + fa_plus_circle('\uf055'), + fa_minus_circle('\uf056'), + fa_times_circle('\uf057'), + fa_check_circle('\uf058'), + fa_question_circle('\uf059'), + fa_info_circle('\uf05a'), + fa_crosshairs('\uf05b'), + fa_times_circle_o('\uf05c'), + fa_check_circle_o('\uf05d'), + fa_ban('\uf05e'), + fa_arrow_left('\uf060'), + fa_arrow_right('\uf061'), + fa_arrow_up('\uf062'), + fa_arrow_down('\uf063'), + fa_mail_forward('\uf064'), + fa_share('\uf064'), + fa_expand('\uf065'), + fa_compress('\uf066'), + fa_plus('\uf067'), + fa_minus('\uf068'), + fa_asterisk('\uf069'), + fa_exclamation_circle('\uf06a'), + fa_gift('\uf06b'), + fa_leaf('\uf06c'), + fa_fire('\uf06d'), + fa_eye('\uf06e'), + fa_eye_slash('\uf070'), + fa_warning('\uf071'), + fa_exclamation_triangle('\uf071'), + fa_plane('\uf072'), + fa_calendar('\uf073'), + fa_random('\uf074'), + fa_comment('\uf075'), + fa_magnet('\uf076'), + fa_chevron_up('\uf077'), + fa_chevron_down('\uf078'), + fa_retweet('\uf079'), + fa_shopping_cart('\uf07a'), + fa_folder('\uf07b'), + fa_folder_open('\uf07c'), + fa_arrows_v('\uf07d'), + fa_arrows_h('\uf07e'), + fa_bar_chart_o('\uf080'), + fa_bar_chart('\uf080'), + fa_twitter_square('\uf081'), + fa_facebook_square('\uf082'), + fa_camera_retro('\uf083'), + fa_key('\uf084'), + fa_gears('\uf085'), + fa_cogs('\uf085'), + fa_comments('\uf086'), + fa_thumbs_o_up('\uf087'), + fa_thumbs_o_down('\uf088'), + fa_star_half('\uf089'), + fa_heart_o('\uf08a'), + fa_sign_out('\uf08b'), + fa_linkedin_square('\uf08c'), + fa_thumb_tack('\uf08d'), + fa_external_link('\uf08e'), + fa_sign_in('\uf090'), + fa_trophy('\uf091'), + fa_github_square('\uf092'), + fa_upload('\uf093'), + fa_lemon_o('\uf094'), + fa_phone('\uf095'), + fa_square_o('\uf096'), + fa_bookmark_o('\uf097'), + fa_phone_square('\uf098'), + fa_twitter('\uf099'), + fa_facebook_f('\uf09a'), + fa_facebook('\uf09a'), + fa_github('\uf09b'), + fa_unlock('\uf09c'), + fa_credit_card('\uf09d'), + fa_feed('\uf09e'), + fa_rss('\uf09e'), + fa_hdd_o('\uf0a0'), + fa_bullhorn('\uf0a1'), + fa_bell('\uf0f3'), + fa_certificate('\uf0a3'), + fa_hand_o_right('\uf0a4'), + fa_hand_o_left('\uf0a5'), + fa_hand_o_up('\uf0a6'), + fa_hand_o_down('\uf0a7'), + fa_arrow_circle_left('\uf0a8'), + fa_arrow_circle_right('\uf0a9'), + fa_arrow_circle_up('\uf0aa'), + fa_arrow_circle_down('\uf0ab'), + fa_globe('\uf0ac'), + fa_wrench('\uf0ad'), + fa_tasks('\uf0ae'), + fa_filter('\uf0b0'), + fa_briefcase('\uf0b1'), + fa_arrows_alt('\uf0b2'), + fa_group('\uf0c0'), + fa_users('\uf0c0'), + fa_chain('\uf0c1'), + fa_link('\uf0c1'), + fa_cloud('\uf0c2'), + fa_flask('\uf0c3'), + fa_cut('\uf0c4'), + fa_scissors('\uf0c4'), + fa_copy('\uf0c5'), + fa_files_o('\uf0c5'), + fa_paperclip('\uf0c6'), + fa_save('\uf0c7'), + fa_floppy_o('\uf0c7'), + fa_square('\uf0c8'), + fa_navicon('\uf0c9'), + fa_reorder('\uf0c9'), + fa_bars('\uf0c9'), + fa_list_ul('\uf0ca'), + fa_list_ol('\uf0cb'), + fa_strikethrough('\uf0cc'), + fa_underline('\uf0cd'), + fa_table('\uf0ce'), + fa_magic('\uf0d0'), + fa_truck('\uf0d1'), + fa_pinterest('\uf0d2'), + fa_pinterest_square('\uf0d3'), + fa_google_plus_square('\uf0d4'), + fa_google_plus('\uf0d5'), + fa_money('\uf0d6'), + fa_caret_down('\uf0d7'), + fa_caret_up('\uf0d8'), + fa_caret_left('\uf0d9'), + fa_caret_right('\uf0da'), + fa_columns('\uf0db'), + fa_unsorted('\uf0dc'), + fa_sort('\uf0dc'), + fa_sort_down('\uf0dd'), + fa_sort_desc('\uf0dd'), + fa_sort_up('\uf0de'), + fa_sort_asc('\uf0de'), + fa_envelope('\uf0e0'), + fa_linkedin('\uf0e1'), + fa_rotate_left('\uf0e2'), + fa_undo('\uf0e2'), + fa_legal('\uf0e3'), + fa_gavel('\uf0e3'), + fa_dashboard('\uf0e4'), + fa_tachometer('\uf0e4'), + fa_comment_o('\uf0e5'), + fa_comments_o('\uf0e6'), + fa_flash('\uf0e7'), + fa_bolt('\uf0e7'), + fa_sitemap('\uf0e8'), + fa_umbrella('\uf0e9'), + fa_paste('\uf0ea'), + fa_clipboard('\uf0ea'), + fa_lightbulb_o('\uf0eb'), + fa_exchange('\uf0ec'), + fa_cloud_download('\uf0ed'), + fa_cloud_upload('\uf0ee'), + fa_user_md('\uf0f0'), + fa_stethoscope('\uf0f1'), + fa_suitcase('\uf0f2'), + fa_bell_o('\uf0a2'), + fa_coffee('\uf0f4'), + fa_cutlery('\uf0f5'), + fa_file_text_o('\uf0f6'), + fa_building_o('\uf0f7'), + fa_hospital_o('\uf0f8'), + fa_ambulance('\uf0f9'), + fa_medkit('\uf0fa'), + fa_fighter_jet('\uf0fb'), + fa_beer('\uf0fc'), + fa_h_square('\uf0fd'), + fa_plus_square('\uf0fe'), + fa_angle_double_left('\uf100'), + fa_angle_double_right('\uf101'), + fa_angle_double_up('\uf102'), + fa_angle_double_down('\uf103'), + fa_angle_left('\uf104'), + fa_angle_right('\uf105'), + fa_angle_up('\uf106'), + fa_angle_down('\uf107'), + fa_desktop('\uf108'), + fa_laptop('\uf109'), + fa_tablet('\uf10a'), + fa_mobile_phone('\uf10b'), + fa_mobile('\uf10b'), + fa_circle_o('\uf10c'), + fa_quote_left('\uf10d'), + fa_quote_right('\uf10e'), + fa_spinner('\uf110'), + fa_circle('\uf111'), + fa_mail_reply('\uf112'), + fa_reply('\uf112'), + fa_github_alt('\uf113'), + fa_folder_o('\uf114'), + fa_folder_open_o('\uf115'), + fa_smile_o('\uf118'), + fa_frown_o('\uf119'), + fa_meh_o('\uf11a'), + fa_gamepad('\uf11b'), + fa_keyboard_o('\uf11c'), + fa_flag_o('\uf11d'), + fa_flag_checkered('\uf11e'), + fa_terminal('\uf120'), + fa_code('\uf121'), + fa_mail_reply_all('\uf122'), + fa_reply_all('\uf122'), + fa_star_half_empty('\uf123'), + fa_star_half_full('\uf123'), + fa_star_half_o('\uf123'), + fa_location_arrow('\uf124'), + fa_crop('\uf125'), + fa_code_fork('\uf126'), + fa_unlink('\uf127'), + fa_chain_broken('\uf127'), + fa_question('\uf128'), + fa_info('\uf129'), + fa_exclamation('\uf12a'), + fa_superscript('\uf12b'), + fa_subscript('\uf12c'), + fa_eraser('\uf12d'), + fa_puzzle_piece('\uf12e'), + fa_microphone('\uf130'), + fa_microphone_slash('\uf131'), + fa_shield('\uf132'), + fa_calendar_o('\uf133'), + fa_fire_extinguisher('\uf134'), + fa_rocket('\uf135'), + fa_maxcdn('\uf136'), + fa_chevron_circle_left('\uf137'), + fa_chevron_circle_right('\uf138'), + fa_chevron_circle_up('\uf139'), + fa_chevron_circle_down('\uf13a'), + fa_html5('\uf13b'), + fa_css3('\uf13c'), + fa_anchor('\uf13d'), + fa_unlock_alt('\uf13e'), + fa_bullseye('\uf140'), + fa_ellipsis_h('\uf141'), + fa_ellipsis_v('\uf142'), + fa_rss_square('\uf143'), + fa_play_circle('\uf144'), + fa_ticket('\uf145'), + fa_minus_square('\uf146'), + fa_minus_square_o('\uf147'), + fa_level_up('\uf148'), + fa_level_down('\uf149'), + fa_check_square('\uf14a'), + fa_pencil_square('\uf14b'), + fa_external_link_square('\uf14c'), + fa_share_square('\uf14d'), + fa_compass('\uf14e'), + fa_toggle_down('\uf150'), + fa_caret_square_o_down('\uf150'), + fa_toggle_up('\uf151'), + fa_caret_square_o_up('\uf151'), + fa_toggle_right('\uf152'), + fa_caret_square_o_right('\uf152'), + fa_euro('\uf153'), + fa_eur('\uf153'), + fa_gbp('\uf154'), + fa_dollar('\uf155'), + fa_usd('\uf155'), + fa_rupee('\uf156'), + fa_inr('\uf156'), + fa_cny('\uf157'), + fa_rmb('\uf157'), + fa_yen('\uf157'), + fa_jpy('\uf157'), + fa_ruble('\uf158'), + fa_rouble('\uf158'), + fa_rub('\uf158'), + fa_won('\uf159'), + fa_krw('\uf159'), + fa_bitcoin('\uf15a'), + fa_btc('\uf15a'), + fa_file('\uf15b'), + fa_file_text('\uf15c'), + fa_sort_alpha_asc('\uf15d'), + fa_sort_alpha_desc('\uf15e'), + fa_sort_amount_asc('\uf160'), + fa_sort_amount_desc('\uf161'), + fa_sort_numeric_asc('\uf162'), + fa_sort_numeric_desc('\uf163'), + fa_thumbs_up('\uf164'), + fa_thumbs_down('\uf165'), + fa_youtube_square('\uf166'), + fa_youtube('\uf167'), + fa_xing('\uf168'), + fa_xing_square('\uf169'), + fa_youtube_play('\uf16a'), + fa_dropbox('\uf16b'), + fa_stack_overflow('\uf16c'), + fa_instagram('\uf16d'), + fa_flickr('\uf16e'), + fa_adn('\uf170'), + fa_bitbucket('\uf171'), + fa_bitbucket_square('\uf172'), + fa_tumblr('\uf173'), + fa_tumblr_square('\uf174'), + fa_long_arrow_down('\uf175'), + fa_long_arrow_up('\uf176'), + fa_long_arrow_left('\uf177'), + fa_long_arrow_right('\uf178'), + fa_apple('\uf179'), + fa_windows('\uf17a'), + fa_android('\uf17b'), + fa_linux('\uf17c'), + fa_dribbble('\uf17d'), + fa_skype('\uf17e'), + fa_foursquare('\uf180'), + fa_trello('\uf181'), + fa_female('\uf182'), + fa_male('\uf183'), + fa_gittip('\uf184'), + fa_gratipay('\uf184'), + fa_sun_o('\uf185'), + fa_moon_o('\uf186'), + fa_archive('\uf187'), + fa_bug('\uf188'), + fa_vk('\uf189'), + fa_weibo('\uf18a'), + fa_renren('\uf18b'), + fa_pagelines('\uf18c'), + fa_stack_exchange('\uf18d'), + fa_arrow_circle_o_right('\uf18e'), + fa_arrow_circle_o_left('\uf190'), + fa_toggle_left('\uf191'), + fa_caret_square_o_left('\uf191'), + fa_dot_circle_o('\uf192'), + fa_wheelchair('\uf193'), + fa_vimeo_square('\uf194'), + fa_turkish_lira('\uf195'), + fa_try('\uf195'), + fa_plus_square_o('\uf196'), + fa_space_shuttle('\uf197'), + fa_slack('\uf198'), + fa_envelope_square('\uf199'), + fa_wordpress('\uf19a'), + fa_openid('\uf19b'), + fa_institution('\uf19c'), + fa_bank('\uf19c'), + fa_university('\uf19c'), + fa_mortar_board('\uf19d'), + fa_graduation_cap('\uf19d'), + fa_yahoo('\uf19e'), + fa_google('\uf1a0'), + fa_reddit('\uf1a1'), + fa_reddit_square('\uf1a2'), + fa_stumbleupon_circle('\uf1a3'), + fa_stumbleupon('\uf1a4'), + fa_delicious('\uf1a5'), + fa_digg('\uf1a6'), + fa_pied_piper('\uf1a7'), + fa_pied_piper_alt('\uf1a8'), + fa_drupal('\uf1a9'), + fa_joomla('\uf1aa'), + fa_language('\uf1ab'), + fa_fax('\uf1ac'), + fa_building('\uf1ad'), + fa_child('\uf1ae'), + fa_paw('\uf1b0'), + fa_spoon('\uf1b1'), + fa_cube('\uf1b2'), + fa_cubes('\uf1b3'), + fa_behance('\uf1b4'), + fa_behance_square('\uf1b5'), + fa_steam('\uf1b6'), + fa_steam_square('\uf1b7'), + fa_recycle('\uf1b8'), + fa_automobile('\uf1b9'), + fa_car('\uf1b9'), + fa_cab('\uf1ba'), + fa_taxi('\uf1ba'), + fa_tree('\uf1bb'), + fa_spotify('\uf1bc'), + fa_deviantart('\uf1bd'), + fa_soundcloud('\uf1be'), + fa_database('\uf1c0'), + fa_file_pdf_o('\uf1c1'), + fa_file_word_o('\uf1c2'), + fa_file_excel_o('\uf1c3'), + fa_file_powerpoint_o('\uf1c4'), + fa_file_photo_o('\uf1c5'), + fa_file_picture_o('\uf1c5'), + fa_file_image_o('\uf1c5'), + fa_file_zip_o('\uf1c6'), + fa_file_archive_o('\uf1c6'), + fa_file_sound_o('\uf1c7'), + fa_file_audio_o('\uf1c7'), + fa_file_movie_o('\uf1c8'), + fa_file_video_o('\uf1c8'), + fa_file_code_o('\uf1c9'), + fa_vine('\uf1ca'), + fa_codepen('\uf1cb'), + fa_jsfiddle('\uf1cc'), + fa_life_bouy('\uf1cd'), + fa_life_buoy('\uf1cd'), + fa_life_saver('\uf1cd'), + fa_support('\uf1cd'), + fa_life_ring('\uf1cd'), + fa_circle_o_notch('\uf1ce'), + fa_ra('\uf1d0'), + fa_rebel('\uf1d0'), + fa_ge('\uf1d1'), + fa_empire('\uf1d1'), + fa_git_square('\uf1d2'), + fa_git('\uf1d3'), + fa_y_combinator_square('\uf1d4'), + fa_yc_square('\uf1d4'), + fa_hacker_news('\uf1d4'), + fa_tencent_weibo('\uf1d5'), + fa_qq('\uf1d6'), + fa_wechat('\uf1d7'), + fa_weixin('\uf1d7'), + fa_send('\uf1d8'), + fa_paper_plane('\uf1d8'), + fa_send_o('\uf1d9'), + fa_paper_plane_o('\uf1d9'), + fa_history('\uf1da'), + fa_circle_thin('\uf1db'), + fa_header('\uf1dc'), + fa_paragraph('\uf1dd'), + fa_sliders('\uf1de'), + fa_share_alt('\uf1e0'), + fa_share_alt_square('\uf1e1'), + fa_bomb('\uf1e2'), + fa_soccer_ball_o('\uf1e3'), + fa_futbol_o('\uf1e3'), + fa_tty('\uf1e4'), + fa_binoculars('\uf1e5'), + fa_plug('\uf1e6'), + fa_slideshare('\uf1e7'), + fa_twitch('\uf1e8'), + fa_yelp('\uf1e9'), + fa_newspaper_o('\uf1ea'), + fa_wifi('\uf1eb'), + fa_calculator('\uf1ec'), + fa_paypal('\uf1ed'), + fa_google_wallet('\uf1ee'), + fa_cc_visa('\uf1f0'), + fa_cc_mastercard('\uf1f1'), + fa_cc_discover('\uf1f2'), + fa_cc_amex('\uf1f3'), + fa_cc_paypal('\uf1f4'), + fa_cc_stripe('\uf1f5'), + fa_bell_slash('\uf1f6'), + fa_bell_slash_o('\uf1f7'), + fa_trash('\uf1f8'), + fa_copyright('\uf1f9'), + fa_at('\uf1fa'), + fa_eyedropper('\uf1fb'), + fa_paint_brush('\uf1fc'), + fa_birthday_cake('\uf1fd'), + fa_area_chart('\uf1fe'), + fa_pie_chart('\uf200'), + fa_line_chart('\uf201'), + fa_lastfm('\uf202'), + fa_lastfm_square('\uf203'), + fa_toggle_off('\uf204'), + fa_toggle_on('\uf205'), + fa_bicycle('\uf206'), + fa_bus('\uf207'), + fa_ioxhost('\uf208'), + fa_angellist('\uf209'), + fa_cc('\uf20a'), + fa_shekel('\uf20b'), + fa_sheqel('\uf20b'), + fa_ils('\uf20b'), + fa_meanpath('\uf20c'), + fa_buysellads('\uf20d'), + fa_connectdevelop('\uf20e'), + fa_dashcube('\uf210'), + fa_forumbee('\uf211'), + fa_leanpub('\uf212'), + fa_sellsy('\uf213'), + fa_shirtsinbulk('\uf214'), + fa_simplybuilt('\uf215'), + fa_skyatlas('\uf216'), + fa_cart_plus('\uf217'), + fa_cart_arrow_down('\uf218'), + fa_diamond('\uf219'), + fa_ship('\uf21a'), + fa_user_secret('\uf21b'), + fa_motorcycle('\uf21c'), + fa_street_view('\uf21d'), + fa_heartbeat('\uf21e'), + fa_venus('\uf221'), + fa_mars('\uf222'), + fa_mercury('\uf223'), + fa_intersex('\uf224'), + fa_transgender('\uf224'), + fa_transgender_alt('\uf225'), + fa_venus_double('\uf226'), + fa_mars_double('\uf227'), + fa_venus_mars('\uf228'), + fa_mars_stroke('\uf229'), + fa_mars_stroke_v('\uf22a'), + fa_mars_stroke_h('\uf22b'), + fa_neuter('\uf22c'), + fa_genderless('\uf22d'), + fa_facebook_official('\uf230'), + fa_pinterest_p('\uf231'), + fa_whatsapp('\uf232'), + fa_server('\uf233'), + fa_user_plus('\uf234'), + fa_user_times('\uf235'), + fa_hotel('\uf236'), + fa_bed('\uf236'), + fa_viacoin('\uf237'), + fa_train('\uf238'), + fa_subway('\uf239'), + fa_medium('\uf23a'), + fa_yc('\uf23b'), + fa_y_combinator('\uf23b'), + fa_optin_monster('\uf23c'), + fa_opencart('\uf23d'), + fa_expeditedssl('\uf23e'), + fa_battery_4('\uf240'), + fa_battery_full('\uf240'), + fa_battery_3('\uf241'), + fa_battery_three_quarters('\uf241'), + fa_battery_2('\uf242'), + fa_battery_half('\uf242'), + fa_battery_1('\uf243'), + fa_battery_quarter('\uf243'), + fa_battery_0('\uf244'), + fa_battery_empty('\uf244'), + fa_mouse_pointer('\uf245'), + fa_i_cursor('\uf246'), + fa_object_group('\uf247'), + fa_object_ungroup('\uf248'), + fa_sticky_note('\uf249'), + fa_sticky_note_o('\uf24a'), + fa_cc_jcb('\uf24b'), + fa_cc_diners_club('\uf24c'), + fa_clone('\uf24d'), + fa_balance_scale('\uf24e'), + fa_hourglass_o('\uf250'), + fa_hourglass_1('\uf251'), + fa_hourglass_start('\uf251'), + fa_hourglass_2('\uf252'), + fa_hourglass_half('\uf252'), + fa_hourglass_3('\uf253'), + fa_hourglass_end('\uf253'), + fa_hourglass('\uf254'), + fa_hand_grab_o('\uf255'), + fa_hand_rock_o('\uf255'), + fa_hand_stop_o('\uf256'), + fa_hand_paper_o('\uf256'), + fa_hand_scissors_o('\uf257'), + fa_hand_lizard_o('\uf258'), + fa_hand_spock_o('\uf259'), + fa_hand_pointer_o('\uf25a'), + fa_hand_peace_o('\uf25b'), + fa_trademark('\uf25c'), + fa_registered('\uf25d'), + fa_creative_commons('\uf25e'), + fa_gg('\uf260'), + fa_gg_circle('\uf261'), + fa_tripadvisor('\uf262'), + fa_odnoklassniki('\uf263'), + fa_odnoklassniki_square('\uf264'), + fa_get_pocket('\uf265'), + fa_wikipedia_w('\uf266'), + fa_safari('\uf267'), + fa_chrome('\uf268'), + fa_firefox('\uf269'), + fa_opera('\uf26a'), + fa_internet_explorer('\uf26b'), + fa_tv('\uf26c'), + fa_television('\uf26c'), + fa_contao('\uf26d'), + fa_500px('\uf26e'), + fa_amazon('\uf270'), + fa_calendar_plus_o('\uf271'), + fa_calendar_minus_o('\uf272'), + fa_calendar_times_o('\uf273'), + fa_calendar_check_o('\uf274'), + fa_industry('\uf275'), + fa_map_pin('\uf276'), + fa_map_signs('\uf277'), + fa_map_o('\uf278'), + fa_map('\uf279'), + fa_commenting('\uf27a'), + fa_commenting_o('\uf27b'), + fa_houzz('\uf27c'), + fa_vimeo('\uf27d'), + fa_black_tie('\uf27e'), + fa_fonticons('\uf280'), + fa_reddit_alien('\uf281'), + fa_edge('\uf282'), + fa_credit_card_alt('\uf283'), + fa_codiepie('\uf284'), + fa_modx('\uf285'), + fa_fort_awesome('\uf286'), + fa_usb('\uf287'), + fa_product_hunt('\uf288'), + fa_mixcloud('\uf289'), + fa_scribd('\uf28a'), + fa_pause_circle('\uf28b'), + fa_pause_circle_o('\uf28c'), + fa_stop_circle('\uf28d'), + fa_stop_circle_o('\uf28e'), + fa_shopping_bag('\uf290'), + fa_shopping_basket('\uf291'), + fa_hashtag('\uf292'), + fa_bluetooth('\uf293'), + fa_bluetooth_b('\uf294'), + fa_percent('\uf295'); + + char character; + + FontAwesomeIcons(char character) { + this.character = character; + } + + @Override + public String key() { + return name().replace('_', '-'); + } + + @Override + public char character() { + return character; + } +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java b/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java new file mode 100644 index 0000000000..0f2dfce4d4 --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java @@ -0,0 +1,17 @@ +package com.joanzapata.iconify.fonts; + +import com.joanzapata.iconify.Icon; +import com.joanzapata.iconify.IconFontDescriptor; + +public class FontAwesomeModule implements IconFontDescriptor { + + @Override + public String ttfFileName() { + return "iconify/android-iconify-fontawesome.ttf"; + } + + @Override + public Icon[] characters() { + return FontAwesomeIcons.values(); + } +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java b/iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java new file mode 100644 index 0000000000..a07bb49ef3 --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java @@ -0,0 +1,88 @@ +package com.joanzapata.iconify.internal; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.text.style.ReplacementSpan; +import com.joanzapata.iconify.Icon; + +public class CustomTypefaceSpan extends ReplacementSpan { + private static final int ROTATION_DURATION = 2000; + private static final Rect TEXT_BOUNDS = new Rect(); + private static final Paint LOCAL_PAINT = new Paint(); + private static final float BASELINE_RATIO = 1 / 7f; + + private final String icon; + private final Typeface type; + private final float iconSizePx; + private final float iconSizeRatio; + private final int iconColor; + private final boolean rotate; + private final boolean baselineAligned; + private final long rotationStartTime; + + public CustomTypefaceSpan(Icon icon, Typeface type, + float iconSizePx, float iconSizeRatio, int iconColor, + boolean rotate, boolean baselineAligned) { + this.rotate = rotate; + this.baselineAligned = baselineAligned; + this.icon = String.valueOf(icon.character()); + this.type = type; + this.iconSizePx = iconSizePx; + this.iconSizeRatio = iconSizeRatio; + this.iconColor = iconColor; + this.rotationStartTime = System.currentTimeMillis(); + } + + @Override + public int getSize(Paint paint, CharSequence text, + int start, int end, Paint.FontMetricsInt fm) { + LOCAL_PAINT.set(paint); + applyCustomTypeFace(LOCAL_PAINT, type); + LOCAL_PAINT.getTextBounds(icon, 0, 1, TEXT_BOUNDS); + if (fm != null) { + float baselineRatio = baselineAligned ? 0 : BASELINE_RATIO; + fm.descent = (int) (TEXT_BOUNDS.height() * baselineRatio); + fm.ascent = -(TEXT_BOUNDS.height() - fm.descent); + fm.top = fm.ascent; + fm.bottom = fm.descent; + } + return TEXT_BOUNDS.width(); + } + + @Override + public void draw(Canvas canvas, CharSequence text, + int start, int end, float x, int top, int y, + int bottom, Paint paint) { + applyCustomTypeFace(paint, type); + paint.getTextBounds(icon, 0, 1, TEXT_BOUNDS); + canvas.save(); + float baselineRatio = baselineAligned ? 0f : BASELINE_RATIO; + if (rotate) { + float rotation = (System.currentTimeMillis() - rotationStartTime) / (float) ROTATION_DURATION * 360f; + float centerX = x + TEXT_BOUNDS.width() / 2f; + float centerY = y - TEXT_BOUNDS.height() / 2f + TEXT_BOUNDS.height() * baselineRatio; + canvas.rotate(rotation, centerX, centerY); + } + + canvas.drawText(icon, + x - TEXT_BOUNDS.left, + y - TEXT_BOUNDS.bottom + TEXT_BOUNDS.height() * baselineRatio, paint); + canvas.restore(); + } + + public boolean isAnimated() { + return rotate; + } + + private void applyCustomTypeFace(Paint paint, Typeface tf) { + paint.setFakeBoldText(false); + paint.setTextSkewX(0f); + paint.setTypeface(tf); + if (rotate) paint.clearShadowLayer(); + if (iconSizeRatio > 0) paint.setTextSize(paint.getTextSize() * iconSizeRatio); + else if (iconSizePx > 0) paint.setTextSize(iconSizePx); + if (iconColor < Integer.MAX_VALUE) paint.setColor(iconColor); + } +} \ No newline at end of file diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java b/iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java new file mode 100644 index 0000000000..773c2a6949 --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java @@ -0,0 +1,82 @@ +package com.joanzapata.iconify.internal; + +import android.widget.TextView; + +import androidx.core.view.ViewCompat; + +/** + * Any TextView subclass that wishes to call {@link com.joanzapata.iconify.Iconify#addIcons(TextView...)} on it + * needs to implement this interface if it ever want to use spinning icons. + *
+ * IconTextView, IconButton and IconToggleButton already implement it, but if you need to implement it + * yourself, please use {@link com.joanzapata.iconify.internal.HasOnViewAttachListener.HasOnViewAttachListenerDelegate} + * to help you. + */ +public interface HasOnViewAttachListener { + void setOnViewAttachListener(OnViewAttachListener listener); + + interface OnViewAttachListener { + void onAttach(); + + void onDetach(); + } + + /** + * Helper class to implement {@link HasOnViewAttachListener}. + * Usual implementation should look like this: + *

+     * {@code
+     * class MyClass extends TextView implements HasOnViewAttachListener {
+     *
+     *       private HasOnViewAttachListenerDelegate delegate
+     *
+     *       @Override
+     *       public void setOnViewAttachListener(OnViewAttachListener listener) {
+     *          if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this);
+     *          delegate.setOnViewAttachListener(listener);
+     *       }
+     *
+     *       @Override
+     *       protected void onAttachedToWindow() {
+     *          super.onAttachedToWindow();
+     *          delegate.onAttachedToWindow();
+     *       }
+     *
+     *       @Override
+     *       protected void onDetachedFromWindow() {
+     *          super.onDetachedFromWindow();
+     *          delegate.onDetachedFromWindow();
+     *      }
+     *
+     *  }
+     * }
+     * 
+ */ + class HasOnViewAttachListenerDelegate { + + private final TextView view; + private OnViewAttachListener listener; + + public HasOnViewAttachListenerDelegate(TextView view) { + this.view = view; + } + + public void setOnViewAttachListener(OnViewAttachListener listener) { + if (this.listener != null) + this.listener.onDetach(); + this.listener = listener; + if (ViewCompat.isAttachedToWindow(view) && listener != null) { + listener.onAttach(); + } + } + + public void onAttachedToWindow() { + if (listener != null) listener.onAttach(); + } + + public void onDetachedFromWindow() { + if (listener != null) listener.onDetach(); + } + + } +} \ No newline at end of file diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java b/iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java new file mode 100644 index 0000000000..b7e1d0045b --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java @@ -0,0 +1,49 @@ +package com.joanzapata.iconify.internal; + +import android.content.Context; +import android.graphics.Typeface; +import com.joanzapata.iconify.Icon; +import com.joanzapata.iconify.IconFontDescriptor; + +import java.util.HashMap; +import java.util.Map; + +public class IconFontDescriptorWrapper { + + private final IconFontDescriptor iconFontDescriptor; + + private final Map iconsByKey; + + private Typeface cachedTypeface; + + public IconFontDescriptorWrapper(IconFontDescriptor iconFontDescriptor) { + this.iconFontDescriptor = iconFontDescriptor; + iconsByKey = new HashMap(); + Icon[] characters = iconFontDescriptor.characters(); + for (int i = 0, charactersLength = characters.length; i < charactersLength; i++) { + Icon icon = characters[i]; + iconsByKey.put(icon.key(), icon); + } + } + + public Icon getIcon(String key) { + return iconsByKey.get(key); + } + + public IconFontDescriptor getIconFontDescriptor() { + return iconFontDescriptor; + } + + public Typeface getTypeface(Context context) { + if (cachedTypeface != null) return cachedTypeface; + synchronized (this) { + if (cachedTypeface != null) return cachedTypeface; + cachedTypeface = Typeface.createFromAsset(context.getAssets(), iconFontDescriptor.ttfFileName()); + return cachedTypeface; + } + } + + public boolean hasIcon(Icon icon) { + return iconsByKey.values().contains(icon); + } +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java b/iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java new file mode 100644 index 0000000000..574e7bbedf --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java @@ -0,0 +1,217 @@ +package com.joanzapata.iconify.internal; + +import java.util.List; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Color; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.util.TypedValue; +import android.widget.TextView; + +import androidx.core.view.ViewCompat; + +import com.joanzapata.iconify.Icon; +import com.joanzapata.iconify.internal.HasOnViewAttachListener.OnViewAttachListener; + +public final class ParsingUtil { + + private static final String ANDROID_PACKAGE_NAME = "android"; + + // Prevents instantiation + private ParsingUtil() {} + + public static CharSequence parse( + Context context, + List iconFontDescriptors, + CharSequence text, + final TextView target) { + context = context.getApplicationContext(); + + // Don't do anything related to iconify if text is null + if (text == null) return text; + + // Analyse the text and replace {} blocks with the appropriate character + // Retain all transformations in the accumulator + final SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(text); + recursivePrepareSpannableIndexes(context, + text.toString(), spannableBuilder, + iconFontDescriptors, 0); + boolean isAnimated = hasAnimatedSpans(spannableBuilder); + + // If animated, periodically invalidate the TextView so that the + // CustomTypefaceSpan can redraw itself + if (isAnimated) { + if (target == null) + throw new IllegalArgumentException("You can't use \"spin\" without providing the target TextView."); + if (!(target instanceof HasOnViewAttachListener)) + throw new IllegalArgumentException(target.getClass().getSimpleName() + " does not implement " + + "HasOnViewAttachListener. Please use IconTextView, IconButton or IconToggleButton."); + + ((HasOnViewAttachListener) target).setOnViewAttachListener(new OnViewAttachListener() { + boolean isAttached = false; + + @Override + public void onAttach() { + isAttached = true; + ViewCompat.postOnAnimation(target, new Runnable() { + @Override + public void run() { + if (isAttached) { + target.invalidate(); + ViewCompat.postOnAnimation(target, this); + } + } + }); + } + + @Override + public void onDetach() { + isAttached = false; + } + }); + + } else if (target instanceof HasOnViewAttachListener) { + ((HasOnViewAttachListener) target).setOnViewAttachListener(null); + } + + return spannableBuilder; + } + + private static boolean hasAnimatedSpans(SpannableStringBuilder spannableBuilder) { + CustomTypefaceSpan[] spans = spannableBuilder.getSpans(0, spannableBuilder.length(), CustomTypefaceSpan.class); + for (CustomTypefaceSpan span : spans) { + if (span.isAnimated()) + return true; + } + return false; + } + + private static void recursivePrepareSpannableIndexes( + Context context, + String fullText, + SpannableStringBuilder text, + List iconFontDescriptors, + int start) { + + // Try to find a {...} in the string and extract expression from it + String stringText = text.toString(); + int startIndex = stringText.indexOf("{", start); + if (startIndex == -1) return; + int endIndex = stringText.indexOf("}", startIndex) + 1; + if (endIndex == -1) return; + String expression = stringText.substring(startIndex + 1, endIndex - 1); + + // Split the expression and retrieve the icon key + String[] strokes = expression.split(" "); + String key = strokes[0]; + + // Loop through the descriptors to find a key match + IconFontDescriptorWrapper iconFontDescriptor = null; + Icon icon = null; + for (int i = 0; i < iconFontDescriptors.size(); i++) { + iconFontDescriptor = iconFontDescriptors.get(i); + icon = iconFontDescriptor.getIcon(key); + if (icon != null) break; + } + + // If no match, ignore and continue + if (icon == null) { + recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, endIndex); + return; + } + + // See if any more stroke within {} should be applied + float iconSizePx = -1; + int iconColor = Integer.MAX_VALUE; + float iconSizeRatio = -1; + boolean spin = false; + boolean baselineAligned = false; + for (int i = 1; i < strokes.length; i++) { + String stroke = strokes[i]; + + // Look for "spin" + if (stroke.equalsIgnoreCase("spin")) { + spin = true; + } + + // Look for "baseline" + else if (stroke.equalsIgnoreCase("baseline")) { + baselineAligned = true; + } + + // Look for an icon size + else if (stroke.matches("([0-9]*(\\.[0-9]*)?)dp")) { + iconSizePx = dpToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2))); + } else if (stroke.matches("([0-9]*(\\.[0-9]*)?)sp")) { + iconSizePx = spToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2))); + } else if (stroke.matches("([0-9]*)px")) { + iconSizePx = Integer.valueOf(stroke.substring(0, stroke.length() - 2)); + } else if (stroke.matches("@dimen/(.*)")) { + iconSizePx = getPxFromDimen(context, context.getPackageName(), stroke.substring(7)); + if (iconSizePx < 0) + throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); + } else if (stroke.matches("@android:dimen/(.*)")) { + iconSizePx = getPxFromDimen(context, ANDROID_PACKAGE_NAME, stroke.substring(15)); + if (iconSizePx < 0) + throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); + } else if (stroke.matches("([0-9]*(\\.[0-9]*)?)%")) { + iconSizeRatio = Float.valueOf(stroke.substring(0, stroke.length() - 1)) / 100f; + } + + // Look for an icon color + else if (stroke.matches("#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})")) { + iconColor = Color.parseColor(stroke); + } else if (stroke.matches("@color/(.*)")) { + iconColor = getColorFromResource(context, context.getPackageName(), stroke.substring(7)); + if (iconColor == Integer.MAX_VALUE) + throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); + } else if (stroke.matches("@android:color/(.*)")) { + iconColor = getColorFromResource(context, ANDROID_PACKAGE_NAME, stroke.substring(15)); + if (iconColor == Integer.MAX_VALUE) + throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); + } else { + throw new IllegalArgumentException("Unknown expression " + stroke + " in \"" + fullText + "\""); + } + } + + // Replace the character and apply the typeface + text = text.replace(startIndex, endIndex, "" + icon.character()); + text.setSpan(new CustomTypefaceSpan(icon, + iconFontDescriptor.getTypeface(context), + iconSizePx, iconSizeRatio, iconColor, spin, baselineAligned), + startIndex, startIndex + 1, + Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, startIndex); + } + + public static float getPxFromDimen(Context context, String packageName, String resName) { + Resources resources = context.getResources(); + int resId = resources.getIdentifier( + resName, "dimen", + packageName); + if (resId <= 0) return -1; + return resources.getDimension(resId); + } + + public static int getColorFromResource(Context context, String packageName, String resName) { + Resources resources = context.getResources(); + int resId = resources.getIdentifier( + resName, "color", + packageName); + if (resId <= 0) return Integer.MAX_VALUE; + return resources.getColor(resId); + } + + public static float dpToPx(Context context, float dp) { + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, + context.getResources().getDisplayMetrics()); + } + + public static float spToPx(Context context, float sp) { + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, + context.getResources().getDisplayMetrics()); + } + +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java b/iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java new file mode 100644 index 0000000000..8f5ee12ecf --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java @@ -0,0 +1,55 @@ +package com.joanzapata.iconify.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.Button; +import com.joanzapata.iconify.Iconify; +import com.joanzapata.iconify.internal.HasOnViewAttachListener; + +public class IconButton extends Button implements HasOnViewAttachListener { + + private HasOnViewAttachListenerDelegate delegate; + + public IconButton(Context context) { + super(context); + init(); + } + + public IconButton(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public IconButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + setTransformationMethod(null); + } + + @Override + public void setText(CharSequence text, BufferType type) { + super.setText(Iconify.compute(getContext(), text, this), type); + } + + + @Override + public void setOnViewAttachListener(HasOnViewAttachListener.OnViewAttachListener listener) { + if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this); + delegate.setOnViewAttachListener(listener); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + delegate.onAttachedToWindow(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + delegate.onDetachedFromWindow(); + } +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java b/iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java new file mode 100644 index 0000000000..00a3b04c54 --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java @@ -0,0 +1,54 @@ +package com.joanzapata.iconify.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.TextView; +import com.joanzapata.iconify.Iconify; +import com.joanzapata.iconify.internal.HasOnViewAttachListener; + +public class IconTextView extends TextView implements HasOnViewAttachListener { + + private HasOnViewAttachListenerDelegate delegate; + + public IconTextView(Context context) { + super(context); + init(); + } + + public IconTextView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public IconTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + setTransformationMethod(null); + } + + @Override + public void setText(CharSequence text, BufferType type) { + super.setText(Iconify.compute(getContext(), text, this), type); + } + + @Override + public void setOnViewAttachListener(OnViewAttachListener listener) { + if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this); + delegate.setOnViewAttachListener(listener); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + delegate.onAttachedToWindow(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + delegate.onDetachedFromWindow(); + } +} diff --git a/iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java b/iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java new file mode 100644 index 0000000000..4bdb9ed5fe --- /dev/null +++ b/iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java @@ -0,0 +1,55 @@ +package com.joanzapata.iconify.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ToggleButton; +import com.joanzapata.iconify.Iconify; +import com.joanzapata.iconify.internal.HasOnViewAttachListener; + +public class IconToggleButton extends ToggleButton implements HasOnViewAttachListener { + + private HasOnViewAttachListenerDelegate delegate; + + public IconToggleButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + public IconToggleButton(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public IconToggleButton(Context context) { + super(context); + init(); + } + + private void init() { + setTransformationMethod(null); + } + + @Override + public void setText(CharSequence text, BufferType type) { + super.setText(Iconify.compute(getContext(), text, this), BufferType.NORMAL); + } + + @Override + public void setOnViewAttachListener(HasOnViewAttachListener.OnViewAttachListener listener) { + if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this); + delegate.setOnViewAttachListener(listener); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + delegate.onAttachedToWindow(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + delegate.onDetachedFromWindow(); + } + +} diff --git a/medtronic/build.gradle b/medtronic/build.gradle index 89b2f37c51..de6506e40d 100644 --- a/medtronic/build.gradle +++ b/medtronic/build.gradle @@ -17,4 +17,5 @@ dependencies { implementation project(':pump-common') implementation project(':rileylink') implementation project(':shared') + implementation project(':iconify') } diff --git a/omnipod-common/build.gradle b/omnipod-common/build.gradle index 3d4aab407b..e1fccf18b1 100644 --- a/omnipod-common/build.gradle +++ b/omnipod-common/build.gradle @@ -16,4 +16,5 @@ android { dependencies { implementation project(':core') implementation project(':shared') + implementation project(':iconify') } \ No newline at end of file diff --git a/omnipod-dash/build.gradle b/omnipod-dash/build.gradle index 631dec2207..307befd0aa 100644 --- a/omnipod-dash/build.gradle +++ b/omnipod-dash/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation project(':omnipod-common') implementation project(':database') implementation project(':shared') + implementation project(':iconify') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/omnipod-eros/build.gradle b/omnipod-eros/build.gradle index a748715b9d..595ed441d0 100644 --- a/omnipod-eros/build.gradle +++ b/omnipod-eros/build.gradle @@ -29,7 +29,7 @@ dependencies { implementation project(':rileylink') implementation project(':database') implementation project(':shared') - + implementation project(':iconify') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/settings.gradle b/settings.gradle index db9ca9d97f..20cc1cc2b6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,3 +18,4 @@ include ':diaconn' include ':openhumans' include ':shared' +include ':iconify' From 6e33d354c74ee26b69dff90f936c55f3cc0fd0b0 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 26 Oct 2022 14:13:08 +0200 Subject: [PATCH 39/77] GraphView 4.0.1 as a module (no support library) --- app/build.gradle | 1 + automation/build.gradle | 1 + core/build.gradle | 1 + core/core_dependencies.gradle | 3 - graphview/.gitignore | 1 + graphview/build.gradle | 20 + graphview/consumer-rules.pro | 0 graphview/proguard-rules.pro | 21 + graphview/src/main/AndroidManifest.xml | 4 + .../graphview/DefaultLabelFormatter.java | 105 ++ .../java/com/jjoe64/graphview/GraphView.java | 548 ++++++ .../jjoe64/graphview/GridLabelRenderer.java | 1467 +++++++++++++++++ .../com/jjoe64/graphview/LabelFormatter.java | 54 + .../com/jjoe64/graphview/LegendRenderer.java | 394 +++++ .../com/jjoe64/graphview/SecondScale.java | 165 ++ .../jjoe64/graphview/ValueDependentColor.java | 41 + .../java/com/jjoe64/graphview/Viewport.java | 996 +++++++++++ .../graphview/compat/OverScrollerCompat.java | 46 + .../helper/DateAsXAxisLabelFormatter.java | 94 ++ .../jjoe64/graphview/helper/GraphViewXML.java | 137 ++ .../helper/StaticLabelsFormatter.java | 209 +++ .../graphview/series/BarGraphSeries.java | 379 +++++ .../jjoe64/graphview/series/BaseSeries.java | 448 +++++ .../jjoe64/graphview/series/DataPoint.java | 63 + .../graphview/series/DataPointInterface.java | 41 + .../graphview/series/LineGraphSeries.java | 409 +++++ .../series/OnDataPointTapListener.java | 38 + .../graphview/series/PointsGraphSeries.java | 312 ++++ .../com/jjoe64/graphview/series/Series.java | 125 ++ graphview/src/main/res/values/attr.xml | 10 + settings.gradle | 1 + 31 files changed, 6131 insertions(+), 3 deletions(-) create mode 100644 graphview/.gitignore create mode 100644 graphview/build.gradle create mode 100644 graphview/consumer-rules.pro create mode 100644 graphview/proguard-rules.pro create mode 100644 graphview/src/main/AndroidManifest.xml create mode 100644 graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/GraphView.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/SecondScale.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/Viewport.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/Series.java create mode 100644 graphview/src/main/res/values/attr.xml diff --git a/app/build.gradle b/app/build.gradle index bb72725052..51246830f1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -170,6 +170,7 @@ dependencies { wearApp project(':wear') implementation project(':iconify') + implementation project(':graphview') implementation project(':shared') implementation project(':core') implementation project(':automation') diff --git a/automation/build.gradle b/automation/build.gradle index e1107c676f..f778782309 100644 --- a/automation/build.gradle +++ b/automation/build.gradle @@ -17,4 +17,5 @@ dependencies { implementation project(':core') implementation project(':database') implementation project(':shared') + implementation project(':graphview') } \ No newline at end of file diff --git a/core/build.gradle b/core/build.gradle index f1b51650c2..567918dc1b 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -14,6 +14,7 @@ apply from: "${project.rootDir}/core/jacoco_global.gradle" dependencies { implementation project(':shared') implementation project(':database') + implementation project(':graphview') } android { diff --git a/core/core_dependencies.gradle b/core/core_dependencies.gradle index 320e025b5c..60ef09a37d 100644 --- a/core/core_dependencies.gradle +++ b/core/core_dependencies.gradle @@ -46,9 +46,6 @@ dependencies { api 'com.madgag.spongycastle:core:1.58.0.0' api "com.google.crypto.tink:tink-android:$tink_version" - // Graphview cannot be upgraded - api "com.jjoe64:graphview:4.0.1" - //db api "com.j256.ormlite:ormlite-core:$ormLite_version" api "com.j256.ormlite:ormlite-android:$ormLite_version" diff --git a/graphview/.gitignore b/graphview/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/graphview/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/graphview/build.gradle b/graphview/build.gradle new file mode 100644 index 0000000000..e1138b7d40 --- /dev/null +++ b/graphview/build.gradle @@ -0,0 +1,20 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-allopen' +apply plugin: 'com.hiya.jacoco-android' +apply plugin: 'kotlinx-serialization' + +apply from: "${project.rootDir}/core/android_dependencies.gradle" +apply from: "${project.rootDir}/core/android_module_dependencies.gradle" +apply from: "${project.rootDir}/core/test_dependencies.gradle" +apply from: "${project.rootDir}/core/jacoco_global.gradle" + +android { + + namespace 'com.jjoe64.graphview' +} + +dependencies { + api "androidx.core:core-ktx:$core_version" +} \ No newline at end of file diff --git a/graphview/consumer-rules.pro b/graphview/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graphview/proguard-rules.pro b/graphview/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/graphview/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/graphview/src/main/AndroidManifest.xml b/graphview/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a5918e68ab --- /dev/null +++ b/graphview/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java new file mode 100644 index 0000000000..0a761e2d73 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java @@ -0,0 +1,105 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import java.text.NumberFormat; + +/** + * The label formatter that will be used + * by default. + * It will use the NumberFormat from Android + * and sets the maximal fraction digits + * depending on the range between min and max + * value of the current viewport. + * + * It is recommended to use this label formatter + * as base class to implement a custom formatter. + * + * @author jjoe64 + */ +public class DefaultLabelFormatter implements LabelFormatter { + /** + * number formatter for x and y values + */ + protected NumberFormat[] mNumberFormatter = new NumberFormat[2]; + + /** + * reference to the viewport of the + * graph. + * Will be used to calculate the current + * range of values. + */ + protected Viewport mViewport; + + /** + * uses the default number format for the labels + */ + public DefaultLabelFormatter() { + } + + /** + * use custom number format + * + * @param xFormat the number format for the x labels + * @param yFormat the number format for the y labels + */ + public DefaultLabelFormatter(NumberFormat xFormat, NumberFormat yFormat) { + mNumberFormatter[0] = yFormat; + mNumberFormatter[1] = xFormat; + } + + /** + * @param viewport the viewport of the graph + */ + @Override + public void setViewport(Viewport viewport) { + mViewport = viewport; + } + + /** + * Formats the raw value to a nice + * looking label, depending on the + * current range of the viewport. + * + * @param value raw value + * @param isValueX true if it's a x value, otherwise false + * @return the formatted value as string + */ + public String formatLabel(double value, boolean isValueX) { + int i = isValueX ? 1 : 0; + if (mNumberFormatter[i] == null) { + mNumberFormatter[i] = NumberFormat.getNumberInstance(); + double highestvalue = isValueX ? mViewport.getMaxX(false) : mViewport.getMaxY(false); + double lowestvalue = isValueX ? mViewport.getMinX(false) : mViewport.getMinY(false); + if (highestvalue - lowestvalue < 0.1) { + mNumberFormatter[i].setMaximumFractionDigits(6); + } else if (highestvalue - lowestvalue < 1) { + mNumberFormatter[i].setMaximumFractionDigits(4); + } else if (highestvalue - lowestvalue < 20) { + mNumberFormatter[i].setMaximumFractionDigits(3); + } else if (highestvalue - lowestvalue < 100) { + mNumberFormatter[i].setMaximumFractionDigits(1); + } else { + mNumberFormatter[i].setMaximumFractionDigits(0); + } + } + return mNumberFormatter[i].format(value); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/GraphView.java b/graphview/src/main/java/com/jjoe64/graphview/GraphView.java new file mode 100644 index 0000000000..51debe1eef --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/GraphView.java @@ -0,0 +1,548 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.PointF; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +import com.jjoe64.graphview.series.Series; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author jjoe64 + * @version 4.0.0 + */ +public class GraphView extends View { + /** + * Class to wrap style options that are general + * to graphs. + * + * @author jjoe64 + */ + private static final class Styles { + /** + * The font size of the title that can be displayed + * above the graph. + * + * @see GraphView#setTitle(String) + */ + float titleTextSize; + + /** + * The font color of the title that can be displayed + * above the graph. + * + * @see GraphView#setTitle(String) + */ + int titleColor; + } + + /** + * Helper class to detect tap events on the + * graph. + * + * @author jjoe64 + */ + private class TapDetector { + /** + * save the time of the last down event + */ + private long lastDown; + + /** + * point of the tap down event + */ + private PointF lastPoint; + + /** + * to be called to process the events + * + * @param event + * @return true if there was a tap event. otherwise returns false. + */ + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + lastDown = System.currentTimeMillis(); + lastPoint = new PointF(event.getX(), event.getY()); + } else if (lastDown > 0 && event.getAction() == MotionEvent.ACTION_MOVE) { + if (Math.abs(event.getX() - lastPoint.x) > 60 + || Math.abs(event.getY() - lastPoint.y) > 60) { + lastDown = 0; + } + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - lastDown < 400) { + return true; + } + } + return false; + } + } + + /** + * our series (this does not contain the series + * that can be displayed on the right side. The + * right side series is a special feature of + * the {@link SecondScale} feature. + */ + private List mSeries; + + /** + * the renderer for the grid and labels + */ + private GridLabelRenderer mGridLabelRenderer; + + /** + * viewport that holds the current bounds of + * view. + */ + private Viewport mViewport; + + /** + * title of the graph that will be shown above + */ + private String mTitle; + + /** + * wraps the general styles + */ + private Styles mStyles; + + /** + * feature to have a second scale e.g. on the + * right side + */ + protected SecondScale mSecondScale; + + /** + * tap detector + */ + private TapDetector mTapDetector; + + /** + * renderer for the legend + */ + private LegendRenderer mLegendRenderer; + + /** + * paint for the graph title + */ + private Paint mPaintTitle; + + /** + * paint for the preview (in the SDK) + */ + private Paint mPreviewPaint; + + /** + * Initialize the GraphView view + * @param context + */ + public GraphView(Context context) { + super(context); + init(); + } + + /** + * Initialize the GraphView view. + * + * @param context + * @param attrs + */ + public GraphView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * Initialize the GraphView view + * + * @param context + * @param attrs + * @param defStyle + */ + public GraphView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + /** + * initialize the internal objects. + * This method has to be called directly + * in the constructors. + */ + protected void init() { + mPreviewPaint = new Paint(); + mPreviewPaint.setTextAlign(Paint.Align.CENTER); + mPreviewPaint.setColor(Color.BLACK); + mPreviewPaint.setTextSize(50); + + mStyles = new Styles(); + mViewport = new Viewport(this); + mGridLabelRenderer = new GridLabelRenderer(this); + mLegendRenderer = new LegendRenderer(this); + + mSeries = new ArrayList(); + mPaintTitle = new Paint(); + + mTapDetector = new TapDetector(); + + loadStyles(); + } + + /** + * loads the font + */ + protected void loadStyles() { + mStyles.titleColor = mGridLabelRenderer.getHorizontalLabelsColor(); + mStyles.titleTextSize = mGridLabelRenderer.getTextSize(); + } + + /** + * @return the renderer for the grid and labels + */ + public GridLabelRenderer getGridLabelRenderer() { + return mGridLabelRenderer; + } + + /** + * Add a new series to the graph. This will + * automatically redraw the graph. + * @param s the series to be added + */ + public void addSeries(Series s) { + s.onGraphViewAttached(this); + mSeries.add(s); + onDataChanged(false, false); + } + + /** + * important: do not do modifications on the list + * object that will be returned. + * Use {@link #removeSeries(com.jjoe64.graphview.series.Series)} and {@link #addSeries(com.jjoe64.graphview.series.Series)} + * + * @return all series + */ + public List getSeries() { + // TODO immutable array + return mSeries; + } + + /** + * call this to let the graph redraw and + * recalculate the viewport. + * This will be called when a new series + * was added or removed and when data + * was appended via {@link com.jjoe64.graphview.series.BaseSeries#appendData(com.jjoe64.graphview.series.DataPointInterface, boolean, int)} + * or {@link com.jjoe64.graphview.series.BaseSeries#resetData(com.jjoe64.graphview.series.DataPointInterface[])}. + * + * @param keepLabelsSize true if you don't want + * to recalculate the size of + * the labels. It is recommended + * to use "true" because this will + * improve performance and prevent + * a flickering. + * @param keepViewport true if you don't want that + * the viewport will be recalculated. + * It is recommended to use "true" for + * performance. + */ + public void onDataChanged(boolean keepLabelsSize, boolean keepViewport) { + // adjust grid system + mViewport.calcCompleteRange(); + mGridLabelRenderer.invalidate(keepLabelsSize, keepViewport); + invalidate(); + } + + /** + * will be called from Android system. + * + * @param canvas Canvas + */ + @Override + protected void onDraw(Canvas canvas) { + if (isInEditMode()) { + canvas.drawColor(Color.rgb(200, 200, 200)); + canvas.drawText("GraphView: No Preview available", canvas.getWidth()/2, canvas.getHeight()/2, mPreviewPaint); + } else { + drawTitle(canvas); + mViewport.drawFirst(canvas); + mGridLabelRenderer.draw(canvas); + for (Series s : mSeries) { + s.draw(this, canvas, false); + } + if (mSecondScale != null) { + for (Series s : mSecondScale.getSeries()) { + s.draw(this, canvas, true); + } + } + mViewport.draw(canvas); + mLegendRenderer.draw(canvas); + } + } + + /** + * Draws the Graphs title that will be + * shown above the viewport. + * Will be called by GraphView. + * + * @param canvas Canvas + */ + protected void drawTitle(Canvas canvas) { + if (mTitle != null && mTitle.length()>0) { + mPaintTitle.setColor(mStyles.titleColor); + mPaintTitle.setTextSize(mStyles.titleTextSize); + mPaintTitle.setTextAlign(Paint.Align.CENTER); + float x = canvas.getWidth()/2; + float y = mPaintTitle.getTextSize(); + canvas.drawText(mTitle, x, y, mPaintTitle); + } + } + + /** + * Calculates the height of the title. + * + * @return the actual size of the title. + * if there is no title, 0 will be + * returned. + */ + protected int getTitleHeight() { + if (mTitle != null && mTitle.length()>0) { + return (int) mPaintTitle.getTextSize(); + } else { + return 0; + } + } + + /** + * @return the viewport of the Graph. + * @see com.jjoe64.graphview.Viewport + */ + public Viewport getViewport() { + return mViewport; + } + + /** + * Called by Android system if the size + * of the view was changed. Will recalculate + * the viewport and labels. + * + * @param w + * @param h + * @param oldw + * @param oldh + */ + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + onDataChanged(false, false); + } + + /** + * @return the space on the left side of the + * view from the left border to the + * beginning of the graph viewport. + */ + public int getGraphContentLeft() { + int border = getGridLabelRenderer().getStyles().padding; + return border + getGridLabelRenderer().getLabelVerticalWidth() + getGridLabelRenderer().getVerticalAxisTitleWidth(); + } + + /** + * @return the space on the top of the + * view from the top border to the + * beginning of the graph viewport. + */ + public int getGraphContentTop() { + int border = getGridLabelRenderer().getStyles().padding + getTitleHeight(); + return border; + } + + /** + * @return the height of the graph viewport. + */ + public int getGraphContentHeight() { + int border = getGridLabelRenderer().getStyles().padding; + int graphheight = getHeight() - (2 * border) - getGridLabelRenderer().getLabelHorizontalHeight() - getTitleHeight(); + graphheight -= getGridLabelRenderer().getHorizontalAxisTitleHeight(); + return graphheight; + } + + /** + * @return the width of the graph viewport. + */ + public int getGraphContentWidth() { + int border = getGridLabelRenderer().getStyles().padding; + int graphwidth = getWidth() - (2 * border) - getGridLabelRenderer().getLabelVerticalWidth(); + if (mSecondScale != null) { + graphwidth -= getGridLabelRenderer().getLabelVerticalSecondScaleWidth(); + } + return graphwidth; + } + + /** + * will be called from Android system. + * + * @param event + * @return + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean b = mViewport.onTouchEvent(event); + boolean a = super.onTouchEvent(event); + + // is it a click? + if (mTapDetector.onTouchEvent(event)) { + for (Series s : mSeries) { + s.onTap(event.getX(), event.getY()); + } + if (mSecondScale != null) { + for (Series s : mSecondScale.getSeries()) { + s.onTap(event.getX(), event.getY()); + } + } + } + + return b || a; + } + + /** + * + */ + @Override + public void computeScroll() { + super.computeScroll(); + mViewport.computeScroll(); + } + + /** + * @return the legend renderer. + * @see com.jjoe64.graphview.LegendRenderer + */ + public LegendRenderer getLegendRenderer() { + return mLegendRenderer; + } + + /** + * use a specific legend renderer + * + * @param mLegendRenderer the new legend renderer + */ + public void setLegendRenderer(LegendRenderer mLegendRenderer) { + this.mLegendRenderer = mLegendRenderer; + } + + /** + * @return the title that will be shown + * above the graph. + */ + public String getTitle() { + return mTitle; + } + + /** + * Set the title of the graph that will + * be shown above the graph's viewport. + * + * @param mTitle the title + * @see #setTitleColor(int) to set the font color + * @see #setTitleTextSize(float) to set the font size + */ + public void setTitle(String mTitle) { + this.mTitle = mTitle; + } + + /** + * @return the title font size + */ + public float getTitleTextSize() { + return mStyles.titleTextSize; + } + + /** + * Set the title's font size + * + * @param titleTextSize font size + * @see #setTitle(String) + */ + public void setTitleTextSize(float titleTextSize) { + mStyles.titleTextSize = titleTextSize; + } + + /** + * @return font color of the title + */ + public int getTitleColor() { + return mStyles.titleColor; + } + + /** + * Set the title's font color + * + * @param titleColor font color of the title + * @see #setTitle(String) + */ + public void setTitleColor(int titleColor) { + mStyles.titleColor = titleColor; + } + + /** + * + * @return + */ + public SecondScale getSecondScale() { + if (mSecondScale == null) { + mSecondScale = new SecondScale(mViewport); + } + return mSecondScale; + } + + /** + * Removes all series of the graph. + */ + public void removeAllSeries() { + mSeries.clear(); + onDataChanged(false, false); + } + + /** + * Remove a specific series of the graph. + * This will also re-render the graph, but + * without recalculating the viewport and + * label sizes. + * If you want this, you have to call {@link #onDataChanged(boolean, boolean)} + * manually. + * + * @param series + */ + public void removeSeries(Series series) { + mSeries.remove(series); + onDataChanged(false, false); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java b/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java new file mode 100644 index 0000000000..e6060c9b50 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java @@ -0,0 +1,1467 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.TypedValue; + +import androidx.core.view.ViewCompat; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * The default renderer for the grid + * and the labels. + * + * @author jjoe64 + */ +public class GridLabelRenderer { + /** + * wrapper for the styles regarding + * to the grid and the labels + */ + public final class Styles { + /** + * the general text size of the axis titles. + * can be overwritten with #verticalAxisTitleTextSize + * and #horizontalAxisTitleTextSize + */ + public float textSize; + + /** + * the alignment of the vertical labels + */ + public Paint.Align verticalLabelsAlign; + + /** + * the alignment of the labels on the right side + */ + public Paint.Align verticalLabelsSecondScaleAlign; + + /** + * the color of the vertical labels + */ + public int verticalLabelsColor; + + /** + * the color of the labels on the right side + */ + public int verticalLabelsSecondScaleColor; + + /** + * the color of the horizontal labels + */ + public int horizontalLabelsColor; + + /** + * the color of the grid lines + */ + public int gridColor; + + /** + * flag whether the zero-lines (vertical+ + * horizontal) shall be highlighted + */ + public boolean highlightZeroLines; + + /** + * the padding around the graph and labels + */ + public int padding; + + /** + * font size of the vertical axis title + */ + public float verticalAxisTitleTextSize; + + /** + * font color of the vertical axis title + */ + public int verticalAxisTitleColor; + + /** + * font size of the horizontal axis title + */ + public float horizontalAxisTitleTextSize; + + /** + * font color of the horizontal axis title + */ + public int horizontalAxisTitleColor; + + /** + * flag whether the horizontal labels are + * visible + */ + boolean horizontalLabelsVisible; + + /** + * flag whether the vertical labels are + * visible + */ + boolean verticalLabelsVisible; + + /** + * defines which lines will be drawn in the background + */ + GridStyle gridStyle; + + /** + * the space between the labels text and the graph content + */ + int labelsSpace; + } + + /** + * Definition which lines will be drawn in the background + */ + public enum GridStyle { + BOTH, VERTICAL, HORIZONTAL, NONE; + + public boolean drawVertical() { return this == BOTH || this == VERTICAL && this != NONE; } + public boolean drawHorizontal() { return this == BOTH || this == HORIZONTAL && this != NONE; } + } + + /** + * wraps the styles regarding the + * grid and labels + */ + protected Styles mStyles; + + /** + * reference to graphview + */ + private final GraphView mGraphView; + + /** + * cache of the vertical steps + * (horizontal lines and vertical labels) + * Key = Pixel (y) + * Value = y-value + */ + private Map mStepsVertical; + + /** + * cache of the vertical steps for the + * second scale, which is on the right side + * (horizontal lines and vertical labels) + * Key = Pixel (y) + * Value = y-value + */ + private Map mStepsVerticalSecondScale; + + /** + * cache of the horizontal steps + * (vertical lines and horizontal labels) + * Key = Pixel (x) + * Value = x-value + */ + private Map mStepsHorizontal; + + /** + * the paint to draw the grid lines + */ + private Paint mPaintLine; + + /** + * the paint to draw the labels + */ + private Paint mPaintLabel; + + /** + * the paint to draw axis titles + */ + private Paint mPaintAxisTitle; + + /** + * flag whether is bounds are automatically + * adjusted for nice human-readable numbers + */ + private boolean mIsAdjusted; + + /** + * the width of the vertical labels + */ + private Integer mLabelVerticalWidth; + + /** + * indicates if the width was set manually + */ + private boolean mLabelVerticalWidthFixed; + + /** + * the height of the vertical labels + */ + private Integer mLabelVerticalHeight; + + /** + * indicates if the height was set manually + */ + private boolean mLabelHorizontalHeightFixed; + + /** + * the width of the vertical labels + * of the second scale + */ + private Integer mLabelVerticalSecondScaleWidth; + + /** + * the height of the vertical labels + * of the second scale + */ + private Integer mLabelVerticalSecondScaleHeight; + + /** + * the width of the horizontal labels + */ + private Integer mLabelHorizontalWidth; + + /** + * the height of the horizontal labels + */ + private Integer mLabelHorizontalHeight; + + /** + * the label formatter, that converts + * the raw numbers to strings + */ + private LabelFormatter mLabelFormatter; + + /** + * the title of the horizontal axis + */ + private String mHorizontalAxisTitle; + + /** + * the title of the vertical axis + */ + private String mVerticalAxisTitle; + + /** + * count of the vertical labels, that + * will be shown at one time. + */ + private int mNumVerticalLabels; + + /** + * count of the horizontal labels, that + * will be shown at one time. + */ + private int mNumHorizontalLabels; + + /** + * create the default grid label renderer. + * + * @param graphView the corresponding graphview object + */ + public GridLabelRenderer(GraphView graphView) { + mGraphView = graphView; + setLabelFormatter(new DefaultLabelFormatter()); + mStyles = new Styles(); + resetStyles(); + mNumVerticalLabels = 5; + mNumHorizontalLabels = 5; + } + + /** + * resets the styles. This loads the style + * from reading the values of the current + * theme. + */ + public void resetStyles() { + // get matching styles from theme + TypedValue typedValue = new TypedValue(); + mGraphView.getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceSmall, typedValue, true); + + int color1; + int color2; + int size; + int size2; + + TypedArray array = null; + try { + array = mGraphView.getContext().obtainStyledAttributes(typedValue.data, new int[]{ + android.R.attr.textColorPrimary + , android.R.attr.textColorSecondary + , android.R.attr.textSize + , android.R.attr.horizontalGap}); + color1 = array.getColor(0, Color.BLACK); + color2 = array.getColor(1, Color.GRAY); + size = array.getDimensionPixelSize(2, 20); + size2 = array.getDimensionPixelSize(3, 20); + array.recycle(); + } catch (Exception e) { + color1 = Color.BLACK; + color2 = Color.GRAY; + size = 20; + size2 = 20; + } + + mStyles.verticalLabelsColor = color1; + mStyles.verticalLabelsSecondScaleColor = color1; + mStyles.horizontalLabelsColor = color1; + mStyles.gridColor = color2; + mStyles.textSize = size; + mStyles.padding = size2; + mStyles.labelsSpace = (int) mStyles.textSize/5; + + mStyles.verticalLabelsAlign = Paint.Align.RIGHT; + mStyles.verticalLabelsSecondScaleAlign = Paint.Align.LEFT; + mStyles.highlightZeroLines = true; + + mStyles.verticalAxisTitleColor = mStyles.verticalLabelsColor; + mStyles.horizontalAxisTitleColor = mStyles.horizontalLabelsColor; + mStyles.verticalAxisTitleTextSize = mStyles.textSize; + mStyles.horizontalAxisTitleTextSize = mStyles.textSize; + + mStyles.horizontalLabelsVisible = true; + mStyles.verticalLabelsVisible = true; + + mStyles.gridStyle = GridStyle.BOTH; + + reloadStyles(); + } + + /** + * will load the styles to the internal + * paint objects (color, text size, text align) + */ + public void reloadStyles() { + mPaintLine = new Paint(); + mPaintLine.setColor(mStyles.gridColor); + mPaintLine.setStrokeWidth(0); + + mPaintLabel = new Paint(); + mPaintLabel.setTextSize(getTextSize()); + + mPaintAxisTitle = new Paint(); + mPaintAxisTitle.setTextSize(getTextSize()); + mPaintAxisTitle.setTextAlign(Paint.Align.CENTER); + } + + /** + * @return the general text size for the axis titles + */ + public float getTextSize() { + return mStyles.textSize; + } + + /** + * @return the font color of the vertical labels + */ + public int getVerticalLabelsColor() { + return mStyles.verticalLabelsColor; + } + + /** + * @return the alignment of the text of the + * vertical labels + */ + public Paint.Align getVerticalLabelsAlign() { + return mStyles.verticalLabelsAlign; + } + + /** + * @return the font color of the horizontal labels + */ + public int getHorizontalLabelsColor() { + return mStyles.horizontalLabelsColor; + } + + /** + * clears the internal cache and forces + * to redraw the grid and labels. + * Normally you should always call {@link GraphView#onDataChanged(boolean, boolean)} + * which will call this method. + * + * @param keepLabelsSize true if you don't want + * to recalculate the size of + * the labels. It is recommended + * to use "true" because this will + * improve performance and prevent + * a flickering. + * @param keepViewport true if you don't want that + * the viewport will be recalculated. + * It is recommended to use "true" for + * performance. + */ + public void invalidate(boolean keepLabelsSize, boolean keepViewport) { + if (!keepViewport) { + mIsAdjusted = false; + } + if (!keepLabelsSize) { + if (!mLabelVerticalWidthFixed) { + mLabelVerticalWidth = null; + } + mLabelVerticalHeight = null; + mLabelVerticalSecondScaleWidth = null; + mLabelVerticalSecondScaleHeight = null; + } + //reloadStyles(); + } + + /** + * calculates the vertical steps of + * the second scale. + * This will not do any automatically update + * of the bounds. + * Use always manual bounds for the second scale. + * + * @return true if it is ready + */ + protected boolean adjustVerticalSecondScale() { + if (mLabelHorizontalHeight == null) { + return false; + } + if (mGraphView.mSecondScale == null) { + return true; + } + + double minY = mGraphView.mSecondScale.getMinY(); + double maxY = mGraphView.mSecondScale.getMaxY(); + + // TODO find the number of labels + int numVerticalLabels = mNumVerticalLabels; + + double newMinY; + double exactSteps; + + if (mGraphView.mSecondScale.isYAxisBoundsManual()) { + newMinY = minY; + double rangeY = maxY - newMinY; + exactSteps = rangeY / (numVerticalLabels - 1); + } else { + // TODO auto adjusting + throw new IllegalStateException("Not yet implemented"); + } + + double newMaxY = newMinY + (numVerticalLabels - 1) * exactSteps; + + // TODO auto adjusting + //mGraphView.getViewport().setMinY(newMinY); + //mGraphView.getViewport().setMaxY(newMaxY); + + //if (!mGraphView.getViewport().isYAxisBoundsManual()) { + // mGraphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); + //} + + if (mStepsVerticalSecondScale != null) { + mStepsVerticalSecondScale.clear(); + } else { + mStepsVerticalSecondScale = new LinkedHashMap(numVerticalLabels); + } + int height = mGraphView.getGraphContentHeight(); + double v = newMaxY; + int p = mGraphView.getGraphContentTop(); // start + int pixelStep = height / (numVerticalLabels - 1); + for (int i = 0; i < numVerticalLabels; i++) { + mStepsVerticalSecondScale.put(p, v); + p += pixelStep; + v -= exactSteps; + } + + return true; + } + + /** + * calculates the vertical steps. This will + * automatically change the bounds to nice + * human-readable min/max. + * + * @return true if it is ready + */ + protected boolean adjustVertical() { + if (mLabelHorizontalHeight == null) { + return false; + } + + double minY = mGraphView.getViewport().getMinY(false); + double maxY = mGraphView.getViewport().getMaxY(false); + + if (minY == maxY) { + return false; + } + + // TODO find the number of labels + int numVerticalLabels = mNumVerticalLabels; + + double newMinY; + double exactSteps; + + if (mGraphView.getViewport().isYAxisBoundsManual()) { + newMinY = minY; + double rangeY = maxY - newMinY; + exactSteps = rangeY / (numVerticalLabels - 1); + } else { + // find good steps + boolean adjusting = true; + newMinY = minY; + exactSteps = 0d; + while (adjusting) { + double rangeY = maxY - newMinY; + exactSteps = rangeY / (numVerticalLabels - 1); + exactSteps = humanRound(exactSteps, true); + + // adjust viewport + // wie oft passt STEP in minY rein? + int count = 0; + if (newMinY >= 0d) { + // positive number + while (newMinY - exactSteps >= 0) { + newMinY -= exactSteps; + count++; + } + newMinY = exactSteps * count; + } else { + // negative number + count++; + while (newMinY + exactSteps < 0) { + newMinY += exactSteps; + count++; + } + newMinY = exactSteps * count * -1; + } + + // wenn minY sich geändert hat, steps nochmal berechnen + // wenn nicht, fertig + if (newMinY == minY) { + adjusting = false; + } else { + minY = newMinY; + } + } + } + + double newMaxY = newMinY + (numVerticalLabels - 1) * exactSteps; + mGraphView.getViewport().setMinY(newMinY); + mGraphView.getViewport().setMaxY(newMaxY); + + if (!mGraphView.getViewport().isYAxisBoundsManual()) { + mGraphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); + } + + if (mStepsVertical != null) { + mStepsVertical.clear(); + } else { + mStepsVertical = new LinkedHashMap(numVerticalLabels); + } + int height = mGraphView.getGraphContentHeight(); + double v = newMaxY; + int p = mGraphView.getGraphContentTop(); // start + int pixelStep = height / (numVerticalLabels - 1); + for (int i = 0; i < numVerticalLabels; i++) { + mStepsVertical.put(p, v); + p += pixelStep; + v -= exactSteps; + } + + return true; + } + + /** + * calculates the horizontal steps. This will + * automatically change the bounds to nice + * human-readable min/max. + * + * @return true if it is ready + */ + protected boolean adjustHorizontal() { + if (mLabelVerticalWidth == null) { + return false; + } + + double minX = mGraphView.getViewport().getMinX(false); + double maxX = mGraphView.getViewport().getMaxX(false); + if (minX == maxX) return false; + + // TODO find the number of labels + int numHorizontalLabels = mNumHorizontalLabels; + + double newMinX; + double exactSteps; + + float scalingOffset = 0f; + if (mGraphView.getViewport().isXAxisBoundsManual() && mGraphView.getViewport().getXAxisBoundsStatus() != Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { + // scaling + if (mGraphView.getViewport().mScalingActive) { + minX = mGraphView.getViewport().mScalingBeginLeft; + maxX = minX + mGraphView.getViewport().mScalingBeginWidth; + + //numHorizontalLabels *= (mGraphView.getViewport().mCurrentViewport.width()+oldStep)/(mGraphView.getViewport().mScalingBeginWidth+oldStep); + //numHorizontalLabels = (float) Math.ceil(numHorizontalLabels); + } + + newMinX = minX; + double rangeX = maxX - newMinX; + exactSteps = rangeX / (numHorizontalLabels - 1); + } else { + // find good steps + boolean adjusting = true; + newMinX = minX; + exactSteps = 0d; + while (adjusting) { + double rangeX = maxX - newMinX; + exactSteps = rangeX / (numHorizontalLabels - 1); + + boolean roundAlwaysUp = true; + if (mGraphView.getViewport().getXAxisBoundsStatus() == Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { + // if viewports gets smaller, round down + if (mGraphView.getViewport().mCurrentViewport.width() < mGraphView.getViewport().mScalingBeginWidth) { + roundAlwaysUp = false; + } + } + exactSteps = humanRound(exactSteps, roundAlwaysUp); + + // adjust viewport + // wie oft passt STEP in minX rein? + int count = 0; + if (newMinX >= 0d) { + // positive number + while (newMinX - exactSteps >= 0) { + newMinX -= exactSteps; + count++; + } + newMinX = exactSteps * count; + } else { + // negative number + count++; + while (newMinX + exactSteps < 0) { + newMinX += exactSteps; + count++; + } + newMinX = exactSteps * count * -1; + } + + // wenn minX sich geändert hat, steps nochmal berechnen + // wenn nicht, fertig + if (newMinX == minX) { + adjusting = false; + } else { + minX = newMinX; + } + } + + double newMaxX = newMinX + (numHorizontalLabels - 1) * exactSteps; + mGraphView.getViewport().setMinX(newMinX); + mGraphView.getViewport().setMaxX(newMaxX); + if (mGraphView.getViewport().getXAxisBoundsStatus() == Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { + mGraphView.getViewport().setXAxisBoundsStatus(Viewport.AxisBoundsStatus.FIX); + } else { + mGraphView.getViewport().setXAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); + } + } + + if (mStepsHorizontal != null) { + mStepsHorizontal.clear(); + } else { + mStepsHorizontal = new LinkedHashMap((int) numHorizontalLabels); + } + int width = mGraphView.getGraphContentWidth(); + + float scrolled = 0; + float scrolledPixels = 0; + + double v = newMinX; + int p = mGraphView.getGraphContentLeft(); // start + float pixelStep = width / (numHorizontalLabels - 1); + + if (mGraphView.getViewport().mScalingActive) { + float oldStep = mGraphView.getViewport().mScalingBeginWidth / (numHorizontalLabels - 1); + float factor = (mGraphView.getViewport().mCurrentViewport.width() + oldStep) / (mGraphView.getViewport().mScalingBeginWidth + oldStep); + pixelStep *= 1f / factor; + + //numHorizontalLabels *= (mGraphView.getViewport().mCurrentViewport.width()+oldStep)/(mGraphView.getViewport().mScalingBeginWidth+oldStep); + //numHorizontalLabels = (float) Math.ceil(numHorizontalLabels); + + //scrolled = ((float) mGraphView.getViewport().getMinX(false) - mGraphView.getViewport().mScalingBeginLeft)*2; + float newWidth = width * 1f / factor; + scrolledPixels = (newWidth - width) * -0.5f; + + } + + // scrolling + if (!Float.isNaN(mGraphView.getViewport().mScrollingReferenceX)) { + scrolled = mGraphView.getViewport().mScrollingReferenceX - (float) newMinX; + scrolledPixels += scrolled * (pixelStep / (float) exactSteps); + + if (scrolled < 0 - exactSteps) { + mGraphView.getViewport().mScrollingReferenceX += exactSteps; + } else if (scrolled > exactSteps) { + mGraphView.getViewport().mScrollingReferenceX -= exactSteps; + } + } + p += scrolledPixels; + v += scrolled; + + for (int i = 0; i < numHorizontalLabels; i++) { + // don't draw steps before 0 (scrolling) + if (p >= mGraphView.getGraphContentLeft()) { + mStepsHorizontal.put(p, v); + } + p += pixelStep; + v += exactSteps; + } + + return true; + } + + /** + * adjusts the grid and labels to match to the data + * this will automatically change the bounds to + * nice human-readable values, except the bounds + * are manual. + */ + protected void adjust() { + mIsAdjusted = adjustVertical(); + mIsAdjusted &= adjustVerticalSecondScale(); + mIsAdjusted &= adjustHorizontal(); + } + + /** + * calculates the vertical label size + * @param canvas canvas + */ + protected void calcLabelVerticalSize(Canvas canvas) { + // test label with first and last label + String testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMaxY(false), false); + if (testLabel == null) testLabel = ""; + + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelVerticalWidth = textBounds.width(); + mLabelVerticalHeight = textBounds.height(); + + testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMinY(false), false); + if (testLabel == null) testLabel = ""; + + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelVerticalWidth = Math.max(mLabelVerticalWidth, textBounds.width()); + + // add some pixel to get a margin + mLabelVerticalWidth += 6; + + // space between text and graph content + mLabelVerticalWidth += mStyles.labelsSpace; + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelVerticalHeight *= lines; + } + + /** + * calculates the vertical second scale + * label size + * @param canvas canvas + */ + protected void calcLabelVerticalSecondScaleSize(Canvas canvas) { + if (mGraphView.mSecondScale == null) { + mLabelVerticalSecondScaleWidth = 0; + mLabelVerticalSecondScaleHeight = 0; + return; + } + + // test label + double testY = ((mGraphView.mSecondScale.getMaxY() - mGraphView.mSecondScale.getMinY()) * 0.783) + mGraphView.mSecondScale.getMinY(); + String testLabel = mGraphView.mSecondScale.getLabelFormatter().formatLabel(testY, false); + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelVerticalSecondScaleWidth = textBounds.width(); + mLabelVerticalSecondScaleHeight = textBounds.height(); + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelVerticalSecondScaleHeight *= lines; + } + + /** + * calculates the horizontal label size + * @param canvas canvas + */ + protected void calcLabelHorizontalSize(Canvas canvas) { + // test label + double testX = ((mGraphView.getViewport().getMaxX(false) - mGraphView.getViewport().getMinX(false)) * 0.783) + mGraphView.getViewport().getMinX(false); + String testLabel = mLabelFormatter.formatLabel(testX, true); + if (testLabel == null) { + testLabel = ""; + } + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelHorizontalWidth = textBounds.width(); + + if (!mLabelHorizontalHeightFixed) { + mLabelHorizontalHeight = textBounds.height(); + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelHorizontalHeight *= lines; + + mLabelHorizontalHeight = (int) Math.max(mLabelHorizontalHeight, mStyles.textSize); + } + + // space between text and graph content + mLabelHorizontalHeight += mStyles.labelsSpace; + } + + /** + * do the drawing of the grid + * and labels + * @param canvas canvas + */ + public void draw(Canvas canvas) { + boolean labelSizeChanged = false; + if (mLabelHorizontalWidth == null) { + calcLabelHorizontalSize(canvas); + labelSizeChanged = true; + } + if (mLabelVerticalWidth == null) { + calcLabelVerticalSize(canvas); + labelSizeChanged = true; + } + if (mLabelVerticalSecondScaleWidth == null) { + calcLabelVerticalSecondScaleSize(canvas); + labelSizeChanged = true; + } + if (labelSizeChanged) { + // redraw + ViewCompat.postInvalidateOnAnimation(mGraphView); + return; + } + + if (!mIsAdjusted) { + adjust(); + } + + if (mIsAdjusted) { + drawVerticalSteps(canvas); + drawVerticalStepsSecondScale(canvas); + drawHorizontalSteps(canvas); + } else { + // we can not draw anything + return; + } + + drawHorizontalAxisTitle(canvas); + drawVerticalAxisTitle(canvas); + } + + /** + * draws the horizontal axis title if + * it is set + * @param canvas canvas + */ + protected void drawHorizontalAxisTitle(Canvas canvas) { + if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { + mPaintAxisTitle.setColor(getHorizontalAxisTitleColor()); + mPaintAxisTitle.setTextSize(getHorizontalAxisTitleTextSize()); + float x = canvas.getWidth() / 2; + float y = canvas.getHeight() - mStyles.padding; + canvas.drawText(mHorizontalAxisTitle, x, y, mPaintAxisTitle); + } + } + + /** + * draws the vertical axis title if + * it is set + * @param canvas canvas + */ + protected void drawVerticalAxisTitle(Canvas canvas) { + if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { + mPaintAxisTitle.setColor(getVerticalAxisTitleColor()); + mPaintAxisTitle.setTextSize(getVerticalAxisTitleTextSize()); + float x = getVerticalAxisTitleWidth(); + float y = canvas.getHeight() / 2; + canvas.save(); + canvas.rotate(-90, x, y); + canvas.drawText(mVerticalAxisTitle, x, y, mPaintAxisTitle); + canvas.restore(); + } + } + + /** + * @return the horizontal axis title height + * or 0 if there is no title + */ + public int getHorizontalAxisTitleHeight() { + if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { + return (int) getHorizontalAxisTitleTextSize(); + } else { + return 0; + } + } + + /** + * @return the vertical axis title width + * or 0 if there is no title + */ + public int getVerticalAxisTitleWidth() { + if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { + return (int) getVerticalAxisTitleTextSize(); + } else { + return 0; + } + } + + /** + * draws the horizontal steps + * vertical lines and horizontal labels + * + * @param canvas canvas + */ + protected void drawHorizontalSteps(Canvas canvas) { + // draw horizontal steps (vertical lines and horizontal labels) + mPaintLabel.setColor(getHorizontalLabelsColor()); + int i = 0; + for (Map.Entry e : mStepsHorizontal.entrySet()) { + // draw line + if (mStyles.highlightZeroLines) { + if (e.getValue() == 0d) { + mPaintLine.setStrokeWidth(5); + } else { + mPaintLine.setStrokeWidth(0); + } + } + if (mStyles.gridStyle.drawVertical()) { + canvas.drawLine(e.getKey(), mGraphView.getGraphContentTop(), e.getKey(), mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight(), mPaintLine); + } + + // draw label + if (isHorizontalLabelsVisible()) { + mPaintLabel.setTextAlign(Paint.Align.CENTER); + if (i == mStepsHorizontal.size() - 1) + mPaintLabel.setTextAlign(Paint.Align.RIGHT); + if (i == 0) + mPaintLabel.setTextAlign(Paint.Align.LEFT); + + // multiline labels + String label = mLabelFormatter.formatLabel(e.getValue(), true); + if (label == null) { + label = ""; + } + String[] lines = label.split("\n"); + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y = (canvas.getHeight() - mStyles.padding - getHorizontalAxisTitleHeight()) - (lines.length - li - 1) * getTextSize() * 1.1f + mStyles.labelsSpace; + canvas.drawText(lines[li], e.getKey(), y, mPaintLabel); + } + } + i++; + } + } + + /** + * draws the vertical steps for the + * second scale on the right side + * + * @param canvas canvas + */ + protected void drawVerticalStepsSecondScale(Canvas canvas) { + if (mGraphView.mSecondScale == null) { + return; + } + + // draw only the vertical labels on the right + float startLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth(); + mPaintLabel.setColor(getVerticalLabelsSecondScaleColor()); + mPaintLabel.setTextAlign(getVerticalLabelsSecondScaleAlign()); + for (Map.Entry e : mStepsVerticalSecondScale.entrySet()) { + // draw label + int labelsWidth = mLabelVerticalSecondScaleWidth; + int labelsOffset = (int) startLeft; + if (getVerticalLabelsSecondScaleAlign() == Paint.Align.RIGHT) { + labelsOffset += labelsWidth; + } else if (getVerticalLabelsSecondScaleAlign() == Paint.Align.CENTER) { + labelsOffset += labelsWidth / 2; + } + + float y = e.getKey(); + + String[] lines = mGraphView.mSecondScale.mLabelFormatter.formatLabel(e.getValue(), false).split("\n"); + y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; + canvas.drawText(lines[li], labelsOffset, y2, mPaintLabel); + } + } + } + + /** + * draws the vertical steps + * horizontal lines and vertical labels + * + * @param canvas canvas + */ + protected void drawVerticalSteps(Canvas canvas) { + // draw vertical steps (horizontal lines and vertical labels) + float startLeft = mGraphView.getGraphContentLeft(); + mPaintLabel.setColor(getVerticalLabelsColor()); + mPaintLabel.setTextAlign(getVerticalLabelsAlign()); + for (Map.Entry e : mStepsVertical.entrySet()) { + // draw line + if (mStyles.highlightZeroLines) { + if (e.getValue() == 0d) { + mPaintLine.setStrokeWidth(5); + } else { + mPaintLine.setStrokeWidth(0); + } + } + if (mStyles.gridStyle.drawHorizontal()) { + canvas.drawLine(startLeft, e.getKey(), startLeft + mGraphView.getGraphContentWidth(), e.getKey(), mPaintLine); + } + + // draw label + if (isVerticalLabelsVisible()) { + int labelsWidth = mLabelVerticalWidth; + int labelsOffset = 0; + if (getVerticalLabelsAlign() == Paint.Align.RIGHT) { + labelsOffset = labelsWidth; + labelsOffset -= mStyles.labelsSpace; + } else if (getVerticalLabelsAlign() == Paint.Align.CENTER) { + labelsOffset = labelsWidth / 2; + } + labelsOffset += mStyles.padding + getVerticalAxisTitleWidth(); + + float y = e.getKey(); + + String label = mLabelFormatter.formatLabel(e.getValue(), false); + if (label == null) { + label = ""; + } + String[] lines = label.split("\n"); + y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; + canvas.drawText(lines[li], labelsOffset, y2, mPaintLabel); + } + } + } + } + + /** + * this will do rounding to generate + * nice human-readable bounds. + * + * @param in the raw value that is to be rounded + * @param roundAlwaysUp true if it shall always round up (ceil) + * @return the rounded number + */ + protected double humanRound(double in, boolean roundAlwaysUp) { + // round-up to 1-steps, 2-steps or 5-steps + int ten = 0; + while (in >= 10d) { + in /= 10d; + ten++; + } + while (in < 1d) { + in *= 10d; + ten--; + } + if (roundAlwaysUp) { + if (in == 1d) { + } else if (in <= 2d) { + in = 2d; + } else if (in <= 5d) { + in = 5d; + } else if (in < 10d) { + in = 10d; + } + } else { // always round down + if (in == 1d) { + } else if (in <= 4.9d) { + in = 2d; + } else if (in <= 9.9d) { + in = 5d; + } else if (in < 15d) { + in = 10d; + } + } + return in * Math.pow(10d, ten); + } + + /** + * @return the wrapped styles + */ + public Styles getStyles() { + return mStyles; + } + + /** + * @return the vertical label width + * 0 if there are no vertical labels + */ + public int getLabelVerticalWidth() { + return mLabelVerticalWidth == null || !isVerticalLabelsVisible() ? 0 : mLabelVerticalWidth; + } + + /** + * sets a manual and fixed with of the space for + * the vertical labels. This will prevent GraphView to + * calculate the width automatically. + * + * @param width the width of the space for the vertical labels. + * Use null to let GraphView automatically calculate the width. + */ + public void setLabelVerticalWidth(Integer width) { + mLabelVerticalWidth = width; + mLabelVerticalWidthFixed = mLabelVerticalWidth != null; + } + + /** + * @return the horizontal label height + * 0 if there are no horizontal labels + */ + public int getLabelHorizontalHeight() { + return mLabelHorizontalHeight == null || !isHorizontalLabelsVisible() ? 0 : mLabelHorizontalHeight; + } + + /** + * sets a manual and fixed height of the space for + * the horizontal labels. This will prevent GraphView to + * calculate the height automatically. + * + * @param height the height of the space for the horizontal labels. + * Use null to let GraphView automatically calculate the height. + */ + public void setLabelHorizontalHeight(Integer height) { + mLabelHorizontalHeight = height; + mLabelHorizontalHeightFixed = mLabelHorizontalHeight != null; + } + + /** + * @return the grid line color + */ + public int getGridColor() { + return mStyles.gridColor; + } + + /** + * @return whether the line at 0 are highlighted + */ + public boolean isHighlightZeroLines() { + return mStyles.highlightZeroLines; + } + + /** + * @return the padding around the grid and labels + */ + public int getPadding() { + return mStyles.padding; + } + + /** + * @param textSize the general text size of the axis titles. + * can be overwritten with {@link #setVerticalAxisTitleTextSize(float)} + * and {@link #setHorizontalAxisTitleTextSize(float)} + */ + public void setTextSize(float textSize) { + mStyles.textSize = textSize; + } + + /** + * @param verticalLabelsAlign the alignment of the vertical labels + */ + public void setVerticalLabelsAlign(Paint.Align verticalLabelsAlign) { + mStyles.verticalLabelsAlign = verticalLabelsAlign; + } + + /** + * @param verticalLabelsColor the color of the vertical labels + */ + public void setVerticalLabelsColor(int verticalLabelsColor) { + mStyles.verticalLabelsColor = verticalLabelsColor; + } + + /** + * @param horizontalLabelsColor the color of the horizontal labels + */ + public void setHorizontalLabelsColor(int horizontalLabelsColor) { + mStyles.horizontalLabelsColor = horizontalLabelsColor; + } + + /** + * @param gridColor the color of the grid lines + */ + public void setGridColor(int gridColor) { + mStyles.gridColor = gridColor; + } + + /** + * @param highlightZeroLines flag whether the zero-lines (vertical+ + * horizontal) shall be highlighted + */ + public void setHighlightZeroLines(boolean highlightZeroLines) { + mStyles.highlightZeroLines = highlightZeroLines; + } + + /** + * @param padding the padding around the graph and labels + */ + public void setPadding(int padding) { + mStyles.padding = padding; + } + + /** + * @return the label formatter, that converts + * the raw numbers to strings + */ + public LabelFormatter getLabelFormatter() { + return mLabelFormatter; + } + + /** + * @param mLabelFormatter the label formatter, that converts + * the raw numbers to strings + */ + public void setLabelFormatter(LabelFormatter mLabelFormatter) { + this.mLabelFormatter = mLabelFormatter; + mLabelFormatter.setViewport(mGraphView.getViewport()); + } + + /** + * @return the title of the horizontal axis + */ + public String getHorizontalAxisTitle() { + return mHorizontalAxisTitle; + } + + /** + * @param mHorizontalAxisTitle the title of the horizontal axis + */ + public void setHorizontalAxisTitle(String mHorizontalAxisTitle) { + this.mHorizontalAxisTitle = mHorizontalAxisTitle; + } + + /** + * @return the title of the vertical axis + */ + public String getVerticalAxisTitle() { + return mVerticalAxisTitle; + } + + /** + * @param mVerticalAxisTitle the title of the vertical axis + */ + public void setVerticalAxisTitle(String mVerticalAxisTitle) { + this.mVerticalAxisTitle = mVerticalAxisTitle; + } + + /** + * @return font size of the vertical axis title + */ + public float getVerticalAxisTitleTextSize() { + return mStyles.verticalAxisTitleTextSize; + } + + /** + * @param verticalAxisTitleTextSize font size of the vertical axis title + */ + public void setVerticalAxisTitleTextSize(float verticalAxisTitleTextSize) { + mStyles.verticalAxisTitleTextSize = verticalAxisTitleTextSize; + } + + /** + * @return font color of the vertical axis title + */ + public int getVerticalAxisTitleColor() { + return mStyles.verticalAxisTitleColor; + } + + /** + * @param verticalAxisTitleColor font color of the vertical axis title + */ + public void setVerticalAxisTitleColor(int verticalAxisTitleColor) { + mStyles.verticalAxisTitleColor = verticalAxisTitleColor; + } + + /** + * @return font size of the horizontal axis title + */ + public float getHorizontalAxisTitleTextSize() { + return mStyles.horizontalAxisTitleTextSize; + } + + /** + * @param horizontalAxisTitleTextSize font size of the horizontal axis title + */ + public void setHorizontalAxisTitleTextSize(float horizontalAxisTitleTextSize) { + mStyles.horizontalAxisTitleTextSize = horizontalAxisTitleTextSize; + } + + /** + * @return font color of the horizontal axis title + */ + public int getHorizontalAxisTitleColor() { + return mStyles.horizontalAxisTitleColor; + } + + /** + * @param horizontalAxisTitleColor font color of the horizontal axis title + */ + public void setHorizontalAxisTitleColor(int horizontalAxisTitleColor) { + mStyles.horizontalAxisTitleColor = horizontalAxisTitleColor; + } + + /** + * @return the alignment of the labels on the right side + */ + public Paint.Align getVerticalLabelsSecondScaleAlign() { + return mStyles.verticalLabelsSecondScaleAlign; + } + + /** + * @param verticalLabelsSecondScaleAlign the alignment of the labels on the right side + */ + public void setVerticalLabelsSecondScaleAlign(Paint.Align verticalLabelsSecondScaleAlign) { + mStyles.verticalLabelsSecondScaleAlign = verticalLabelsSecondScaleAlign; + } + + /** + * @return the color of the labels on the right side + */ + public int getVerticalLabelsSecondScaleColor() { + return mStyles.verticalLabelsSecondScaleColor; + } + + /** + * @param verticalLabelsSecondScaleColor the color of the labels on the right side + */ + public void setVerticalLabelsSecondScaleColor(int verticalLabelsSecondScaleColor) { + mStyles.verticalLabelsSecondScaleColor = verticalLabelsSecondScaleColor; + } + + /** + * @return the width of the vertical labels + * of the second scale + */ + public int getLabelVerticalSecondScaleWidth() { + return mLabelVerticalSecondScaleWidth==null?0:mLabelVerticalSecondScaleWidth; + } + + /** + * @return flag whether the horizontal labels are + * visible + */ + public boolean isHorizontalLabelsVisible() { + return mStyles.horizontalLabelsVisible; + } + + /** + * @param horizontalTitleVisible flag whether the horizontal labels are + * visible + */ + public void setHorizontalLabelsVisible(boolean horizontalTitleVisible) { + mStyles.horizontalLabelsVisible = horizontalTitleVisible; + } + + /** + * @return flag whether the vertical labels are + * visible + */ + public boolean isVerticalLabelsVisible() { + return mStyles.verticalLabelsVisible; + } + + /** + * @param verticalTitleVisible flag whether the vertical labels are + * visible + */ + public void setVerticalLabelsVisible(boolean verticalTitleVisible) { + mStyles.verticalLabelsVisible = verticalTitleVisible; + } + + /** + * @return count of the vertical labels, that + * will be shown at one time. + */ + public int getNumVerticalLabels() { + return mNumVerticalLabels; + } + + /** + * @param mNumVerticalLabels count of the vertical labels, that + * will be shown at one time. + */ + public void setNumVerticalLabels(int mNumVerticalLabels) { + this.mNumVerticalLabels = mNumVerticalLabels; + } + + /** + * @return count of the horizontal labels, that + * will be shown at one time. + */ + public int getNumHorizontalLabels() { + return mNumHorizontalLabels; + } + + /** + * @param mNumHorizontalLabels count of the horizontal labels, that + * will be shown at one time. + */ + public void setNumHorizontalLabels(int mNumHorizontalLabels) { + this.mNumHorizontalLabels = mNumHorizontalLabels; + } + + /** + * @return the grid style + */ + public GridStyle getGridStyle() { + return mStyles.gridStyle; + } + + /** + * Define which grid lines shall be drawn + * + * @param gridStyle the grid style + */ + public void setGridStyle(GridStyle gridStyle) { + mStyles.gridStyle = gridStyle; + } + + /** + * @return the space between the labels text and the graph content + */ + public int getLabelsSpace() { + return mStyles.labelsSpace; + } + + /** + * the space between the labels text and the graph content + * + * @param labelsSpace the space between the labels text and the graph content + */ + public void setLabelsSpace(int labelsSpace) { + mStyles.labelsSpace = labelsSpace; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java new file mode 100644 index 0000000000..80aad2990a --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java @@ -0,0 +1,54 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +/** + * Interface to use as label formatter. + * Implement this in order to generate + * your own labels format. + * It is recommended to override {@link com.jjoe64.graphview.DefaultLabelFormatter}. + * + * @author jjoe64 + */ +public interface LabelFormatter { + /** + * converts a raw number as input to + * a formatted string for the label. + * + * @param value raw input number + * @param isValueX true if it is a value for the x axis + * false if it is a value for the y axis + * @return the formatted number as string + */ + public String formatLabel(double value, boolean isValueX); + + /** + * will be called in order to have a + * reference to the current viewport. + * This is useful if you need the bounds + * to generate your labels. + * You store this viewport in as member variable + * and access it e.g. in the {@link #formatLabel(double, boolean)} + * method. + * + * @param viewport the used viewport + */ + public void setViewport(Viewport viewport); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java b/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java new file mode 100644 index 0000000000..db901577f7 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java @@ -0,0 +1,394 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.RectF; +import android.util.TypedValue; + +import com.jjoe64.graphview.series.Series; + +import java.util.ArrayList; +import java.util.List; + +/** + * The default renderer for the legend box + * + * @author jjoe64 + */ +public class LegendRenderer { + /** + * wrapped styles regarding to the + * legend + */ + private final class Styles { + float textSize; + int spacing; + int padding; + int width; + int backgroundColor; + int textColor; + int margin; + LegendAlign align; + Point fixedPosition; + } + + /** + * alignment of the legend + */ + public enum LegendAlign { + /** + * top right corner + */ + TOP, + + /** + * middle right + */ + MIDDLE, + + /** + * bottom right corner + */ + BOTTOM + } + + /** + * wrapped styles + */ + private Styles mStyles; + + /** + * reference to the graphview + */ + private final GraphView mGraphView; + + /** + * flag whether legend will be + * drawn + */ + private boolean mIsVisible; + + /** + * paint for the drawing + */ + private Paint mPaint; + + /** + * cached legend width + * this will be filled in the drawing. + * Can be cleared via {@link #resetStyles()} + */ + private int cachedLegendWidth; + + /** + * creates legend renderer + * + * @param graphView regarding graphview + */ + public LegendRenderer(GraphView graphView) { + mGraphView = graphView; + mIsVisible = false; + mPaint = new Paint(); + mPaint.setTextAlign(Paint.Align.LEFT); + mStyles = new Styles(); + cachedLegendWidth = 0; + resetStyles(); + } + + /** + * resets the styles to the defaults + * and clears the legend width cache + */ + public void resetStyles() { + mStyles.align = LegendAlign.MIDDLE; + mStyles.textSize = mGraphView.getGridLabelRenderer().getTextSize(); + mStyles.spacing = (int) (mStyles.textSize / 5); + mStyles.padding = (int) (mStyles.textSize / 2); + mStyles.width = 0; + mStyles.backgroundColor = Color.argb(180, 100, 100, 100); + mStyles.margin = (int) (mStyles.textSize / 5); + + // get matching styles from theme + TypedValue typedValue = new TypedValue(); + mGraphView.getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceSmall, typedValue, true); + + int color1; + + try { + TypedArray array = mGraphView.getContext().obtainStyledAttributes(typedValue.data, new int[]{ + android.R.attr.textColorPrimary}); + color1 = array.getColor(0, Color.BLACK); + array.recycle(); + } catch (Exception e) { + color1 = Color.BLACK; + } + + mStyles.textColor = color1; + + cachedLegendWidth = 0; + } + + /** + * draws the legend if it is visible + * + * @param canvas canvas + * @see #setVisible(boolean) + */ + public void draw(Canvas canvas) { + if (!mIsVisible) return; + + mPaint.setTextSize(mStyles.textSize); + + int shapeSize = (int) (mStyles.textSize*0.8d); + + List allSeries = new ArrayList(); + allSeries.addAll(mGraphView.getSeries()); + if (mGraphView.mSecondScale != null) { + allSeries.addAll(mGraphView.getSecondScale().getSeries()); + } + + // width + int legendWidth = mStyles.width; + if (legendWidth == 0) { + // auto + legendWidth = cachedLegendWidth; + + if (legendWidth == 0) { + Rect textBounds = new Rect(); + for (Series s : allSeries) { + if (s.getTitle() != null) { + mPaint.getTextBounds(s.getTitle(), 0, s.getTitle().length(), textBounds); + legendWidth = Math.max(legendWidth, textBounds.width()); + } + } + if (legendWidth == 0) legendWidth = 1; + + // add shape size + legendWidth += shapeSize+mStyles.padding*2 + mStyles.spacing; + cachedLegendWidth = legendWidth; + } + } + + // rect + float legendHeight = (mStyles.textSize+mStyles.spacing)*allSeries.size() -mStyles.spacing; + float lLeft; + float lTop; + if (mStyles.fixedPosition != null) { + // use fied position + lLeft = mGraphView.getGraphContentLeft() + mStyles.margin + mStyles.fixedPosition.x; + lTop = mGraphView.getGraphContentTop() + mStyles.margin + mStyles.fixedPosition.y; + } else { + lLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth() - legendWidth - mStyles.margin; + switch (mStyles.align) { + case TOP: + lTop = mGraphView.getGraphContentTop() + mStyles.margin; + break; + case MIDDLE: + lTop = mGraphView.getHeight() / 2 - legendHeight / 2; + break; + default: + lTop = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - mStyles.margin - legendHeight - 2*mStyles.padding; + } + } + float lRight = lLeft+legendWidth; + float lBottom = lTop+legendHeight+2*mStyles.padding; + mPaint.setColor(mStyles.backgroundColor); + canvas.drawRoundRect(new RectF(lLeft, lTop, lRight, lBottom), 8, 8, mPaint); + + int i=0; + for (Series series : allSeries) { + mPaint.setColor(series.getColor()); + canvas.drawRect(new RectF(lLeft+mStyles.padding, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing)), lLeft+mStyles.padding+shapeSize, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing))+shapeSize), mPaint); + if (series.getTitle() != null) { + mPaint.setColor(mStyles.textColor); + canvas.drawText(series.getTitle(), lLeft+mStyles.padding+shapeSize+mStyles.spacing, lTop+mStyles.padding+mStyles.textSize+(i*(mStyles.textSize+mStyles.spacing)), mPaint); + } + i++; + } + } + + /** + * @return the flag whether the legend will be drawn + */ + public boolean isVisible() { + return mIsVisible; + } + + /** + * set the flag whether the legend will be drawn + * + * @param mIsVisible visible flag + */ + public void setVisible(boolean mIsVisible) { + this.mIsVisible = mIsVisible; + } + + /** + * @return font size + */ + public float getTextSize() { + return mStyles.textSize; + } + + /** + * sets the font size. this will clear + * the internal legend width cache + * + * @param textSize font size + */ + public void setTextSize(float textSize) { + mStyles.textSize = textSize; + cachedLegendWidth = 0; + } + + /** + * @return the spacing between the text lines + */ + public int getSpacing() { + return mStyles.spacing; + } + + /** + * set the spacing between the text lines + * + * @param spacing the spacing between the text lines + */ + public void setSpacing(int spacing) { + mStyles.spacing = spacing; + } + + /** + * padding is the space between the edge of the box + * and the beginning of the text + * + * @return padding from edge to text + */ + public int getPadding() { + return mStyles.padding; + } + + /** + * padding is the space between the edge of the box + * and the beginning of the text + * + * @param padding padding from edge to text + */ + public void setPadding(int padding) { + mStyles.padding = padding; + } + + /** + * the width of the box exclusive padding + * + * @return the width of the box + * 0 => auto + */ + public int getWidth() { + return mStyles.width; + } + + /** + * the width of the box exclusive padding + * @param width the width of the box exclusive padding + * 0 => auto + */ + public void setWidth(int width) { + mStyles.width = width; + } + + /** + * @return background color of the box + * it is recommended to use semi-transparent + * color. + */ + public int getBackgroundColor() { + return mStyles.backgroundColor; + } + + /** + * @param backgroundColor background color of the box + * it is recommended to use semi-transparent + * color. + */ + public void setBackgroundColor(int backgroundColor) { + mStyles.backgroundColor = backgroundColor; + } + + /** + * @return margin from the edge of the box + * to the corner of the graphview + */ + public int getMargin() { + return mStyles.margin; + } + + /** + * @param margin margin from the edge of the box + * to the corner of the graphview + */ + public void setMargin(int margin) { + mStyles.margin = margin; + } + + /** + * @return the vertical alignment of the box + */ + public LegendAlign getAlign() { + return mStyles.align; + } + + /** + * @param align the vertical alignment of the box + */ + public void setAlign(LegendAlign align) { + mStyles.align = align; + } + + /** + * @return font color + */ + public int getTextColor() { + return mStyles.textColor; + } + + /** + * @param textColor font color + */ + public void setTextColor(int textColor) { + mStyles.textColor = textColor; + } + + /** + * Use fixed coordinates to position the legend. + * This will override the align setting. + * + * @param x x coordinates in pixel + * @param y y coordinates in pixel + */ + public void setFixedPosition(int x, int y) { + mStyles.fixedPosition = new Point(x, y); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java b/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java new file mode 100644 index 0000000000..1fff8ee8a9 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java @@ -0,0 +1,165 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import com.jjoe64.graphview.series.Series; + +import java.util.ArrayList; +import java.util.List; + +/** + * To be used to plot a second scale + * on the graph. + * The second scale has always to have + * manual bounds. + * Use {@link #setMinY(double)} and {@link #setMaxY(double)} + * to set them. + * The second scale has it's own array of series. + * + * @author jjoe64 + */ +public class SecondScale { + /** + * reference to the viewport of the graph + */ + protected final Viewport mViewport; + + /** + * array of series for the second + * scale + */ + protected List mSeries; + + /** + * flag whether the y axis bounds + * are manual. + * For the current version this is always + * true. + */ + private boolean mYAxisBoundsManual = true; + + /** + * min y value for the y axis bounds + */ + private double mMinY; + + /** + * max y value for the y axis bounds + */ + private double mMaxY; + + /** + * label formatter for the y labels + * on the right side + */ + protected LabelFormatter mLabelFormatter; + + /** + * creates the second scale. + * normally you do not call this contructor. + * Use {@link com.jjoe64.graphview.GraphView#getSecondScale()} + * in order to get the instance. + */ + SecondScale(Viewport viewport) { + mViewport = viewport; + mSeries = new ArrayList(); + mLabelFormatter = new DefaultLabelFormatter(); + mLabelFormatter.setViewport(mViewport); + } + + /** + * add a series to the second scale. + * Don't add this series also to the GraphView + * object. + * + * @param s the series + */ + public void addSeries(Series s) { + mSeries.add(s); + } + + //public void setYAxisBoundsManual(boolean mYAxisBoundsManual) { + // this.mYAxisBoundsManual = mYAxisBoundsManual; + //} + + /** + * set the min y bounds + * + * @param d min y value + */ + public void setMinY(double d) { + mMinY = d; + } + + /** + * set the max y bounds + * + * @param d max y value + */ + public void setMaxY(double d) { + mMaxY = d; + } + + /** + * @return the series of the second scale + */ + public List getSeries() { + return mSeries; + } + + /** + * @return min y bound + */ + public double getMinY() { + return mMinY; + } + + /** + * @return max y bound + */ + public double getMaxY() { + return mMaxY; + } + + /** + * @return always true for the current implementation + */ + public boolean isYAxisBoundsManual() { + return mYAxisBoundsManual; + } + + /** + * @return label formatter for the y labels on the right side + */ + public LabelFormatter getLabelFormatter() { + return mLabelFormatter; + } + + /** + * Set a custom label formatter that is used + * for the y labels on the right side. + * + * @param formatter label formatter for the y labels + */ + public void setLabelFormatter(LabelFormatter formatter) { + mLabelFormatter = formatter; + mLabelFormatter.setViewport(mViewport); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java b/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java new file mode 100644 index 0000000000..a02f22a21e --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java @@ -0,0 +1,41 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ + +package com.jjoe64.graphview; + +import com.jjoe64.graphview.series.DataPointInterface; + +/** + * you can change the color depending on the value. + * takes only effect for BarGraphSeries. + * + * @see com.jjoe64.graphview.series.BarGraphSeries#setValueDependentColor(ValueDependentColor) + */ +public interface ValueDependentColor { + /** + * this is called when a bar is about to draw + * and the color is be loaded. + * + * @param data the current input value + * @return the color that the bar should be drawn with + * Generate the int via the android.graphics.Color class. + */ + public int get(T data); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/Viewport.java b/graphview/src/main/java/com/jjoe64/graphview/Viewport.java new file mode 100644 index 0000000000..de90c05ea2 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/Viewport.java @@ -0,0 +1,996 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.widget.OverScroller; + +import androidx.core.view.ViewCompat; +import androidx.core.widget.EdgeEffectCompat; + +import com.jjoe64.graphview.compat.OverScrollerCompat; +import com.jjoe64.graphview.series.DataPointInterface; +import com.jjoe64.graphview.series.Series; + +import java.util.Iterator; +import java.util.List; + +/** + * This is the default implementation for the viewport. + * This implementation so for a normal viewport + * where there is a horizontal x-axis and a + * vertical y-axis. + * This viewport is compatible with + * - {@link com.jjoe64.graphview.series.BarGraphSeries} + * - {@link com.jjoe64.graphview.series.LineGraphSeries} + * - {@link com.jjoe64.graphview.series.PointsGraphSeries} + * + * @author jjoe64 + */ +public class Viewport { + /** + * listener for the scale gesture + */ + private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener + = new ScaleGestureDetector.OnScaleGestureListener() { + /** + * called by android + * @param detector detector + * @return always true + */ + @Override + public boolean onScale(ScaleGestureDetector detector) { + float viewportWidth = mCurrentViewport.width(); + float center = mCurrentViewport.left + viewportWidth / 2; + viewportWidth /= detector.getScaleFactor(); + mCurrentViewport.left = center - viewportWidth / 2; + mCurrentViewport.right = mCurrentViewport.left+viewportWidth; + + // viewportStart must not be < minX + float minX = (float) getMinX(true); + if (mCurrentViewport.left < minX) { + mCurrentViewport.left = minX; + mCurrentViewport.right = mCurrentViewport.left+viewportWidth; + } + + // viewportStart + viewportSize must not be > maxX + float maxX = (float) getMaxX(true); + if (viewportWidth == 0) { + mCurrentViewport.right = maxX; + } + double overlap = mCurrentViewport.left + viewportWidth - maxX; + if (overlap > 0) { + // scroll left + if (mCurrentViewport.left-overlap > minX) { + mCurrentViewport.left -= overlap; + mCurrentViewport.right = mCurrentViewport.left+viewportWidth; + } else { + // maximal scale + mCurrentViewport.left = minX; + mCurrentViewport.right = maxX; + } + } + + // adjust viewport, labels, etc. + mGraphView.onDataChanged(true, false); + + ViewCompat.postInvalidateOnAnimation(mGraphView); + + return true; + } + + /** + * called when scaling begins + * + * @param detector detector + * @return true if it is scalable + */ + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + if (mIsScalable) { + mScalingBeginWidth = mCurrentViewport.width(); + mScalingBeginLeft = mCurrentViewport.left; + mScalingActive = true; + return true; + } else { + return false; + } + } + + /** + * called when sacling ends + * This will re-adjust the viewport. + * + * @param detector detector + */ + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + mScalingActive = false; + + // re-adjust + mXAxisBoundsStatus = AxisBoundsStatus.READJUST_AFTER_SCALE; + + mScrollingReferenceX = Float.NaN; + + // adjust viewport, labels, etc. + mGraphView.onDataChanged(true, false); + + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + }; + + /** + * simple gesture listener to track scroll events + */ + private final GestureDetector.SimpleOnGestureListener mGestureListener + = new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDown(MotionEvent e) { + if (!mIsScrollable || mScalingActive) return false; + + // Initiates the decay phase of any active edge effects. + releaseEdgeEffects(); + mScrollerStartViewport.set(mCurrentViewport); + // Aborts any active scroll animations and invalidates. + mScroller.forceFinished(true); + ViewCompat.postInvalidateOnAnimation(mGraphView); + return true; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if (!mIsScrollable || mScalingActive) return false; + + if (Float.isNaN(mScrollingReferenceX)) { + mScrollingReferenceX = mCurrentViewport.left; + } + + // Scrolling uses math based on the viewport (as opposed to math using pixels). + /** + * Pixel offset is the offset in screen pixels, while viewport offset is the + * offset within the current viewport. For additional information on surface sizes + * and pixel offsets, see the docs for {@link computeScrollSurfaceSize()}. For + * additional information about the viewport, see the comments for + * {@link mCurrentViewport}. + */ + float viewportOffsetX = distanceX * mCurrentViewport.width() / mGraphView.getGraphContentWidth(); + float viewportOffsetY = -distanceY * mCurrentViewport.height() / mGraphView.getGraphContentHeight(); + + int completeWidth = (int)((mCompleteRange.width()/mCurrentViewport.width()) * (float) mGraphView.getGraphContentWidth()); + int completeHeight = (int)((mCompleteRange.height()/mCurrentViewport.height()) * (float) mGraphView.getGraphContentHeight()); + + int scrolledX = (int) (completeWidth + * (mCurrentViewport.left + viewportOffsetX - mCompleteRange.left) + / mCompleteRange.width()); + int scrolledY = (int) (completeHeight + * (mCompleteRange.bottom - mCurrentViewport.bottom - viewportOffsetY) + / mCompleteRange.height()); + boolean canScrollX = mCurrentViewport.left > mCompleteRange.left + || mCurrentViewport.right < mCompleteRange.right; + boolean canScrollY = mCurrentViewport.bottom > mCompleteRange.bottom + || mCurrentViewport.top < mCompleteRange.top; + + if (canScrollX) { + if (viewportOffsetX < 0) { + float tooMuch = mCurrentViewport.left+viewportOffsetX - mCompleteRange.left; + if (tooMuch < 0) { + viewportOffsetX -= tooMuch; + } + } else { + float tooMuch = mCurrentViewport.right+viewportOffsetX - mCompleteRange.right; + if (tooMuch > 0) { + viewportOffsetX -= tooMuch; + } + } + mCurrentViewport.left += viewportOffsetX; + mCurrentViewport.right += viewportOffsetX; + } + if (canScrollY) { + //mCurrentViewport.top += viewportOffsetX; + //mCurrentViewport.bottom -= viewportOffsetX; + } + + if (canScrollX && scrolledX < 0) { + mEdgeEffectLeft.onPull(scrolledX / (float) mGraphView.getGraphContentWidth()); + mEdgeEffectLeftActive = true; + } + if (canScrollY && scrolledY < 0) { + mEdgeEffectBottom.onPull(scrolledY / (float) mGraphView.getGraphContentHeight()); + mEdgeEffectBottomActive = true; + } + if (canScrollX && scrolledX > completeWidth - mGraphView.getGraphContentWidth()) { + mEdgeEffectRight.onPull((scrolledX - completeWidth + mGraphView.getGraphContentWidth()) + / (float) mGraphView.getGraphContentWidth()); + mEdgeEffectRightActive = true; + } + //if (canScrollY && scrolledY > mSurfaceSizeBuffer.y - mContentRect.height()) { + // mEdgeEffectTop.onPull((scrolledY - mSurfaceSizeBuffer.y + mContentRect.height()) + // / (float) mContentRect.height()); + // mEdgeEffectTopActive = true; + //} + + // adjust viewport, labels, etc. + mGraphView.onDataChanged(true, false); + + ViewCompat.postInvalidateOnAnimation(mGraphView); + return true; + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, + float velocityX, float velocityY) { + //fling((int) -velocityX, (int) -velocityY); + return true; + } + }; + + /** + * the state of the axis bounds + */ + public enum AxisBoundsStatus { + /** + * initial means that the bounds gets + * auto adjusted if they are not manual. + * After adjusting the status comes to + * #AUTO_ADJUSTED. + */ + INITIAL, + + /** + * after the bounds got auto-adjusted, + * this status will set. + */ + AUTO_ADJUSTED, + + /** + * this flags the status that a scale was + * done and the bounds has to be auto-adjusted + * afterwards. + */ + READJUST_AFTER_SCALE, + + /** + * means that the bounds are fix (manually) and + * are not to be auto-adjusted. + */ + FIX + } + + /** + * paint to draw background + */ + private Paint mPaint; + + /** + * reference to the graphview + */ + private final GraphView mGraphView; + + /** + * this holds the current visible viewport + * left = minX, right = maxX + * bottom = minY, top = maxY + */ + protected RectF mCurrentViewport = new RectF(); + + /** + * this holds the whole range of the data + * left = minX, right = maxX + * bottom = minY, top = maxY + */ + protected RectF mCompleteRange = new RectF(); + + /** + * flag whether scaling is currently active + */ + protected boolean mScalingActive; + + /** + * stores the width of the viewport at the time + * of beginning of the scaling. + */ + protected float mScalingBeginWidth; + + /** + * stores the viewport left at the time of + * beginning of the scaling. + */ + protected float mScalingBeginLeft; + + /** + * flag whether the viewport is scrollable + */ + private boolean mIsScrollable; + + /** + * flag whether the viewport is scalable + */ + private boolean mIsScalable; + + /** + * gesture detector to detect scrolling + */ + protected GestureDetector mGestureDetector; + + /** + * detect scaling + */ + protected ScaleGestureDetector mScaleGestureDetector; + + /** + * not used - for fling + */ + protected OverScroller mScroller; + + /** + * not used + */ + private EdgeEffectCompat mEdgeEffectTop; + + /** + * not used + */ + private EdgeEffectCompat mEdgeEffectBottom; + + /** + * glow effect when scrolling left + */ + private EdgeEffectCompat mEdgeEffectLeft; + + /** + * glow effect when scrolling right + */ + private EdgeEffectCompat mEdgeEffectRight; + + /** + * not used + */ + private boolean mEdgeEffectTopActive; + + /** + * not used + */ + private boolean mEdgeEffectBottomActive; + + /** + * glow effect when scrolling left + */ + private boolean mEdgeEffectLeftActive; + + /** + * glow effect when scrolling right + */ + private boolean mEdgeEffectRightActive; + + /** + * stores the viewport at the time of + * the beginning of scaling + */ + private RectF mScrollerStartViewport = new RectF(); + + /** + * stores the viewport left value at the + * time of beginning of the scrolling + */ + protected float mScrollingReferenceX = Float.NaN; + + /** + * state of the x axis + */ + private AxisBoundsStatus mXAxisBoundsStatus; + + /** + * state of the y axis + */ + private AxisBoundsStatus mYAxisBoundsStatus; + + /** + * flag whether the x axis bounds are manual + */ + private boolean mXAxisBoundsManual; + + /** + * flag whether the y axis bounds are manual + */ + private boolean mYAxisBoundsManual; + + /** + * background color of the viewport area + * it is recommended to use a semi-transparent color + */ + private int mBackgroundColor; + + /** + * creates the viewport + * + * @param graphView graphview + */ + Viewport(GraphView graphView) { + mScroller = new OverScroller(graphView.getContext()); + mEdgeEffectTop = new EdgeEffectCompat(graphView.getContext()); + mEdgeEffectBottom = new EdgeEffectCompat(graphView.getContext()); + mEdgeEffectLeft = new EdgeEffectCompat(graphView.getContext()); + mEdgeEffectRight = new EdgeEffectCompat(graphView.getContext()); + mGestureDetector = new GestureDetector(graphView.getContext(), mGestureListener); + mScaleGestureDetector = new ScaleGestureDetector(graphView.getContext(), mScaleGestureListener); + + mGraphView = graphView; + mXAxisBoundsStatus = AxisBoundsStatus.INITIAL; + mYAxisBoundsStatus = AxisBoundsStatus.INITIAL; + mBackgroundColor = Color.TRANSPARENT; + mPaint = new Paint(); + } + + /** + * will be called on a touch event. + * needed to use scaling and scrolling + * + * @param event + * @return true if it was consumed + */ + public boolean onTouchEvent(MotionEvent event) { + boolean b = mScaleGestureDetector.onTouchEvent(event); + b |= mGestureDetector.onTouchEvent(event); + return b; + } + + /** + * change the state of the x axis. + * normally you do not call this method. + * If you want to set manual axis use + * {@link #setXAxisBoundsManual(boolean)} and {@link #setYAxisBoundsManual(boolean)} + * + * @param s state + */ + public void setXAxisBoundsStatus(AxisBoundsStatus s) { + mXAxisBoundsStatus = s; + } + + /** + * change the state of the y axis. + * normally you do not call this method. + * If you want to set manual axis use + * {@link #setXAxisBoundsManual(boolean)} and {@link #setYAxisBoundsManual(boolean)} + * + * @param s state + */ + public void setYAxisBoundsStatus(AxisBoundsStatus s) { + mYAxisBoundsStatus = s; + } + + /** + * @return whether the viewport is scrollable + */ + public boolean isScrollable() { + return mIsScrollable; + } + + /** + * @param mIsScrollable whether is viewport is scrollable + */ + public void setScrollable(boolean mIsScrollable) { + this.mIsScrollable = mIsScrollable; + } + + /** + * @return the x axis state + */ + public AxisBoundsStatus getXAxisBoundsStatus() { + return mXAxisBoundsStatus; + } + + /** + * @return the y axis state + */ + public AxisBoundsStatus getYAxisBoundsStatus() { + return mYAxisBoundsStatus; + } + + /** + * caches the complete range (minX, maxX, minY, maxY) + * by iterating all series and all datapoints and + * stores it into #mCompleteRange + */ + public void calcCompleteRange() { + List series = mGraphView.getSeries(); + mCompleteRange.set(0, 0, 0, 0); + if (!series.isEmpty() && !series.get(0).isEmpty()) { + double d = series.get(0).getLowestValueX(); + for (Series s : series) { + if (!s.isEmpty() && d > s.getLowestValueX()) { + d = s.getLowestValueX(); + } + } + mCompleteRange.left = (float) d; + + d = series.get(0).getHighestValueX(); + for (Series s : series) { + if (!s.isEmpty() && d < s.getHighestValueX()) { + d = s.getHighestValueX(); + } + } + mCompleteRange.right = (float) d; + + d = series.get(0).getLowestValueY(); + for (Series s : series) { + if (!s.isEmpty() && d > s.getLowestValueY()) { + d = s.getLowestValueY(); + } + } + mCompleteRange.bottom = (float) d; + + d = series.get(0).getHighestValueY(); + for (Series s : series) { + if (!s.isEmpty() && d < s.getHighestValueY()) { + d = s.getHighestValueY(); + } + } + mCompleteRange.top = (float) d; + } + + // calc current viewport bounds + if (mYAxisBoundsStatus == AxisBoundsStatus.AUTO_ADJUSTED) { + mYAxisBoundsStatus = AxisBoundsStatus.INITIAL; + } + if (mYAxisBoundsStatus == AxisBoundsStatus.INITIAL) { + mCurrentViewport.top = mCompleteRange.top; + mCurrentViewport.bottom = mCompleteRange.bottom; + } + + if (mXAxisBoundsStatus == AxisBoundsStatus.AUTO_ADJUSTED) { + mXAxisBoundsStatus = AxisBoundsStatus.INITIAL; + } + if (mXAxisBoundsStatus == AxisBoundsStatus.INITIAL) { + mCurrentViewport.left = mCompleteRange.left; + mCurrentViewport.right = mCompleteRange.right; + } else if (mXAxisBoundsManual && !mYAxisBoundsManual && mCompleteRange.width() != 0) { + // get highest/lowest of current viewport + // lowest + double d = Double.MAX_VALUE; + for (Series s : series) { + Iterator values = s.getValues(mCurrentViewport.left, mCurrentViewport.right); + while (values.hasNext()) { + double v = values.next().getY(); + if (d > v) { + d = v; + } + } + } + + mCurrentViewport.bottom = (float) d; + + // highest + d = Double.MIN_VALUE; + for (Series s : series) { + Iterator values = s.getValues(mCurrentViewport.left, mCurrentViewport.right); + while (values.hasNext()) { + double v = values.next().getY(); + if (d < v) { + d = v; + } + } + } + mCurrentViewport.top = (float) d; + } + + // fixes blank screen when range is zero + if (mCurrentViewport.left == mCurrentViewport.right) mCurrentViewport.right++; + if (mCurrentViewport.top == mCurrentViewport.bottom) mCurrentViewport.top++; + } + + /** + * @param completeRange if true => minX of the complete range of all series + * if false => minX of the current visible viewport + * @return the min x value + */ + public double getMinX(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.left; + } else { + return (double) mCurrentViewport.left; + } + } + + /** + * @param completeRange if true => maxX of the complete range of all series + * if false => maxX of the current visible viewport + * @return the max x value + */ + public double getMaxX(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.right; + } else { + return mCurrentViewport.right; + } + } + + /** + * @param completeRange if true => minY of the complete range of all series + * if false => minY of the current visible viewport + * @return the min y value + */ + public double getMinY(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.bottom; + } else { + return mCurrentViewport.bottom; + } + } + + /** + * @param completeRange if true => maxY of the complete range of all series + * if false => maxY of the current visible viewport + * @return the max y value + */ + public double getMaxY(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.top; + } else { + return mCurrentViewport.top; + } + } + + /** + * set the maximal y value for the current viewport. + * Make sure to set the y bounds to manual via + * {@link #setYAxisBoundsManual(boolean)} + * @param y max / highest value + */ + public void setMaxY(double y) { + mCurrentViewport.top = (float) y; + } + + /** + * set the minimal y value for the current viewport. + * Make sure to set the y bounds to manual via + * {@link #setYAxisBoundsManual(boolean)} + * @param y min / lowest value + */ + public void setMinY(double y) { + mCurrentViewport.bottom = (float) y; + } + + /** + * set the maximal x value for the current viewport. + * Make sure to set the x bounds to manual via + * {@link #setXAxisBoundsManual(boolean)} + * @param x max / highest value + */ + public void setMaxX(double x) { + mCurrentViewport.right = (float) x; + } + + /** + * set the minimal x value for the current viewport. + * Make sure to set the x bounds to manual via + * {@link #setXAxisBoundsManual(boolean)} + * @param x min / lowest value + */ + public void setMinX(double x) { + mCurrentViewport.left = (float) x; + } + + /** + * release the glowing effects + */ + private void releaseEdgeEffects() { + mEdgeEffectLeftActive + = mEdgeEffectRightActive + = false; + mEdgeEffectLeft.onRelease(); + mEdgeEffectRight.onRelease(); + } + + /** + * not used currently + * + * @param velocityX + * @param velocityY + */ + private void fling(int velocityX, int velocityY) { + velocityY = 0; + releaseEdgeEffects(); + // Flings use math in pixels (as opposed to math based on the viewport). + mScrollerStartViewport.set(mCurrentViewport); + int maxX = (int)((mCurrentViewport.width()/mCompleteRange.width())*(float)mGraphView.getGraphContentWidth()) - mGraphView.getGraphContentWidth(); + int maxY = (int)((mCurrentViewport.height()/mCompleteRange.height())*(float)mGraphView.getGraphContentHeight()) - mGraphView.getGraphContentHeight(); + int startX = (int)((mCurrentViewport.left - mCompleteRange.left)/mCompleteRange.width())*maxX; + int startY = (int)((mCurrentViewport.top - mCompleteRange.top)/mCompleteRange.height())*maxY; + mScroller.forceFinished(true); + mScroller.fling( + startX, + startY, + velocityX, + velocityY, + 0, maxX, + 0, maxY, + mGraphView.getGraphContentWidth() / 2, + mGraphView.getGraphContentHeight() / 2); + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + + /** + * not used currently + */ + public void computeScroll() { + if (true) return; + + boolean needsInvalidate = false; + + if (mScroller.computeScrollOffset()) { + // The scroller isn't finished, meaning a fling or programmatic pan operation is + // currently active. + + int completeWidth = (int)((mCompleteRange.width()/mCurrentViewport.width()) * (float) mGraphView.getGraphContentWidth()); + int completeHeight = (int)((mCompleteRange.height()/mCurrentViewport.height()) * (float) mGraphView.getGraphContentHeight()); + + int currX = mScroller.getCurrX(); + int currY = mScroller.getCurrY(); + + boolean canScrollX = mCurrentViewport.left > mCompleteRange.left + || mCurrentViewport.right < mCompleteRange.right; + boolean canScrollY = mCurrentViewport.bottom > mCompleteRange.bottom + || mCurrentViewport.top < mCompleteRange.top; + + if (canScrollX + && currX < 0 + && mEdgeEffectLeft.isFinished() + && !mEdgeEffectLeftActive) { + mEdgeEffectLeft.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectLeftActive = true; + needsInvalidate = true; + } else if (canScrollX + && currX > (completeWidth - mGraphView.getGraphContentWidth()) + && mEdgeEffectRight.isFinished() + && !mEdgeEffectRightActive) { + mEdgeEffectRight.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectRightActive = true; + needsInvalidate = true; + } + + if (canScrollY + && currY < 0 + && mEdgeEffectTop.isFinished() + && !mEdgeEffectTopActive) { + mEdgeEffectTop.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectTopActive = true; + needsInvalidate = true; + } else if (canScrollY + && currY > (completeHeight - mGraphView.getGraphContentHeight()) + && mEdgeEffectBottom.isFinished() + && !mEdgeEffectBottomActive) { + mEdgeEffectBottom.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectBottomActive = true; + needsInvalidate = true; + } + + float currXRange = mCompleteRange.left + mCompleteRange.width() + * currX / completeWidth; + float currYRange = mCompleteRange.top - mCompleteRange.height() + * currY / completeHeight; + + float currWidth = mCurrentViewport.width(); + float currHeight = mCurrentViewport.height(); + mCurrentViewport.left = currXRange; + mCurrentViewport.right = currXRange + currWidth; + //mCurrentViewport.bottom = currYRange; + //mCurrentViewport.top = currYRange + currHeight; + } + + if (needsInvalidate) { + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + } + + /** + * Draws the overscroll "glow" at the four edges of the chart region, if necessary. + * + * @see EdgeEffectCompat + */ + private void drawEdgeEffectsUnclipped(Canvas canvas) { + // The methods below rotate and translate the canvas as needed before drawing the glow, + // since EdgeEffectCompat always draws a top-glow at 0,0. + + boolean needsInvalidate = false; + + if (!mEdgeEffectTop.isFinished()) { + final int restoreCount = canvas.save(); + canvas.translate(mGraphView.getGraphContentLeft(), mGraphView.getGraphContentTop()); + mEdgeEffectTop.setSize(mGraphView.getGraphContentWidth(), mGraphView.getGraphContentHeight()); + if (mEdgeEffectTop.draw(canvas)) { + needsInvalidate = true; + } + canvas.restoreToCount(restoreCount); + } + + //if (!mEdgeEffectBottom.isFinished()) { + // final int restoreCount = canvas.save(); + // canvas.translate(2 * mContentRect.left - mContentRect.right, mContentRect.bottom); + // canvas.rotate(180, mContentRect.width(), 0); + // mEdgeEffectBottom.setSize(mContentRect.width(), mContentRect.height()); + // if (mEdgeEffectBottom.draw(canvas)) { + // needsInvalidate = true; + // } + // canvas.restoreToCount(restoreCount); + //} + + if (!mEdgeEffectLeft.isFinished()) { + final int restoreCount = canvas.save(); + canvas.translate(mGraphView.getGraphContentLeft(), mGraphView.getGraphContentTop()+ mGraphView.getGraphContentHeight()); + canvas.rotate(-90, 0, 0); + mEdgeEffectLeft.setSize(mGraphView.getGraphContentHeight(), mGraphView.getGraphContentWidth()); + if (mEdgeEffectLeft.draw(canvas)) { + needsInvalidate = true; + } + canvas.restoreToCount(restoreCount); + } + + if (!mEdgeEffectRight.isFinished()) { + final int restoreCount = canvas.save(); + canvas.translate(mGraphView.getGraphContentLeft()+ mGraphView.getGraphContentWidth(), mGraphView.getGraphContentTop()); + canvas.rotate(90, 0, 0); + mEdgeEffectRight.setSize(mGraphView.getGraphContentHeight(), mGraphView.getGraphContentWidth()); + if (mEdgeEffectRight.draw(canvas)) { + needsInvalidate = true; + } + canvas.restoreToCount(restoreCount); + } + + if (needsInvalidate) { + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + } + + /** + * will be first called in order to draw + * the canvas + * Used to draw the background + * + * @param c canvas. + */ + public void drawFirst(Canvas c) { + // draw background + if (mBackgroundColor != Color.TRANSPARENT) { + mPaint.setColor(mBackgroundColor); + c.drawRect( + mGraphView.getGraphContentLeft(), + mGraphView.getGraphContentTop(), + mGraphView.getGraphContentLeft()+mGraphView.getGraphContentWidth(), + mGraphView.getGraphContentTop()+mGraphView.getGraphContentHeight(), + mPaint + ); + } + } + + /** + * draws the glowing edge effect + * + * @param c canvas + */ + public void draw(Canvas c) { + drawEdgeEffectsUnclipped(c); + } + + /** + * @return background of the viewport area + */ + public int getBackgroundColor() { + return mBackgroundColor; + } + + /** + * @param mBackgroundColor background of the viewport area + * use transparent to have no background + */ + public void setBackgroundColor(int mBackgroundColor) { + this.mBackgroundColor = mBackgroundColor; + } + + /** + * @return whether the viewport is scalable + */ + public boolean isScalable() { + return mIsScalable; + } + + /** + * active the scaling/zooming feature + * notice: sets the x axis bounds to manual + * + * @param mIsScalable whether the viewport is scalable + */ + public void setScalable(boolean mIsScalable) { + this.mIsScalable = mIsScalable; + if (mIsScalable) { + mIsScrollable = true; + + // set viewport to manual + setXAxisBoundsManual(true); + } + + } + + /** + * @return whether the x axis bounds are manual. + * @see #setMinX(double) + * @see #setMaxX(double) + */ + public boolean isXAxisBoundsManual() { + return mXAxisBoundsManual; + } + + /** + * @param mXAxisBoundsManual whether the x axis bounds are manual. + * @see #setMinX(double) + * @see #setMaxX(double) + */ + public void setXAxisBoundsManual(boolean mXAxisBoundsManual) { + this.mXAxisBoundsManual = mXAxisBoundsManual; + if (mXAxisBoundsManual) { + mXAxisBoundsStatus = AxisBoundsStatus.FIX; + } + } + + /** + * @return whether the y axis bound are manual + */ + public boolean isYAxisBoundsManual() { + return mYAxisBoundsManual; + } + + /** + * @param mYAxisBoundsManual whether the y axis bounds are manual + * @see #setMaxY(double) + * @see #setMinY(double) + */ + public void setYAxisBoundsManual(boolean mYAxisBoundsManual) { + this.mYAxisBoundsManual = mYAxisBoundsManual; + if (mYAxisBoundsManual) { + mYAxisBoundsStatus = AxisBoundsStatus.FIX; + } + } + + /** + * forces the viewport to scroll to the end + * of the range by keeping the current viewport size. + * + * Important: Only takes effect if x axis bounds are manual. + * + * @see #setXAxisBoundsManual(boolean) + */ + public void scrollToEnd() { + if (mXAxisBoundsManual) { + float size = mCurrentViewport.width(); + mCurrentViewport.right = mCompleteRange.right; + mCurrentViewport.left = mCompleteRange.right - size; + mScrollingReferenceX = Float.NaN; + mGraphView.onDataChanged(true, false); + } else { + Log.w("GraphView", "scrollToEnd works only with manual x axis bounds"); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java b/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java new file mode 100644 index 0000000000..20b497c91f --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java @@ -0,0 +1,46 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.compat; + +import android.annotation.TargetApi; +import android.os.Build; +import android.widget.OverScroller; + +/** + * A utility class for using {@link android.widget.OverScroller} in a backward-compatible fashion. + */ +public class OverScrollerCompat { + /** + * Disallow instantiation. + */ + private OverScrollerCompat() { + } + /** + * @see android.view.ScaleGestureDetector#getCurrentSpanY() + */ + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) + public static float getCurrVelocity(OverScroller overScroller) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return overScroller.getCurrVelocity(); + } else { + return 0; + } + } +} \ No newline at end of file diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java new file mode 100644 index 0000000000..1e9fa3cff4 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java @@ -0,0 +1,94 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.helper; + +import android.content.Context; + +import com.jjoe64.graphview.DefaultLabelFormatter; + +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Helper class to use date objects as x-values. + * This will use your own Date Format or by default + * the Android default date format to convert + * the x-values (that has to be millis from + * 01-01-1970) into a formatted date string. + * + * See the DateAsXAxis example in the GraphView-Demos project + * to see a working example. + * + * @author jjoe64 + */ +public class DateAsXAxisLabelFormatter extends DefaultLabelFormatter { + /** + * the date format that will convert + * the unix timestamp to string + */ + protected final DateFormat mDateFormat; + + /** + * calendar to avoid creating new date objects + */ + protected final Calendar mCalendar; + + /** + * create the formatter with the Android default date format to convert + * the x-values. + * + * @param context the application context + */ + public DateAsXAxisLabelFormatter(Context context) { + mDateFormat = android.text.format.DateFormat.getDateFormat(context); + mCalendar = Calendar.getInstance(); + } + + /** + * create the formatter with your own custom + * date format to convert the x-values. + * + * @param context the application context + * @param dateFormat custom date format + */ + public DateAsXAxisLabelFormatter(Context context, DateFormat dateFormat) { + mDateFormat = dateFormat; + mCalendar = Calendar.getInstance(); + } + + /** + * formats the x-values as date string. + * + * @param value raw value + * @param isValueX true if it's a x value, otherwise false + * @return value converted to string + */ + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX) { + // format as date + mCalendar.setTimeInMillis((long) value); + return mDateFormat.format(mCalendar.getTimeInMillis()); + } else { + return super.formatLabel(value, isValueX); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java b/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java new file mode 100644 index 0000000000..d036805bc8 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java @@ -0,0 +1,137 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.helper; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; +import android.util.Log; + +import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.R; +import com.jjoe64.graphview.series.BarGraphSeries; +import com.jjoe64.graphview.series.BaseSeries; +import com.jjoe64.graphview.series.DataPoint; +import com.jjoe64.graphview.series.DataPointInterface; +import com.jjoe64.graphview.series.LineGraphSeries; +import com.jjoe64.graphview.series.PointsGraphSeries; +import com.jjoe64.graphview.series.Series; + +/** + * helper class to use GraphView directly + * in a XML layout file. + * + * You can set the data via attribute app:seriesData + * in the format: "X=Y;X=Y;..." e.g. "0=5.0;1=5;2=4;3=9" + * + * Other styling options: + *
  • app:seriesType="line|bar|points"
  • + *
  • app:seriesColor="#ff0000"
  • + *
  • app:seriesTitle="foobar" - if this is set, the legend will be drawn
  • + *
  • android:title="foobar"
  • + * + * Example: + *
    + * {@code
    + *  
    + * }
    + * 
    + * + * @author jjoe64 + */ +public class GraphViewXML extends GraphView { + /** + * creates the graphview object with data and + * other options from xml attributes. + * + * @param context + * @param attrs + */ + public GraphViewXML(Context context, AttributeSet attrs) { + super(context, attrs); + + // get attributes + TypedArray a=context.obtainStyledAttributes( + attrs, + R.styleable.GraphViewXML); + + String dataStr = a.getString(R.styleable.GraphViewXML_seriesData); + int color = a.getColor(R.styleable.GraphViewXML_seriesColor, Color.TRANSPARENT); + String type = a.getString(R.styleable.GraphViewXML_seriesType); + String seriesTitle = a.getString(R.styleable.GraphViewXML_seriesTitle); + String title = a.getString(R.styleable.GraphViewXML_android_title); + + a.recycle(); + + // decode data + DataPoint[] data; + if (dataStr == null || dataStr.isEmpty()) { + throw new IllegalArgumentException("Attribute seriesData is required in the format: 0=5.0;1=5;2=4;3=9"); + } else { + String[] d = dataStr.split(";"); + try { + data = new DataPoint[d.length]; + int i = 0; + for (String dd : d) { + String[] xy = dd.split("="); + data[i] = new DataPoint(Double.parseDouble(xy[0]), Double.parseDouble(xy[1])); + i++; + } + } catch (Exception e) { + Log.e("GraphViewXML", e.toString()); + throw new IllegalArgumentException("Attribute seriesData is broken. Use this format: 0=5.0;1=5;2=4;3=9"); + } + } + + // create series + BaseSeries series; + if (type == null || type.isEmpty()) { + type = "line"; + } + if (type.equals("line")) { + series = new LineGraphSeries(data); + } else if (type.equals("bar")) { + series = new BarGraphSeries(data); + } else if (type.equals("points")) { + series = new PointsGraphSeries(data); + } else { + throw new IllegalArgumentException("unknown graph type: "+type+". Possible is line|bar|points"); + } + if (color != Color.TRANSPARENT) { + series.setColor(color); + } + addSeries(series); + + if (seriesTitle != null && !seriesTitle.isEmpty()) { + series.setTitle(seriesTitle); + getLegendRenderer().setVisible(true); + } + + if (title != null && !title.isEmpty()) { + setTitle(title); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java new file mode 100644 index 0000000000..4b38dbf4c2 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java @@ -0,0 +1,209 @@ +package com.jjoe64.graphview.helper; + +import com.jjoe64.graphview.DefaultLabelFormatter; +import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.LabelFormatter; +import com.jjoe64.graphview.Viewport; + +/** + * Use this label formatter to show static labels. + * Static labels are not bound to the data. It is typical used + * for show text like "low", "middle", "high". + * + * You can set the static labels for vertical or horizontal + * individually and you can define a label formatter that + * is to be used if you don't define static labels. + * + * For example if you only use static labels for horizontal labels, + * graphview will use the dynamicLabelFormatter for the vertical labels. + */ +public class StaticLabelsFormatter implements LabelFormatter { + /** + * reference to the viewport + */ + protected Viewport mViewport; + + /** + * the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + protected String[] mVerticalLabels; + + /** + * the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + protected String[] mHorizontalLabels; + + /** + * the label formatter that will format the labels + * for that there are no static labels defined. + */ + protected LabelFormatter mDynamicLabelFormatter; + + /** + * reference to the graphview + */ + protected final GraphView mGraphView; + + /** + * creates the formatter without any static labels + * define your static labels via {@link #setHorizontalLabels(String[])} and {@link #setVerticalLabels(String[])} + * + * @param graphView reference to the graphview + */ + public StaticLabelsFormatter(GraphView graphView) { + mGraphView = graphView; + init(null, null, null); + } + + /** + * creates the formatter without any static labels. + * define your static labels via {@link #setHorizontalLabels(String[])} and {@link #setVerticalLabels(String[])} + * + * @param graphView reference to the graphview + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + public StaticLabelsFormatter(GraphView graphView, LabelFormatter dynamicLabelFormatter) { + mGraphView = graphView; + init(null, null, dynamicLabelFormatter); + } + + /** + * creates the formatter with static labels defined. + * + * @param graphView reference to the graphview + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + public StaticLabelsFormatter(GraphView graphView, String[] horizontalLabels, String[] verticalLabels) { + mGraphView = graphView; + init(horizontalLabels, verticalLabels, null); + } + + /** + * creates the formatter with static labels defined. + * + * @param graphView reference to the graphview + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + public StaticLabelsFormatter(GraphView graphView, String[] horizontalLabels, String[] verticalLabels, LabelFormatter dynamicLabelFormatter) { + mGraphView = graphView; + init(horizontalLabels, verticalLabels, dynamicLabelFormatter); + } + + /** + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + protected void init(String[] horizontalLabels, String[] verticalLabels, LabelFormatter dynamicLabelFormatter) { + mDynamicLabelFormatter = dynamicLabelFormatter; + if (mDynamicLabelFormatter == null) { + mDynamicLabelFormatter = new DefaultLabelFormatter(); + } + + mHorizontalLabels = horizontalLabels; + mVerticalLabels = verticalLabels; + } + + /** + * Set a label formatter that will be used for the labels + * that don't have static labels. + * + * For example if you only use static labels for horizontal labels, + * graphview will use the dynamicLabelFormatter for the vertical labels. + * + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + public void setDynamicLabelFormatter(LabelFormatter dynamicLabelFormatter) { + this.mDynamicLabelFormatter = dynamicLabelFormatter; + adjust(); + } + + /** + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + public void setHorizontalLabels(String[] horizontalLabels) { + this.mHorizontalLabels = horizontalLabels; + adjust(); + } + + /** + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + public void setVerticalLabels(String[] verticalLabels) { + this.mVerticalLabels = verticalLabels; + adjust(); + } + + /** + * + * @param value raw input number + * @param isValueX true if it is a value for the x axis + * false if it is a value for the y axis + * @return + */ + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX && mHorizontalLabels != null) { + double minX = mViewport.getMinX(false); + double maxX = mViewport.getMaxX(false); + double range = maxX - minX; + value = value-minX; + int idx = (int)((value/range) * (mHorizontalLabels.length-1)); + return mHorizontalLabels[idx]; + } else if (!isValueX && mVerticalLabels != null) { + double minY = mViewport.getMinY(false); + double maxY = mViewport.getMaxY(false); + double range = maxY - minY; + value = value-minY; + int idx = (int)((value/range) * (mVerticalLabels.length-1)); + return mVerticalLabels[idx]; + } else { + return mDynamicLabelFormatter.formatLabel(value, isValueX); + } + } + + /** + * @param viewport the used viewport + */ + @Override + public void setViewport(Viewport viewport) { + mViewport = viewport; + adjust(); + } + + /** + * adjusts the number of vertical/horizontal labels + */ + protected void adjust() { + mDynamicLabelFormatter.setViewport(mViewport); + if (mVerticalLabels != null) { + if (mVerticalLabels.length < 2) { + throw new IllegalStateException("You need at least 2 vertical labels if you use static label formatter."); + } + mGraphView.getGridLabelRenderer().setNumVerticalLabels(mVerticalLabels.length); + } + if (mHorizontalLabels != null) { + if (mHorizontalLabels.length < 2) { + throw new IllegalStateException("You need at least 2 horizontal labels if you use static label formatter."); + } + mGraphView.getGridLabelRenderer().setNumHorizontalLabels(mHorizontalLabels.length); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java new file mode 100644 index 0000000000..8db7bac94b --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java @@ -0,0 +1,379 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.Log; + +import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.ValueDependentColor; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Series with Bars to visualize the data. + * The Bars are always vertical. + * + * @author jjoe64 + */ +public class BarGraphSeries extends BaseSeries { + /** + * paint to do drawing on canvas + */ + private Paint mPaint; + + /** + * spacing between the bars in percentage. + * 0 => no spacing + * 100 => the space bewetten the bars is as big as the bars itself + */ + private int mSpacing; + + /** + * callback to generate value-dependent colors + * of the bars + */ + private ValueDependentColor mValueDependentColor; + + /** + * flag whether the values should drawn + * above the bars as text + */ + private boolean mDrawValuesOnTop; + + /** + * color of the text above the bars. + * + * @see #mDrawValuesOnTop + */ + private int mValuesOnTopColor; + + /** + * font size of the text above the bars. + * + * @see #mDrawValuesOnTop + */ + private float mValuesOnTopSize; + + /** + * stores the coordinates of the bars to + * trigger tap on series events. + */ + private Map mDataPoints = new HashMap(); + + /** + * creates bar series without any data + */ + public BarGraphSeries() { + mPaint = new Paint(); + } + + /** + * creates bar series with data + * + * @param data values + */ + public BarGraphSeries(E[] data) { + super(data); + mPaint = new Paint(); + } + + /** + * draws the bars on the canvas + * + * @param graphView corresponding graphview + * @param canvas canvas + * @param isSecondScale whether we are plotting the second scale or not + */ + @Override + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { + mPaint.setTextAlign(Paint.Align.CENTER); + if (mValuesOnTopSize == 0) { + mValuesOnTopSize = graphView.getGridLabelRenderer().getTextSize(); + } + mPaint.setTextSize(mValuesOnTopSize); + + // get data + double maxX = graphView.getViewport().getMaxX(false); + double minX = graphView.getViewport().getMinX(false); + + double maxY; + double minY; + if (isSecondScale) { + maxY = graphView.getSecondScale().getMaxY(); + minY = graphView.getSecondScale().getMinY(); + } else { + maxY = graphView.getViewport().getMaxY(false); + minY = graphView.getViewport().getMinY(false); + } + + // Iterate through all bar graph series + // so we know how wide to make our bar, + // and in what position to put it in + int numBarSeries = 0; + int currentSeriesOrder = 0; + int numValues = 0; + boolean isCurrentSeries; + SortedSet xVals = new TreeSet(); + for(Series inspectedSeries: graphView.getSeries()) { + if(inspectedSeries instanceof BarGraphSeries) { + isCurrentSeries = (inspectedSeries == this); + if(isCurrentSeries) { + currentSeriesOrder = numBarSeries; + } + numBarSeries++; + + // calculate the number of slots for bars based on the minimum distance between + // x coordinates in the series. This is divided into the range to find + // the placement and width of bar slots + // (sections of the x axis for each bar or set of bars) + // TODO: Move this somewhere more general and cache it, so we don't recalculate it for each series + Iterator curValues = inspectedSeries.getValues(minX, maxX); + if (curValues.hasNext()) { + xVals.add(curValues.next().getX()); + if(isCurrentSeries) { numValues++; } + while (curValues.hasNext()) { + xVals.add(curValues.next().getX()); + if(isCurrentSeries) { numValues++; } + } + } + } + } + if (numValues == 0) { + return; + } + + Double lastVal = null; + double minGap = 0; + for(Double curVal: xVals) { + if(lastVal != null) { + double curGap = Math.abs(curVal - lastVal); + if (minGap == 0 || (curGap > 0 && curGap < minGap)) { + minGap = curGap; + } + } + lastVal = curVal; + } + + int numBarSlots = (minGap == 0) ? 1 : (int)Math.round((maxX - minX)/minGap) + 1; + + Iterator values = getValues(minX, maxX); + + // Calculate the overall bar slot width - this includes all bars across + // all series, and any spacing between sets of bars + float barSlotWidth = numBarSlots == 1 + ? graphView.getGraphContentWidth() + : graphView.getGraphContentWidth() / (numBarSlots-1); + Log.d("BarGraphSeries", "numBars=" + numBarSlots); + + // Total spacing (both sides) between sets of bars + float spacing = Math.min((float) barSlotWidth*mSpacing/100, barSlotWidth*0.98f); + // Width of an individual bar + float barWidth = (barSlotWidth - spacing) / numBarSeries; + // Offset from the center of a given bar to start drawing + float offset = barSlotWidth/2; + + double diffY = maxY - minY; + double diffX = maxX - minX; + float contentHeight = graphView.getGraphContentHeight(); + float contentWidth = graphView.getGraphContentWidth(); + float contentLeft = graphView.getGraphContentLeft(); + float contentTop = graphView.getGraphContentTop(); + + // draw data + int i=0; + while (values.hasNext()) { + E value = values.next(); + + double valY = value.getY() - minY; + double ratY = valY / diffY; + double y = contentHeight * ratY; + + double valY0 = 0 - minY; + double ratY0 = valY0 / diffY; + double y0 = contentHeight * ratY0; + + double valX = value.getX() - minX; + double ratX = valX / diffX; + double x = contentWidth * ratX; + + // hook for value dependent color + if (getValueDependentColor() != null) { + mPaint.setColor(getValueDependentColor().get(value)); + } else { + mPaint.setColor(getColor()); + } + + float left = (float)x + contentLeft - offset + spacing/2 + currentSeriesOrder*barWidth; + float top = (contentTop - (float)y) + contentHeight; + float right = left + barWidth; + float bottom = (contentTop - (float)y0) + contentHeight - (graphView.getGridLabelRenderer().isHighlightZeroLines()?4:1); + + boolean reverse = top > bottom; + if (reverse) { + float tmp = top; + top = bottom + (graphView.getGridLabelRenderer().isHighlightZeroLines()?4:1); + bottom = tmp; + } + + // overdraw + left = Math.max(left, contentLeft); + right = Math.min(right, contentLeft+contentWidth); + bottom = Math.min(bottom, contentTop+contentHeight); + top = Math.max(top, contentTop); + + mDataPoints.put(new RectF(left, top, right, bottom), value); + + canvas.drawRect(left, top, right, bottom, mPaint); + + // set values on top of graph + if (mDrawValuesOnTop) { + if (reverse) { + top = bottom + mValuesOnTopSize + 4; + if (top > contentTop+contentHeight) top = contentTop + contentHeight; + } else { + top -= 4; + if (top<=contentTop) top+=contentTop+4; + } + + mPaint.setColor(mValuesOnTopColor); + canvas.drawText( + graphView.getGridLabelRenderer().getLabelFormatter().formatLabel(value.getY(), false) + , (left+right)/2, top, mPaint); + } + + i++; + } + } + + /** + * @return the hook to generate value-dependent color. default null + */ + public ValueDependentColor getValueDependentColor() { + return mValueDependentColor; + } + + /** + * set a hook to make the color of the bars depending + * on the actually value/data. + * + * @param mValueDependentColor hook + * null to disable + */ + public void setValueDependentColor(ValueDependentColor mValueDependentColor) { + this.mValueDependentColor = mValueDependentColor; + } + + /** + * @return the spacing between the bars in percentage + */ + public int getSpacing() { + return mSpacing; + } + + /** + * @param mSpacing spacing between the bars in percentage. + * 0 => no spacing + * 100 => the space between the bars is as big as the bars itself + */ + public void setSpacing(int mSpacing) { + this.mSpacing = mSpacing; + } + + /** + * @return whether the values should be drawn above the bars + */ + public boolean isDrawValuesOnTop() { + return mDrawValuesOnTop; + } + + /** + * @param mDrawValuesOnTop flag whether the values should drawn + * above the bars as text + */ + public void setDrawValuesOnTop(boolean mDrawValuesOnTop) { + this.mDrawValuesOnTop = mDrawValuesOnTop; + } + + /** + * @return font color of the values on top of the bars + * @see #setDrawValuesOnTop(boolean) + */ + public int getValuesOnTopColor() { + return mValuesOnTopColor; + } + + /** + * @param mValuesOnTopColor the font color of the values on top of the bars + * @see #setDrawValuesOnTop(boolean) + */ + public void setValuesOnTopColor(int mValuesOnTopColor) { + this.mValuesOnTopColor = mValuesOnTopColor; + } + + /** + * @return font size of the values above the bars + * @see #setDrawValuesOnTop(boolean) + */ + public float getValuesOnTopSize() { + return mValuesOnTopSize; + } + + /** + * @param mValuesOnTopSize font size of the values above the bars + * @see #setDrawValuesOnTop(boolean) + */ + public void setValuesOnTopSize(float mValuesOnTopSize) { + this.mValuesOnTopSize = mValuesOnTopSize; + } + + /** + * resets the cached coordinates of the bars + */ + @Override + protected void resetDataPoints() { + mDataPoints.clear(); + } + + /** + * find the corresponding data point by + * coordinates. + * + * @param x pixels + * @param y pixels + * @return datapoint or null + */ + @Override + protected E findDataPoint(float x, float y) { + for (Map.Entry entry : mDataPoints.entrySet()) { + if (x >= entry.getKey().left && x <= entry.getKey().right + && y >= entry.getKey().top && y <= entry.getKey().bottom) { + return entry.getValue(); + } + } + return null; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java new file mode 100644 index 0000000000..8ecdf23a73 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java @@ -0,0 +1,448 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.PointF; +import android.util.Log; + +import com.jjoe64.graphview.GraphView; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * Basis implementation for series. + * Used for series that are plotted on + * a default x/y 2d viewport. + * + * Extend this class to implement your own custom + * graph type. + * + * This implementation uses a internal Array to store + * the data. If you want to implement a custom data provider + * you may want to implement {@link com.jjoe64.graphview.series.Series}. + * + * @author jjoe64 + */ +public abstract class BaseSeries implements Series { + /** + * holds the data + */ + final private List mData = new ArrayList(); + + /** + * stores the used coordinates to find the + * corresponding data point on a tap + * + * Key => x/y pixel + * Value => Plotted Datapoint + * + * will be filled while drawing via {@link #registerDataPoint(float, float, DataPointInterface)} + */ + private Map mDataPoints = new HashMap(); + + /** + * title for this series that can be displayed + * in the legend. + */ + private String mTitle; + + /** + * base color for this series. will be used also in + * the legend + */ + private int mColor = 0xff0077cc; + + /** + * listener to handle tap events on a data point + */ + protected OnDataPointTapListener mOnDataPointTapListener; + + /** + * stores the graphviews where this series is used. + * Can be more than one. + */ + private List mGraphViews; + + /** + * creates series without data + */ + public BaseSeries() { + mGraphViews = new ArrayList(); + } + + /** + * creates series with data + * + * @param data data points + * important: array has to be sorted from lowest x-value to the highest + */ + public BaseSeries(E[] data) { + mGraphViews = new ArrayList(); + for (E d : data) { + mData.add(d); + } + } + + /** + * @return the lowest x value, or 0 if there is no data + */ + public double getLowestValueX() { + if (mData.isEmpty()) return 0d; + return mData.get(0).getX(); + } + + /** + * @return the highest x value, or 0 if there is no data + */ + public double getHighestValueX() { + if (mData.isEmpty()) return 0d; + return mData.get(mData.size()-1).getX(); + } + + /** + * @return the lowest y value, or 0 if there is no data + */ + public double getLowestValueY() { + if (mData.isEmpty()) return 0d; + double l = mData.get(0).getY(); + for (int i = 1; i < mData.size(); i++) { + double c = mData.get(i).getY(); + if (l > c) { + l = c; + } + } + return l; + } + + /** + * @return the highest y value, or 0 if there is no data + */ + public double getHighestValueY() { + if (mData.isEmpty()) return 0d; + double h = mData.get(0).getY(); + for (int i = 1; i < mData.size(); i++) { + double c = mData.get(i).getY(); + if (h < c) { + h = c; + } + } + return h; + } + + /** + * get the values for a given x range. if from and until are bigger or equal than + * all the data, the original data is returned. + * If it is only a part of the data, the range is returned plus one datapoint + * before and after to get a nice scrolling. + * + * @param from minimal x-value + * @param until maximal x-value + * @return data for the range +/- 1 datapoint + */ + @Override + public Iterator getValues(final double from, final double until) { + if (from <= getLowestValueX() && until >= getHighestValueX()) { + return mData.iterator(); + } else { + return new Iterator() { + Iterator org = mData.iterator(); + E nextValue = null; + E nextNextValue = null; + boolean plusOne = true; + + { + // go to first + boolean found = false; + E prevValue = null; + if (org.hasNext()) { + prevValue = org.next(); + } + if (prevValue.getX() >= from) { + nextValue = prevValue; + found = true; + } else { + while (org.hasNext()) { + nextValue = org.next(); + if (nextValue.getX() >= from) { + found = true; + nextNextValue = nextValue; + nextValue = prevValue; + break; + } + prevValue = nextValue; + } + } + if (!found) { + nextValue = null; + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public E next() { + if (hasNext()) { + E r = nextValue; + if (r.getX() > until) { + plusOne = false; + } + if (nextNextValue != null) { + nextValue = nextNextValue; + nextNextValue = null; + } else if (org.hasNext()) nextValue = org.next(); + else nextValue = null; + return r; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public boolean hasNext() { + return nextValue != null && (nextValue.getX() <= until || plusOne); + } + }; + } + } + + /** + * @return the title of the series + */ + public String getTitle() { + return mTitle; + } + + /** + * set the title of the series. This will be used in + * the legend. + * + * @param mTitle title of the series + */ + public void setTitle(String mTitle) { + this.mTitle = mTitle; + } + + /** + * @return color of the series + */ + public int getColor() { + return mColor; + } + + /** + * set the color of the series. This will be used in + * plotting (depends on the series implementation) and + * is used in the legend. + * + * @param mColor + */ + public void setColor(int mColor) { + this.mColor = mColor; + } + + /** + * set a listener for tap on a data point. + * + * @param l listener + */ + public void setOnDataPointTapListener(OnDataPointTapListener l) { + this.mOnDataPointTapListener = l; + } + + /** + * called by the tap detector in order to trigger + * the on tap on datapoint event. + * + * @param x pixel + * @param y pixel + */ + @Override + public void onTap(float x, float y) { + if (mOnDataPointTapListener != null) { + E p = findDataPoint(x, y); + if (p != null) { + mOnDataPointTapListener.onTap(this, p); + } + } + } + + /** + * find the data point which is next to the + * coordinates + * + * @param x pixel + * @param y pixel + * @return the data point or null if nothing was found + */ + protected E findDataPoint(float x, float y) { + float shortestDistance = Float.NaN; + E shortest = null; + for (Map.Entry entry : mDataPoints.entrySet()) { + float x1 = entry.getKey().x; + float y1 = entry.getKey().y; + float x2 = x; + float y2 = y; + + float distance = (float) Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); + if (shortest == null || distance < shortestDistance) { + shortestDistance = distance; + shortest = entry.getValue(); + } + } + if (shortest != null) { + if (shortestDistance < 120) { + return shortest; + } + } + return null; + } + + /** + * register the datapoint to find it at a tap + * + * @param x pixel + * @param y pixel + * @param dp the data point to save + */ + protected void registerDataPoint(float x, float y, E dp) { + mDataPoints.put(new PointF(x, y), dp); + } + + /** + * clears the cached data point coordinates + */ + protected void resetDataPoints() { + mDataPoints.clear(); + } + + /** + * clears the data of this series and sets new. + * will redraw the graph + * + * @param data the values must be in the correct order! + * x-value has to be ASC. First the lowest x value and at least the highest x value. + */ + public void resetData(E[] data) { + mData.clear(); + for (E d : data) { + mData.add(d); + } + checkValueOrder(null); + + // update graphview + for (GraphView gv : mGraphViews) { + gv.onDataChanged(true, false); + } + } + + /** + * called when the series was added to a graph + * + * @param graphView graphview + */ + @Override + public void onGraphViewAttached(GraphView graphView) { + mGraphViews.add(graphView); + } + + /** + * + * @param dataPoint values the values must be in the correct order! + * x-value has to be ASC. First the lowest x value and at least the highest x value. + * @param scrollToEnd true => graphview will scroll to the end (maxX) + * @param maxDataPoints if max data count is reached, the oldest data + * value will be lost to avoid memory leaks + */ + public void appendData(E dataPoint, boolean scrollToEnd, int maxDataPoints) { + checkValueOrder(dataPoint); + + if (!mData.isEmpty() && dataPoint.getX() < mData.get(mData.size()-1).getX()) { + throw new IllegalArgumentException("new x-value must be greater then the last value. x-values has to be ordered in ASC."); + } + synchronized (mData) { + int curDataCount = mData.size(); + if (curDataCount < maxDataPoints) { + // enough space + mData.add(dataPoint); + } else { + // we have to trim one data + mData.remove(0); + mData.add(dataPoint); + } + } + + // recalc the labels when it was the first data + boolean keepLabels = mData.size() != 1; + + // update linked graph views + // update graphview + for (GraphView gv : mGraphViews) { + gv.onDataChanged(keepLabels, scrollToEnd); + if (scrollToEnd) { + gv.getViewport().scrollToEnd(); + } + } + } + + /** + * @return whether there are data points + */ + @Override + public boolean isEmpty() { + return mData.isEmpty(); + } + + /** + * checks that the data is in the correct order + * + * @param onlyLast if not null, it will only check that this + * datapoint is after the last point. + */ + protected void checkValueOrder(DataPointInterface onlyLast) { + if (mData.size()>1) { + if (onlyLast != null) { + // only check last + if (onlyLast.getX() < mData.get(mData.size()-1).getX()) { + throw new IllegalArgumentException("new x-value must be greater then the last value. x-values has to be ordered in ASC."); + } + } else { + double lx = mData.get(0).getX(); + + for (int i = 1; i < mData.size(); i++) { + if (mData.get(i).getX() != Double.NaN) { + if (lx > mData.get(i).getX()) { + throw new IllegalArgumentException("The order of the values is not correct. X-Values have to be ordered ASC. First the lowest x value and at least the highest x value."); + } + lx = mData.get(i).getX(); + } + } + } + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java b/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java new file mode 100644 index 0000000000..b5f5eb3ef3 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java @@ -0,0 +1,63 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.provider.ContactsContract; + +import java.io.Serializable; +import java.util.Date; + +/** + * default data point implementation. + * This stores the x and y values. + * + * @author jjoe64 + */ +public class DataPoint implements DataPointInterface, Serializable { + private static final long serialVersionUID=1428263322645L; + + private double x; + private double y; + + public DataPoint(double x, double y) { + this.x=x; + this.y=y; + } + + public DataPoint(Date x, double y) { + this.x = x.getTime(); + this.y = y; + } + + @Override + public double getX() { + return x; + } + + @Override + public double getY() { + return y; + } + + @Override + public String toString() { + return "["+x+"/"+y+"]"; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java b/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java new file mode 100644 index 0000000000..9be683bef8 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java @@ -0,0 +1,41 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +/** + * interface of data points. Implement this in order + * to use your class in {@link com.jjoe64.graphview.series.Series}. + * + * You can also use the default implementation {@link com.jjoe64.graphview.series.DataPoint} so + * you do not have to implement it for yourself. + * + * @author jjoe64 + */ +public interface DataPointInterface { + /** + * @return the x value + */ + public double getX(); + + /** + * @return the y value + */ + public double getY(); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java new file mode 100644 index 0000000000..4d721c2e6c --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java @@ -0,0 +1,409 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; + +import com.jjoe64.graphview.GraphView; + +import java.util.Iterator; + +/** + * Series to plot the data as line. + * The line can be styled with many options. + * + * @author jjoe64 + */ +public class LineGraphSeries extends BaseSeries { + /** + * wrapped styles regarding the line + */ + private final class Styles { + /** + * the thickness of the line. + * This option will be ignored if you are + * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} + */ + private int thickness = 5; + + /** + * flag whether the area under the line to the bottom + * of the viewport will be filled with a + * specific background color. + * + * @see #backgroundColor + */ + private boolean drawBackground = false; + + /** + * flag whether the data points are highlighted as + * a visible point. + * + * @see #dataPointsRadius + */ + private boolean drawDataPoints = false; + + /** + * the radius for the data points. + * + * @see #drawDataPoints + */ + private float dataPointsRadius = 10f; + + /** + * the background color for the filling under + * the line. + * + * @see #drawBackground + */ + private int backgroundColor = Color.argb(100, 172, 218, 255); + } + + /** + * wrapped styles + */ + private Styles mStyles; + + /** + * internal paint object + */ + private Paint mPaint; + + /** + * paint for the background + */ + private Paint mPaintBackground; + + /** + * path for the background filling + */ + private Path mPathBackground; + + /** + * path to the line + */ + private Path mPath; + + /** + * custom paint that can be used. + * this will ignore the thickness and color styles. + */ + private Paint mCustomPaint; + + /** + * creates a series without data + */ + public LineGraphSeries() { + init(); + } + + /** + * creates a series with data + * + * @param data data points + */ + public LineGraphSeries(E[] data) { + super(data); + init(); + } + + /** + * do the initialization + * creates internal objects + */ + protected void init() { + mStyles = new Styles(); + mPaint = new Paint(); + mPaint.setStrokeCap(Paint.Cap.ROUND); + mPaint.setStyle(Paint.Style.STROKE); + mPaintBackground = new Paint(); + + mPathBackground = new Path(); + mPath = new Path(); + } + + /** + * plots the series + * draws the line and the background + * + * @param graphView graphview + * @param canvas canvas + * @param isSecondScale flag if it is the second scale + */ + @Override + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { + resetDataPoints(); + + // get data + double maxX = graphView.getViewport().getMaxX(false); + double minX = graphView.getViewport().getMinX(false); + + double maxY; + double minY; + if (isSecondScale) { + maxY = graphView.getSecondScale().getMaxY(); + minY = graphView.getSecondScale().getMinY(); + } else { + maxY = graphView.getViewport().getMaxY(false); + minY = graphView.getViewport().getMinY(false); + } + + Iterator values = getValues(minX, maxX); + + // draw background + double lastEndY = 0; + double lastEndX = 0; + + // draw data + mPaint.setStrokeWidth(mStyles.thickness); + mPaint.setColor(getColor()); + mPaintBackground.setColor(mStyles.backgroundColor); + + Paint paint; + if (mCustomPaint != null) { + paint = mCustomPaint; + } else { + paint = mPaint; + } + + if (mStyles.drawBackground) { + mPathBackground.reset(); + } + + double diffY = maxY - minY; + double diffX = maxX - minX; + + float graphHeight = graphView.getGraphContentHeight(); + float graphWidth = graphView.getGraphContentWidth(); + float graphLeft = graphView.getGraphContentLeft(); + float graphTop = graphView.getGraphContentTop(); + + lastEndY = 0; + lastEndX = 0; + double lastUsedEndX = 0; + float firstX = 0; + int i=0; + while (values.hasNext()) { + E value = values.next(); + + double valY = value.getY() - minY; + double ratY = valY / diffY; + double y = graphHeight * ratY; + + double valX = value.getX() - minX; + double ratX = valX / diffX; + double x = graphWidth * ratX; + + double orgX = x; + double orgY = y; + + if (i > 0) { + // overdraw + if (x > graphWidth) { // end right + double b = ((graphWidth - lastEndX) * (y - lastEndY)/(x - lastEndX)); + y = lastEndY+b; + x = graphWidth; + } + if (y < 0) { // end bottom + double b = ((0 - lastEndY) * (x - lastEndX)/(y - lastEndY)); + x = lastEndX+b; + y = 0; + } + if (y > graphHeight) { // end top + double b = ((graphHeight - lastEndY) * (x - lastEndX)/(y - lastEndY)); + x = lastEndX+b; + y = graphHeight; + } + if (lastEndY < 0) { // start bottom + double b = ((0 - y) * (x - lastEndX)/(lastEndY - y)); + lastEndX = x-b; + lastEndY = 0; + } + if (lastEndX < 0) { // start left + double b = ((0 - x) * (y - lastEndY)/(lastEndX - x)); + lastEndY = y-b; + lastEndX = 0; + } + if (lastEndY > graphHeight) { // start top + double b = ((graphHeight - y) * (x - lastEndX)/(lastEndY - y)); + lastEndX = x-b; + lastEndY = graphHeight; + } + + float startX = (float) lastEndX + (graphLeft + 1); + float startY = (float) (graphTop - lastEndY) + graphHeight; + float endX = (float) x + (graphLeft + 1); + float endY = (float) (graphTop - y) + graphHeight; + + // draw data point + if (mStyles.drawDataPoints) { + //fix: last value was not drawn. Draw here now the end values + canvas.drawCircle(endX, endY, mStyles.dataPointsRadius, mPaint); + } + registerDataPoint(endX, endY, value); + + mPath.reset(); + mPath.moveTo(startX, startY); + mPath.lineTo(endX, endY); + canvas.drawPath(mPath, paint); + if (mStyles.drawBackground) { + if (i==1) { + firstX = startX; + mPathBackground.moveTo(startX, startY); + } + mPathBackground.lineTo(endX, endY); + } + lastUsedEndX = endX; + } else if (mStyles.drawDataPoints) { + //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above) + float first_X = (float) x + (graphLeft + 1); + float first_Y = (float) (graphTop - y) + graphHeight; + //TODO canvas.drawCircle(first_X, first_Y, dataPointsRadius, mPaint); + } + lastEndY = orgY; + lastEndX = orgX; + i++; + } + + if (mStyles.drawBackground) { + // end / close path + mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop); + mPathBackground.lineTo(firstX, graphHeight + graphTop); + mPathBackground.close(); + canvas.drawPath(mPathBackground, mPaintBackground); + } + + } + + /** + * the thickness of the line. + * This option will be ignored if you are + * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} + * + * @return the thickness of the line + */ + public int getThickness() { + return mStyles.thickness; + } + + /** + * the thickness of the line. + * This option will be ignored if you are + * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} + * + * @param thickness thickness of the line + */ + public void setThickness(int thickness) { + mStyles.thickness = thickness; + } + + /** + * flag whether the area under the line to the bottom + * of the viewport will be filled with a + * specific background color. + * + * @return whether the background will be drawn + * @see #getBackgroundColor() + */ + public boolean isDrawBackground() { + return mStyles.drawBackground; + } + + /** + * flag whether the area under the line to the bottom + * of the viewport will be filled with a + * specific background color. + * + * @param drawBackground whether the background will be drawn + * @see #setBackgroundColor(int) + */ + public void setDrawBackground(boolean drawBackground) { + mStyles.drawBackground = drawBackground; + } + + /** + * flag whether the data points are highlighted as + * a visible point. + * + * @return flag whether the data points are highlighted + * @see #setDataPointsRadius(float) + */ + public boolean isDrawDataPoints() { + return mStyles.drawDataPoints; + } + + /** + * flag whether the data points are highlighted as + * a visible point. + * + * @param drawDataPoints flag whether the data points are highlighted + * @see #setDataPointsRadius(float) + */ + public void setDrawDataPoints(boolean drawDataPoints) { + mStyles.drawDataPoints = drawDataPoints; + } + + /** + * @return the radius for the data points. + * @see #setDrawDataPoints(boolean) + */ + public float getDataPointsRadius() { + return mStyles.dataPointsRadius; + } + + /** + * @param dataPointsRadius the radius for the data points. + * @see #setDrawDataPoints(boolean) + */ + public void setDataPointsRadius(float dataPointsRadius) { + mStyles.dataPointsRadius = dataPointsRadius; + } + + /** + * @return the background color for the filling under + * the line. + * @see #setDrawBackground(boolean) + */ + public int getBackgroundColor() { + return mStyles.backgroundColor; + } + + /** + * @param backgroundColor the background color for the filling under + * the line. + * @see #setDrawBackground(boolean) + */ + public void setBackgroundColor(int backgroundColor) { + mStyles.backgroundColor = backgroundColor; + } + + /** + * custom paint that can be used. + * this will ignore the thickness and color styles. + * + * @param customPaint the custom paint to be used for rendering the line + */ + public void setCustomPaint(Paint customPaint) { + this.mCustomPaint = customPaint; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java b/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java new file mode 100644 index 0000000000..748a1122ee --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java @@ -0,0 +1,38 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +/** + * Listener for the tap event which will be + * triggered when the user touches on a datapoint. + * + * Use this in {@link com.jjoe64.graphview.series.BaseSeries#setOnDataPointTapListener(OnDataPointTapListener)} + * + * @author jjoe64 + */ +public interface OnDataPointTapListener { + /** + * gets called when the user touches on a datapoint. + * + * @param series the corresponding series + * @param dataPoint the data point that was tapped on + */ + void onTap(Series series, DataPointInterface dataPoint); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java new file mode 100644 index 0000000000..c57d476d7b --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java @@ -0,0 +1,312 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Point; + +import com.jjoe64.graphview.GraphView; + +import java.util.Iterator; + +/** + * Series that plots the data as points. + * The points can be different shapes or a + * complete custom drawing. + * + * @author jjoe64 + */ +public class PointsGraphSeries extends BaseSeries { + /** + * interface to implement a custom + * drawing for the data points. + */ + public static interface CustomShape { + /** + * called when drawing a single data point. + * use the x and y coordinates to render your + * drawing at this point. + * + * @param canvas canvas to draw on + * @param paint internal paint object. this has the correct color. + * But you can use your own paint. + * @param x x-coordinate the point has to be drawn to + * @param y y-coordinate the point has to be drawn to + * @param dataPoint the related data point + */ + void draw(Canvas canvas, Paint paint, float x, float y, DataPointInterface dataPoint); + } + + /** + * choose a predefined shape to render for + * each data point. + * You can also render a custom drawing via {@link com.jjoe64.graphview.series.PointsGraphSeries.CustomShape} + */ + public enum Shape { + /** + * draws a point / circle + */ + POINT, + + /** + * draws a triangle + */ + TRIANGLE, + + /** + * draws a rectangle + */ + RECTANGLE + } + + /** + * wrapped styles for this series + */ + private final class Styles { + /** + * this is used for the size of the shape that + * will be drawn. + * This is useless if you are using a custom shape. + */ + float size; + + /** + * the shape that will be drawn for each point. + */ + Shape shape; + } + + /** + * wrapped styles + */ + private Styles mStyles; + + /** + * internal paint object + */ + private Paint mPaint; + + /** + * handler to use a custom drawing + */ + private CustomShape mCustomShape; + + /** + * creates the series without data + */ + public PointsGraphSeries() { + init(); + } + + /** + * creates the series with data + * + * @param data datapoints + */ + public PointsGraphSeries(E[] data) { + super(data); + init(); + } + + /** + * inits the internal objects + * set the defaults + */ + protected void init() { + mStyles = new Styles(); + mStyles.size = 20f; + mPaint = new Paint(); + mPaint.setStrokeCap(Paint.Cap.ROUND); + setShape(Shape.POINT); + } + + /** + * plot the data to the viewport + * + * @param graphView graphview + * @param canvas canvas to draw on + * @param isSecondScale whether it is the second scale + */ + @Override + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { + resetDataPoints(); + + // get data + double maxX = graphView.getViewport().getMaxX(false); + double minX = graphView.getViewport().getMinX(false); + + double maxY; + double minY; + if (isSecondScale) { + maxY = graphView.getSecondScale().getMaxY(); + minY = graphView.getSecondScale().getMinY(); + } else { + maxY = graphView.getViewport().getMaxY(false); + minY = graphView.getViewport().getMinY(false); + } + + Iterator values = getValues(minX, maxX); + + // draw background + double lastEndY = 0; + double lastEndX = 0; + + // draw data + mPaint.setColor(getColor()); + + double diffY = maxY - minY; + double diffX = maxX - minX; + + float graphHeight = graphView.getGraphContentHeight(); + float graphWidth = graphView.getGraphContentWidth(); + float graphLeft = graphView.getGraphContentLeft(); + float graphTop = graphView.getGraphContentTop(); + + lastEndY = 0; + lastEndX = 0; + float firstX = 0; + int i=0; + while (values.hasNext()) { + E value = values.next(); + + double valY = value.getY() - minY; + double ratY = valY / diffY; + double y = graphHeight * ratY; + + double valX = value.getX() - minX; + double ratX = valX / diffX; + double x = graphWidth * ratX; + + double orgX = x; + double orgY = y; + + // overdraw + boolean overdraw = false; + if (x > graphWidth) { // end right + overdraw = true; + } + if (y < 0) { // end bottom + overdraw = true; + } + if (y > graphHeight) { // end top + overdraw = true; + } + + float endX = (float) x + (graphLeft + 1); + float endY = (float) (graphTop - y) + graphHeight; + registerDataPoint(endX, endY, value); + + // draw data point + if (!overdraw) { + if (mCustomShape != null) { + mCustomShape.draw(canvas, mPaint, endX, endY, value); + } else if (mStyles.shape == Shape.POINT) { + canvas.drawCircle(endX, endY, mStyles.size, mPaint); + } else if (mStyles.shape == Shape.RECTANGLE) { + canvas.drawRect(endX-mStyles.size, endY-mStyles.size, endX+mStyles.size, endY+mStyles.size, mPaint); + } else if (mStyles.shape == Shape.TRIANGLE) { + Point[] points = new Point[3]; + points[0] = new Point((int)endX, (int)(endY-getSize())); + points[1] = new Point((int)(endX+getSize()), (int)(endY+getSize()*0.67)); + points[2] = new Point((int)(endX-getSize()), (int)(endY+getSize()*0.67)); + drawArrows(points, canvas, mPaint); + } + } + + i++; + } + + } + + /** + * helper to render triangle + * + * @param point array with 3 coordinates + * @param canvas canvas to draw on + * @param paint paint object + */ + private void drawArrows(Point[] point, Canvas canvas, Paint paint) { + float [] points = new float[8]; + points[0] = point[0].x; + points[1] = point[0].y; + points[2] = point[1].x; + points[3] = point[1].y; + points[4] = point[2].x; + points[5] = point[2].y; + points[6] = point[0].x; + points[7] = point[0].y; + + canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint); + Path path = new Path(); + path.moveTo(point[0].x , point[0].y); + path.lineTo(point[1].x,point[1].y); + path.lineTo(point[2].x,point[2].y); + canvas.drawPath(path,paint); + } + + /** + * This is used for the size of the shape that + * will be drawn. + * This is useless if you are using a custom shape. + * + * @return the size of the shape + */ + public float getSize() { + return mStyles.size; + } + + /** + * This is used for the size of the shape that + * will be drawn. + * This is useless if you are using a custom shape. + * + * @param radius the size of the shape + */ + public void setSize(float radius) { + mStyles.size = radius; + } + + /** + * @return the shape that will be drawn for each point + */ + public Shape getShape() { + return mStyles.shape; + } + + /** + * @param s the shape that will be drawn for each point + */ + public void setShape(Shape s) { + mStyles.shape = s; + } + + /** + * Use a custom handler to render your own + * drawing for each data point. + * + * @param shape handler to use a custom drawing + */ + public void setCustomShape(CustomShape shape) { + mCustomShape = shape; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/Series.java b/graphview/src/main/java/com/jjoe64/graphview/series/Series.java new file mode 100644 index 0000000000..dce32eb78e --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/Series.java @@ -0,0 +1,125 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; + +import com.jjoe64.graphview.GraphView; + +import java.util.Iterator; + +/** + * Basis interface for series that can be plotted + * on the graph. + * You can implement this in order to create a completely + * custom series type. + * But it is recommended to extend {@link com.jjoe64.graphview.series.BaseSeries} or another + * implemented Series class to save time. + * Anyway this interface can make sense if you want to implement + * a custom data provider, because BaseSeries uses a internal Array to store + * the data. + * + * @author jjoe64 + */ +public interface Series { + /** + * @return the lowest x-value of the data + */ + public double getLowestValueX(); + + /** + * @return the highest x-value of the data + */ + public double getHighestValueX(); + + /** + * @return the lowest y-value of the data + */ + public double getLowestValueY(); + + /** + * @return the highest y-value of the data + */ + public double getHighestValueY(); + + /** + * get the values for a specific range. It is + * important that the data comes in the sorted order + * (from lowest to highest x-value). + * + * @param from the minimal x-value + * @param until the maximal x-value + * @return all datapoints between the from and until x-value + * including the from and until data points. + */ + public Iterator getValues(double from, double until); + + /** + * Plots the series to the viewport. + * You have to care about overdrawing. + * This method may be called 2 times: one for + * the default scale and one time for the + * second scale. + * + * @param graphView corresponding graphview + * @param canvas canvas to draw on + * @param isSecondScale true if the drawing is for the second scale + */ + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale); + + /** + * @return the title of the series. Used in the legend + */ + public String getTitle(); + + /** + * @return the color of the series. Used in the legend and should + * be used for the plotted points or lines. + */ + public int getColor(); + + /** + * set a listener for tap on a data point. + * + * @param l listener + */ + public void setOnDataPointTapListener(OnDataPointTapListener l); + + /** + * called by the tap detector in order to trigger + * the on tap on datapoint event. + * + * @param x pixel + * @param y pixel + */ + void onTap(float x, float y); + + /** + * called when the series was added to a graph + * + * @param graphView graphview + */ + void onGraphViewAttached(GraphView graphView); + + /** + * @return whether there are data points + */ + boolean isEmpty(); +} diff --git a/graphview/src/main/res/values/attr.xml b/graphview/src/main/res/values/attr.xml new file mode 100644 index 0000000000..8b73838605 --- /dev/null +++ b/graphview/src/main/res/values/attr.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/settings.gradle b/settings.gradle index 20cc1cc2b6..b11f11adfc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,3 +19,4 @@ include ':diaconn' include ':openhumans' include ':shared' include ':iconify' +include ':graphview' From e7c41beab74306ee3b5c68c41aac9bf05da36034 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 26 Oct 2022 14:50:11 +0200 Subject: [PATCH 40/77] Gradle: turn Jetifier off --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ed6d237aa1..5690db57d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ org.gradle.parallel=true org.gradle.warning.mode=all org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC -android.enableJetifier=true +android.enableJetifier=false android.useAndroidX=true # Cache is causeing issues with CircleCI nad maybe Studio 2021 # org.gradle.unsafe.configuration-cache=true From cc343a49441bb26438a9eeb4e6bac5970d290715 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 26 Oct 2022 15:05:34 +0200 Subject: [PATCH 41/77] fix tests --- {app => core}/src/main/res/drawable/ic_trash_outline.xml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {app => core}/src/main/res/drawable/ic_trash_outline.xml (100%) diff --git a/app/src/main/res/drawable/ic_trash_outline.xml b/core/src/main/res/drawable/ic_trash_outline.xml similarity index 100% rename from app/src/main/res/drawable/ic_trash_outline.xml rename to core/src/main/res/drawable/ic_trash_outline.xml From 5f8abca2ca309cb89789b3cb8ebf7c413df546c6 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 26 Oct 2022 16:09:04 +0200 Subject: [PATCH 42/77] Move NtpProgressDialog --- .../main/java/info/nightscout/androidaps/di/FragmentsModule.kt | 3 ++- .../info/nightscout/androidaps/dialogs/NtpProgressDialog.kt | 0 .../java/info/nightscout/androidaps/di/CoreFragmentsModule.kt | 2 -- 3 files changed, 2 insertions(+), 3 deletions(-) rename {core => app}/src/main/java/info/nightscout/androidaps/dialogs/NtpProgressDialog.kt (100%) diff --git a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt index 2042bfd5a0..4e4afffa2e 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt @@ -17,6 +17,7 @@ import info.nightscout.androidaps.dialogs.ExtendedBolusDialog import info.nightscout.androidaps.dialogs.FillDialog import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.dialogs.LoopDialog +import info.nightscout.androidaps.dialogs.NtpProgressDialog import info.nightscout.androidaps.dialogs.ProfileSwitchDialog import info.nightscout.androidaps.dialogs.TempBasalDialog import info.nightscout.androidaps.dialogs.TempTargetDialog @@ -110,6 +111,6 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesTreatmentDialog(): TreatmentDialog @ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog @ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog - + @ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): NtpProgressDialog @ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/dialogs/NtpProgressDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/NtpProgressDialog.kt similarity index 100% rename from core/src/main/java/info/nightscout/androidaps/dialogs/NtpProgressDialog.kt rename to app/src/main/java/info/nightscout/androidaps/dialogs/NtpProgressDialog.kt diff --git a/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt b/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt index e30a92c223..c51a379622 100644 --- a/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt +++ b/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt @@ -7,7 +7,6 @@ import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.TDDStatsActivity import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.dialogs.ErrorDialog -import info.nightscout.androidaps.dialogs.NtpProgressDialog import info.nightscout.androidaps.dialogs.ProfileViewerDialog import info.nightscout.androidaps.plugins.general.maintenance.activities.PrefImportListActivity import info.nightscout.androidaps.utils.ui.SingleClickButton @@ -23,7 +22,6 @@ abstract class CoreFragmentsModule { @ContributesAndroidInjector abstract fun contributesBolusProgressDialog(): BolusProgressDialog @ContributesAndroidInjector abstract fun contributesErrorDialog(): ErrorDialog - @ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): NtpProgressDialog @ContributesAndroidInjector abstract fun contributesProfileViewerDialog(): ProfileViewerDialog @ContributesAndroidInjector abstract fun contributesSingleClickButton(): SingleClickButton From eb9646cc7e01366527b5ecfe2700300ce276bb36 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 27 Oct 2022 10:16:49 +0200 Subject: [PATCH 43/77] replace graphview module by aar --- app/build.gradle | 5 +- automation/build.gradle | 4 +- core/build.gradle | 3 +- graphview/.gitignore | 1 - graphview/build.gradle | 20 - graphview/consumer-rules.pro | 0 graphview/proguard-rules.pro | 21 - graphview/src/main/AndroidManifest.xml | 4 - .../graphview/DefaultLabelFormatter.java | 105 -- .../java/com/jjoe64/graphview/GraphView.java | 548 ------ .../jjoe64/graphview/GridLabelRenderer.java | 1467 ----------------- .../com/jjoe64/graphview/LabelFormatter.java | 54 - .../com/jjoe64/graphview/LegendRenderer.java | 394 ----- .../com/jjoe64/graphview/SecondScale.java | 165 -- .../jjoe64/graphview/ValueDependentColor.java | 41 - .../java/com/jjoe64/graphview/Viewport.java | 996 ----------- .../graphview/compat/OverScrollerCompat.java | 46 - .../helper/DateAsXAxisLabelFormatter.java | 94 -- .../jjoe64/graphview/helper/GraphViewXML.java | 137 -- .../helper/StaticLabelsFormatter.java | 209 --- .../graphview/series/BarGraphSeries.java | 379 ----- .../jjoe64/graphview/series/BaseSeries.java | 448 ----- .../jjoe64/graphview/series/DataPoint.java | 63 - .../graphview/series/DataPointInterface.java | 41 - .../graphview/series/LineGraphSeries.java | 409 ----- .../series/OnDataPointTapListener.java | 38 - .../graphview/series/PointsGraphSeries.java | 312 ---- .../com/jjoe64/graphview/series/Series.java | 125 -- graphview/src/main/res/values/attr.xml | 10 - .../com/joanzapata/iconify/IconDrawable.java | 229 --- libs/graphview.aar | Bin 0 -> 62697 bytes {app/libs => libs}/ustwo-clockwise-debug.aar | Bin .../wearpreferenceactivity-0.5.0.aar | Bin settings.gradle | 3 +- wear/build.gradle | 4 +- wear/libs/ustwo-clockwise-debug.aar | Bin 90266 -> 0 bytes wear/libs/wearpreferenceactivity-0.5.0.aar | Bin 30815 -> 0 bytes 37 files changed, 11 insertions(+), 6364 deletions(-) delete mode 100644 graphview/.gitignore delete mode 100644 graphview/build.gradle delete mode 100644 graphview/consumer-rules.pro delete mode 100644 graphview/proguard-rules.pro delete mode 100644 graphview/src/main/AndroidManifest.xml delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/GraphView.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/SecondScale.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/Viewport.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java delete mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/Series.java delete mode 100644 graphview/src/main/res/values/attr.xml delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/IconDrawable.java create mode 100644 libs/graphview.aar rename {app/libs => libs}/ustwo-clockwise-debug.aar (100%) rename {app/libs => libs}/wearpreferenceactivity-0.5.0.aar (100%) delete mode 100644 wear/libs/ustwo-clockwise-debug.aar delete mode 100644 wear/libs/wearpreferenceactivity-0.5.0.aar diff --git a/app/build.gradle b/app/build.gradle index 51246830f1..82ecb4b85d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -169,8 +169,11 @@ allprojects { dependencies { wearApp project(':wear') + // https://github.com/nightscout/graphview.git + // in order to use internet's version you'd need to enable Jetifier again + implementation(files("${rootProject.rootDir}/libs/graphview.aar")) + implementation project(':iconify') - implementation project(':graphview') implementation project(':shared') implementation project(':core') implementation project(':automation') diff --git a/automation/build.gradle b/automation/build.gradle index f778782309..9d2099d443 100644 --- a/automation/build.gradle +++ b/automation/build.gradle @@ -12,10 +12,10 @@ android { namespace 'info.nightscout.androidaps.automation' } - dependencies { + implementation(files("${rootProject.rootDir}/libs/graphview.aar")) + implementation project(':core') implementation project(':database') implementation project(':shared') - implementation project(':graphview') } \ No newline at end of file diff --git a/core/build.gradle b/core/build.gradle index 567918dc1b..784e264e5d 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -12,9 +12,10 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" dependencies { + implementation(files("${rootProject.rootDir}/libs/graphview.aar")) + implementation project(':shared') implementation project(':database') - implementation project(':graphview') } android { diff --git a/graphview/.gitignore b/graphview/.gitignore deleted file mode 100644 index 42afabfd2a..0000000000 --- a/graphview/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/graphview/build.gradle b/graphview/build.gradle deleted file mode 100644 index e1138b7d40..0000000000 --- a/graphview/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-kapt' -apply plugin: 'kotlin-allopen' -apply plugin: 'com.hiya.jacoco-android' -apply plugin: 'kotlinx-serialization' - -apply from: "${project.rootDir}/core/android_dependencies.gradle" -apply from: "${project.rootDir}/core/android_module_dependencies.gradle" -apply from: "${project.rootDir}/core/test_dependencies.gradle" -apply from: "${project.rootDir}/core/jacoco_global.gradle" - -android { - - namespace 'com.jjoe64.graphview' -} - -dependencies { - api "androidx.core:core-ktx:$core_version" -} \ No newline at end of file diff --git a/graphview/consumer-rules.pro b/graphview/consumer-rules.pro deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/graphview/proguard-rules.pro b/graphview/proguard-rules.pro deleted file mode 100644 index 481bb43481..0000000000 --- a/graphview/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/graphview/src/main/AndroidManifest.xml b/graphview/src/main/AndroidManifest.xml deleted file mode 100644 index a5918e68ab..0000000000 --- a/graphview/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java deleted file mode 100644 index 0a761e2d73..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -import java.text.NumberFormat; - -/** - * The label formatter that will be used - * by default. - * It will use the NumberFormat from Android - * and sets the maximal fraction digits - * depending on the range between min and max - * value of the current viewport. - * - * It is recommended to use this label formatter - * as base class to implement a custom formatter. - * - * @author jjoe64 - */ -public class DefaultLabelFormatter implements LabelFormatter { - /** - * number formatter for x and y values - */ - protected NumberFormat[] mNumberFormatter = new NumberFormat[2]; - - /** - * reference to the viewport of the - * graph. - * Will be used to calculate the current - * range of values. - */ - protected Viewport mViewport; - - /** - * uses the default number format for the labels - */ - public DefaultLabelFormatter() { - } - - /** - * use custom number format - * - * @param xFormat the number format for the x labels - * @param yFormat the number format for the y labels - */ - public DefaultLabelFormatter(NumberFormat xFormat, NumberFormat yFormat) { - mNumberFormatter[0] = yFormat; - mNumberFormatter[1] = xFormat; - } - - /** - * @param viewport the viewport of the graph - */ - @Override - public void setViewport(Viewport viewport) { - mViewport = viewport; - } - - /** - * Formats the raw value to a nice - * looking label, depending on the - * current range of the viewport. - * - * @param value raw value - * @param isValueX true if it's a x value, otherwise false - * @return the formatted value as string - */ - public String formatLabel(double value, boolean isValueX) { - int i = isValueX ? 1 : 0; - if (mNumberFormatter[i] == null) { - mNumberFormatter[i] = NumberFormat.getNumberInstance(); - double highestvalue = isValueX ? mViewport.getMaxX(false) : mViewport.getMaxY(false); - double lowestvalue = isValueX ? mViewport.getMinX(false) : mViewport.getMinY(false); - if (highestvalue - lowestvalue < 0.1) { - mNumberFormatter[i].setMaximumFractionDigits(6); - } else if (highestvalue - lowestvalue < 1) { - mNumberFormatter[i].setMaximumFractionDigits(4); - } else if (highestvalue - lowestvalue < 20) { - mNumberFormatter[i].setMaximumFractionDigits(3); - } else if (highestvalue - lowestvalue < 100) { - mNumberFormatter[i].setMaximumFractionDigits(1); - } else { - mNumberFormatter[i].setMaximumFractionDigits(0); - } - } - return mNumberFormatter[i].format(value); - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/GraphView.java b/graphview/src/main/java/com/jjoe64/graphview/GraphView.java deleted file mode 100644 index 51debe1eef..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/GraphView.java +++ /dev/null @@ -1,548 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Point; -import android.graphics.PointF; -import android.util.AttributeSet; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; - -import com.jjoe64.graphview.series.Series; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author jjoe64 - * @version 4.0.0 - */ -public class GraphView extends View { - /** - * Class to wrap style options that are general - * to graphs. - * - * @author jjoe64 - */ - private static final class Styles { - /** - * The font size of the title that can be displayed - * above the graph. - * - * @see GraphView#setTitle(String) - */ - float titleTextSize; - - /** - * The font color of the title that can be displayed - * above the graph. - * - * @see GraphView#setTitle(String) - */ - int titleColor; - } - - /** - * Helper class to detect tap events on the - * graph. - * - * @author jjoe64 - */ - private class TapDetector { - /** - * save the time of the last down event - */ - private long lastDown; - - /** - * point of the tap down event - */ - private PointF lastPoint; - - /** - * to be called to process the events - * - * @param event - * @return true if there was a tap event. otherwise returns false. - */ - public boolean onTouchEvent(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - lastDown = System.currentTimeMillis(); - lastPoint = new PointF(event.getX(), event.getY()); - } else if (lastDown > 0 && event.getAction() == MotionEvent.ACTION_MOVE) { - if (Math.abs(event.getX() - lastPoint.x) > 60 - || Math.abs(event.getY() - lastPoint.y) > 60) { - lastDown = 0; - } - } else if (event.getAction() == MotionEvent.ACTION_UP) { - if (System.currentTimeMillis() - lastDown < 400) { - return true; - } - } - return false; - } - } - - /** - * our series (this does not contain the series - * that can be displayed on the right side. The - * right side series is a special feature of - * the {@link SecondScale} feature. - */ - private List mSeries; - - /** - * the renderer for the grid and labels - */ - private GridLabelRenderer mGridLabelRenderer; - - /** - * viewport that holds the current bounds of - * view. - */ - private Viewport mViewport; - - /** - * title of the graph that will be shown above - */ - private String mTitle; - - /** - * wraps the general styles - */ - private Styles mStyles; - - /** - * feature to have a second scale e.g. on the - * right side - */ - protected SecondScale mSecondScale; - - /** - * tap detector - */ - private TapDetector mTapDetector; - - /** - * renderer for the legend - */ - private LegendRenderer mLegendRenderer; - - /** - * paint for the graph title - */ - private Paint mPaintTitle; - - /** - * paint for the preview (in the SDK) - */ - private Paint mPreviewPaint; - - /** - * Initialize the GraphView view - * @param context - */ - public GraphView(Context context) { - super(context); - init(); - } - - /** - * Initialize the GraphView view. - * - * @param context - * @param attrs - */ - public GraphView(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - /** - * Initialize the GraphView view - * - * @param context - * @param attrs - * @param defStyle - */ - public GraphView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - /** - * initialize the internal objects. - * This method has to be called directly - * in the constructors. - */ - protected void init() { - mPreviewPaint = new Paint(); - mPreviewPaint.setTextAlign(Paint.Align.CENTER); - mPreviewPaint.setColor(Color.BLACK); - mPreviewPaint.setTextSize(50); - - mStyles = new Styles(); - mViewport = new Viewport(this); - mGridLabelRenderer = new GridLabelRenderer(this); - mLegendRenderer = new LegendRenderer(this); - - mSeries = new ArrayList(); - mPaintTitle = new Paint(); - - mTapDetector = new TapDetector(); - - loadStyles(); - } - - /** - * loads the font - */ - protected void loadStyles() { - mStyles.titleColor = mGridLabelRenderer.getHorizontalLabelsColor(); - mStyles.titleTextSize = mGridLabelRenderer.getTextSize(); - } - - /** - * @return the renderer for the grid and labels - */ - public GridLabelRenderer getGridLabelRenderer() { - return mGridLabelRenderer; - } - - /** - * Add a new series to the graph. This will - * automatically redraw the graph. - * @param s the series to be added - */ - public void addSeries(Series s) { - s.onGraphViewAttached(this); - mSeries.add(s); - onDataChanged(false, false); - } - - /** - * important: do not do modifications on the list - * object that will be returned. - * Use {@link #removeSeries(com.jjoe64.graphview.series.Series)} and {@link #addSeries(com.jjoe64.graphview.series.Series)} - * - * @return all series - */ - public List getSeries() { - // TODO immutable array - return mSeries; - } - - /** - * call this to let the graph redraw and - * recalculate the viewport. - * This will be called when a new series - * was added or removed and when data - * was appended via {@link com.jjoe64.graphview.series.BaseSeries#appendData(com.jjoe64.graphview.series.DataPointInterface, boolean, int)} - * or {@link com.jjoe64.graphview.series.BaseSeries#resetData(com.jjoe64.graphview.series.DataPointInterface[])}. - * - * @param keepLabelsSize true if you don't want - * to recalculate the size of - * the labels. It is recommended - * to use "true" because this will - * improve performance and prevent - * a flickering. - * @param keepViewport true if you don't want that - * the viewport will be recalculated. - * It is recommended to use "true" for - * performance. - */ - public void onDataChanged(boolean keepLabelsSize, boolean keepViewport) { - // adjust grid system - mViewport.calcCompleteRange(); - mGridLabelRenderer.invalidate(keepLabelsSize, keepViewport); - invalidate(); - } - - /** - * will be called from Android system. - * - * @param canvas Canvas - */ - @Override - protected void onDraw(Canvas canvas) { - if (isInEditMode()) { - canvas.drawColor(Color.rgb(200, 200, 200)); - canvas.drawText("GraphView: No Preview available", canvas.getWidth()/2, canvas.getHeight()/2, mPreviewPaint); - } else { - drawTitle(canvas); - mViewport.drawFirst(canvas); - mGridLabelRenderer.draw(canvas); - for (Series s : mSeries) { - s.draw(this, canvas, false); - } - if (mSecondScale != null) { - for (Series s : mSecondScale.getSeries()) { - s.draw(this, canvas, true); - } - } - mViewport.draw(canvas); - mLegendRenderer.draw(canvas); - } - } - - /** - * Draws the Graphs title that will be - * shown above the viewport. - * Will be called by GraphView. - * - * @param canvas Canvas - */ - protected void drawTitle(Canvas canvas) { - if (mTitle != null && mTitle.length()>0) { - mPaintTitle.setColor(mStyles.titleColor); - mPaintTitle.setTextSize(mStyles.titleTextSize); - mPaintTitle.setTextAlign(Paint.Align.CENTER); - float x = canvas.getWidth()/2; - float y = mPaintTitle.getTextSize(); - canvas.drawText(mTitle, x, y, mPaintTitle); - } - } - - /** - * Calculates the height of the title. - * - * @return the actual size of the title. - * if there is no title, 0 will be - * returned. - */ - protected int getTitleHeight() { - if (mTitle != null && mTitle.length()>0) { - return (int) mPaintTitle.getTextSize(); - } else { - return 0; - } - } - - /** - * @return the viewport of the Graph. - * @see com.jjoe64.graphview.Viewport - */ - public Viewport getViewport() { - return mViewport; - } - - /** - * Called by Android system if the size - * of the view was changed. Will recalculate - * the viewport and labels. - * - * @param w - * @param h - * @param oldw - * @param oldh - */ - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - onDataChanged(false, false); - } - - /** - * @return the space on the left side of the - * view from the left border to the - * beginning of the graph viewport. - */ - public int getGraphContentLeft() { - int border = getGridLabelRenderer().getStyles().padding; - return border + getGridLabelRenderer().getLabelVerticalWidth() + getGridLabelRenderer().getVerticalAxisTitleWidth(); - } - - /** - * @return the space on the top of the - * view from the top border to the - * beginning of the graph viewport. - */ - public int getGraphContentTop() { - int border = getGridLabelRenderer().getStyles().padding + getTitleHeight(); - return border; - } - - /** - * @return the height of the graph viewport. - */ - public int getGraphContentHeight() { - int border = getGridLabelRenderer().getStyles().padding; - int graphheight = getHeight() - (2 * border) - getGridLabelRenderer().getLabelHorizontalHeight() - getTitleHeight(); - graphheight -= getGridLabelRenderer().getHorizontalAxisTitleHeight(); - return graphheight; - } - - /** - * @return the width of the graph viewport. - */ - public int getGraphContentWidth() { - int border = getGridLabelRenderer().getStyles().padding; - int graphwidth = getWidth() - (2 * border) - getGridLabelRenderer().getLabelVerticalWidth(); - if (mSecondScale != null) { - graphwidth -= getGridLabelRenderer().getLabelVerticalSecondScaleWidth(); - } - return graphwidth; - } - - /** - * will be called from Android system. - * - * @param event - * @return - */ - @Override - public boolean onTouchEvent(MotionEvent event) { - boolean b = mViewport.onTouchEvent(event); - boolean a = super.onTouchEvent(event); - - // is it a click? - if (mTapDetector.onTouchEvent(event)) { - for (Series s : mSeries) { - s.onTap(event.getX(), event.getY()); - } - if (mSecondScale != null) { - for (Series s : mSecondScale.getSeries()) { - s.onTap(event.getX(), event.getY()); - } - } - } - - return b || a; - } - - /** - * - */ - @Override - public void computeScroll() { - super.computeScroll(); - mViewport.computeScroll(); - } - - /** - * @return the legend renderer. - * @see com.jjoe64.graphview.LegendRenderer - */ - public LegendRenderer getLegendRenderer() { - return mLegendRenderer; - } - - /** - * use a specific legend renderer - * - * @param mLegendRenderer the new legend renderer - */ - public void setLegendRenderer(LegendRenderer mLegendRenderer) { - this.mLegendRenderer = mLegendRenderer; - } - - /** - * @return the title that will be shown - * above the graph. - */ - public String getTitle() { - return mTitle; - } - - /** - * Set the title of the graph that will - * be shown above the graph's viewport. - * - * @param mTitle the title - * @see #setTitleColor(int) to set the font color - * @see #setTitleTextSize(float) to set the font size - */ - public void setTitle(String mTitle) { - this.mTitle = mTitle; - } - - /** - * @return the title font size - */ - public float getTitleTextSize() { - return mStyles.titleTextSize; - } - - /** - * Set the title's font size - * - * @param titleTextSize font size - * @see #setTitle(String) - */ - public void setTitleTextSize(float titleTextSize) { - mStyles.titleTextSize = titleTextSize; - } - - /** - * @return font color of the title - */ - public int getTitleColor() { - return mStyles.titleColor; - } - - /** - * Set the title's font color - * - * @param titleColor font color of the title - * @see #setTitle(String) - */ - public void setTitleColor(int titleColor) { - mStyles.titleColor = titleColor; - } - - /** - * - * @return - */ - public SecondScale getSecondScale() { - if (mSecondScale == null) { - mSecondScale = new SecondScale(mViewport); - } - return mSecondScale; - } - - /** - * Removes all series of the graph. - */ - public void removeAllSeries() { - mSeries.clear(); - onDataChanged(false, false); - } - - /** - * Remove a specific series of the graph. - * This will also re-render the graph, but - * without recalculating the viewport and - * label sizes. - * If you want this, you have to call {@link #onDataChanged(boolean, boolean)} - * manually. - * - * @param series - */ - public void removeSeries(Series series) { - mSeries.remove(series); - onDataChanged(false, false); - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java b/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java deleted file mode 100644 index e6060c9b50..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java +++ /dev/null @@ -1,1467 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.util.TypedValue; - -import androidx.core.view.ViewCompat; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * The default renderer for the grid - * and the labels. - * - * @author jjoe64 - */ -public class GridLabelRenderer { - /** - * wrapper for the styles regarding - * to the grid and the labels - */ - public final class Styles { - /** - * the general text size of the axis titles. - * can be overwritten with #verticalAxisTitleTextSize - * and #horizontalAxisTitleTextSize - */ - public float textSize; - - /** - * the alignment of the vertical labels - */ - public Paint.Align verticalLabelsAlign; - - /** - * the alignment of the labels on the right side - */ - public Paint.Align verticalLabelsSecondScaleAlign; - - /** - * the color of the vertical labels - */ - public int verticalLabelsColor; - - /** - * the color of the labels on the right side - */ - public int verticalLabelsSecondScaleColor; - - /** - * the color of the horizontal labels - */ - public int horizontalLabelsColor; - - /** - * the color of the grid lines - */ - public int gridColor; - - /** - * flag whether the zero-lines (vertical+ - * horizontal) shall be highlighted - */ - public boolean highlightZeroLines; - - /** - * the padding around the graph and labels - */ - public int padding; - - /** - * font size of the vertical axis title - */ - public float verticalAxisTitleTextSize; - - /** - * font color of the vertical axis title - */ - public int verticalAxisTitleColor; - - /** - * font size of the horizontal axis title - */ - public float horizontalAxisTitleTextSize; - - /** - * font color of the horizontal axis title - */ - public int horizontalAxisTitleColor; - - /** - * flag whether the horizontal labels are - * visible - */ - boolean horizontalLabelsVisible; - - /** - * flag whether the vertical labels are - * visible - */ - boolean verticalLabelsVisible; - - /** - * defines which lines will be drawn in the background - */ - GridStyle gridStyle; - - /** - * the space between the labels text and the graph content - */ - int labelsSpace; - } - - /** - * Definition which lines will be drawn in the background - */ - public enum GridStyle { - BOTH, VERTICAL, HORIZONTAL, NONE; - - public boolean drawVertical() { return this == BOTH || this == VERTICAL && this != NONE; } - public boolean drawHorizontal() { return this == BOTH || this == HORIZONTAL && this != NONE; } - } - - /** - * wraps the styles regarding the - * grid and labels - */ - protected Styles mStyles; - - /** - * reference to graphview - */ - private final GraphView mGraphView; - - /** - * cache of the vertical steps - * (horizontal lines and vertical labels) - * Key = Pixel (y) - * Value = y-value - */ - private Map mStepsVertical; - - /** - * cache of the vertical steps for the - * second scale, which is on the right side - * (horizontal lines and vertical labels) - * Key = Pixel (y) - * Value = y-value - */ - private Map mStepsVerticalSecondScale; - - /** - * cache of the horizontal steps - * (vertical lines and horizontal labels) - * Key = Pixel (x) - * Value = x-value - */ - private Map mStepsHorizontal; - - /** - * the paint to draw the grid lines - */ - private Paint mPaintLine; - - /** - * the paint to draw the labels - */ - private Paint mPaintLabel; - - /** - * the paint to draw axis titles - */ - private Paint mPaintAxisTitle; - - /** - * flag whether is bounds are automatically - * adjusted for nice human-readable numbers - */ - private boolean mIsAdjusted; - - /** - * the width of the vertical labels - */ - private Integer mLabelVerticalWidth; - - /** - * indicates if the width was set manually - */ - private boolean mLabelVerticalWidthFixed; - - /** - * the height of the vertical labels - */ - private Integer mLabelVerticalHeight; - - /** - * indicates if the height was set manually - */ - private boolean mLabelHorizontalHeightFixed; - - /** - * the width of the vertical labels - * of the second scale - */ - private Integer mLabelVerticalSecondScaleWidth; - - /** - * the height of the vertical labels - * of the second scale - */ - private Integer mLabelVerticalSecondScaleHeight; - - /** - * the width of the horizontal labels - */ - private Integer mLabelHorizontalWidth; - - /** - * the height of the horizontal labels - */ - private Integer mLabelHorizontalHeight; - - /** - * the label formatter, that converts - * the raw numbers to strings - */ - private LabelFormatter mLabelFormatter; - - /** - * the title of the horizontal axis - */ - private String mHorizontalAxisTitle; - - /** - * the title of the vertical axis - */ - private String mVerticalAxisTitle; - - /** - * count of the vertical labels, that - * will be shown at one time. - */ - private int mNumVerticalLabels; - - /** - * count of the horizontal labels, that - * will be shown at one time. - */ - private int mNumHorizontalLabels; - - /** - * create the default grid label renderer. - * - * @param graphView the corresponding graphview object - */ - public GridLabelRenderer(GraphView graphView) { - mGraphView = graphView; - setLabelFormatter(new DefaultLabelFormatter()); - mStyles = new Styles(); - resetStyles(); - mNumVerticalLabels = 5; - mNumHorizontalLabels = 5; - } - - /** - * resets the styles. This loads the style - * from reading the values of the current - * theme. - */ - public void resetStyles() { - // get matching styles from theme - TypedValue typedValue = new TypedValue(); - mGraphView.getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceSmall, typedValue, true); - - int color1; - int color2; - int size; - int size2; - - TypedArray array = null; - try { - array = mGraphView.getContext().obtainStyledAttributes(typedValue.data, new int[]{ - android.R.attr.textColorPrimary - , android.R.attr.textColorSecondary - , android.R.attr.textSize - , android.R.attr.horizontalGap}); - color1 = array.getColor(0, Color.BLACK); - color2 = array.getColor(1, Color.GRAY); - size = array.getDimensionPixelSize(2, 20); - size2 = array.getDimensionPixelSize(3, 20); - array.recycle(); - } catch (Exception e) { - color1 = Color.BLACK; - color2 = Color.GRAY; - size = 20; - size2 = 20; - } - - mStyles.verticalLabelsColor = color1; - mStyles.verticalLabelsSecondScaleColor = color1; - mStyles.horizontalLabelsColor = color1; - mStyles.gridColor = color2; - mStyles.textSize = size; - mStyles.padding = size2; - mStyles.labelsSpace = (int) mStyles.textSize/5; - - mStyles.verticalLabelsAlign = Paint.Align.RIGHT; - mStyles.verticalLabelsSecondScaleAlign = Paint.Align.LEFT; - mStyles.highlightZeroLines = true; - - mStyles.verticalAxisTitleColor = mStyles.verticalLabelsColor; - mStyles.horizontalAxisTitleColor = mStyles.horizontalLabelsColor; - mStyles.verticalAxisTitleTextSize = mStyles.textSize; - mStyles.horizontalAxisTitleTextSize = mStyles.textSize; - - mStyles.horizontalLabelsVisible = true; - mStyles.verticalLabelsVisible = true; - - mStyles.gridStyle = GridStyle.BOTH; - - reloadStyles(); - } - - /** - * will load the styles to the internal - * paint objects (color, text size, text align) - */ - public void reloadStyles() { - mPaintLine = new Paint(); - mPaintLine.setColor(mStyles.gridColor); - mPaintLine.setStrokeWidth(0); - - mPaintLabel = new Paint(); - mPaintLabel.setTextSize(getTextSize()); - - mPaintAxisTitle = new Paint(); - mPaintAxisTitle.setTextSize(getTextSize()); - mPaintAxisTitle.setTextAlign(Paint.Align.CENTER); - } - - /** - * @return the general text size for the axis titles - */ - public float getTextSize() { - return mStyles.textSize; - } - - /** - * @return the font color of the vertical labels - */ - public int getVerticalLabelsColor() { - return mStyles.verticalLabelsColor; - } - - /** - * @return the alignment of the text of the - * vertical labels - */ - public Paint.Align getVerticalLabelsAlign() { - return mStyles.verticalLabelsAlign; - } - - /** - * @return the font color of the horizontal labels - */ - public int getHorizontalLabelsColor() { - return mStyles.horizontalLabelsColor; - } - - /** - * clears the internal cache and forces - * to redraw the grid and labels. - * Normally you should always call {@link GraphView#onDataChanged(boolean, boolean)} - * which will call this method. - * - * @param keepLabelsSize true if you don't want - * to recalculate the size of - * the labels. It is recommended - * to use "true" because this will - * improve performance and prevent - * a flickering. - * @param keepViewport true if you don't want that - * the viewport will be recalculated. - * It is recommended to use "true" for - * performance. - */ - public void invalidate(boolean keepLabelsSize, boolean keepViewport) { - if (!keepViewport) { - mIsAdjusted = false; - } - if (!keepLabelsSize) { - if (!mLabelVerticalWidthFixed) { - mLabelVerticalWidth = null; - } - mLabelVerticalHeight = null; - mLabelVerticalSecondScaleWidth = null; - mLabelVerticalSecondScaleHeight = null; - } - //reloadStyles(); - } - - /** - * calculates the vertical steps of - * the second scale. - * This will not do any automatically update - * of the bounds. - * Use always manual bounds for the second scale. - * - * @return true if it is ready - */ - protected boolean adjustVerticalSecondScale() { - if (mLabelHorizontalHeight == null) { - return false; - } - if (mGraphView.mSecondScale == null) { - return true; - } - - double minY = mGraphView.mSecondScale.getMinY(); - double maxY = mGraphView.mSecondScale.getMaxY(); - - // TODO find the number of labels - int numVerticalLabels = mNumVerticalLabels; - - double newMinY; - double exactSteps; - - if (mGraphView.mSecondScale.isYAxisBoundsManual()) { - newMinY = minY; - double rangeY = maxY - newMinY; - exactSteps = rangeY / (numVerticalLabels - 1); - } else { - // TODO auto adjusting - throw new IllegalStateException("Not yet implemented"); - } - - double newMaxY = newMinY + (numVerticalLabels - 1) * exactSteps; - - // TODO auto adjusting - //mGraphView.getViewport().setMinY(newMinY); - //mGraphView.getViewport().setMaxY(newMaxY); - - //if (!mGraphView.getViewport().isYAxisBoundsManual()) { - // mGraphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); - //} - - if (mStepsVerticalSecondScale != null) { - mStepsVerticalSecondScale.clear(); - } else { - mStepsVerticalSecondScale = new LinkedHashMap(numVerticalLabels); - } - int height = mGraphView.getGraphContentHeight(); - double v = newMaxY; - int p = mGraphView.getGraphContentTop(); // start - int pixelStep = height / (numVerticalLabels - 1); - for (int i = 0; i < numVerticalLabels; i++) { - mStepsVerticalSecondScale.put(p, v); - p += pixelStep; - v -= exactSteps; - } - - return true; - } - - /** - * calculates the vertical steps. This will - * automatically change the bounds to nice - * human-readable min/max. - * - * @return true if it is ready - */ - protected boolean adjustVertical() { - if (mLabelHorizontalHeight == null) { - return false; - } - - double minY = mGraphView.getViewport().getMinY(false); - double maxY = mGraphView.getViewport().getMaxY(false); - - if (minY == maxY) { - return false; - } - - // TODO find the number of labels - int numVerticalLabels = mNumVerticalLabels; - - double newMinY; - double exactSteps; - - if (mGraphView.getViewport().isYAxisBoundsManual()) { - newMinY = minY; - double rangeY = maxY - newMinY; - exactSteps = rangeY / (numVerticalLabels - 1); - } else { - // find good steps - boolean adjusting = true; - newMinY = minY; - exactSteps = 0d; - while (adjusting) { - double rangeY = maxY - newMinY; - exactSteps = rangeY / (numVerticalLabels - 1); - exactSteps = humanRound(exactSteps, true); - - // adjust viewport - // wie oft passt STEP in minY rein? - int count = 0; - if (newMinY >= 0d) { - // positive number - while (newMinY - exactSteps >= 0) { - newMinY -= exactSteps; - count++; - } - newMinY = exactSteps * count; - } else { - // negative number - count++; - while (newMinY + exactSteps < 0) { - newMinY += exactSteps; - count++; - } - newMinY = exactSteps * count * -1; - } - - // wenn minY sich geändert hat, steps nochmal berechnen - // wenn nicht, fertig - if (newMinY == minY) { - adjusting = false; - } else { - minY = newMinY; - } - } - } - - double newMaxY = newMinY + (numVerticalLabels - 1) * exactSteps; - mGraphView.getViewport().setMinY(newMinY); - mGraphView.getViewport().setMaxY(newMaxY); - - if (!mGraphView.getViewport().isYAxisBoundsManual()) { - mGraphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); - } - - if (mStepsVertical != null) { - mStepsVertical.clear(); - } else { - mStepsVertical = new LinkedHashMap(numVerticalLabels); - } - int height = mGraphView.getGraphContentHeight(); - double v = newMaxY; - int p = mGraphView.getGraphContentTop(); // start - int pixelStep = height / (numVerticalLabels - 1); - for (int i = 0; i < numVerticalLabels; i++) { - mStepsVertical.put(p, v); - p += pixelStep; - v -= exactSteps; - } - - return true; - } - - /** - * calculates the horizontal steps. This will - * automatically change the bounds to nice - * human-readable min/max. - * - * @return true if it is ready - */ - protected boolean adjustHorizontal() { - if (mLabelVerticalWidth == null) { - return false; - } - - double minX = mGraphView.getViewport().getMinX(false); - double maxX = mGraphView.getViewport().getMaxX(false); - if (minX == maxX) return false; - - // TODO find the number of labels - int numHorizontalLabels = mNumHorizontalLabels; - - double newMinX; - double exactSteps; - - float scalingOffset = 0f; - if (mGraphView.getViewport().isXAxisBoundsManual() && mGraphView.getViewport().getXAxisBoundsStatus() != Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { - // scaling - if (mGraphView.getViewport().mScalingActive) { - minX = mGraphView.getViewport().mScalingBeginLeft; - maxX = minX + mGraphView.getViewport().mScalingBeginWidth; - - //numHorizontalLabels *= (mGraphView.getViewport().mCurrentViewport.width()+oldStep)/(mGraphView.getViewport().mScalingBeginWidth+oldStep); - //numHorizontalLabels = (float) Math.ceil(numHorizontalLabels); - } - - newMinX = minX; - double rangeX = maxX - newMinX; - exactSteps = rangeX / (numHorizontalLabels - 1); - } else { - // find good steps - boolean adjusting = true; - newMinX = minX; - exactSteps = 0d; - while (adjusting) { - double rangeX = maxX - newMinX; - exactSteps = rangeX / (numHorizontalLabels - 1); - - boolean roundAlwaysUp = true; - if (mGraphView.getViewport().getXAxisBoundsStatus() == Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { - // if viewports gets smaller, round down - if (mGraphView.getViewport().mCurrentViewport.width() < mGraphView.getViewport().mScalingBeginWidth) { - roundAlwaysUp = false; - } - } - exactSteps = humanRound(exactSteps, roundAlwaysUp); - - // adjust viewport - // wie oft passt STEP in minX rein? - int count = 0; - if (newMinX >= 0d) { - // positive number - while (newMinX - exactSteps >= 0) { - newMinX -= exactSteps; - count++; - } - newMinX = exactSteps * count; - } else { - // negative number - count++; - while (newMinX + exactSteps < 0) { - newMinX += exactSteps; - count++; - } - newMinX = exactSteps * count * -1; - } - - // wenn minX sich geändert hat, steps nochmal berechnen - // wenn nicht, fertig - if (newMinX == minX) { - adjusting = false; - } else { - minX = newMinX; - } - } - - double newMaxX = newMinX + (numHorizontalLabels - 1) * exactSteps; - mGraphView.getViewport().setMinX(newMinX); - mGraphView.getViewport().setMaxX(newMaxX); - if (mGraphView.getViewport().getXAxisBoundsStatus() == Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { - mGraphView.getViewport().setXAxisBoundsStatus(Viewport.AxisBoundsStatus.FIX); - } else { - mGraphView.getViewport().setXAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); - } - } - - if (mStepsHorizontal != null) { - mStepsHorizontal.clear(); - } else { - mStepsHorizontal = new LinkedHashMap((int) numHorizontalLabels); - } - int width = mGraphView.getGraphContentWidth(); - - float scrolled = 0; - float scrolledPixels = 0; - - double v = newMinX; - int p = mGraphView.getGraphContentLeft(); // start - float pixelStep = width / (numHorizontalLabels - 1); - - if (mGraphView.getViewport().mScalingActive) { - float oldStep = mGraphView.getViewport().mScalingBeginWidth / (numHorizontalLabels - 1); - float factor = (mGraphView.getViewport().mCurrentViewport.width() + oldStep) / (mGraphView.getViewport().mScalingBeginWidth + oldStep); - pixelStep *= 1f / factor; - - //numHorizontalLabels *= (mGraphView.getViewport().mCurrentViewport.width()+oldStep)/(mGraphView.getViewport().mScalingBeginWidth+oldStep); - //numHorizontalLabels = (float) Math.ceil(numHorizontalLabels); - - //scrolled = ((float) mGraphView.getViewport().getMinX(false) - mGraphView.getViewport().mScalingBeginLeft)*2; - float newWidth = width * 1f / factor; - scrolledPixels = (newWidth - width) * -0.5f; - - } - - // scrolling - if (!Float.isNaN(mGraphView.getViewport().mScrollingReferenceX)) { - scrolled = mGraphView.getViewport().mScrollingReferenceX - (float) newMinX; - scrolledPixels += scrolled * (pixelStep / (float) exactSteps); - - if (scrolled < 0 - exactSteps) { - mGraphView.getViewport().mScrollingReferenceX += exactSteps; - } else if (scrolled > exactSteps) { - mGraphView.getViewport().mScrollingReferenceX -= exactSteps; - } - } - p += scrolledPixels; - v += scrolled; - - for (int i = 0; i < numHorizontalLabels; i++) { - // don't draw steps before 0 (scrolling) - if (p >= mGraphView.getGraphContentLeft()) { - mStepsHorizontal.put(p, v); - } - p += pixelStep; - v += exactSteps; - } - - return true; - } - - /** - * adjusts the grid and labels to match to the data - * this will automatically change the bounds to - * nice human-readable values, except the bounds - * are manual. - */ - protected void adjust() { - mIsAdjusted = adjustVertical(); - mIsAdjusted &= adjustVerticalSecondScale(); - mIsAdjusted &= adjustHorizontal(); - } - - /** - * calculates the vertical label size - * @param canvas canvas - */ - protected void calcLabelVerticalSize(Canvas canvas) { - // test label with first and last label - String testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMaxY(false), false); - if (testLabel == null) testLabel = ""; - - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); - mLabelVerticalWidth = textBounds.width(); - mLabelVerticalHeight = textBounds.height(); - - testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMinY(false), false); - if (testLabel == null) testLabel = ""; - - mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); - mLabelVerticalWidth = Math.max(mLabelVerticalWidth, textBounds.width()); - - // add some pixel to get a margin - mLabelVerticalWidth += 6; - - // space between text and graph content - mLabelVerticalWidth += mStyles.labelsSpace; - - // multiline - int lines = 1; - for (byte c : testLabel.getBytes()) { - if (c == '\n') lines++; - } - mLabelVerticalHeight *= lines; - } - - /** - * calculates the vertical second scale - * label size - * @param canvas canvas - */ - protected void calcLabelVerticalSecondScaleSize(Canvas canvas) { - if (mGraphView.mSecondScale == null) { - mLabelVerticalSecondScaleWidth = 0; - mLabelVerticalSecondScaleHeight = 0; - return; - } - - // test label - double testY = ((mGraphView.mSecondScale.getMaxY() - mGraphView.mSecondScale.getMinY()) * 0.783) + mGraphView.mSecondScale.getMinY(); - String testLabel = mGraphView.mSecondScale.getLabelFormatter().formatLabel(testY, false); - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); - mLabelVerticalSecondScaleWidth = textBounds.width(); - mLabelVerticalSecondScaleHeight = textBounds.height(); - - // multiline - int lines = 1; - for (byte c : testLabel.getBytes()) { - if (c == '\n') lines++; - } - mLabelVerticalSecondScaleHeight *= lines; - } - - /** - * calculates the horizontal label size - * @param canvas canvas - */ - protected void calcLabelHorizontalSize(Canvas canvas) { - // test label - double testX = ((mGraphView.getViewport().getMaxX(false) - mGraphView.getViewport().getMinX(false)) * 0.783) + mGraphView.getViewport().getMinX(false); - String testLabel = mLabelFormatter.formatLabel(testX, true); - if (testLabel == null) { - testLabel = ""; - } - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); - mLabelHorizontalWidth = textBounds.width(); - - if (!mLabelHorizontalHeightFixed) { - mLabelHorizontalHeight = textBounds.height(); - - // multiline - int lines = 1; - for (byte c : testLabel.getBytes()) { - if (c == '\n') lines++; - } - mLabelHorizontalHeight *= lines; - - mLabelHorizontalHeight = (int) Math.max(mLabelHorizontalHeight, mStyles.textSize); - } - - // space between text and graph content - mLabelHorizontalHeight += mStyles.labelsSpace; - } - - /** - * do the drawing of the grid - * and labels - * @param canvas canvas - */ - public void draw(Canvas canvas) { - boolean labelSizeChanged = false; - if (mLabelHorizontalWidth == null) { - calcLabelHorizontalSize(canvas); - labelSizeChanged = true; - } - if (mLabelVerticalWidth == null) { - calcLabelVerticalSize(canvas); - labelSizeChanged = true; - } - if (mLabelVerticalSecondScaleWidth == null) { - calcLabelVerticalSecondScaleSize(canvas); - labelSizeChanged = true; - } - if (labelSizeChanged) { - // redraw - ViewCompat.postInvalidateOnAnimation(mGraphView); - return; - } - - if (!mIsAdjusted) { - adjust(); - } - - if (mIsAdjusted) { - drawVerticalSteps(canvas); - drawVerticalStepsSecondScale(canvas); - drawHorizontalSteps(canvas); - } else { - // we can not draw anything - return; - } - - drawHorizontalAxisTitle(canvas); - drawVerticalAxisTitle(canvas); - } - - /** - * draws the horizontal axis title if - * it is set - * @param canvas canvas - */ - protected void drawHorizontalAxisTitle(Canvas canvas) { - if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { - mPaintAxisTitle.setColor(getHorizontalAxisTitleColor()); - mPaintAxisTitle.setTextSize(getHorizontalAxisTitleTextSize()); - float x = canvas.getWidth() / 2; - float y = canvas.getHeight() - mStyles.padding; - canvas.drawText(mHorizontalAxisTitle, x, y, mPaintAxisTitle); - } - } - - /** - * draws the vertical axis title if - * it is set - * @param canvas canvas - */ - protected void drawVerticalAxisTitle(Canvas canvas) { - if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { - mPaintAxisTitle.setColor(getVerticalAxisTitleColor()); - mPaintAxisTitle.setTextSize(getVerticalAxisTitleTextSize()); - float x = getVerticalAxisTitleWidth(); - float y = canvas.getHeight() / 2; - canvas.save(); - canvas.rotate(-90, x, y); - canvas.drawText(mVerticalAxisTitle, x, y, mPaintAxisTitle); - canvas.restore(); - } - } - - /** - * @return the horizontal axis title height - * or 0 if there is no title - */ - public int getHorizontalAxisTitleHeight() { - if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { - return (int) getHorizontalAxisTitleTextSize(); - } else { - return 0; - } - } - - /** - * @return the vertical axis title width - * or 0 if there is no title - */ - public int getVerticalAxisTitleWidth() { - if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { - return (int) getVerticalAxisTitleTextSize(); - } else { - return 0; - } - } - - /** - * draws the horizontal steps - * vertical lines and horizontal labels - * - * @param canvas canvas - */ - protected void drawHorizontalSteps(Canvas canvas) { - // draw horizontal steps (vertical lines and horizontal labels) - mPaintLabel.setColor(getHorizontalLabelsColor()); - int i = 0; - for (Map.Entry e : mStepsHorizontal.entrySet()) { - // draw line - if (mStyles.highlightZeroLines) { - if (e.getValue() == 0d) { - mPaintLine.setStrokeWidth(5); - } else { - mPaintLine.setStrokeWidth(0); - } - } - if (mStyles.gridStyle.drawVertical()) { - canvas.drawLine(e.getKey(), mGraphView.getGraphContentTop(), e.getKey(), mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight(), mPaintLine); - } - - // draw label - if (isHorizontalLabelsVisible()) { - mPaintLabel.setTextAlign(Paint.Align.CENTER); - if (i == mStepsHorizontal.size() - 1) - mPaintLabel.setTextAlign(Paint.Align.RIGHT); - if (i == 0) - mPaintLabel.setTextAlign(Paint.Align.LEFT); - - // multiline labels - String label = mLabelFormatter.formatLabel(e.getValue(), true); - if (label == null) { - label = ""; - } - String[] lines = label.split("\n"); - for (int li = 0; li < lines.length; li++) { - // for the last line y = height - float y = (canvas.getHeight() - mStyles.padding - getHorizontalAxisTitleHeight()) - (lines.length - li - 1) * getTextSize() * 1.1f + mStyles.labelsSpace; - canvas.drawText(lines[li], e.getKey(), y, mPaintLabel); - } - } - i++; - } - } - - /** - * draws the vertical steps for the - * second scale on the right side - * - * @param canvas canvas - */ - protected void drawVerticalStepsSecondScale(Canvas canvas) { - if (mGraphView.mSecondScale == null) { - return; - } - - // draw only the vertical labels on the right - float startLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth(); - mPaintLabel.setColor(getVerticalLabelsSecondScaleColor()); - mPaintLabel.setTextAlign(getVerticalLabelsSecondScaleAlign()); - for (Map.Entry e : mStepsVerticalSecondScale.entrySet()) { - // draw label - int labelsWidth = mLabelVerticalSecondScaleWidth; - int labelsOffset = (int) startLeft; - if (getVerticalLabelsSecondScaleAlign() == Paint.Align.RIGHT) { - labelsOffset += labelsWidth; - } else if (getVerticalLabelsSecondScaleAlign() == Paint.Align.CENTER) { - labelsOffset += labelsWidth / 2; - } - - float y = e.getKey(); - - String[] lines = mGraphView.mSecondScale.mLabelFormatter.formatLabel(e.getValue(), false).split("\n"); - y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically - for (int li = 0; li < lines.length; li++) { - // for the last line y = height - float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; - canvas.drawText(lines[li], labelsOffset, y2, mPaintLabel); - } - } - } - - /** - * draws the vertical steps - * horizontal lines and vertical labels - * - * @param canvas canvas - */ - protected void drawVerticalSteps(Canvas canvas) { - // draw vertical steps (horizontal lines and vertical labels) - float startLeft = mGraphView.getGraphContentLeft(); - mPaintLabel.setColor(getVerticalLabelsColor()); - mPaintLabel.setTextAlign(getVerticalLabelsAlign()); - for (Map.Entry e : mStepsVertical.entrySet()) { - // draw line - if (mStyles.highlightZeroLines) { - if (e.getValue() == 0d) { - mPaintLine.setStrokeWidth(5); - } else { - mPaintLine.setStrokeWidth(0); - } - } - if (mStyles.gridStyle.drawHorizontal()) { - canvas.drawLine(startLeft, e.getKey(), startLeft + mGraphView.getGraphContentWidth(), e.getKey(), mPaintLine); - } - - // draw label - if (isVerticalLabelsVisible()) { - int labelsWidth = mLabelVerticalWidth; - int labelsOffset = 0; - if (getVerticalLabelsAlign() == Paint.Align.RIGHT) { - labelsOffset = labelsWidth; - labelsOffset -= mStyles.labelsSpace; - } else if (getVerticalLabelsAlign() == Paint.Align.CENTER) { - labelsOffset = labelsWidth / 2; - } - labelsOffset += mStyles.padding + getVerticalAxisTitleWidth(); - - float y = e.getKey(); - - String label = mLabelFormatter.formatLabel(e.getValue(), false); - if (label == null) { - label = ""; - } - String[] lines = label.split("\n"); - y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically - for (int li = 0; li < lines.length; li++) { - // for the last line y = height - float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; - canvas.drawText(lines[li], labelsOffset, y2, mPaintLabel); - } - } - } - } - - /** - * this will do rounding to generate - * nice human-readable bounds. - * - * @param in the raw value that is to be rounded - * @param roundAlwaysUp true if it shall always round up (ceil) - * @return the rounded number - */ - protected double humanRound(double in, boolean roundAlwaysUp) { - // round-up to 1-steps, 2-steps or 5-steps - int ten = 0; - while (in >= 10d) { - in /= 10d; - ten++; - } - while (in < 1d) { - in *= 10d; - ten--; - } - if (roundAlwaysUp) { - if (in == 1d) { - } else if (in <= 2d) { - in = 2d; - } else if (in <= 5d) { - in = 5d; - } else if (in < 10d) { - in = 10d; - } - } else { // always round down - if (in == 1d) { - } else if (in <= 4.9d) { - in = 2d; - } else if (in <= 9.9d) { - in = 5d; - } else if (in < 15d) { - in = 10d; - } - } - return in * Math.pow(10d, ten); - } - - /** - * @return the wrapped styles - */ - public Styles getStyles() { - return mStyles; - } - - /** - * @return the vertical label width - * 0 if there are no vertical labels - */ - public int getLabelVerticalWidth() { - return mLabelVerticalWidth == null || !isVerticalLabelsVisible() ? 0 : mLabelVerticalWidth; - } - - /** - * sets a manual and fixed with of the space for - * the vertical labels. This will prevent GraphView to - * calculate the width automatically. - * - * @param width the width of the space for the vertical labels. - * Use null to let GraphView automatically calculate the width. - */ - public void setLabelVerticalWidth(Integer width) { - mLabelVerticalWidth = width; - mLabelVerticalWidthFixed = mLabelVerticalWidth != null; - } - - /** - * @return the horizontal label height - * 0 if there are no horizontal labels - */ - public int getLabelHorizontalHeight() { - return mLabelHorizontalHeight == null || !isHorizontalLabelsVisible() ? 0 : mLabelHorizontalHeight; - } - - /** - * sets a manual and fixed height of the space for - * the horizontal labels. This will prevent GraphView to - * calculate the height automatically. - * - * @param height the height of the space for the horizontal labels. - * Use null to let GraphView automatically calculate the height. - */ - public void setLabelHorizontalHeight(Integer height) { - mLabelHorizontalHeight = height; - mLabelHorizontalHeightFixed = mLabelHorizontalHeight != null; - } - - /** - * @return the grid line color - */ - public int getGridColor() { - return mStyles.gridColor; - } - - /** - * @return whether the line at 0 are highlighted - */ - public boolean isHighlightZeroLines() { - return mStyles.highlightZeroLines; - } - - /** - * @return the padding around the grid and labels - */ - public int getPadding() { - return mStyles.padding; - } - - /** - * @param textSize the general text size of the axis titles. - * can be overwritten with {@link #setVerticalAxisTitleTextSize(float)} - * and {@link #setHorizontalAxisTitleTextSize(float)} - */ - public void setTextSize(float textSize) { - mStyles.textSize = textSize; - } - - /** - * @param verticalLabelsAlign the alignment of the vertical labels - */ - public void setVerticalLabelsAlign(Paint.Align verticalLabelsAlign) { - mStyles.verticalLabelsAlign = verticalLabelsAlign; - } - - /** - * @param verticalLabelsColor the color of the vertical labels - */ - public void setVerticalLabelsColor(int verticalLabelsColor) { - mStyles.verticalLabelsColor = verticalLabelsColor; - } - - /** - * @param horizontalLabelsColor the color of the horizontal labels - */ - public void setHorizontalLabelsColor(int horizontalLabelsColor) { - mStyles.horizontalLabelsColor = horizontalLabelsColor; - } - - /** - * @param gridColor the color of the grid lines - */ - public void setGridColor(int gridColor) { - mStyles.gridColor = gridColor; - } - - /** - * @param highlightZeroLines flag whether the zero-lines (vertical+ - * horizontal) shall be highlighted - */ - public void setHighlightZeroLines(boolean highlightZeroLines) { - mStyles.highlightZeroLines = highlightZeroLines; - } - - /** - * @param padding the padding around the graph and labels - */ - public void setPadding(int padding) { - mStyles.padding = padding; - } - - /** - * @return the label formatter, that converts - * the raw numbers to strings - */ - public LabelFormatter getLabelFormatter() { - return mLabelFormatter; - } - - /** - * @param mLabelFormatter the label formatter, that converts - * the raw numbers to strings - */ - public void setLabelFormatter(LabelFormatter mLabelFormatter) { - this.mLabelFormatter = mLabelFormatter; - mLabelFormatter.setViewport(mGraphView.getViewport()); - } - - /** - * @return the title of the horizontal axis - */ - public String getHorizontalAxisTitle() { - return mHorizontalAxisTitle; - } - - /** - * @param mHorizontalAxisTitle the title of the horizontal axis - */ - public void setHorizontalAxisTitle(String mHorizontalAxisTitle) { - this.mHorizontalAxisTitle = mHorizontalAxisTitle; - } - - /** - * @return the title of the vertical axis - */ - public String getVerticalAxisTitle() { - return mVerticalAxisTitle; - } - - /** - * @param mVerticalAxisTitle the title of the vertical axis - */ - public void setVerticalAxisTitle(String mVerticalAxisTitle) { - this.mVerticalAxisTitle = mVerticalAxisTitle; - } - - /** - * @return font size of the vertical axis title - */ - public float getVerticalAxisTitleTextSize() { - return mStyles.verticalAxisTitleTextSize; - } - - /** - * @param verticalAxisTitleTextSize font size of the vertical axis title - */ - public void setVerticalAxisTitleTextSize(float verticalAxisTitleTextSize) { - mStyles.verticalAxisTitleTextSize = verticalAxisTitleTextSize; - } - - /** - * @return font color of the vertical axis title - */ - public int getVerticalAxisTitleColor() { - return mStyles.verticalAxisTitleColor; - } - - /** - * @param verticalAxisTitleColor font color of the vertical axis title - */ - public void setVerticalAxisTitleColor(int verticalAxisTitleColor) { - mStyles.verticalAxisTitleColor = verticalAxisTitleColor; - } - - /** - * @return font size of the horizontal axis title - */ - public float getHorizontalAxisTitleTextSize() { - return mStyles.horizontalAxisTitleTextSize; - } - - /** - * @param horizontalAxisTitleTextSize font size of the horizontal axis title - */ - public void setHorizontalAxisTitleTextSize(float horizontalAxisTitleTextSize) { - mStyles.horizontalAxisTitleTextSize = horizontalAxisTitleTextSize; - } - - /** - * @return font color of the horizontal axis title - */ - public int getHorizontalAxisTitleColor() { - return mStyles.horizontalAxisTitleColor; - } - - /** - * @param horizontalAxisTitleColor font color of the horizontal axis title - */ - public void setHorizontalAxisTitleColor(int horizontalAxisTitleColor) { - mStyles.horizontalAxisTitleColor = horizontalAxisTitleColor; - } - - /** - * @return the alignment of the labels on the right side - */ - public Paint.Align getVerticalLabelsSecondScaleAlign() { - return mStyles.verticalLabelsSecondScaleAlign; - } - - /** - * @param verticalLabelsSecondScaleAlign the alignment of the labels on the right side - */ - public void setVerticalLabelsSecondScaleAlign(Paint.Align verticalLabelsSecondScaleAlign) { - mStyles.verticalLabelsSecondScaleAlign = verticalLabelsSecondScaleAlign; - } - - /** - * @return the color of the labels on the right side - */ - public int getVerticalLabelsSecondScaleColor() { - return mStyles.verticalLabelsSecondScaleColor; - } - - /** - * @param verticalLabelsSecondScaleColor the color of the labels on the right side - */ - public void setVerticalLabelsSecondScaleColor(int verticalLabelsSecondScaleColor) { - mStyles.verticalLabelsSecondScaleColor = verticalLabelsSecondScaleColor; - } - - /** - * @return the width of the vertical labels - * of the second scale - */ - public int getLabelVerticalSecondScaleWidth() { - return mLabelVerticalSecondScaleWidth==null?0:mLabelVerticalSecondScaleWidth; - } - - /** - * @return flag whether the horizontal labels are - * visible - */ - public boolean isHorizontalLabelsVisible() { - return mStyles.horizontalLabelsVisible; - } - - /** - * @param horizontalTitleVisible flag whether the horizontal labels are - * visible - */ - public void setHorizontalLabelsVisible(boolean horizontalTitleVisible) { - mStyles.horizontalLabelsVisible = horizontalTitleVisible; - } - - /** - * @return flag whether the vertical labels are - * visible - */ - public boolean isVerticalLabelsVisible() { - return mStyles.verticalLabelsVisible; - } - - /** - * @param verticalTitleVisible flag whether the vertical labels are - * visible - */ - public void setVerticalLabelsVisible(boolean verticalTitleVisible) { - mStyles.verticalLabelsVisible = verticalTitleVisible; - } - - /** - * @return count of the vertical labels, that - * will be shown at one time. - */ - public int getNumVerticalLabels() { - return mNumVerticalLabels; - } - - /** - * @param mNumVerticalLabels count of the vertical labels, that - * will be shown at one time. - */ - public void setNumVerticalLabels(int mNumVerticalLabels) { - this.mNumVerticalLabels = mNumVerticalLabels; - } - - /** - * @return count of the horizontal labels, that - * will be shown at one time. - */ - public int getNumHorizontalLabels() { - return mNumHorizontalLabels; - } - - /** - * @param mNumHorizontalLabels count of the horizontal labels, that - * will be shown at one time. - */ - public void setNumHorizontalLabels(int mNumHorizontalLabels) { - this.mNumHorizontalLabels = mNumHorizontalLabels; - } - - /** - * @return the grid style - */ - public GridStyle getGridStyle() { - return mStyles.gridStyle; - } - - /** - * Define which grid lines shall be drawn - * - * @param gridStyle the grid style - */ - public void setGridStyle(GridStyle gridStyle) { - mStyles.gridStyle = gridStyle; - } - - /** - * @return the space between the labels text and the graph content - */ - public int getLabelsSpace() { - return mStyles.labelsSpace; - } - - /** - * the space between the labels text and the graph content - * - * @param labelsSpace the space between the labels text and the graph content - */ - public void setLabelsSpace(int labelsSpace) { - mStyles.labelsSpace = labelsSpace; - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java deleted file mode 100644 index 80aad2990a..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -/** - * Interface to use as label formatter. - * Implement this in order to generate - * your own labels format. - * It is recommended to override {@link com.jjoe64.graphview.DefaultLabelFormatter}. - * - * @author jjoe64 - */ -public interface LabelFormatter { - /** - * converts a raw number as input to - * a formatted string for the label. - * - * @param value raw input number - * @param isValueX true if it is a value for the x axis - * false if it is a value for the y axis - * @return the formatted number as string - */ - public String formatLabel(double value, boolean isValueX); - - /** - * will be called in order to have a - * reference to the current viewport. - * This is useful if you need the bounds - * to generate your labels. - * You store this viewport in as member variable - * and access it e.g. in the {@link #formatLabel(double, boolean)} - * method. - * - * @param viewport the used viewport - */ - public void setViewport(Viewport viewport); -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java b/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java deleted file mode 100644 index db901577f7..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java +++ /dev/null @@ -1,394 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.util.TypedValue; - -import com.jjoe64.graphview.series.Series; - -import java.util.ArrayList; -import java.util.List; - -/** - * The default renderer for the legend box - * - * @author jjoe64 - */ -public class LegendRenderer { - /** - * wrapped styles regarding to the - * legend - */ - private final class Styles { - float textSize; - int spacing; - int padding; - int width; - int backgroundColor; - int textColor; - int margin; - LegendAlign align; - Point fixedPosition; - } - - /** - * alignment of the legend - */ - public enum LegendAlign { - /** - * top right corner - */ - TOP, - - /** - * middle right - */ - MIDDLE, - - /** - * bottom right corner - */ - BOTTOM - } - - /** - * wrapped styles - */ - private Styles mStyles; - - /** - * reference to the graphview - */ - private final GraphView mGraphView; - - /** - * flag whether legend will be - * drawn - */ - private boolean mIsVisible; - - /** - * paint for the drawing - */ - private Paint mPaint; - - /** - * cached legend width - * this will be filled in the drawing. - * Can be cleared via {@link #resetStyles()} - */ - private int cachedLegendWidth; - - /** - * creates legend renderer - * - * @param graphView regarding graphview - */ - public LegendRenderer(GraphView graphView) { - mGraphView = graphView; - mIsVisible = false; - mPaint = new Paint(); - mPaint.setTextAlign(Paint.Align.LEFT); - mStyles = new Styles(); - cachedLegendWidth = 0; - resetStyles(); - } - - /** - * resets the styles to the defaults - * and clears the legend width cache - */ - public void resetStyles() { - mStyles.align = LegendAlign.MIDDLE; - mStyles.textSize = mGraphView.getGridLabelRenderer().getTextSize(); - mStyles.spacing = (int) (mStyles.textSize / 5); - mStyles.padding = (int) (mStyles.textSize / 2); - mStyles.width = 0; - mStyles.backgroundColor = Color.argb(180, 100, 100, 100); - mStyles.margin = (int) (mStyles.textSize / 5); - - // get matching styles from theme - TypedValue typedValue = new TypedValue(); - mGraphView.getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceSmall, typedValue, true); - - int color1; - - try { - TypedArray array = mGraphView.getContext().obtainStyledAttributes(typedValue.data, new int[]{ - android.R.attr.textColorPrimary}); - color1 = array.getColor(0, Color.BLACK); - array.recycle(); - } catch (Exception e) { - color1 = Color.BLACK; - } - - mStyles.textColor = color1; - - cachedLegendWidth = 0; - } - - /** - * draws the legend if it is visible - * - * @param canvas canvas - * @see #setVisible(boolean) - */ - public void draw(Canvas canvas) { - if (!mIsVisible) return; - - mPaint.setTextSize(mStyles.textSize); - - int shapeSize = (int) (mStyles.textSize*0.8d); - - List allSeries = new ArrayList(); - allSeries.addAll(mGraphView.getSeries()); - if (mGraphView.mSecondScale != null) { - allSeries.addAll(mGraphView.getSecondScale().getSeries()); - } - - // width - int legendWidth = mStyles.width; - if (legendWidth == 0) { - // auto - legendWidth = cachedLegendWidth; - - if (legendWidth == 0) { - Rect textBounds = new Rect(); - for (Series s : allSeries) { - if (s.getTitle() != null) { - mPaint.getTextBounds(s.getTitle(), 0, s.getTitle().length(), textBounds); - legendWidth = Math.max(legendWidth, textBounds.width()); - } - } - if (legendWidth == 0) legendWidth = 1; - - // add shape size - legendWidth += shapeSize+mStyles.padding*2 + mStyles.spacing; - cachedLegendWidth = legendWidth; - } - } - - // rect - float legendHeight = (mStyles.textSize+mStyles.spacing)*allSeries.size() -mStyles.spacing; - float lLeft; - float lTop; - if (mStyles.fixedPosition != null) { - // use fied position - lLeft = mGraphView.getGraphContentLeft() + mStyles.margin + mStyles.fixedPosition.x; - lTop = mGraphView.getGraphContentTop() + mStyles.margin + mStyles.fixedPosition.y; - } else { - lLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth() - legendWidth - mStyles.margin; - switch (mStyles.align) { - case TOP: - lTop = mGraphView.getGraphContentTop() + mStyles.margin; - break; - case MIDDLE: - lTop = mGraphView.getHeight() / 2 - legendHeight / 2; - break; - default: - lTop = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - mStyles.margin - legendHeight - 2*mStyles.padding; - } - } - float lRight = lLeft+legendWidth; - float lBottom = lTop+legendHeight+2*mStyles.padding; - mPaint.setColor(mStyles.backgroundColor); - canvas.drawRoundRect(new RectF(lLeft, lTop, lRight, lBottom), 8, 8, mPaint); - - int i=0; - for (Series series : allSeries) { - mPaint.setColor(series.getColor()); - canvas.drawRect(new RectF(lLeft+mStyles.padding, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing)), lLeft+mStyles.padding+shapeSize, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing))+shapeSize), mPaint); - if (series.getTitle() != null) { - mPaint.setColor(mStyles.textColor); - canvas.drawText(series.getTitle(), lLeft+mStyles.padding+shapeSize+mStyles.spacing, lTop+mStyles.padding+mStyles.textSize+(i*(mStyles.textSize+mStyles.spacing)), mPaint); - } - i++; - } - } - - /** - * @return the flag whether the legend will be drawn - */ - public boolean isVisible() { - return mIsVisible; - } - - /** - * set the flag whether the legend will be drawn - * - * @param mIsVisible visible flag - */ - public void setVisible(boolean mIsVisible) { - this.mIsVisible = mIsVisible; - } - - /** - * @return font size - */ - public float getTextSize() { - return mStyles.textSize; - } - - /** - * sets the font size. this will clear - * the internal legend width cache - * - * @param textSize font size - */ - public void setTextSize(float textSize) { - mStyles.textSize = textSize; - cachedLegendWidth = 0; - } - - /** - * @return the spacing between the text lines - */ - public int getSpacing() { - return mStyles.spacing; - } - - /** - * set the spacing between the text lines - * - * @param spacing the spacing between the text lines - */ - public void setSpacing(int spacing) { - mStyles.spacing = spacing; - } - - /** - * padding is the space between the edge of the box - * and the beginning of the text - * - * @return padding from edge to text - */ - public int getPadding() { - return mStyles.padding; - } - - /** - * padding is the space between the edge of the box - * and the beginning of the text - * - * @param padding padding from edge to text - */ - public void setPadding(int padding) { - mStyles.padding = padding; - } - - /** - * the width of the box exclusive padding - * - * @return the width of the box - * 0 => auto - */ - public int getWidth() { - return mStyles.width; - } - - /** - * the width of the box exclusive padding - * @param width the width of the box exclusive padding - * 0 => auto - */ - public void setWidth(int width) { - mStyles.width = width; - } - - /** - * @return background color of the box - * it is recommended to use semi-transparent - * color. - */ - public int getBackgroundColor() { - return mStyles.backgroundColor; - } - - /** - * @param backgroundColor background color of the box - * it is recommended to use semi-transparent - * color. - */ - public void setBackgroundColor(int backgroundColor) { - mStyles.backgroundColor = backgroundColor; - } - - /** - * @return margin from the edge of the box - * to the corner of the graphview - */ - public int getMargin() { - return mStyles.margin; - } - - /** - * @param margin margin from the edge of the box - * to the corner of the graphview - */ - public void setMargin(int margin) { - mStyles.margin = margin; - } - - /** - * @return the vertical alignment of the box - */ - public LegendAlign getAlign() { - return mStyles.align; - } - - /** - * @param align the vertical alignment of the box - */ - public void setAlign(LegendAlign align) { - mStyles.align = align; - } - - /** - * @return font color - */ - public int getTextColor() { - return mStyles.textColor; - } - - /** - * @param textColor font color - */ - public void setTextColor(int textColor) { - mStyles.textColor = textColor; - } - - /** - * Use fixed coordinates to position the legend. - * This will override the align setting. - * - * @param x x coordinates in pixel - * @param y y coordinates in pixel - */ - public void setFixedPosition(int x, int y) { - mStyles.fixedPosition = new Point(x, y); - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java b/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java deleted file mode 100644 index 1fff8ee8a9..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java +++ /dev/null @@ -1,165 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -import com.jjoe64.graphview.series.Series; - -import java.util.ArrayList; -import java.util.List; - -/** - * To be used to plot a second scale - * on the graph. - * The second scale has always to have - * manual bounds. - * Use {@link #setMinY(double)} and {@link #setMaxY(double)} - * to set them. - * The second scale has it's own array of series. - * - * @author jjoe64 - */ -public class SecondScale { - /** - * reference to the viewport of the graph - */ - protected final Viewport mViewport; - - /** - * array of series for the second - * scale - */ - protected List mSeries; - - /** - * flag whether the y axis bounds - * are manual. - * For the current version this is always - * true. - */ - private boolean mYAxisBoundsManual = true; - - /** - * min y value for the y axis bounds - */ - private double mMinY; - - /** - * max y value for the y axis bounds - */ - private double mMaxY; - - /** - * label formatter for the y labels - * on the right side - */ - protected LabelFormatter mLabelFormatter; - - /** - * creates the second scale. - * normally you do not call this contructor. - * Use {@link com.jjoe64.graphview.GraphView#getSecondScale()} - * in order to get the instance. - */ - SecondScale(Viewport viewport) { - mViewport = viewport; - mSeries = new ArrayList(); - mLabelFormatter = new DefaultLabelFormatter(); - mLabelFormatter.setViewport(mViewport); - } - - /** - * add a series to the second scale. - * Don't add this series also to the GraphView - * object. - * - * @param s the series - */ - public void addSeries(Series s) { - mSeries.add(s); - } - - //public void setYAxisBoundsManual(boolean mYAxisBoundsManual) { - // this.mYAxisBoundsManual = mYAxisBoundsManual; - //} - - /** - * set the min y bounds - * - * @param d min y value - */ - public void setMinY(double d) { - mMinY = d; - } - - /** - * set the max y bounds - * - * @param d max y value - */ - public void setMaxY(double d) { - mMaxY = d; - } - - /** - * @return the series of the second scale - */ - public List getSeries() { - return mSeries; - } - - /** - * @return min y bound - */ - public double getMinY() { - return mMinY; - } - - /** - * @return max y bound - */ - public double getMaxY() { - return mMaxY; - } - - /** - * @return always true for the current implementation - */ - public boolean isYAxisBoundsManual() { - return mYAxisBoundsManual; - } - - /** - * @return label formatter for the y labels on the right side - */ - public LabelFormatter getLabelFormatter() { - return mLabelFormatter; - } - - /** - * Set a custom label formatter that is used - * for the y labels on the right side. - * - * @param formatter label formatter for the y labels - */ - public void setLabelFormatter(LabelFormatter formatter) { - mLabelFormatter = formatter; - mLabelFormatter.setViewport(mViewport); - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java b/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java deleted file mode 100644 index a02f22a21e..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ - -package com.jjoe64.graphview; - -import com.jjoe64.graphview.series.DataPointInterface; - -/** - * you can change the color depending on the value. - * takes only effect for BarGraphSeries. - * - * @see com.jjoe64.graphview.series.BarGraphSeries#setValueDependentColor(ValueDependentColor) - */ -public interface ValueDependentColor { - /** - * this is called when a bar is about to draw - * and the color is be loaded. - * - * @param data the current input value - * @return the color that the bar should be drawn with - * Generate the int via the android.graphics.Color class. - */ - public int get(T data); -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/Viewport.java b/graphview/src/main/java/com/jjoe64/graphview/Viewport.java deleted file mode 100644 index de90c05ea2..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/Viewport.java +++ /dev/null @@ -1,996 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.RectF; -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; -import android.widget.OverScroller; - -import androidx.core.view.ViewCompat; -import androidx.core.widget.EdgeEffectCompat; - -import com.jjoe64.graphview.compat.OverScrollerCompat; -import com.jjoe64.graphview.series.DataPointInterface; -import com.jjoe64.graphview.series.Series; - -import java.util.Iterator; -import java.util.List; - -/** - * This is the default implementation for the viewport. - * This implementation so for a normal viewport - * where there is a horizontal x-axis and a - * vertical y-axis. - * This viewport is compatible with - * - {@link com.jjoe64.graphview.series.BarGraphSeries} - * - {@link com.jjoe64.graphview.series.LineGraphSeries} - * - {@link com.jjoe64.graphview.series.PointsGraphSeries} - * - * @author jjoe64 - */ -public class Viewport { - /** - * listener for the scale gesture - */ - private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener - = new ScaleGestureDetector.OnScaleGestureListener() { - /** - * called by android - * @param detector detector - * @return always true - */ - @Override - public boolean onScale(ScaleGestureDetector detector) { - float viewportWidth = mCurrentViewport.width(); - float center = mCurrentViewport.left + viewportWidth / 2; - viewportWidth /= detector.getScaleFactor(); - mCurrentViewport.left = center - viewportWidth / 2; - mCurrentViewport.right = mCurrentViewport.left+viewportWidth; - - // viewportStart must not be < minX - float minX = (float) getMinX(true); - if (mCurrentViewport.left < minX) { - mCurrentViewport.left = minX; - mCurrentViewport.right = mCurrentViewport.left+viewportWidth; - } - - // viewportStart + viewportSize must not be > maxX - float maxX = (float) getMaxX(true); - if (viewportWidth == 0) { - mCurrentViewport.right = maxX; - } - double overlap = mCurrentViewport.left + viewportWidth - maxX; - if (overlap > 0) { - // scroll left - if (mCurrentViewport.left-overlap > minX) { - mCurrentViewport.left -= overlap; - mCurrentViewport.right = mCurrentViewport.left+viewportWidth; - } else { - // maximal scale - mCurrentViewport.left = minX; - mCurrentViewport.right = maxX; - } - } - - // adjust viewport, labels, etc. - mGraphView.onDataChanged(true, false); - - ViewCompat.postInvalidateOnAnimation(mGraphView); - - return true; - } - - /** - * called when scaling begins - * - * @param detector detector - * @return true if it is scalable - */ - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - if (mIsScalable) { - mScalingBeginWidth = mCurrentViewport.width(); - mScalingBeginLeft = mCurrentViewport.left; - mScalingActive = true; - return true; - } else { - return false; - } - } - - /** - * called when sacling ends - * This will re-adjust the viewport. - * - * @param detector detector - */ - @Override - public void onScaleEnd(ScaleGestureDetector detector) { - mScalingActive = false; - - // re-adjust - mXAxisBoundsStatus = AxisBoundsStatus.READJUST_AFTER_SCALE; - - mScrollingReferenceX = Float.NaN; - - // adjust viewport, labels, etc. - mGraphView.onDataChanged(true, false); - - ViewCompat.postInvalidateOnAnimation(mGraphView); - } - }; - - /** - * simple gesture listener to track scroll events - */ - private final GestureDetector.SimpleOnGestureListener mGestureListener - = new GestureDetector.SimpleOnGestureListener() { - @Override - public boolean onDown(MotionEvent e) { - if (!mIsScrollable || mScalingActive) return false; - - // Initiates the decay phase of any active edge effects. - releaseEdgeEffects(); - mScrollerStartViewport.set(mCurrentViewport); - // Aborts any active scroll animations and invalidates. - mScroller.forceFinished(true); - ViewCompat.postInvalidateOnAnimation(mGraphView); - return true; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (!mIsScrollable || mScalingActive) return false; - - if (Float.isNaN(mScrollingReferenceX)) { - mScrollingReferenceX = mCurrentViewport.left; - } - - // Scrolling uses math based on the viewport (as opposed to math using pixels). - /** - * Pixel offset is the offset in screen pixels, while viewport offset is the - * offset within the current viewport. For additional information on surface sizes - * and pixel offsets, see the docs for {@link computeScrollSurfaceSize()}. For - * additional information about the viewport, see the comments for - * {@link mCurrentViewport}. - */ - float viewportOffsetX = distanceX * mCurrentViewport.width() / mGraphView.getGraphContentWidth(); - float viewportOffsetY = -distanceY * mCurrentViewport.height() / mGraphView.getGraphContentHeight(); - - int completeWidth = (int)((mCompleteRange.width()/mCurrentViewport.width()) * (float) mGraphView.getGraphContentWidth()); - int completeHeight = (int)((mCompleteRange.height()/mCurrentViewport.height()) * (float) mGraphView.getGraphContentHeight()); - - int scrolledX = (int) (completeWidth - * (mCurrentViewport.left + viewportOffsetX - mCompleteRange.left) - / mCompleteRange.width()); - int scrolledY = (int) (completeHeight - * (mCompleteRange.bottom - mCurrentViewport.bottom - viewportOffsetY) - / mCompleteRange.height()); - boolean canScrollX = mCurrentViewport.left > mCompleteRange.left - || mCurrentViewport.right < mCompleteRange.right; - boolean canScrollY = mCurrentViewport.bottom > mCompleteRange.bottom - || mCurrentViewport.top < mCompleteRange.top; - - if (canScrollX) { - if (viewportOffsetX < 0) { - float tooMuch = mCurrentViewport.left+viewportOffsetX - mCompleteRange.left; - if (tooMuch < 0) { - viewportOffsetX -= tooMuch; - } - } else { - float tooMuch = mCurrentViewport.right+viewportOffsetX - mCompleteRange.right; - if (tooMuch > 0) { - viewportOffsetX -= tooMuch; - } - } - mCurrentViewport.left += viewportOffsetX; - mCurrentViewport.right += viewportOffsetX; - } - if (canScrollY) { - //mCurrentViewport.top += viewportOffsetX; - //mCurrentViewport.bottom -= viewportOffsetX; - } - - if (canScrollX && scrolledX < 0) { - mEdgeEffectLeft.onPull(scrolledX / (float) mGraphView.getGraphContentWidth()); - mEdgeEffectLeftActive = true; - } - if (canScrollY && scrolledY < 0) { - mEdgeEffectBottom.onPull(scrolledY / (float) mGraphView.getGraphContentHeight()); - mEdgeEffectBottomActive = true; - } - if (canScrollX && scrolledX > completeWidth - mGraphView.getGraphContentWidth()) { - mEdgeEffectRight.onPull((scrolledX - completeWidth + mGraphView.getGraphContentWidth()) - / (float) mGraphView.getGraphContentWidth()); - mEdgeEffectRightActive = true; - } - //if (canScrollY && scrolledY > mSurfaceSizeBuffer.y - mContentRect.height()) { - // mEdgeEffectTop.onPull((scrolledY - mSurfaceSizeBuffer.y + mContentRect.height()) - // / (float) mContentRect.height()); - // mEdgeEffectTopActive = true; - //} - - // adjust viewport, labels, etc. - mGraphView.onDataChanged(true, false); - - ViewCompat.postInvalidateOnAnimation(mGraphView); - return true; - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, - float velocityX, float velocityY) { - //fling((int) -velocityX, (int) -velocityY); - return true; - } - }; - - /** - * the state of the axis bounds - */ - public enum AxisBoundsStatus { - /** - * initial means that the bounds gets - * auto adjusted if they are not manual. - * After adjusting the status comes to - * #AUTO_ADJUSTED. - */ - INITIAL, - - /** - * after the bounds got auto-adjusted, - * this status will set. - */ - AUTO_ADJUSTED, - - /** - * this flags the status that a scale was - * done and the bounds has to be auto-adjusted - * afterwards. - */ - READJUST_AFTER_SCALE, - - /** - * means that the bounds are fix (manually) and - * are not to be auto-adjusted. - */ - FIX - } - - /** - * paint to draw background - */ - private Paint mPaint; - - /** - * reference to the graphview - */ - private final GraphView mGraphView; - - /** - * this holds the current visible viewport - * left = minX, right = maxX - * bottom = minY, top = maxY - */ - protected RectF mCurrentViewport = new RectF(); - - /** - * this holds the whole range of the data - * left = minX, right = maxX - * bottom = minY, top = maxY - */ - protected RectF mCompleteRange = new RectF(); - - /** - * flag whether scaling is currently active - */ - protected boolean mScalingActive; - - /** - * stores the width of the viewport at the time - * of beginning of the scaling. - */ - protected float mScalingBeginWidth; - - /** - * stores the viewport left at the time of - * beginning of the scaling. - */ - protected float mScalingBeginLeft; - - /** - * flag whether the viewport is scrollable - */ - private boolean mIsScrollable; - - /** - * flag whether the viewport is scalable - */ - private boolean mIsScalable; - - /** - * gesture detector to detect scrolling - */ - protected GestureDetector mGestureDetector; - - /** - * detect scaling - */ - protected ScaleGestureDetector mScaleGestureDetector; - - /** - * not used - for fling - */ - protected OverScroller mScroller; - - /** - * not used - */ - private EdgeEffectCompat mEdgeEffectTop; - - /** - * not used - */ - private EdgeEffectCompat mEdgeEffectBottom; - - /** - * glow effect when scrolling left - */ - private EdgeEffectCompat mEdgeEffectLeft; - - /** - * glow effect when scrolling right - */ - private EdgeEffectCompat mEdgeEffectRight; - - /** - * not used - */ - private boolean mEdgeEffectTopActive; - - /** - * not used - */ - private boolean mEdgeEffectBottomActive; - - /** - * glow effect when scrolling left - */ - private boolean mEdgeEffectLeftActive; - - /** - * glow effect when scrolling right - */ - private boolean mEdgeEffectRightActive; - - /** - * stores the viewport at the time of - * the beginning of scaling - */ - private RectF mScrollerStartViewport = new RectF(); - - /** - * stores the viewport left value at the - * time of beginning of the scrolling - */ - protected float mScrollingReferenceX = Float.NaN; - - /** - * state of the x axis - */ - private AxisBoundsStatus mXAxisBoundsStatus; - - /** - * state of the y axis - */ - private AxisBoundsStatus mYAxisBoundsStatus; - - /** - * flag whether the x axis bounds are manual - */ - private boolean mXAxisBoundsManual; - - /** - * flag whether the y axis bounds are manual - */ - private boolean mYAxisBoundsManual; - - /** - * background color of the viewport area - * it is recommended to use a semi-transparent color - */ - private int mBackgroundColor; - - /** - * creates the viewport - * - * @param graphView graphview - */ - Viewport(GraphView graphView) { - mScroller = new OverScroller(graphView.getContext()); - mEdgeEffectTop = new EdgeEffectCompat(graphView.getContext()); - mEdgeEffectBottom = new EdgeEffectCompat(graphView.getContext()); - mEdgeEffectLeft = new EdgeEffectCompat(graphView.getContext()); - mEdgeEffectRight = new EdgeEffectCompat(graphView.getContext()); - mGestureDetector = new GestureDetector(graphView.getContext(), mGestureListener); - mScaleGestureDetector = new ScaleGestureDetector(graphView.getContext(), mScaleGestureListener); - - mGraphView = graphView; - mXAxisBoundsStatus = AxisBoundsStatus.INITIAL; - mYAxisBoundsStatus = AxisBoundsStatus.INITIAL; - mBackgroundColor = Color.TRANSPARENT; - mPaint = new Paint(); - } - - /** - * will be called on a touch event. - * needed to use scaling and scrolling - * - * @param event - * @return true if it was consumed - */ - public boolean onTouchEvent(MotionEvent event) { - boolean b = mScaleGestureDetector.onTouchEvent(event); - b |= mGestureDetector.onTouchEvent(event); - return b; - } - - /** - * change the state of the x axis. - * normally you do not call this method. - * If you want to set manual axis use - * {@link #setXAxisBoundsManual(boolean)} and {@link #setYAxisBoundsManual(boolean)} - * - * @param s state - */ - public void setXAxisBoundsStatus(AxisBoundsStatus s) { - mXAxisBoundsStatus = s; - } - - /** - * change the state of the y axis. - * normally you do not call this method. - * If you want to set manual axis use - * {@link #setXAxisBoundsManual(boolean)} and {@link #setYAxisBoundsManual(boolean)} - * - * @param s state - */ - public void setYAxisBoundsStatus(AxisBoundsStatus s) { - mYAxisBoundsStatus = s; - } - - /** - * @return whether the viewport is scrollable - */ - public boolean isScrollable() { - return mIsScrollable; - } - - /** - * @param mIsScrollable whether is viewport is scrollable - */ - public void setScrollable(boolean mIsScrollable) { - this.mIsScrollable = mIsScrollable; - } - - /** - * @return the x axis state - */ - public AxisBoundsStatus getXAxisBoundsStatus() { - return mXAxisBoundsStatus; - } - - /** - * @return the y axis state - */ - public AxisBoundsStatus getYAxisBoundsStatus() { - return mYAxisBoundsStatus; - } - - /** - * caches the complete range (minX, maxX, minY, maxY) - * by iterating all series and all datapoints and - * stores it into #mCompleteRange - */ - public void calcCompleteRange() { - List series = mGraphView.getSeries(); - mCompleteRange.set(0, 0, 0, 0); - if (!series.isEmpty() && !series.get(0).isEmpty()) { - double d = series.get(0).getLowestValueX(); - for (Series s : series) { - if (!s.isEmpty() && d > s.getLowestValueX()) { - d = s.getLowestValueX(); - } - } - mCompleteRange.left = (float) d; - - d = series.get(0).getHighestValueX(); - for (Series s : series) { - if (!s.isEmpty() && d < s.getHighestValueX()) { - d = s.getHighestValueX(); - } - } - mCompleteRange.right = (float) d; - - d = series.get(0).getLowestValueY(); - for (Series s : series) { - if (!s.isEmpty() && d > s.getLowestValueY()) { - d = s.getLowestValueY(); - } - } - mCompleteRange.bottom = (float) d; - - d = series.get(0).getHighestValueY(); - for (Series s : series) { - if (!s.isEmpty() && d < s.getHighestValueY()) { - d = s.getHighestValueY(); - } - } - mCompleteRange.top = (float) d; - } - - // calc current viewport bounds - if (mYAxisBoundsStatus == AxisBoundsStatus.AUTO_ADJUSTED) { - mYAxisBoundsStatus = AxisBoundsStatus.INITIAL; - } - if (mYAxisBoundsStatus == AxisBoundsStatus.INITIAL) { - mCurrentViewport.top = mCompleteRange.top; - mCurrentViewport.bottom = mCompleteRange.bottom; - } - - if (mXAxisBoundsStatus == AxisBoundsStatus.AUTO_ADJUSTED) { - mXAxisBoundsStatus = AxisBoundsStatus.INITIAL; - } - if (mXAxisBoundsStatus == AxisBoundsStatus.INITIAL) { - mCurrentViewport.left = mCompleteRange.left; - mCurrentViewport.right = mCompleteRange.right; - } else if (mXAxisBoundsManual && !mYAxisBoundsManual && mCompleteRange.width() != 0) { - // get highest/lowest of current viewport - // lowest - double d = Double.MAX_VALUE; - for (Series s : series) { - Iterator values = s.getValues(mCurrentViewport.left, mCurrentViewport.right); - while (values.hasNext()) { - double v = values.next().getY(); - if (d > v) { - d = v; - } - } - } - - mCurrentViewport.bottom = (float) d; - - // highest - d = Double.MIN_VALUE; - for (Series s : series) { - Iterator values = s.getValues(mCurrentViewport.left, mCurrentViewport.right); - while (values.hasNext()) { - double v = values.next().getY(); - if (d < v) { - d = v; - } - } - } - mCurrentViewport.top = (float) d; - } - - // fixes blank screen when range is zero - if (mCurrentViewport.left == mCurrentViewport.right) mCurrentViewport.right++; - if (mCurrentViewport.top == mCurrentViewport.bottom) mCurrentViewport.top++; - } - - /** - * @param completeRange if true => minX of the complete range of all series - * if false => minX of the current visible viewport - * @return the min x value - */ - public double getMinX(boolean completeRange) { - if (completeRange) { - return (double) mCompleteRange.left; - } else { - return (double) mCurrentViewport.left; - } - } - - /** - * @param completeRange if true => maxX of the complete range of all series - * if false => maxX of the current visible viewport - * @return the max x value - */ - public double getMaxX(boolean completeRange) { - if (completeRange) { - return (double) mCompleteRange.right; - } else { - return mCurrentViewport.right; - } - } - - /** - * @param completeRange if true => minY of the complete range of all series - * if false => minY of the current visible viewport - * @return the min y value - */ - public double getMinY(boolean completeRange) { - if (completeRange) { - return (double) mCompleteRange.bottom; - } else { - return mCurrentViewport.bottom; - } - } - - /** - * @param completeRange if true => maxY of the complete range of all series - * if false => maxY of the current visible viewport - * @return the max y value - */ - public double getMaxY(boolean completeRange) { - if (completeRange) { - return (double) mCompleteRange.top; - } else { - return mCurrentViewport.top; - } - } - - /** - * set the maximal y value for the current viewport. - * Make sure to set the y bounds to manual via - * {@link #setYAxisBoundsManual(boolean)} - * @param y max / highest value - */ - public void setMaxY(double y) { - mCurrentViewport.top = (float) y; - } - - /** - * set the minimal y value for the current viewport. - * Make sure to set the y bounds to manual via - * {@link #setYAxisBoundsManual(boolean)} - * @param y min / lowest value - */ - public void setMinY(double y) { - mCurrentViewport.bottom = (float) y; - } - - /** - * set the maximal x value for the current viewport. - * Make sure to set the x bounds to manual via - * {@link #setXAxisBoundsManual(boolean)} - * @param x max / highest value - */ - public void setMaxX(double x) { - mCurrentViewport.right = (float) x; - } - - /** - * set the minimal x value for the current viewport. - * Make sure to set the x bounds to manual via - * {@link #setXAxisBoundsManual(boolean)} - * @param x min / lowest value - */ - public void setMinX(double x) { - mCurrentViewport.left = (float) x; - } - - /** - * release the glowing effects - */ - private void releaseEdgeEffects() { - mEdgeEffectLeftActive - = mEdgeEffectRightActive - = false; - mEdgeEffectLeft.onRelease(); - mEdgeEffectRight.onRelease(); - } - - /** - * not used currently - * - * @param velocityX - * @param velocityY - */ - private void fling(int velocityX, int velocityY) { - velocityY = 0; - releaseEdgeEffects(); - // Flings use math in pixels (as opposed to math based on the viewport). - mScrollerStartViewport.set(mCurrentViewport); - int maxX = (int)((mCurrentViewport.width()/mCompleteRange.width())*(float)mGraphView.getGraphContentWidth()) - mGraphView.getGraphContentWidth(); - int maxY = (int)((mCurrentViewport.height()/mCompleteRange.height())*(float)mGraphView.getGraphContentHeight()) - mGraphView.getGraphContentHeight(); - int startX = (int)((mCurrentViewport.left - mCompleteRange.left)/mCompleteRange.width())*maxX; - int startY = (int)((mCurrentViewport.top - mCompleteRange.top)/mCompleteRange.height())*maxY; - mScroller.forceFinished(true); - mScroller.fling( - startX, - startY, - velocityX, - velocityY, - 0, maxX, - 0, maxY, - mGraphView.getGraphContentWidth() / 2, - mGraphView.getGraphContentHeight() / 2); - ViewCompat.postInvalidateOnAnimation(mGraphView); - } - - /** - * not used currently - */ - public void computeScroll() { - if (true) return; - - boolean needsInvalidate = false; - - if (mScroller.computeScrollOffset()) { - // The scroller isn't finished, meaning a fling or programmatic pan operation is - // currently active. - - int completeWidth = (int)((mCompleteRange.width()/mCurrentViewport.width()) * (float) mGraphView.getGraphContentWidth()); - int completeHeight = (int)((mCompleteRange.height()/mCurrentViewport.height()) * (float) mGraphView.getGraphContentHeight()); - - int currX = mScroller.getCurrX(); - int currY = mScroller.getCurrY(); - - boolean canScrollX = mCurrentViewport.left > mCompleteRange.left - || mCurrentViewport.right < mCompleteRange.right; - boolean canScrollY = mCurrentViewport.bottom > mCompleteRange.bottom - || mCurrentViewport.top < mCompleteRange.top; - - if (canScrollX - && currX < 0 - && mEdgeEffectLeft.isFinished() - && !mEdgeEffectLeftActive) { - mEdgeEffectLeft.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); - mEdgeEffectLeftActive = true; - needsInvalidate = true; - } else if (canScrollX - && currX > (completeWidth - mGraphView.getGraphContentWidth()) - && mEdgeEffectRight.isFinished() - && !mEdgeEffectRightActive) { - mEdgeEffectRight.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); - mEdgeEffectRightActive = true; - needsInvalidate = true; - } - - if (canScrollY - && currY < 0 - && mEdgeEffectTop.isFinished() - && !mEdgeEffectTopActive) { - mEdgeEffectTop.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); - mEdgeEffectTopActive = true; - needsInvalidate = true; - } else if (canScrollY - && currY > (completeHeight - mGraphView.getGraphContentHeight()) - && mEdgeEffectBottom.isFinished() - && !mEdgeEffectBottomActive) { - mEdgeEffectBottom.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); - mEdgeEffectBottomActive = true; - needsInvalidate = true; - } - - float currXRange = mCompleteRange.left + mCompleteRange.width() - * currX / completeWidth; - float currYRange = mCompleteRange.top - mCompleteRange.height() - * currY / completeHeight; - - float currWidth = mCurrentViewport.width(); - float currHeight = mCurrentViewport.height(); - mCurrentViewport.left = currXRange; - mCurrentViewport.right = currXRange + currWidth; - //mCurrentViewport.bottom = currYRange; - //mCurrentViewport.top = currYRange + currHeight; - } - - if (needsInvalidate) { - ViewCompat.postInvalidateOnAnimation(mGraphView); - } - } - - /** - * Draws the overscroll "glow" at the four edges of the chart region, if necessary. - * - * @see EdgeEffectCompat - */ - private void drawEdgeEffectsUnclipped(Canvas canvas) { - // The methods below rotate and translate the canvas as needed before drawing the glow, - // since EdgeEffectCompat always draws a top-glow at 0,0. - - boolean needsInvalidate = false; - - if (!mEdgeEffectTop.isFinished()) { - final int restoreCount = canvas.save(); - canvas.translate(mGraphView.getGraphContentLeft(), mGraphView.getGraphContentTop()); - mEdgeEffectTop.setSize(mGraphView.getGraphContentWidth(), mGraphView.getGraphContentHeight()); - if (mEdgeEffectTop.draw(canvas)) { - needsInvalidate = true; - } - canvas.restoreToCount(restoreCount); - } - - //if (!mEdgeEffectBottom.isFinished()) { - // final int restoreCount = canvas.save(); - // canvas.translate(2 * mContentRect.left - mContentRect.right, mContentRect.bottom); - // canvas.rotate(180, mContentRect.width(), 0); - // mEdgeEffectBottom.setSize(mContentRect.width(), mContentRect.height()); - // if (mEdgeEffectBottom.draw(canvas)) { - // needsInvalidate = true; - // } - // canvas.restoreToCount(restoreCount); - //} - - if (!mEdgeEffectLeft.isFinished()) { - final int restoreCount = canvas.save(); - canvas.translate(mGraphView.getGraphContentLeft(), mGraphView.getGraphContentTop()+ mGraphView.getGraphContentHeight()); - canvas.rotate(-90, 0, 0); - mEdgeEffectLeft.setSize(mGraphView.getGraphContentHeight(), mGraphView.getGraphContentWidth()); - if (mEdgeEffectLeft.draw(canvas)) { - needsInvalidate = true; - } - canvas.restoreToCount(restoreCount); - } - - if (!mEdgeEffectRight.isFinished()) { - final int restoreCount = canvas.save(); - canvas.translate(mGraphView.getGraphContentLeft()+ mGraphView.getGraphContentWidth(), mGraphView.getGraphContentTop()); - canvas.rotate(90, 0, 0); - mEdgeEffectRight.setSize(mGraphView.getGraphContentHeight(), mGraphView.getGraphContentWidth()); - if (mEdgeEffectRight.draw(canvas)) { - needsInvalidate = true; - } - canvas.restoreToCount(restoreCount); - } - - if (needsInvalidate) { - ViewCompat.postInvalidateOnAnimation(mGraphView); - } - } - - /** - * will be first called in order to draw - * the canvas - * Used to draw the background - * - * @param c canvas. - */ - public void drawFirst(Canvas c) { - // draw background - if (mBackgroundColor != Color.TRANSPARENT) { - mPaint.setColor(mBackgroundColor); - c.drawRect( - mGraphView.getGraphContentLeft(), - mGraphView.getGraphContentTop(), - mGraphView.getGraphContentLeft()+mGraphView.getGraphContentWidth(), - mGraphView.getGraphContentTop()+mGraphView.getGraphContentHeight(), - mPaint - ); - } - } - - /** - * draws the glowing edge effect - * - * @param c canvas - */ - public void draw(Canvas c) { - drawEdgeEffectsUnclipped(c); - } - - /** - * @return background of the viewport area - */ - public int getBackgroundColor() { - return mBackgroundColor; - } - - /** - * @param mBackgroundColor background of the viewport area - * use transparent to have no background - */ - public void setBackgroundColor(int mBackgroundColor) { - this.mBackgroundColor = mBackgroundColor; - } - - /** - * @return whether the viewport is scalable - */ - public boolean isScalable() { - return mIsScalable; - } - - /** - * active the scaling/zooming feature - * notice: sets the x axis bounds to manual - * - * @param mIsScalable whether the viewport is scalable - */ - public void setScalable(boolean mIsScalable) { - this.mIsScalable = mIsScalable; - if (mIsScalable) { - mIsScrollable = true; - - // set viewport to manual - setXAxisBoundsManual(true); - } - - } - - /** - * @return whether the x axis bounds are manual. - * @see #setMinX(double) - * @see #setMaxX(double) - */ - public boolean isXAxisBoundsManual() { - return mXAxisBoundsManual; - } - - /** - * @param mXAxisBoundsManual whether the x axis bounds are manual. - * @see #setMinX(double) - * @see #setMaxX(double) - */ - public void setXAxisBoundsManual(boolean mXAxisBoundsManual) { - this.mXAxisBoundsManual = mXAxisBoundsManual; - if (mXAxisBoundsManual) { - mXAxisBoundsStatus = AxisBoundsStatus.FIX; - } - } - - /** - * @return whether the y axis bound are manual - */ - public boolean isYAxisBoundsManual() { - return mYAxisBoundsManual; - } - - /** - * @param mYAxisBoundsManual whether the y axis bounds are manual - * @see #setMaxY(double) - * @see #setMinY(double) - */ - public void setYAxisBoundsManual(boolean mYAxisBoundsManual) { - this.mYAxisBoundsManual = mYAxisBoundsManual; - if (mYAxisBoundsManual) { - mYAxisBoundsStatus = AxisBoundsStatus.FIX; - } - } - - /** - * forces the viewport to scroll to the end - * of the range by keeping the current viewport size. - * - * Important: Only takes effect if x axis bounds are manual. - * - * @see #setXAxisBoundsManual(boolean) - */ - public void scrollToEnd() { - if (mXAxisBoundsManual) { - float size = mCurrentViewport.width(); - mCurrentViewport.right = mCompleteRange.right; - mCurrentViewport.left = mCompleteRange.right - size; - mScrollingReferenceX = Float.NaN; - mGraphView.onDataChanged(true, false); - } else { - Log.w("GraphView", "scrollToEnd works only with manual x axis bounds"); - } - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java b/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java deleted file mode 100644 index 20b497c91f..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.compat; - -import android.annotation.TargetApi; -import android.os.Build; -import android.widget.OverScroller; - -/** - * A utility class for using {@link android.widget.OverScroller} in a backward-compatible fashion. - */ -public class OverScrollerCompat { - /** - * Disallow instantiation. - */ - private OverScrollerCompat() { - } - /** - * @see android.view.ScaleGestureDetector#getCurrentSpanY() - */ - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - public static float getCurrVelocity(OverScroller overScroller) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return overScroller.getCurrVelocity(); - } else { - return 0; - } - } -} \ No newline at end of file diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java deleted file mode 100644 index 1e9fa3cff4..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.helper; - -import android.content.Context; - -import com.jjoe64.graphview.DefaultLabelFormatter; - -import java.text.DateFormat; -import java.util.Calendar; -import java.util.Date; - -/** - * Helper class to use date objects as x-values. - * This will use your own Date Format or by default - * the Android default date format to convert - * the x-values (that has to be millis from - * 01-01-1970) into a formatted date string. - * - * See the DateAsXAxis example in the GraphView-Demos project - * to see a working example. - * - * @author jjoe64 - */ -public class DateAsXAxisLabelFormatter extends DefaultLabelFormatter { - /** - * the date format that will convert - * the unix timestamp to string - */ - protected final DateFormat mDateFormat; - - /** - * calendar to avoid creating new date objects - */ - protected final Calendar mCalendar; - - /** - * create the formatter with the Android default date format to convert - * the x-values. - * - * @param context the application context - */ - public DateAsXAxisLabelFormatter(Context context) { - mDateFormat = android.text.format.DateFormat.getDateFormat(context); - mCalendar = Calendar.getInstance(); - } - - /** - * create the formatter with your own custom - * date format to convert the x-values. - * - * @param context the application context - * @param dateFormat custom date format - */ - public DateAsXAxisLabelFormatter(Context context, DateFormat dateFormat) { - mDateFormat = dateFormat; - mCalendar = Calendar.getInstance(); - } - - /** - * formats the x-values as date string. - * - * @param value raw value - * @param isValueX true if it's a x value, otherwise false - * @return value converted to string - */ - @Override - public String formatLabel(double value, boolean isValueX) { - if (isValueX) { - // format as date - mCalendar.setTimeInMillis((long) value); - return mDateFormat.format(mCalendar.getTimeInMillis()); - } else { - return super.formatLabel(value, isValueX); - } - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java b/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java deleted file mode 100644 index d036805bc8..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.helper; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.util.AttributeSet; -import android.util.Log; - -import com.jjoe64.graphview.GraphView; -import com.jjoe64.graphview.R; -import com.jjoe64.graphview.series.BarGraphSeries; -import com.jjoe64.graphview.series.BaseSeries; -import com.jjoe64.graphview.series.DataPoint; -import com.jjoe64.graphview.series.DataPointInterface; -import com.jjoe64.graphview.series.LineGraphSeries; -import com.jjoe64.graphview.series.PointsGraphSeries; -import com.jjoe64.graphview.series.Series; - -/** - * helper class to use GraphView directly - * in a XML layout file. - * - * You can set the data via attribute app:seriesData - * in the format: "X=Y;X=Y;..." e.g. "0=5.0;1=5;2=4;3=9" - * - * Other styling options: - *
  • app:seriesType="line|bar|points"
  • - *
  • app:seriesColor="#ff0000"
  • - *
  • app:seriesTitle="foobar" - if this is set, the legend will be drawn
  • - *
  • android:title="foobar"
  • - * - * Example: - *
    - * {@code
    - *  
    - * }
    - * 
    - * - * @author jjoe64 - */ -public class GraphViewXML extends GraphView { - /** - * creates the graphview object with data and - * other options from xml attributes. - * - * @param context - * @param attrs - */ - public GraphViewXML(Context context, AttributeSet attrs) { - super(context, attrs); - - // get attributes - TypedArray a=context.obtainStyledAttributes( - attrs, - R.styleable.GraphViewXML); - - String dataStr = a.getString(R.styleable.GraphViewXML_seriesData); - int color = a.getColor(R.styleable.GraphViewXML_seriesColor, Color.TRANSPARENT); - String type = a.getString(R.styleable.GraphViewXML_seriesType); - String seriesTitle = a.getString(R.styleable.GraphViewXML_seriesTitle); - String title = a.getString(R.styleable.GraphViewXML_android_title); - - a.recycle(); - - // decode data - DataPoint[] data; - if (dataStr == null || dataStr.isEmpty()) { - throw new IllegalArgumentException("Attribute seriesData is required in the format: 0=5.0;1=5;2=4;3=9"); - } else { - String[] d = dataStr.split(";"); - try { - data = new DataPoint[d.length]; - int i = 0; - for (String dd : d) { - String[] xy = dd.split("="); - data[i] = new DataPoint(Double.parseDouble(xy[0]), Double.parseDouble(xy[1])); - i++; - } - } catch (Exception e) { - Log.e("GraphViewXML", e.toString()); - throw new IllegalArgumentException("Attribute seriesData is broken. Use this format: 0=5.0;1=5;2=4;3=9"); - } - } - - // create series - BaseSeries series; - if (type == null || type.isEmpty()) { - type = "line"; - } - if (type.equals("line")) { - series = new LineGraphSeries(data); - } else if (type.equals("bar")) { - series = new BarGraphSeries(data); - } else if (type.equals("points")) { - series = new PointsGraphSeries(data); - } else { - throw new IllegalArgumentException("unknown graph type: "+type+". Possible is line|bar|points"); - } - if (color != Color.TRANSPARENT) { - series.setColor(color); - } - addSeries(series); - - if (seriesTitle != null && !seriesTitle.isEmpty()) { - series.setTitle(seriesTitle); - getLegendRenderer().setVisible(true); - } - - if (title != null && !title.isEmpty()) { - setTitle(title); - } - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java deleted file mode 100644 index 4b38dbf4c2..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java +++ /dev/null @@ -1,209 +0,0 @@ -package com.jjoe64.graphview.helper; - -import com.jjoe64.graphview.DefaultLabelFormatter; -import com.jjoe64.graphview.GraphView; -import com.jjoe64.graphview.LabelFormatter; -import com.jjoe64.graphview.Viewport; - -/** - * Use this label formatter to show static labels. - * Static labels are not bound to the data. It is typical used - * for show text like "low", "middle", "high". - * - * You can set the static labels for vertical or horizontal - * individually and you can define a label formatter that - * is to be used if you don't define static labels. - * - * For example if you only use static labels for horizontal labels, - * graphview will use the dynamicLabelFormatter for the vertical labels. - */ -public class StaticLabelsFormatter implements LabelFormatter { - /** - * reference to the viewport - */ - protected Viewport mViewport; - - /** - * the vertical labels, ordered from bottom to the top - * if it is null, the labels will be generated via the #dynamicLabelFormatter - */ - protected String[] mVerticalLabels; - - /** - * the horizontal labels, ordered form the left to the right - * if it is null, the labels will be generated via the #dynamicLabelFormatter - */ - protected String[] mHorizontalLabels; - - /** - * the label formatter that will format the labels - * for that there are no static labels defined. - */ - protected LabelFormatter mDynamicLabelFormatter; - - /** - * reference to the graphview - */ - protected final GraphView mGraphView; - - /** - * creates the formatter without any static labels - * define your static labels via {@link #setHorizontalLabels(String[])} and {@link #setVerticalLabels(String[])} - * - * @param graphView reference to the graphview - */ - public StaticLabelsFormatter(GraphView graphView) { - mGraphView = graphView; - init(null, null, null); - } - - /** - * creates the formatter without any static labels. - * define your static labels via {@link #setHorizontalLabels(String[])} and {@link #setVerticalLabels(String[])} - * - * @param graphView reference to the graphview - * @param dynamicLabelFormatter the label formatter that will format the labels - * for that there are no static labels defined. - */ - public StaticLabelsFormatter(GraphView graphView, LabelFormatter dynamicLabelFormatter) { - mGraphView = graphView; - init(null, null, dynamicLabelFormatter); - } - - /** - * creates the formatter with static labels defined. - * - * @param graphView reference to the graphview - * @param horizontalLabels the horizontal labels, ordered form the left to the right - * if it is null, the labels will be generated via the #dynamicLabelFormatter - * @param verticalLabels the vertical labels, ordered from bottom to the top - * if it is null, the labels will be generated via the #dynamicLabelFormatter - */ - public StaticLabelsFormatter(GraphView graphView, String[] horizontalLabels, String[] verticalLabels) { - mGraphView = graphView; - init(horizontalLabels, verticalLabels, null); - } - - /** - * creates the formatter with static labels defined. - * - * @param graphView reference to the graphview - * @param horizontalLabels the horizontal labels, ordered form the left to the right - * if it is null, the labels will be generated via the #dynamicLabelFormatter - * @param verticalLabels the vertical labels, ordered from bottom to the top - * if it is null, the labels will be generated via the #dynamicLabelFormatter - * @param dynamicLabelFormatter the label formatter that will format the labels - * for that there are no static labels defined. - */ - public StaticLabelsFormatter(GraphView graphView, String[] horizontalLabels, String[] verticalLabels, LabelFormatter dynamicLabelFormatter) { - mGraphView = graphView; - init(horizontalLabels, verticalLabels, dynamicLabelFormatter); - } - - /** - * @param horizontalLabels the horizontal labels, ordered form the left to the right - * if it is null, the labels will be generated via the #dynamicLabelFormatter - * @param verticalLabels the vertical labels, ordered from bottom to the top - * if it is null, the labels will be generated via the #dynamicLabelFormatter - * @param dynamicLabelFormatter the label formatter that will format the labels - * for that there are no static labels defined. - */ - protected void init(String[] horizontalLabels, String[] verticalLabels, LabelFormatter dynamicLabelFormatter) { - mDynamicLabelFormatter = dynamicLabelFormatter; - if (mDynamicLabelFormatter == null) { - mDynamicLabelFormatter = new DefaultLabelFormatter(); - } - - mHorizontalLabels = horizontalLabels; - mVerticalLabels = verticalLabels; - } - - /** - * Set a label formatter that will be used for the labels - * that don't have static labels. - * - * For example if you only use static labels for horizontal labels, - * graphview will use the dynamicLabelFormatter for the vertical labels. - * - * @param dynamicLabelFormatter the label formatter that will format the labels - * for that there are no static labels defined. - */ - public void setDynamicLabelFormatter(LabelFormatter dynamicLabelFormatter) { - this.mDynamicLabelFormatter = dynamicLabelFormatter; - adjust(); - } - - /** - * @param horizontalLabels the horizontal labels, ordered form the left to the right - * if it is null, the labels will be generated via the #dynamicLabelFormatter - */ - public void setHorizontalLabels(String[] horizontalLabels) { - this.mHorizontalLabels = horizontalLabels; - adjust(); - } - - /** - * @param verticalLabels the vertical labels, ordered from bottom to the top - * if it is null, the labels will be generated via the #dynamicLabelFormatter - */ - public void setVerticalLabels(String[] verticalLabels) { - this.mVerticalLabels = verticalLabels; - adjust(); - } - - /** - * - * @param value raw input number - * @param isValueX true if it is a value for the x axis - * false if it is a value for the y axis - * @return - */ - @Override - public String formatLabel(double value, boolean isValueX) { - if (isValueX && mHorizontalLabels != null) { - double minX = mViewport.getMinX(false); - double maxX = mViewport.getMaxX(false); - double range = maxX - minX; - value = value-minX; - int idx = (int)((value/range) * (mHorizontalLabels.length-1)); - return mHorizontalLabels[idx]; - } else if (!isValueX && mVerticalLabels != null) { - double minY = mViewport.getMinY(false); - double maxY = mViewport.getMaxY(false); - double range = maxY - minY; - value = value-minY; - int idx = (int)((value/range) * (mVerticalLabels.length-1)); - return mVerticalLabels[idx]; - } else { - return mDynamicLabelFormatter.formatLabel(value, isValueX); - } - } - - /** - * @param viewport the used viewport - */ - @Override - public void setViewport(Viewport viewport) { - mViewport = viewport; - adjust(); - } - - /** - * adjusts the number of vertical/horizontal labels - */ - protected void adjust() { - mDynamicLabelFormatter.setViewport(mViewport); - if (mVerticalLabels != null) { - if (mVerticalLabels.length < 2) { - throw new IllegalStateException("You need at least 2 vertical labels if you use static label formatter."); - } - mGraphView.getGridLabelRenderer().setNumVerticalLabels(mVerticalLabels.length); - } - if (mHorizontalLabels != null) { - if (mHorizontalLabels.length < 2) { - throw new IllegalStateException("You need at least 2 horizontal labels if you use static label formatter."); - } - mGraphView.getGridLabelRenderer().setNumHorizontalLabels(mHorizontalLabels.length); - } - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java deleted file mode 100644 index 8db7bac94b..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java +++ /dev/null @@ -1,379 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; -import android.util.Log; - -import com.jjoe64.graphview.GraphView; -import com.jjoe64.graphview.ValueDependentColor; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -/** - * Series with Bars to visualize the data. - * The Bars are always vertical. - * - * @author jjoe64 - */ -public class BarGraphSeries extends BaseSeries { - /** - * paint to do drawing on canvas - */ - private Paint mPaint; - - /** - * spacing between the bars in percentage. - * 0 => no spacing - * 100 => the space bewetten the bars is as big as the bars itself - */ - private int mSpacing; - - /** - * callback to generate value-dependent colors - * of the bars - */ - private ValueDependentColor mValueDependentColor; - - /** - * flag whether the values should drawn - * above the bars as text - */ - private boolean mDrawValuesOnTop; - - /** - * color of the text above the bars. - * - * @see #mDrawValuesOnTop - */ - private int mValuesOnTopColor; - - /** - * font size of the text above the bars. - * - * @see #mDrawValuesOnTop - */ - private float mValuesOnTopSize; - - /** - * stores the coordinates of the bars to - * trigger tap on series events. - */ - private Map mDataPoints = new HashMap(); - - /** - * creates bar series without any data - */ - public BarGraphSeries() { - mPaint = new Paint(); - } - - /** - * creates bar series with data - * - * @param data values - */ - public BarGraphSeries(E[] data) { - super(data); - mPaint = new Paint(); - } - - /** - * draws the bars on the canvas - * - * @param graphView corresponding graphview - * @param canvas canvas - * @param isSecondScale whether we are plotting the second scale or not - */ - @Override - public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { - mPaint.setTextAlign(Paint.Align.CENTER); - if (mValuesOnTopSize == 0) { - mValuesOnTopSize = graphView.getGridLabelRenderer().getTextSize(); - } - mPaint.setTextSize(mValuesOnTopSize); - - // get data - double maxX = graphView.getViewport().getMaxX(false); - double minX = graphView.getViewport().getMinX(false); - - double maxY; - double minY; - if (isSecondScale) { - maxY = graphView.getSecondScale().getMaxY(); - minY = graphView.getSecondScale().getMinY(); - } else { - maxY = graphView.getViewport().getMaxY(false); - minY = graphView.getViewport().getMinY(false); - } - - // Iterate through all bar graph series - // so we know how wide to make our bar, - // and in what position to put it in - int numBarSeries = 0; - int currentSeriesOrder = 0; - int numValues = 0; - boolean isCurrentSeries; - SortedSet xVals = new TreeSet(); - for(Series inspectedSeries: graphView.getSeries()) { - if(inspectedSeries instanceof BarGraphSeries) { - isCurrentSeries = (inspectedSeries == this); - if(isCurrentSeries) { - currentSeriesOrder = numBarSeries; - } - numBarSeries++; - - // calculate the number of slots for bars based on the minimum distance between - // x coordinates in the series. This is divided into the range to find - // the placement and width of bar slots - // (sections of the x axis for each bar or set of bars) - // TODO: Move this somewhere more general and cache it, so we don't recalculate it for each series - Iterator curValues = inspectedSeries.getValues(minX, maxX); - if (curValues.hasNext()) { - xVals.add(curValues.next().getX()); - if(isCurrentSeries) { numValues++; } - while (curValues.hasNext()) { - xVals.add(curValues.next().getX()); - if(isCurrentSeries) { numValues++; } - } - } - } - } - if (numValues == 0) { - return; - } - - Double lastVal = null; - double minGap = 0; - for(Double curVal: xVals) { - if(lastVal != null) { - double curGap = Math.abs(curVal - lastVal); - if (minGap == 0 || (curGap > 0 && curGap < minGap)) { - minGap = curGap; - } - } - lastVal = curVal; - } - - int numBarSlots = (minGap == 0) ? 1 : (int)Math.round((maxX - minX)/minGap) + 1; - - Iterator values = getValues(minX, maxX); - - // Calculate the overall bar slot width - this includes all bars across - // all series, and any spacing between sets of bars - float barSlotWidth = numBarSlots == 1 - ? graphView.getGraphContentWidth() - : graphView.getGraphContentWidth() / (numBarSlots-1); - Log.d("BarGraphSeries", "numBars=" + numBarSlots); - - // Total spacing (both sides) between sets of bars - float spacing = Math.min((float) barSlotWidth*mSpacing/100, barSlotWidth*0.98f); - // Width of an individual bar - float barWidth = (barSlotWidth - spacing) / numBarSeries; - // Offset from the center of a given bar to start drawing - float offset = barSlotWidth/2; - - double diffY = maxY - minY; - double diffX = maxX - minX; - float contentHeight = graphView.getGraphContentHeight(); - float contentWidth = graphView.getGraphContentWidth(); - float contentLeft = graphView.getGraphContentLeft(); - float contentTop = graphView.getGraphContentTop(); - - // draw data - int i=0; - while (values.hasNext()) { - E value = values.next(); - - double valY = value.getY() - minY; - double ratY = valY / diffY; - double y = contentHeight * ratY; - - double valY0 = 0 - minY; - double ratY0 = valY0 / diffY; - double y0 = contentHeight * ratY0; - - double valX = value.getX() - minX; - double ratX = valX / diffX; - double x = contentWidth * ratX; - - // hook for value dependent color - if (getValueDependentColor() != null) { - mPaint.setColor(getValueDependentColor().get(value)); - } else { - mPaint.setColor(getColor()); - } - - float left = (float)x + contentLeft - offset + spacing/2 + currentSeriesOrder*barWidth; - float top = (contentTop - (float)y) + contentHeight; - float right = left + barWidth; - float bottom = (contentTop - (float)y0) + contentHeight - (graphView.getGridLabelRenderer().isHighlightZeroLines()?4:1); - - boolean reverse = top > bottom; - if (reverse) { - float tmp = top; - top = bottom + (graphView.getGridLabelRenderer().isHighlightZeroLines()?4:1); - bottom = tmp; - } - - // overdraw - left = Math.max(left, contentLeft); - right = Math.min(right, contentLeft+contentWidth); - bottom = Math.min(bottom, contentTop+contentHeight); - top = Math.max(top, contentTop); - - mDataPoints.put(new RectF(left, top, right, bottom), value); - - canvas.drawRect(left, top, right, bottom, mPaint); - - // set values on top of graph - if (mDrawValuesOnTop) { - if (reverse) { - top = bottom + mValuesOnTopSize + 4; - if (top > contentTop+contentHeight) top = contentTop + contentHeight; - } else { - top -= 4; - if (top<=contentTop) top+=contentTop+4; - } - - mPaint.setColor(mValuesOnTopColor); - canvas.drawText( - graphView.getGridLabelRenderer().getLabelFormatter().formatLabel(value.getY(), false) - , (left+right)/2, top, mPaint); - } - - i++; - } - } - - /** - * @return the hook to generate value-dependent color. default null - */ - public ValueDependentColor getValueDependentColor() { - return mValueDependentColor; - } - - /** - * set a hook to make the color of the bars depending - * on the actually value/data. - * - * @param mValueDependentColor hook - * null to disable - */ - public void setValueDependentColor(ValueDependentColor mValueDependentColor) { - this.mValueDependentColor = mValueDependentColor; - } - - /** - * @return the spacing between the bars in percentage - */ - public int getSpacing() { - return mSpacing; - } - - /** - * @param mSpacing spacing between the bars in percentage. - * 0 => no spacing - * 100 => the space between the bars is as big as the bars itself - */ - public void setSpacing(int mSpacing) { - this.mSpacing = mSpacing; - } - - /** - * @return whether the values should be drawn above the bars - */ - public boolean isDrawValuesOnTop() { - return mDrawValuesOnTop; - } - - /** - * @param mDrawValuesOnTop flag whether the values should drawn - * above the bars as text - */ - public void setDrawValuesOnTop(boolean mDrawValuesOnTop) { - this.mDrawValuesOnTop = mDrawValuesOnTop; - } - - /** - * @return font color of the values on top of the bars - * @see #setDrawValuesOnTop(boolean) - */ - public int getValuesOnTopColor() { - return mValuesOnTopColor; - } - - /** - * @param mValuesOnTopColor the font color of the values on top of the bars - * @see #setDrawValuesOnTop(boolean) - */ - public void setValuesOnTopColor(int mValuesOnTopColor) { - this.mValuesOnTopColor = mValuesOnTopColor; - } - - /** - * @return font size of the values above the bars - * @see #setDrawValuesOnTop(boolean) - */ - public float getValuesOnTopSize() { - return mValuesOnTopSize; - } - - /** - * @param mValuesOnTopSize font size of the values above the bars - * @see #setDrawValuesOnTop(boolean) - */ - public void setValuesOnTopSize(float mValuesOnTopSize) { - this.mValuesOnTopSize = mValuesOnTopSize; - } - - /** - * resets the cached coordinates of the bars - */ - @Override - protected void resetDataPoints() { - mDataPoints.clear(); - } - - /** - * find the corresponding data point by - * coordinates. - * - * @param x pixels - * @param y pixels - * @return datapoint or null - */ - @Override - protected E findDataPoint(float x, float y) { - for (Map.Entry entry : mDataPoints.entrySet()) { - if (x >= entry.getKey().left && x <= entry.getKey().right - && y >= entry.getKey().top && y <= entry.getKey().bottom) { - return entry.getValue(); - } - } - return null; - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java deleted file mode 100644 index 8ecdf23a73..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java +++ /dev/null @@ -1,448 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -import android.graphics.PointF; -import android.util.Log; - -import com.jjoe64.graphview.GraphView; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * Basis implementation for series. - * Used for series that are plotted on - * a default x/y 2d viewport. - * - * Extend this class to implement your own custom - * graph type. - * - * This implementation uses a internal Array to store - * the data. If you want to implement a custom data provider - * you may want to implement {@link com.jjoe64.graphview.series.Series}. - * - * @author jjoe64 - */ -public abstract class BaseSeries implements Series { - /** - * holds the data - */ - final private List mData = new ArrayList(); - - /** - * stores the used coordinates to find the - * corresponding data point on a tap - * - * Key => x/y pixel - * Value => Plotted Datapoint - * - * will be filled while drawing via {@link #registerDataPoint(float, float, DataPointInterface)} - */ - private Map mDataPoints = new HashMap(); - - /** - * title for this series that can be displayed - * in the legend. - */ - private String mTitle; - - /** - * base color for this series. will be used also in - * the legend - */ - private int mColor = 0xff0077cc; - - /** - * listener to handle tap events on a data point - */ - protected OnDataPointTapListener mOnDataPointTapListener; - - /** - * stores the graphviews where this series is used. - * Can be more than one. - */ - private List mGraphViews; - - /** - * creates series without data - */ - public BaseSeries() { - mGraphViews = new ArrayList(); - } - - /** - * creates series with data - * - * @param data data points - * important: array has to be sorted from lowest x-value to the highest - */ - public BaseSeries(E[] data) { - mGraphViews = new ArrayList(); - for (E d : data) { - mData.add(d); - } - } - - /** - * @return the lowest x value, or 0 if there is no data - */ - public double getLowestValueX() { - if (mData.isEmpty()) return 0d; - return mData.get(0).getX(); - } - - /** - * @return the highest x value, or 0 if there is no data - */ - public double getHighestValueX() { - if (mData.isEmpty()) return 0d; - return mData.get(mData.size()-1).getX(); - } - - /** - * @return the lowest y value, or 0 if there is no data - */ - public double getLowestValueY() { - if (mData.isEmpty()) return 0d; - double l = mData.get(0).getY(); - for (int i = 1; i < mData.size(); i++) { - double c = mData.get(i).getY(); - if (l > c) { - l = c; - } - } - return l; - } - - /** - * @return the highest y value, or 0 if there is no data - */ - public double getHighestValueY() { - if (mData.isEmpty()) return 0d; - double h = mData.get(0).getY(); - for (int i = 1; i < mData.size(); i++) { - double c = mData.get(i).getY(); - if (h < c) { - h = c; - } - } - return h; - } - - /** - * get the values for a given x range. if from and until are bigger or equal than - * all the data, the original data is returned. - * If it is only a part of the data, the range is returned plus one datapoint - * before and after to get a nice scrolling. - * - * @param from minimal x-value - * @param until maximal x-value - * @return data for the range +/- 1 datapoint - */ - @Override - public Iterator getValues(final double from, final double until) { - if (from <= getLowestValueX() && until >= getHighestValueX()) { - return mData.iterator(); - } else { - return new Iterator() { - Iterator org = mData.iterator(); - E nextValue = null; - E nextNextValue = null; - boolean plusOne = true; - - { - // go to first - boolean found = false; - E prevValue = null; - if (org.hasNext()) { - prevValue = org.next(); - } - if (prevValue.getX() >= from) { - nextValue = prevValue; - found = true; - } else { - while (org.hasNext()) { - nextValue = org.next(); - if (nextValue.getX() >= from) { - found = true; - nextNextValue = nextValue; - nextValue = prevValue; - break; - } - prevValue = nextValue; - } - } - if (!found) { - nextValue = null; - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public E next() { - if (hasNext()) { - E r = nextValue; - if (r.getX() > until) { - plusOne = false; - } - if (nextNextValue != null) { - nextValue = nextNextValue; - nextNextValue = null; - } else if (org.hasNext()) nextValue = org.next(); - else nextValue = null; - return r; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public boolean hasNext() { - return nextValue != null && (nextValue.getX() <= until || plusOne); - } - }; - } - } - - /** - * @return the title of the series - */ - public String getTitle() { - return mTitle; - } - - /** - * set the title of the series. This will be used in - * the legend. - * - * @param mTitle title of the series - */ - public void setTitle(String mTitle) { - this.mTitle = mTitle; - } - - /** - * @return color of the series - */ - public int getColor() { - return mColor; - } - - /** - * set the color of the series. This will be used in - * plotting (depends on the series implementation) and - * is used in the legend. - * - * @param mColor - */ - public void setColor(int mColor) { - this.mColor = mColor; - } - - /** - * set a listener for tap on a data point. - * - * @param l listener - */ - public void setOnDataPointTapListener(OnDataPointTapListener l) { - this.mOnDataPointTapListener = l; - } - - /** - * called by the tap detector in order to trigger - * the on tap on datapoint event. - * - * @param x pixel - * @param y pixel - */ - @Override - public void onTap(float x, float y) { - if (mOnDataPointTapListener != null) { - E p = findDataPoint(x, y); - if (p != null) { - mOnDataPointTapListener.onTap(this, p); - } - } - } - - /** - * find the data point which is next to the - * coordinates - * - * @param x pixel - * @param y pixel - * @return the data point or null if nothing was found - */ - protected E findDataPoint(float x, float y) { - float shortestDistance = Float.NaN; - E shortest = null; - for (Map.Entry entry : mDataPoints.entrySet()) { - float x1 = entry.getKey().x; - float y1 = entry.getKey().y; - float x2 = x; - float y2 = y; - - float distance = (float) Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); - if (shortest == null || distance < shortestDistance) { - shortestDistance = distance; - shortest = entry.getValue(); - } - } - if (shortest != null) { - if (shortestDistance < 120) { - return shortest; - } - } - return null; - } - - /** - * register the datapoint to find it at a tap - * - * @param x pixel - * @param y pixel - * @param dp the data point to save - */ - protected void registerDataPoint(float x, float y, E dp) { - mDataPoints.put(new PointF(x, y), dp); - } - - /** - * clears the cached data point coordinates - */ - protected void resetDataPoints() { - mDataPoints.clear(); - } - - /** - * clears the data of this series and sets new. - * will redraw the graph - * - * @param data the values must be in the correct order! - * x-value has to be ASC. First the lowest x value and at least the highest x value. - */ - public void resetData(E[] data) { - mData.clear(); - for (E d : data) { - mData.add(d); - } - checkValueOrder(null); - - // update graphview - for (GraphView gv : mGraphViews) { - gv.onDataChanged(true, false); - } - } - - /** - * called when the series was added to a graph - * - * @param graphView graphview - */ - @Override - public void onGraphViewAttached(GraphView graphView) { - mGraphViews.add(graphView); - } - - /** - * - * @param dataPoint values the values must be in the correct order! - * x-value has to be ASC. First the lowest x value and at least the highest x value. - * @param scrollToEnd true => graphview will scroll to the end (maxX) - * @param maxDataPoints if max data count is reached, the oldest data - * value will be lost to avoid memory leaks - */ - public void appendData(E dataPoint, boolean scrollToEnd, int maxDataPoints) { - checkValueOrder(dataPoint); - - if (!mData.isEmpty() && dataPoint.getX() < mData.get(mData.size()-1).getX()) { - throw new IllegalArgumentException("new x-value must be greater then the last value. x-values has to be ordered in ASC."); - } - synchronized (mData) { - int curDataCount = mData.size(); - if (curDataCount < maxDataPoints) { - // enough space - mData.add(dataPoint); - } else { - // we have to trim one data - mData.remove(0); - mData.add(dataPoint); - } - } - - // recalc the labels when it was the first data - boolean keepLabels = mData.size() != 1; - - // update linked graph views - // update graphview - for (GraphView gv : mGraphViews) { - gv.onDataChanged(keepLabels, scrollToEnd); - if (scrollToEnd) { - gv.getViewport().scrollToEnd(); - } - } - } - - /** - * @return whether there are data points - */ - @Override - public boolean isEmpty() { - return mData.isEmpty(); - } - - /** - * checks that the data is in the correct order - * - * @param onlyLast if not null, it will only check that this - * datapoint is after the last point. - */ - protected void checkValueOrder(DataPointInterface onlyLast) { - if (mData.size()>1) { - if (onlyLast != null) { - // only check last - if (onlyLast.getX() < mData.get(mData.size()-1).getX()) { - throw new IllegalArgumentException("new x-value must be greater then the last value. x-values has to be ordered in ASC."); - } - } else { - double lx = mData.get(0).getX(); - - for (int i = 1; i < mData.size(); i++) { - if (mData.get(i).getX() != Double.NaN) { - if (lx > mData.get(i).getX()) { - throw new IllegalArgumentException("The order of the values is not correct. X-Values have to be ordered ASC. First the lowest x value and at least the highest x value."); - } - lx = mData.get(i).getX(); - } - } - } - } - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java b/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java deleted file mode 100644 index b5f5eb3ef3..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -import android.provider.ContactsContract; - -import java.io.Serializable; -import java.util.Date; - -/** - * default data point implementation. - * This stores the x and y values. - * - * @author jjoe64 - */ -public class DataPoint implements DataPointInterface, Serializable { - private static final long serialVersionUID=1428263322645L; - - private double x; - private double y; - - public DataPoint(double x, double y) { - this.x=x; - this.y=y; - } - - public DataPoint(Date x, double y) { - this.x = x.getTime(); - this.y = y; - } - - @Override - public double getX() { - return x; - } - - @Override - public double getY() { - return y; - } - - @Override - public String toString() { - return "["+x+"/"+y+"]"; - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java b/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java deleted file mode 100644 index 9be683bef8..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -/** - * interface of data points. Implement this in order - * to use your class in {@link com.jjoe64.graphview.series.Series}. - * - * You can also use the default implementation {@link com.jjoe64.graphview.series.DataPoint} so - * you do not have to implement it for yourself. - * - * @author jjoe64 - */ -public interface DataPointInterface { - /** - * @return the x value - */ - public double getX(); - - /** - * @return the y value - */ - public double getY(); -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java deleted file mode 100644 index 4d721c2e6c..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java +++ /dev/null @@ -1,409 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; - -import com.jjoe64.graphview.GraphView; - -import java.util.Iterator; - -/** - * Series to plot the data as line. - * The line can be styled with many options. - * - * @author jjoe64 - */ -public class LineGraphSeries extends BaseSeries { - /** - * wrapped styles regarding the line - */ - private final class Styles { - /** - * the thickness of the line. - * This option will be ignored if you are - * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} - */ - private int thickness = 5; - - /** - * flag whether the area under the line to the bottom - * of the viewport will be filled with a - * specific background color. - * - * @see #backgroundColor - */ - private boolean drawBackground = false; - - /** - * flag whether the data points are highlighted as - * a visible point. - * - * @see #dataPointsRadius - */ - private boolean drawDataPoints = false; - - /** - * the radius for the data points. - * - * @see #drawDataPoints - */ - private float dataPointsRadius = 10f; - - /** - * the background color for the filling under - * the line. - * - * @see #drawBackground - */ - private int backgroundColor = Color.argb(100, 172, 218, 255); - } - - /** - * wrapped styles - */ - private Styles mStyles; - - /** - * internal paint object - */ - private Paint mPaint; - - /** - * paint for the background - */ - private Paint mPaintBackground; - - /** - * path for the background filling - */ - private Path mPathBackground; - - /** - * path to the line - */ - private Path mPath; - - /** - * custom paint that can be used. - * this will ignore the thickness and color styles. - */ - private Paint mCustomPaint; - - /** - * creates a series without data - */ - public LineGraphSeries() { - init(); - } - - /** - * creates a series with data - * - * @param data data points - */ - public LineGraphSeries(E[] data) { - super(data); - init(); - } - - /** - * do the initialization - * creates internal objects - */ - protected void init() { - mStyles = new Styles(); - mPaint = new Paint(); - mPaint.setStrokeCap(Paint.Cap.ROUND); - mPaint.setStyle(Paint.Style.STROKE); - mPaintBackground = new Paint(); - - mPathBackground = new Path(); - mPath = new Path(); - } - - /** - * plots the series - * draws the line and the background - * - * @param graphView graphview - * @param canvas canvas - * @param isSecondScale flag if it is the second scale - */ - @Override - public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { - resetDataPoints(); - - // get data - double maxX = graphView.getViewport().getMaxX(false); - double minX = graphView.getViewport().getMinX(false); - - double maxY; - double minY; - if (isSecondScale) { - maxY = graphView.getSecondScale().getMaxY(); - minY = graphView.getSecondScale().getMinY(); - } else { - maxY = graphView.getViewport().getMaxY(false); - minY = graphView.getViewport().getMinY(false); - } - - Iterator values = getValues(minX, maxX); - - // draw background - double lastEndY = 0; - double lastEndX = 0; - - // draw data - mPaint.setStrokeWidth(mStyles.thickness); - mPaint.setColor(getColor()); - mPaintBackground.setColor(mStyles.backgroundColor); - - Paint paint; - if (mCustomPaint != null) { - paint = mCustomPaint; - } else { - paint = mPaint; - } - - if (mStyles.drawBackground) { - mPathBackground.reset(); - } - - double diffY = maxY - minY; - double diffX = maxX - minX; - - float graphHeight = graphView.getGraphContentHeight(); - float graphWidth = graphView.getGraphContentWidth(); - float graphLeft = graphView.getGraphContentLeft(); - float graphTop = graphView.getGraphContentTop(); - - lastEndY = 0; - lastEndX = 0; - double lastUsedEndX = 0; - float firstX = 0; - int i=0; - while (values.hasNext()) { - E value = values.next(); - - double valY = value.getY() - minY; - double ratY = valY / diffY; - double y = graphHeight * ratY; - - double valX = value.getX() - minX; - double ratX = valX / diffX; - double x = graphWidth * ratX; - - double orgX = x; - double orgY = y; - - if (i > 0) { - // overdraw - if (x > graphWidth) { // end right - double b = ((graphWidth - lastEndX) * (y - lastEndY)/(x - lastEndX)); - y = lastEndY+b; - x = graphWidth; - } - if (y < 0) { // end bottom - double b = ((0 - lastEndY) * (x - lastEndX)/(y - lastEndY)); - x = lastEndX+b; - y = 0; - } - if (y > graphHeight) { // end top - double b = ((graphHeight - lastEndY) * (x - lastEndX)/(y - lastEndY)); - x = lastEndX+b; - y = graphHeight; - } - if (lastEndY < 0) { // start bottom - double b = ((0 - y) * (x - lastEndX)/(lastEndY - y)); - lastEndX = x-b; - lastEndY = 0; - } - if (lastEndX < 0) { // start left - double b = ((0 - x) * (y - lastEndY)/(lastEndX - x)); - lastEndY = y-b; - lastEndX = 0; - } - if (lastEndY > graphHeight) { // start top - double b = ((graphHeight - y) * (x - lastEndX)/(lastEndY - y)); - lastEndX = x-b; - lastEndY = graphHeight; - } - - float startX = (float) lastEndX + (graphLeft + 1); - float startY = (float) (graphTop - lastEndY) + graphHeight; - float endX = (float) x + (graphLeft + 1); - float endY = (float) (graphTop - y) + graphHeight; - - // draw data point - if (mStyles.drawDataPoints) { - //fix: last value was not drawn. Draw here now the end values - canvas.drawCircle(endX, endY, mStyles.dataPointsRadius, mPaint); - } - registerDataPoint(endX, endY, value); - - mPath.reset(); - mPath.moveTo(startX, startY); - mPath.lineTo(endX, endY); - canvas.drawPath(mPath, paint); - if (mStyles.drawBackground) { - if (i==1) { - firstX = startX; - mPathBackground.moveTo(startX, startY); - } - mPathBackground.lineTo(endX, endY); - } - lastUsedEndX = endX; - } else if (mStyles.drawDataPoints) { - //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above) - float first_X = (float) x + (graphLeft + 1); - float first_Y = (float) (graphTop - y) + graphHeight; - //TODO canvas.drawCircle(first_X, first_Y, dataPointsRadius, mPaint); - } - lastEndY = orgY; - lastEndX = orgX; - i++; - } - - if (mStyles.drawBackground) { - // end / close path - mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop); - mPathBackground.lineTo(firstX, graphHeight + graphTop); - mPathBackground.close(); - canvas.drawPath(mPathBackground, mPaintBackground); - } - - } - - /** - * the thickness of the line. - * This option will be ignored if you are - * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} - * - * @return the thickness of the line - */ - public int getThickness() { - return mStyles.thickness; - } - - /** - * the thickness of the line. - * This option will be ignored if you are - * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} - * - * @param thickness thickness of the line - */ - public void setThickness(int thickness) { - mStyles.thickness = thickness; - } - - /** - * flag whether the area under the line to the bottom - * of the viewport will be filled with a - * specific background color. - * - * @return whether the background will be drawn - * @see #getBackgroundColor() - */ - public boolean isDrawBackground() { - return mStyles.drawBackground; - } - - /** - * flag whether the area under the line to the bottom - * of the viewport will be filled with a - * specific background color. - * - * @param drawBackground whether the background will be drawn - * @see #setBackgroundColor(int) - */ - public void setDrawBackground(boolean drawBackground) { - mStyles.drawBackground = drawBackground; - } - - /** - * flag whether the data points are highlighted as - * a visible point. - * - * @return flag whether the data points are highlighted - * @see #setDataPointsRadius(float) - */ - public boolean isDrawDataPoints() { - return mStyles.drawDataPoints; - } - - /** - * flag whether the data points are highlighted as - * a visible point. - * - * @param drawDataPoints flag whether the data points are highlighted - * @see #setDataPointsRadius(float) - */ - public void setDrawDataPoints(boolean drawDataPoints) { - mStyles.drawDataPoints = drawDataPoints; - } - - /** - * @return the radius for the data points. - * @see #setDrawDataPoints(boolean) - */ - public float getDataPointsRadius() { - return mStyles.dataPointsRadius; - } - - /** - * @param dataPointsRadius the radius for the data points. - * @see #setDrawDataPoints(boolean) - */ - public void setDataPointsRadius(float dataPointsRadius) { - mStyles.dataPointsRadius = dataPointsRadius; - } - - /** - * @return the background color for the filling under - * the line. - * @see #setDrawBackground(boolean) - */ - public int getBackgroundColor() { - return mStyles.backgroundColor; - } - - /** - * @param backgroundColor the background color for the filling under - * the line. - * @see #setDrawBackground(boolean) - */ - public void setBackgroundColor(int backgroundColor) { - mStyles.backgroundColor = backgroundColor; - } - - /** - * custom paint that can be used. - * this will ignore the thickness and color styles. - * - * @param customPaint the custom paint to be used for rendering the line - */ - public void setCustomPaint(Paint customPaint) { - this.mCustomPaint = customPaint; - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java b/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java deleted file mode 100644 index 748a1122ee..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -/** - * Listener for the tap event which will be - * triggered when the user touches on a datapoint. - * - * Use this in {@link com.jjoe64.graphview.series.BaseSeries#setOnDataPointTapListener(OnDataPointTapListener)} - * - * @author jjoe64 - */ -public interface OnDataPointTapListener { - /** - * gets called when the user touches on a datapoint. - * - * @param series the corresponding series - * @param dataPoint the data point that was tapped on - */ - void onTap(Series series, DataPointInterface dataPoint); -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java deleted file mode 100644 index c57d476d7b..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java +++ /dev/null @@ -1,312 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.Point; - -import com.jjoe64.graphview.GraphView; - -import java.util.Iterator; - -/** - * Series that plots the data as points. - * The points can be different shapes or a - * complete custom drawing. - * - * @author jjoe64 - */ -public class PointsGraphSeries extends BaseSeries { - /** - * interface to implement a custom - * drawing for the data points. - */ - public static interface CustomShape { - /** - * called when drawing a single data point. - * use the x and y coordinates to render your - * drawing at this point. - * - * @param canvas canvas to draw on - * @param paint internal paint object. this has the correct color. - * But you can use your own paint. - * @param x x-coordinate the point has to be drawn to - * @param y y-coordinate the point has to be drawn to - * @param dataPoint the related data point - */ - void draw(Canvas canvas, Paint paint, float x, float y, DataPointInterface dataPoint); - } - - /** - * choose a predefined shape to render for - * each data point. - * You can also render a custom drawing via {@link com.jjoe64.graphview.series.PointsGraphSeries.CustomShape} - */ - public enum Shape { - /** - * draws a point / circle - */ - POINT, - - /** - * draws a triangle - */ - TRIANGLE, - - /** - * draws a rectangle - */ - RECTANGLE - } - - /** - * wrapped styles for this series - */ - private final class Styles { - /** - * this is used for the size of the shape that - * will be drawn. - * This is useless if you are using a custom shape. - */ - float size; - - /** - * the shape that will be drawn for each point. - */ - Shape shape; - } - - /** - * wrapped styles - */ - private Styles mStyles; - - /** - * internal paint object - */ - private Paint mPaint; - - /** - * handler to use a custom drawing - */ - private CustomShape mCustomShape; - - /** - * creates the series without data - */ - public PointsGraphSeries() { - init(); - } - - /** - * creates the series with data - * - * @param data datapoints - */ - public PointsGraphSeries(E[] data) { - super(data); - init(); - } - - /** - * inits the internal objects - * set the defaults - */ - protected void init() { - mStyles = new Styles(); - mStyles.size = 20f; - mPaint = new Paint(); - mPaint.setStrokeCap(Paint.Cap.ROUND); - setShape(Shape.POINT); - } - - /** - * plot the data to the viewport - * - * @param graphView graphview - * @param canvas canvas to draw on - * @param isSecondScale whether it is the second scale - */ - @Override - public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { - resetDataPoints(); - - // get data - double maxX = graphView.getViewport().getMaxX(false); - double minX = graphView.getViewport().getMinX(false); - - double maxY; - double minY; - if (isSecondScale) { - maxY = graphView.getSecondScale().getMaxY(); - minY = graphView.getSecondScale().getMinY(); - } else { - maxY = graphView.getViewport().getMaxY(false); - minY = graphView.getViewport().getMinY(false); - } - - Iterator values = getValues(minX, maxX); - - // draw background - double lastEndY = 0; - double lastEndX = 0; - - // draw data - mPaint.setColor(getColor()); - - double diffY = maxY - minY; - double diffX = maxX - minX; - - float graphHeight = graphView.getGraphContentHeight(); - float graphWidth = graphView.getGraphContentWidth(); - float graphLeft = graphView.getGraphContentLeft(); - float graphTop = graphView.getGraphContentTop(); - - lastEndY = 0; - lastEndX = 0; - float firstX = 0; - int i=0; - while (values.hasNext()) { - E value = values.next(); - - double valY = value.getY() - minY; - double ratY = valY / diffY; - double y = graphHeight * ratY; - - double valX = value.getX() - minX; - double ratX = valX / diffX; - double x = graphWidth * ratX; - - double orgX = x; - double orgY = y; - - // overdraw - boolean overdraw = false; - if (x > graphWidth) { // end right - overdraw = true; - } - if (y < 0) { // end bottom - overdraw = true; - } - if (y > graphHeight) { // end top - overdraw = true; - } - - float endX = (float) x + (graphLeft + 1); - float endY = (float) (graphTop - y) + graphHeight; - registerDataPoint(endX, endY, value); - - // draw data point - if (!overdraw) { - if (mCustomShape != null) { - mCustomShape.draw(canvas, mPaint, endX, endY, value); - } else if (mStyles.shape == Shape.POINT) { - canvas.drawCircle(endX, endY, mStyles.size, mPaint); - } else if (mStyles.shape == Shape.RECTANGLE) { - canvas.drawRect(endX-mStyles.size, endY-mStyles.size, endX+mStyles.size, endY+mStyles.size, mPaint); - } else if (mStyles.shape == Shape.TRIANGLE) { - Point[] points = new Point[3]; - points[0] = new Point((int)endX, (int)(endY-getSize())); - points[1] = new Point((int)(endX+getSize()), (int)(endY+getSize()*0.67)); - points[2] = new Point((int)(endX-getSize()), (int)(endY+getSize()*0.67)); - drawArrows(points, canvas, mPaint); - } - } - - i++; - } - - } - - /** - * helper to render triangle - * - * @param point array with 3 coordinates - * @param canvas canvas to draw on - * @param paint paint object - */ - private void drawArrows(Point[] point, Canvas canvas, Paint paint) { - float [] points = new float[8]; - points[0] = point[0].x; - points[1] = point[0].y; - points[2] = point[1].x; - points[3] = point[1].y; - points[4] = point[2].x; - points[5] = point[2].y; - points[6] = point[0].x; - points[7] = point[0].y; - - canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint); - Path path = new Path(); - path.moveTo(point[0].x , point[0].y); - path.lineTo(point[1].x,point[1].y); - path.lineTo(point[2].x,point[2].y); - canvas.drawPath(path,paint); - } - - /** - * This is used for the size of the shape that - * will be drawn. - * This is useless if you are using a custom shape. - * - * @return the size of the shape - */ - public float getSize() { - return mStyles.size; - } - - /** - * This is used for the size of the shape that - * will be drawn. - * This is useless if you are using a custom shape. - * - * @param radius the size of the shape - */ - public void setSize(float radius) { - mStyles.size = radius; - } - - /** - * @return the shape that will be drawn for each point - */ - public Shape getShape() { - return mStyles.shape; - } - - /** - * @param s the shape that will be drawn for each point - */ - public void setShape(Shape s) { - mStyles.shape = s; - } - - /** - * Use a custom handler to render your own - * drawing for each data point. - * - * @param shape handler to use a custom drawing - */ - public void setCustomShape(CustomShape shape) { - mCustomShape = shape; - } -} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/Series.java b/graphview/src/main/java/com/jjoe64/graphview/series/Series.java deleted file mode 100644 index dce32eb78e..0000000000 --- a/graphview/src/main/java/com/jjoe64/graphview/series/Series.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * GraphView - * Copyright (C) 2014 Jonas Gehring - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, - * with the "Linking Exception", which can be found at the license.txt - * file in this program. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * with the "Linking Exception" along with this program; if not, - * write to the author Jonas Gehring . - */ -package com.jjoe64.graphview.series; - -import android.graphics.Canvas; - -import com.jjoe64.graphview.GraphView; - -import java.util.Iterator; - -/** - * Basis interface for series that can be plotted - * on the graph. - * You can implement this in order to create a completely - * custom series type. - * But it is recommended to extend {@link com.jjoe64.graphview.series.BaseSeries} or another - * implemented Series class to save time. - * Anyway this interface can make sense if you want to implement - * a custom data provider, because BaseSeries uses a internal Array to store - * the data. - * - * @author jjoe64 - */ -public interface Series { - /** - * @return the lowest x-value of the data - */ - public double getLowestValueX(); - - /** - * @return the highest x-value of the data - */ - public double getHighestValueX(); - - /** - * @return the lowest y-value of the data - */ - public double getLowestValueY(); - - /** - * @return the highest y-value of the data - */ - public double getHighestValueY(); - - /** - * get the values for a specific range. It is - * important that the data comes in the sorted order - * (from lowest to highest x-value). - * - * @param from the minimal x-value - * @param until the maximal x-value - * @return all datapoints between the from and until x-value - * including the from and until data points. - */ - public Iterator getValues(double from, double until); - - /** - * Plots the series to the viewport. - * You have to care about overdrawing. - * This method may be called 2 times: one for - * the default scale and one time for the - * second scale. - * - * @param graphView corresponding graphview - * @param canvas canvas to draw on - * @param isSecondScale true if the drawing is for the second scale - */ - public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale); - - /** - * @return the title of the series. Used in the legend - */ - public String getTitle(); - - /** - * @return the color of the series. Used in the legend and should - * be used for the plotted points or lines. - */ - public int getColor(); - - /** - * set a listener for tap on a data point. - * - * @param l listener - */ - public void setOnDataPointTapListener(OnDataPointTapListener l); - - /** - * called by the tap detector in order to trigger - * the on tap on datapoint event. - * - * @param x pixel - * @param y pixel - */ - void onTap(float x, float y); - - /** - * called when the series was added to a graph - * - * @param graphView graphview - */ - void onGraphViewAttached(GraphView graphView); - - /** - * @return whether there are data points - */ - boolean isEmpty(); -} diff --git a/graphview/src/main/res/values/attr.xml b/graphview/src/main/res/values/attr.xml deleted file mode 100644 index 8b73838605..0000000000 --- a/graphview/src/main/res/values/attr.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/iconify/src/main/java/com/joanzapata/iconify/IconDrawable.java b/iconify/src/main/java/com/joanzapata/iconify/IconDrawable.java deleted file mode 100644 index ea8783672e..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/IconDrawable.java +++ /dev/null @@ -1,229 +0,0 @@ -package com.joanzapata.iconify; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.*; -import android.graphics.drawable.Drawable; -import android.text.TextPaint; -import android.util.TypedValue; -import com.joanzapata.iconify.internal.IconFontDescriptorWrapper; - -import static android.util.TypedValue.COMPLEX_UNIT_DIP; - -/** - * Embed an icon into a Drawable that can be used as TextView icons, or ActionBar icons. - *
    - *     new IconDrawable(context, IconValue.icon_star)
    - *           .colorRes(R.color.white)
    - *           .actionBarSize();
    - * 
    - * If you don't set the size of the drawable, it will use the size - * that is given to him. Note that in an ActionBar, if you don't - * set the size explicitly it uses 0, so please use actionBarSize(). - */ -public class IconDrawable extends Drawable { - - public static final int ANDROID_ACTIONBAR_ICON_SIZE_DP = 24; - - private Context context; - - private Icon icon; - - private TextPaint paint; - - private int size = -1; - - private int alpha = 255; - - /** - * Create an IconDrawable. - * @param context Your activity or application context. - * @param iconKey The icon key you want this drawable to display. - * @throws IllegalArgumentException if the key doesn't match any icon. - */ - public IconDrawable(Context context, String iconKey) { - Icon icon = Iconify.findIconForKey(iconKey); - if (icon == null) { - throw new IllegalArgumentException("No icon with that key \"" + iconKey + "\"."); - } - init(context, icon); - } - - /** - * Create an IconDrawable. - * @param context Your activity or application context. - * @param icon The icon you want this drawable to display. - */ - public IconDrawable(Context context, Icon icon) { - init(context, icon); - } - - private void init(Context context, Icon icon) { - this.context = context; - this.icon = icon; - paint = new TextPaint(); - IconFontDescriptorWrapper descriptor = Iconify.findTypefaceOf(icon); - if (descriptor == null) { - throw new IllegalStateException("Unable to find the module associated " + - "with icon " + icon.key() + ", have you registered the module " + - "you are trying to use with Iconify.with(...) in your Application?"); - } - paint.setTypeface(descriptor.getTypeface(context)); - paint.setStyle(Paint.Style.FILL); - paint.setTextAlign(Paint.Align.CENTER); - paint.setUnderlineText(false); - paint.setColor(Color.BLACK); - paint.setAntiAlias(true); - } - - /** - * Set the size of this icon to the standard Android ActionBar. - * @return The current IconDrawable for chaining. - */ - public IconDrawable actionBarSize() { - return sizeDp(ANDROID_ACTIONBAR_ICON_SIZE_DP); - } - - /** - * Set the size of the drawable. - * @param dimenRes The dimension resource. - * @return The current IconDrawable for chaining. - */ - public IconDrawable sizeRes(int dimenRes) { - return sizePx(context.getResources().getDimensionPixelSize(dimenRes)); - } - - /** - * Set the size of the drawable. - * @param size The size in density-independent pixels (dp). - * @return The current IconDrawable for chaining. - */ - public IconDrawable sizeDp(int size) { - return sizePx(convertDpToPx(context, size)); - } - - /** - * Set the size of the drawable. - * @param size The size in pixels (px). - * @return The current IconDrawable for chaining. - */ - public IconDrawable sizePx(int size) { - this.size = size; - setBounds(0, 0, size, size); - invalidateSelf(); - return this; - } - - /** - * Set the color of the drawable. - * @param color The color, usually from android.graphics.Color or 0xFF012345. - * @return The current IconDrawable for chaining. - */ - public IconDrawable color(int color) { - paint.setColor(color); - invalidateSelf(); - return this; - } - - /** - * Set the color of the drawable. - * @param colorRes The color resource, from your R file. - * @return The current IconDrawable for chaining. - */ - public IconDrawable colorRes(int colorRes) { - paint.setColor(context.getColor(colorRes)); - invalidateSelf(); - return this; - } - - /** - * Set the alpha of this drawable. - * @param alpha The alpha, between 0 (transparent) and 255 (opaque). - * @return The current IconDrawable for chaining. - */ - public IconDrawable alpha(int alpha) { - setAlpha(alpha); - invalidateSelf(); - return this; - } - - @Override - public int getIntrinsicHeight() { - return size; - } - - @Override - public int getIntrinsicWidth() { - return size; - } - - @Override - public void draw(Canvas canvas) { - Rect bounds = getBounds(); - int height = bounds.height(); - paint.setTextSize(height); - Rect textBounds = new Rect(); - String textValue = String.valueOf(icon.character()); - paint.getTextBounds(textValue, 0, 1, textBounds); - int textHeight = textBounds.height(); - float textBottom = bounds.top + (height - textHeight) / 2f + textHeight - textBounds.bottom; - canvas.drawText(textValue, bounds.exactCenterX(), textBottom, paint); - } - - @Override - public boolean isStateful() { - return true; - } - - @Override - public boolean setState(int[] stateSet) { - int oldValue = paint.getAlpha(); - int newValue = isEnabled(stateSet) ? alpha : alpha / 2; - paint.setAlpha(newValue); - return oldValue != newValue; - } - - @Override - public void setAlpha(int alpha) { - this.alpha = alpha; - paint.setAlpha(alpha); - } - - @Override - public void setColorFilter(ColorFilter cf) { - paint.setColorFilter(cf); - } - - @Override - public void clearColorFilter() { - paint.setColorFilter(null); - } - - @SuppressLint("WrongConstant") @Override - public int getOpacity() { - return this.alpha; - } - - /** - * Sets paint style. - * @param style to be applied - */ - public void setStyle(Paint.Style style) { - paint.setStyle(style); - } - - // Util - private boolean isEnabled(int[] stateSet) { - for (int state : stateSet) - if (state == android.R.attr.state_enabled) - return true; - return false; - } - - // Util - private int convertDpToPx(Context context, float dp) { - return (int) TypedValue.applyDimension( - COMPLEX_UNIT_DIP, dp, - context.getResources().getDisplayMetrics()); - } -} \ No newline at end of file diff --git a/libs/graphview.aar b/libs/graphview.aar new file mode 100644 index 0000000000000000000000000000000000000000..f3d0206ceebf549858dade47e8069709509a96d5 GIT binary patch literal 62697 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 literal 0 HcmV?d00001 diff --git a/app/libs/ustwo-clockwise-debug.aar b/libs/ustwo-clockwise-debug.aar similarity index 100% rename from app/libs/ustwo-clockwise-debug.aar rename to libs/ustwo-clockwise-debug.aar diff --git a/app/libs/wearpreferenceactivity-0.5.0.aar b/libs/wearpreferenceactivity-0.5.0.aar similarity index 100% rename from app/libs/wearpreferenceactivity-0.5.0.aar rename to libs/wearpreferenceactivity-0.5.0.aar diff --git a/settings.gradle b/settings.gradle index b11f11adfc..d34737dfb6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,5 +18,4 @@ include ':diaconn' include ':openhumans' include ':shared' -include ':iconify' -include ':graphview' +include ':iconify' \ No newline at end of file diff --git a/wear/build.gradle b/wear/build.gradle index f530c47ebe..e02bd28f66 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -107,8 +107,8 @@ dependencies { compileOnly "com.google.android.wearable:wearable:$wearable_version" implementation "com.google.android.support:wearable:$wearable_version" implementation "com.google.android.gms:play-services-wearable:$play_services_wearable_version" - implementation(files('libs/ustwo-clockwise-debug.aar')) - implementation(files('libs/wearpreferenceactivity-0.5.0.aar')) + implementation(files("${rootProject.rootDir}/libs/ustwo-clockwise-debug.aar")) + implementation(files("${rootProject.rootDir}/libs/wearpreferenceactivity-0.5.0.aar")) implementation('com.github.lecho:hellocharts-library:1.5.8@aar') implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" diff --git a/wear/libs/ustwo-clockwise-debug.aar b/wear/libs/ustwo-clockwise-debug.aar deleted file mode 100644 index 8257a991be6e1ff5490cafa8f66372d72b49e003..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90266 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 z zV8FIN%pg~c>q-Sk?C5QB$7+DTl83+j<9XAaKcNHUxjA?QePxzQE)huke$zLm^Iq02VyvFq!$={}@AdiN*`${_Q#=3Dl*^&4MUE=!({N|Nf1 zJq+d3zj^3T%U_b>Ab^1x6a0UehcW+a9;WX{SXo4h=`bK4N4_9&t@stlj>^?n1B~x zx8;bF2O5dAz-o-yyV6Rt(|UWZ*abCHw@x(_&pK=zq)$r|I&LhZbl3K2^YYI)$Dy0Z z|5glQw-y`7GFA&+2DdZIB8;td2*{%~6syysG79z{5z>P;r2$tvYTiBRX50Y`=F&+} zo(GNLiN&ic)mps=Ng>0Z!nw}mP-h`gx1_}5PLDiO_*cEI46#6E@{{NIdX_a|LfU$|UaGGs zJfpRUD4G)j1|Uu^466^gO(nr!-pj>YtI$`i*A#RG&@foN>H1!!1c5YM3N7xeu?FlR zZX)xJ5Ir45>BI6Wlt^UdS7k4tPf+U43h+aUWBPFnhKudky{-nFIY<{G=J4>w6W7%p z5ELaH$z|a)%5g9Bi4TP2-~;C-W8QPHUsi={%pd$v&o*en99Uh$nzUAeLBhkLCpsQ- z8J_#PKUIt%$iyFnvzgG_#_bj6Pc-xyoiys#t|2le{xm6=_olA+UF)Y5#sZHR9Z84^ za!f?vFg5zt*1H}vM8xslxsb>#$;BHAJ(FjzM{#O*TS`5ZA5QXF#rS%OofbUKdn2;R z{p$Dg7+)TC3S;hnk7(eoih6U@#sFoZFNNGg{dZUNu4bRGth?{?n*6FyCm8JPfvMh;Wfg!oiHJ+na3D>9oo7k^w}5FB^SP@bRsQzhH;p z=UX#}09veaOmWHN8;L!zmP`#>}qzOcsmG! zzHYl{ZM*Zz`8Pr-n9aEq@lw*ie_7l2zND57Mug^G?u-RqbFHc3ts|a~Sam4aCT9c* zPhHv7JVQogKX_V~xe}x3m+f-*Tf-0 z=-bBij6niH*UFW3LntqA6FvYpG5@?x{i1w{B=HtV?#}P6Q_M8vM7Kx5)R<7)#k4nZ zhOfHeQd0i@6DqVvbPt0Cr|1~xYY)L!o+xJcP(Ra=Uh>Z2PlUI=-T}f|j(C|b#AmqE z4O~FDfzt>rIGVboLtO@)u(NLBem~aGf-%5caEDA}HYKDq8WeZ8R}1Q096~#8=Z2JH#$~B+Ye(Bc|ZL z>#|q~WzI>+M4%JM%;$HOr&e2~(q^c}?~q1=Ll&jsipTQiR-AxV``bpWfjHe>#Hg z#_1*LEZU)edy+iynTff2y;1%02F9OwC<^OSxkLU%YDDvk)PU~9{zi|xdvs}blE;+p#{8z+Ee(2+$Z9mU*hKGIZ=Dk+;NN*8E6Po1FCD~k$V zI4_)*wqJ6#&#j*K2aF9w%ddQ$Qarl92&Sx%lv6yW*Df^!Ju6j?PSfzFL>#zU&nB9# zVSZSz#v%(={ivwzcenta)}0p_&?uK43y&e*p!U-?aSO$~zuvqoCwa`N3qJYPJQzuv za-srFqiR+<=!}bndbvS8;$&*fhPVuMQH-gqBppSAtEvPBU@cP9y()EYu{>Sfn0>mU z7=+bTRfo@;Eq-jTZgUl3nVh|5oDL(%;URps(vLME7G!9`lq_C!R|t4uVYpumm&M}^Vw-PB(GW1>{a@m<=GCR zrEF8OEl?@g3>PEK!@4xaW9zt2P=}$}0pfW!K{X5+KFq6$^XeY`nYktPK0*Z0EhY*f zSWXpbp$*kRZS(jYvZ>CbVnA*y5-aa%eB+?d_f@MJ=KVnx$p}2_xfd&cj-y)o)G=v~ zHHowl7*YX3?lfrvZmvl=P~iH*L_C!QTjL-ZZyqC$HHap*&i~;z6U1J9udo7o%_Vu_ zNTZRIEPP9Q+%!(aW|UEjbSAqLTSB#4bp-OEw!D0t*x>S#KKFjAMbIi9!=6eEg&cdk zr<+52+D6ftXhx%wS4x@*@?@bC0l#`22M z!voVd0T?Fkb)yo4y7-t!#xGpM{3KbRpF(VMMX=g0L}EZ82ON#b5H#M?Xmh?hD;H_YZ0 zoO`Z_7Q&`8x(9&4BtX{tY+K-^w5nhFmoR&Kn~aY`L?BQdP6kJHnO6x~o@Y*EIm1?& zlGc{1yIYH#m(up?5L-K8!3=O+idWoCWXc%@HpsuAh)AItI9-s6Mg5Cvj^U`OplI48lQfq5$d0ASLIbW5UO1ky z^?KoX+6+*7sv&jWR7g8N-|2f4eK=iQg}~j+VyjRV#%8ZW z1>aScHx;;_+RigRy?n^_;EO_Nvvr78ZD1Za&|sOU7y@K6|4#tCB#nrK)7U!^l|U@_OE)NX;+`YoKfe&H-8V$6QTWRQlH_V3SUf=LuiZmUIZ3 zM~uYdf@hlqO|`XAKpaU;x9nhR&Q{IrS1Mky45iK>*}9=Wbult8mKMq$q5db|HVftl z?m{I9az#mfR)5fg0R0F9NRgFaEiIz%@Dt9)J!HD6c!$S}5$8dfKxL1BY^4)Q^K3Ge z&yeE*s;ojqsw{Mk8Q9=k6n({8N~4D6aPlELA)0Y>BfmiKg>W3J(Zki$F1{*mpu3FakSo~ z3npJxoMcB1xkn1wpjW7G@R5q9`e;+hcy2Al)Yz^&d~eq3-^H%p^SY&Gp7(4Rc^q>W zahkzDpleW&)`%1qq}yYKD5|4R@sd4QSC=Hgj%s9Mzu2fNON!Fr&^O*)r7bShmS(X# zCRhMPn}q}fZ&5Z|cfhvq>8PYyXfxVr#btIhI+hs*OEb(%KS&8)@~KbNAWgAH5+X-+ zuBo7F)gnx(o}*M-UV5{~=cuc|KA-C)!Mo^wrT?Wo)>+x10nHL4@LO<2r6(=YVq^+_ z!nu}Ve6CVU#8b6R^j3Mu^iAe*Jg&aO)m+j&xV-9* z@@gM(GcvopHerCkyPbc1(piU}n}@UAKKC4RP+M^5>_m7!KWP;O6ap?a91g z|MS+tboEXC?G*(i5i{I$iaj&WR=)cj15nDIB6(q1yiy z>)P@7FG!I=}h^R7OHu}*O>$1<7fJw>x!g$ z{iB8_2(`MD;81zbR!AjTVA9#WBM3XiIA+y-o>(*Wwly272t!VEr|&Hjlkl5bq>EJU zccuBN(jxEH>>fBX{(dLui4(TUg7vyMmJIJD{a)kGFF1(7X*D6dbSw3Y5M~CWyJr4Z zJi`Z8ct{!Z@}-HR0~~Wh6ruR`$ld`!a+ZRc+Od$?(TL3rLXi&_hp8EoHTrebdEhh{kh)`+(>bmra z7@L=vb&oNdxZ_cPXS!9`;h_VE?WLG`M%JzW%1)XkI1O62pXB+8PVa=nX+JfUgzu-T zU|z@X&8soRfyCYLDm^RNJxWCO)t}6`8*E{4Y9bsELnD7uI?v@P06*L55pN@TCP9og zYa)I3EZO$m5hhDY^+Tt4!Sn=!;prHe$91CA)ZQ~7GFLT){@Oq*6wlTd zlEc>Qu>zXN+ctM3O9$9gN|z#0Igyz95?)}^9fwUGxxHU@ox0BM_1?*6E)L23Yb+k* zJoi`^N{4H>C!Z#Zj3Ar}!@fDsnZ)w+EVwS^vwoFbgBj8pZuN4Elt2kbwyYx$e?-}x zmJV$Bom$zT<5Q@0=+RApWPZ#LvS<~o@=SS|!GSf>or^D0%f1+2co0IEw;5LmAm1aAwmbik7A5CQ%k8Z~TsW_zRQpCHJ7m)*GF7p2PKVTtQ3Gs z!kRXMzK>upe$l#fA1xh#9h4VG6jpe`cm4`=6Taw*r7PXr`{ zsV_aG^0hle&DbN2>4qzVa^KGS@6nEF&o+72+Z7&@mI|Unth8GZPT3(@!dQ&t=jRvC z%$lAV{ac~QLV`Le{xM0bTVTm#8xQ9`=lW)K11*Z_LW2u8%`{u6&B#KztcO#`+1!`{ zzcKFz{L-Bx-9^ui)xG5MQ4O6VSKH1rl4HGJM-3={LOiiVxQeaJqSr+4mD)^I-7cz+K^@h}Ib!cOM2}v4$W(+ z+6;6(@-SUP_=R&T@lW41lvgEjbtt5VJ1JPJXI2mP8=lW_@BwtF&BNTk=^A#&QO-*4CWm#|RvSrt_k?E_z!EXclqs%Z@toAn#xp2m;`gjOwb6$M&V zv(O*tf`l|DrZ06W>ub^#o9vn$tD80!fELG>f`94>y_pk`#KB=K4xXCbA3L_aujuGM z-#pK3!Km#jP;Te02Ea@6IZ1YFzfFaRhraIk)A8XXiR}barHX~eDF>rL4w}`%iZYNq z-~swYNjr}RoJw_YQQsw%IigVw?&=Y1c9iL5JZ{ocdoG7?bUIIlGzFg$F-m@YHpe6) z2Qs5fOSp;ld!q2^#jZPNWmKidOZ_1ca_-EaE}pNrk?vS)v8U~m1{UpxA|n>XFXtkM zn~CgS=cexyYDD08P?-8M2hw*_<~3VTtCBp1}hf-*y7?c}a(s@++Bt@E! zPk7Ff;##nd-h~boY=#3)w)2HKPO=P+tH@Moy47Ri=wJv?F-#|G3FQc6G-IVmQGn)A zy$G<0e1b5>*IaF!xgxFGaTqH080PO?yGqy|II6wk zNY-1ix#18ZLgFigryz`yAzw64E62B_8|P>T1>iIUn6t|kvs5V0HR?FPAE}^*FVP2( ziZTYGIp>bahMV;5M72J_Pe>jOGMrtu;z@ASQSYLL_uZ*;D!^-uVJ~AC!;<2DZnmeh zhaR6Q8MYe~Nx=q1e4ZI^ezoS-8=cWwF*KVQ@baA)d=r)UAGEzwtZ32JB)o0gwr$(C zZQEztwr$%w+qP}n-hIFO-Twb{(tR80PUh1}Rx%%Ij+$%L7*!O)nFR`O$=CJ?ca$M& zm1k!BdHC+HC6HcF#wEg?gsh)rGGlauCs zrAUOre@rJ+nX{pjbvnotOrS$Q(?dG0#+c?=OqEMhdKW0=W%}wCB{C3uMNwO7$kRumx`>6xRR0px?`v%p{)*!%1&!)YEBVL8ASMr$n<)1(Mh?lnhhi#%AN0b|6J!lq?wBcbzMmJ+w2%AE%;2@fDAb?UtylEAFeP z^sI@(iHtASOguR_5?7~>)^w#5qoH@C?0*4s2K!hV8l7|rYF=&jN<1=`!;gIVyxRz! zs8d9M&@!@|c#^D~(sYoffqV~dAq& z3mFoN{T&9wFgqdMW}QgS=?SBViLs2Ht!aC)??y!~2TZ1nob89vzL6(;S~BEA%g6Df z86rxa$LFmExHxwd?|~uH^H`!Q(G2$z`!3#dP1bE~3n{OuM;F#OftmwjG30!f>4wqW zx07hbPZu6I-ruwJ@G8$(5?+kFjIaH>=|Bn08NvZ*4PilRc1Vfsl}dagBwzTB#bd{; zm1X#bI1UM9`?t!#ea-_k#R#PvQlGQ4E`K6t{Kck`J4=We%j>qEywgyIRB16d;FvAz z{Z6SX3dRGAxgkrgI!WV-^jdc<+9fJ?xX`s!^ZrO+#+DM zAnlA9V$~$Ve=Op#>xPKsV+3UCS+j85^wx-j*N*Hxe6ekbVlbpRcFYJ401$}r z|0v+*U*iNh%A0bV0tmcG#g4`>k_9MQ`2v?tkV>#BLJA1<5G2JYBw8V-(~VLx(^?N3 z)8HyrePu|hi16S3ek#M&Nr6jc6s_I4IlRs@QyyQZx7YRnxAi)IiFw==N1~vp(j6J2 zIKk<0r?@o;k{9JHzF@(lf-gEGOiv{wT+25L)Ie@EtW$7A1~5z^HeoUKK{F(~90`gv z{BAmbc>^Qzcwcv>qC~pEjlMMIDsFGS_9xH}O?A zBItQ|LQf4*lJNBQTYz^5v1uH!!(_u0nv?`dT(~)Gb*VC(j^S&YWG?lNwFf1?vcg;k z^7A6Jn^`atKgo+#M&7b6Y3kYP2dt2xd4^39a1?6HJ|_ls_smg@uWA}wX1y;RFRl3n zpYc@c4I72M`(%#aV%=Z?7Hk)u{b)@{Z|0%Wu+L8IT0s;UO|64mVs{a8({_)J# z-tIr~A!~2)ud7;&vaS4v0tRo0kaUfGdHK|I4+H4-l}`?`naBVV($El5=v7dKZkTI{ zZ2lSiI(|m_l<6cI|E)N!_e~39W=05`=M3+wXRh;XPtW)F=_ftFr{EZL~zpZOBqBb(J1c2JTV&DP`! z#kM~-i*&}F+YYdOi$o<3nWRVA=OELUZC+7!Wf_;#w`7#$Ol9zn2x6?!77GQ?FxA*WPg43$RFAt2C)G%^OsD;?JA0>L1U`zSa?+cP__2{)ByZD{9sqvvJecCt+L0Q(yL5dfpW*#;cRCfucPh>Se_C?Gr} zFUj$|Qs@Kf!L@et`R5Cn||1C?>`D zSTU<(TiRSHKo2IoC>l9~Jfr`LU;+nKCiMEBs)a276GZ>3^a(0R{;N@h<6i?HYPQN) z>L`A61k~+nEGtV-wDc^33TY~frSn#(f|hd{l17QWda2r5ChH}iNM-t;aSN6bw&q;# z$?)IOIp>OEotb&>R@g*m4EkHUkGr?3SbnwY8RS?>$c_lHCXGb%T%;@7N$xZ@SK;WU*7l-7L3i z>8!$Sy|#4v)Ebm{!GjMUo{CK*yy6BM^r$c%Map%XWrP?Nxkfpiv_Hr)Y`${*9%r*} z4q|)NqPs@84=unpMgS*Otamc7yTP= zQ|g7pMNg;%c}y$SD;?58+YQ`RX`np}cT?^GzDQN-pf?P9RrvJxUW`UOy% zUnm4_NNU#h^Cw+JN31cX@t4m)!o@r-({k>KX$tNjbzes{eE=B{6tk(2`~t?lOb#Dm zKRFrdS+XiksUoBIBI1Hkjuu->~Nha}FS?pLt-E$7YmF32*oP(*Mx7l5uM$hAV8BLBSTxzawtilKAz^nx7z$Zyj zGolSD{+w5&OEW6|0TM!Wv80&(#aHWJVkYzgYr;n;>K!83Ph4YXaf#rDUm5@!M;*~GV}@xqhm2#!L8x@& ztg%K~nnt3BD>r{;S%^}`sJL(sh^VKs6RKKJ7U^S0{j7%;roN6_=+LTp@@3@w83S1p_UBDX`Us=jzZ7?}~#T+NA9VsTEWwt)} z{P&+NFoy{PYsdc}#U#joS4OD+7l={W!qDNrGNY2MJhC8yUu)0H#-YW&NOQP7#8b$G z=3n^I;5imnLOrP?5TUPTUU`o0os1W#Khjb}VnzE+{1Y5qY#U-mooQ27S3Hkb%-)ZO zr)jqUEA_ddf!(1%kyK_X$t))IL^7Nq)nem~0z7htT5roJF#EEo@)%1!CzB^Lf=Pt- zoQ9iMu0>6AE?;w=e@~B|SH_D?vS*_~~ znNfD4<(((Kb2m*XP$Li3DWC6ZCgWSW`)yw~Xxkn$+kChbNw;UXL#_UD?U!vmc{-SE zD2_tMRt`7NGgQy*|M1;<1iA~LEldg&x93=D{zs1?qVl%lyqM7HAsO8+Fw85VCr)cT!cjXeTT+5)%iN$4nh5 zTuvCwjP-7>BaWiPT^ztjHyVq+Fp)rz7eJpyi4^9&YL?R>Cvuz()i1euv}^O)zQr`H zu~W4WVP@H#P?Mto7?X$ZCj45;wvZu+ACa93+(#3IJ{n&5Fvvsb68a(*g=rfnGquaO zq{`OK1-yx@$oE!fpJpM>%m+KRLG?g9?Q@cmlMtH2pyufBa3Z@*pTa zEEu982oYDR&v&dqY_QTVz`?TmLaKl+HqEDGN{D<(lG2fB6 zYbW_62W_cn#@@cm#^&~E$94~I&&OpPKj2hh$_Rs*Nwk1$QE+3lr3zE?T|=-nlhPYW zkof!L!S3j+H>EQgllt(=;5rf-$@by=C7Y}+Rq02b8^+?V z(b6<}#;GM&b8%RnKdXwalk<5unRx1wt%qwDWUD$gmiHmg8&GW7f@M7e)ryXz=IR^W0LU#&zkfvkY6}3Hx6K>`FEudRd#HcUd$`!D-5! zXdWVI%NTO(KC*v0D_e?a$6(1FTzhRI)8>gy%yTXHEm7h~v)E2D+^kbR<8XzAWdCCH zsyP7OhHL5$R0gtcDb~l@lWeKZ_47i>c8?uR4y^k^Vnear*96kqFzXg_{fw^Nw>f&=cC0>G3pSlJyBvnOD>(5fY!R^0ch8b4={83Aw$^q6~biMI>Uq@nvnvk-O7jjN#h4k10&XEspk^gQ803um%<*hf!K}?ON&01hn(vCBi4ciJDZTi; z0VtfcwsjoBtVN5Z!*2=q0>jiRtbN0u4C-A(oZr7;g7aBax`d0sD6wmVH^7H#+2NZo z!k^tKC)gc;G|}+m&c$$w{ob(Jl`g~Ss!k}9k3yW|1xuZdqz>uj06Y5wgD%M>*W^iZ z20k`S-4}$KM|=<6L+TJQf^rVf#wd7bAr5_ez)O$~X`jqC;KBdkia)MkeV`75@&|ZR z`~jd0$s=G1%`+8_Azfg$2ZyR|!RM1TJVH1e(#IcOIGl%09DyI%w?K7W`~&o;=5!2( z(wl>~H;mbvqbu&p4E%jd+N5ax4KS3e9hmS2VID+R75(0yhhHSat`g7h7@;pPjzO|L zWG*qqG979h-7zFr@?))2N{k>=GSc~!9+h|27?Zk!#Wza!(2eT*pM%oZ;lT+T{~)uQ ze@kX!|Gswo_q|j9Wu5xpx&YQ_LHejX=lp(~k$EPKLyHqgh#WH*AR&bcD@qn00f9M7 z4j>kej7||_rcXsPBMWuk7PW4uRRz{))yTrzE>D0IYpB=Ubh@=|4{q0ZyVTv-z4GZ& zO7->qdOMRm3Q#4=?|kC-UH*3c(szH)Pu3yKQ~do#{Uld z5hVCg6#G??>MQ=Ua;ER&!q!8b^k?~O*T;qKyNl;Xxajw3{?Gg$=$7C6`QL?K$f?hg zr{AXlp4fK_%x@_XPC5eoNF4kK1boOXNE-&rDSsn$wKZ6Zmt+S-^hpV7L;AF_F>p7X z3*($g6WdIgvPt7m8FMQgI)x@5o-FEa9&xvshkKpc|GesNtLT5r}yrK)=+{AY(22<@`@B&^j>3v86>$?mJy zdndgB&bp@uDo_2hBxIgN?5`A?FK!v1t+MAqlc+lEn_&O>cH~*k%`37j{>$PA+gZ+w*f=i}ke?C(nFm zU}euwJL9_jIE;D0Kk`(Fv2bh*DJ?^V$gO3hP^L!>O&g zdi71>dvj1XI1Yo~R08fES(YTxIfzXa-1YO(L(?FOjV}f^Yy62aF(Y4pC1~2sS+ZHa zHLznvzd`R1OlI!L1lnLS{_@6Gld|Ek7w&7I__#4lW8JVJ5AK^FQIAibv=Eyy4ZCCz z$0=sD^XCfRqZhJ6EJqV`*p{}GC2nPu$}+_>g$cUtIH-O2#2-nJfKpF4Rx>0*iGN|o z94Uk$g3C$DdoWlPiy<-m%@hhB5n4R1VHq_-TnuNc1}$(7O@W$@4}#g_BaUuihv%pz3DN#tI_X(P$<$#G;JPQQo!_5suK{IEo|vo+h4G7_vb)pAg4|;ilFo zM=D(qneh;i!SbF~5C{>OyON}2Yr<(KaH_}N0zNEfCc3xm#_K?6jTY4wWI)6==Hm7a zl*FUx?N`ynJ)>7~`y(LNzn^W9S}A?_9-4jZAAx`?Ly+9mdvXC!P-OjtvcM11<4KYU z1)mjgw&TD=GZ7FQI-Q(h5h-TOQ7PI%<-Ktv!GkAV{3YhLxr-U)7Arzz;F?RTQ`SL$ zyk{+O7$K8A6FtIZ1nHbeOeX<1EQWixAw(=V99dEEF-4@fbQXIPcwy!?qI7A@ptISV zkJ(mUH-^WI5mh>6F_FiRpOYeKt#R;g;@Klj8I$3pl$9^je@tyXNuS1m2B7~wbty5Ws^^-9~W8kYI)E{@QV_76&yLXSjTf`&db20TVu+>_d*Po$>vD5o7gIOq z$^3feLcCqKEYe#z6ndd4Cc#=_>ZGcK4TY*Q$7(JjpY?kOQ2v03wo7klQSa^(d8k7q_| zKx4f11txylzNZI`@BznL<*0Ouh_&oVA7|Aqe|l-+#JijS7}Kq5OmS*9GC|wuLv6qM z&ep4Y%58x{m76#OJUEh1si||y{Z1EiyYi0Li@q&JVHh20eD zFsH9y-{j#p)K%n^eq0bAg>r^Vl5+l?5b<@A=zEapk@%~8=JOZ_+~gyjfIY85Sgj^L z+)Mhj?hcuY|NVSUr{Zz-jj|M4j=8C5p96Gu>KX*KOvDRaCiD=CzvglE9W$rz?_u~G z%y_r|{Cn0HZSw(~Hn7|K();EYZcg6urXn9X?hGWQ;i^PV-r?=V7q6e*Df&<>{lhD( zA0#U``tp0oBTm_IfDNeoPHR>53^?a>vs0o2XK;N97CB{xm3-ilM=>N{FtACr$OMw2H>gpnW)Ks-tA57a zKIW?lWY9L2(hr$La{#Y2bnu*5^+{=VW)gdT_Cgs@GBkfD6Iz4{%bGFNh@4>@U)Pv}H-8e;-Z%df_i zJt!P^XVoE$sEDWG48f3$jyKE%ogff=smuzr$t5L>W29mi-qj2{3~;A$;|SuOfcoV3 zfSmSrc(P(D;Sb$?3keDKI8dR&YXQ21tKr7o-VIuRW^?+o>;1n4D$c1=(lkV3d7A#@ z_$X6C{lhZ@5%}_nwtjrGYQzm?{tJbI%dnJQ2TZGzoH zNQmxMXS^knP_Gl4t;c9Vmc=A zB=HapMk`pAJuH=3FGE3|-gNq6l20Q?4w*a!o*Izzf{qr^SZe{D?J8d?Jog5X%x0=+ z+7d`nlL=H3>xi_HAp()Z zE3GKT9svB{<4wbLwq#qyL28MA|shlQlZg` znCMf@m5Z6bY)F=LceA5W_F=I8M=S7&J?{!Tej63*zJB+kaNS6RC=oB^Zg^~S{|Euh zd#VBNT*geUvO^;=t~m*9PEA1O^C01y%irw1I8pAsH)TH4SEBU@R{8Mq9PGI_!A|Km z>m2R5H^mP4>)Of(-0!xytMRd`0_M>BOpk{@Dh1HVSfsh#Eilq*8@!@D6+ThTJGk2y zS;Z+{2jhc*hF9VS9VO!PE?ZdCV}=x-wjU8~o~1HyFY4S`W0^Ma$+HvRKF$ZJF}(vT zKvibwx<#5?0(`%*S1UK)65P_u);7~DIjw7vMcPE6Y2C7tL&ON^UejKwqkDnn zl|hvWH-CZHg$*R@RoHvoH+{x&zRJZeb7m7hyJFI*I!(emN$WVJ^gVLs&?SL)8i4Ms zyoOr@`fvUUvtZPSrCH4>1?`#h>hqL8&uQG^x29laI@blrAXBtUzK5s^ciGl@`xp@ zZvaU^w!a+KIYmtf#pT)Ql1N`M8eNH6uB>f$I@=u;)ScDFP?{2VT@l=lfUXbcGX=Lk zgq-}G=aXoA6|~0k6KQm$fH^fUgt|*qi7kEnyzrCh+uuPb=Z`vz9yRA|HS4D_Mk;4q za@`{FxJ6E^YkoOC))#GW{P;_Zj)|?iVqnd->j3=7wCPYND@?77ADHGq^~}^079}{G zLR$~JF!h&tnv2=Tx%E~XcxsQ_km1oYY62KA9cU8A`>K=aa*xChn$e2#8h3hbflTvk z9=l_#%dIM2)Z9+>+`<$9$5mAiHM~+TbX(-Z@#@}zq~Us6&#r{eB5{#&G zERb@+M@k6k&@&?@OXiVH%lO*h5N0oZ5NkMY}N5OU!gZ2C|y28dpBC&aB>m?ehnA zt5A8lNg~s#>ygV zL|(`Xv5T0h;%;>QPnC}z$njUS;$7|ppIgC$9{48kcn^G$%;~jqY_*hd3a}Ku543#V z{4Q!_>~Qc&J30Yh>@GE%C57=YmYk;fJHiyrq$m{*6hbt#8?|HG-A} z?-u%n36`3H%K;YMW)|71MHfc1G>s-{M&s^P9^tBn4gY2J3dHl5MwXfu{YKp%OrF(} z3QE~&ODjxrdvV>&4gW^H0-LjP;QkR7(4!to*)-#-?Tw4-wzi{fLt9rZ?L^S)X{lMn zi;Ec>d_L=XM;RS5si??7{e4Y;TA=on5JA%hR;)Y z8oC;d+yTV~2Bfh8JVAt_F1m+CEtACf`@byMhIL?3qkj3#@C$t{PY~Qb7YI9uWV_&y zwO(huxU;IOX33D_Vkm#q`BcvTN-{!Jp&X8vV&HVwHd4rTDaOaq(e4Hzi_^$XwOKW_ z`FLbUP88)dQUMY`MVO)-C_-sUFW!IA;vBP59JzYjW0w!}7ovG3ZJg6?NcO?nf8a*W zZI0phMfp6!!F?Fx{F2|zfeaphzzG?Ic92Rz%S-3HX6)QHZ$Z;62>V z-=Y(2s=gV=H~b<$e^EY!QV0lx3$-R`{c3sA`KC$D5vJUa7`?~2K*|vY_ISkYf2*#% z-ybCE|Fca~C=7lx4G{o9mg4`!?(Bc(SI~d8#4Sg~x_6^0&caSt&g1 zUQu``5KlexMrBw{eYl^8j4 zEIcTok%>gp#>ImoNkg+Lx^@4O@z?C&H@V>KV`60$LoXZKQka8PoVnt2s2IinvX6N2cB++UU0?*Z>aN)b6K0Y;&aBW44tR`HW+Omt& zmFRg?1#|XHt#}AH}B0DM{PM}svvI>4qN?njRuZX{&#*!X!wa_Ya|#$UO-KoSpQ$z*$SzUVP2@5BE;jx%b^v60)+KNJa#BD1 zF9svQxT?^^q1K5rF1rQoT$T&8>Omz**5C2deY_iV=|BI}*6x+pgy4Vx04Dyel<_|b zS^QtYprnhb?Z42Mda1N2hB6u#9r1UJjf1g7Cr}t-tu$s~4o!=qBV8xE{qHac(gGXe z!wQW?BK3I5li~-=_uNeKxD59q_?U1BZx>ptX5AIM>4l*d7BA3y?Te zbmvfkmu(scT}#brh%9I_In>ZY>#RdqK7(h!^WZVx9h1qyUe)DDJdLUYA6>j3RX!wx6rQQ^LYQbZ1KRm?$-c~+i{?g z*k`$J3#m%$Ih9v%m&w*OiztwV+NydThNfk3i7PAyz-}f@wA4Vu?!Whi(EzKSd_Esn9G?ty|{C3%w36SNG z^{QORxj$OYar=}qlem4Yn4!QG|HsGXXp#sMM?extb~*JasKdRCYo)LFv z=WY|UPxomP#$FRfN1|DJ?GqL34$^@66)kyd7s2Zt4Qz%W8#?c=0Uai15TRX|a{+Vs zNg}a%z7zH#+l+1C<~+Yga@^d`$S~*>VYDrfQMx9Mvn0VO#X^kX5s6QrX5C&^T|5Om z@*QJ6?LLhIGRsfg2(3y8M_DNEiygx&dGH^5(9R+7GOlcJ-_w)E?U4r4x23$|VB2ud z<5ULGQ0{*7h=+O2C)vl0ku0h|WG_#cyOFcnifdyo*3N2omZ-gVY0b#4ckF=Aogk_K z^oG;!I~Ig;`(VxL%@OV4d>H^ks?~649=Phw*d`Jnnu&on{kWK8@eqXtvo!$mUG0%H zcf6Ei^$?9TpdIw!m}r7(bLOl7B)35}Qi6p-U1W(t={52*OZ})Zmz? zf|X~^7yyl@LEU?N^#3_YAx`L-TKA9A=neP(oTC3f^;cINSscTUETTF%B)GhJd1Zuc z10g`vqDDlnRDeRI7SJWq{Tz&F1~p zvMVM;ln?4`%Sy0*f*=7edp+IibydtgI>v^ICRm1GXvFFaiygIQ(nakI87^dG? zYi=#8RSz^wL$^8-iMC>=QK^8e%$zExM_S?kJ>RTwA;icAXrnlRBYkf+9J*FH>MM}oDPGTWUay}{fjcl$;dR1ky z@qFz=$HN%s3YAo-i^9vwl*N^9HN zoM@CNcAa%w*nWOB^h%R;e{1}QO0p*d@l83xITEfQyA94x>~2Fi3hrquZ6JZOS^Q1a zyKlSUOFrUp3DRJK&Epr=E?XdBjDcewqRf5140xJ=3p-if9gn!f1{~P-w<_ajj+(P& z8ILyNvmv)LVqOasq?a8$pEtu7|9lwh@%VSX40mJKIRlYwoe9!Xhy+tb9j3okr}G(U z%v>M1y~1sl$#Dg430DI5Hw4YHjTY!QRmMSSAv`VA^O)LD-6%Z;>oAVKi=GzRpQxim?7yqKe+;>w!hRzf|4Jo<$ioVUZAPHBN zRMm3H&wE&tqL_aqCf#1_LO`3kQcv>3=NFy=g(*&wQ0dSFgdU3M1{ypUA~eoAQj z!Ywo6y`z{G@H!SntgTE8*hG^vnizmAW^o-I&{YtgvGCnI)?3$u^IgcRl4>LI8PIyo zAv?7+hu8d&Rf!sZ;(=dCPIs!x2D4Q3<*nbtM?ZN!_%fH zOfxI*2xTC7P2kh?l-7WuVfre`?H5|FrCL)DvIy1Mn`SHzzqoy zcEC>@AMoRJ>cq*K)|2?H;)MzMJ&Y)j_XIDFNmHvmXAWfH#mvb!3L;JVn8{Bo4*4N> zjBGE9$SmzSNf#c>>kn<6e;`~qFJu+u5`Z+fxZYSE(0l?wEa_34b%5(()xSlIY9@0- z_>6q3vc-`mZ8d<5Ev+y0D=SsI zSs6LoBwh7gkjJl^p7v%tufD&x9=D%6S$A*R@H`*}fS#tw2iOM>vX1Ym?L3*2Y4%Z* z#s?3$j-EPV*u7anw~}wY(L7%Y192uthoc84w4=7q11I$r}#kp1p9GJW_zHRi}&P?o{A3N&UktQ z`XpbfVyt>&gOhJr!F`kEgZx96e@^yMzoZAMn6ls6qF3+m9pCGsSMNj5dML$uQo`CG z4}_37O=t>W%%n4rOvfz>Z6Zi8PZeV^5+<1>QYq-+X_M&}K{Cf2Dg;V}s1hxZ3QS5W ztFAj&`V^rkdx=dLM$`74f<1U^me)!DO@SZ+CGa-^zTWq$+Nw~FF z-Q8-fuI==9JDR$Dx2b?ykRP;xf8uLDo~JA6t4$%ik)b}+!GU~fEc!Pu9hlM2 z&)i=y<8mr@kzqV|XL^6)lki``zvNu|FL4Bi8dH8^{k5N6!FaT~!s0jaMY~4~FyPL; zf#urh_jY<#u@{K8#4Nd}3vOsgyVfsXFD4;#FJd8B-1}$iT+OR2Ue9F@No&lQ37b-$ z31zPCK3ZlR{?wsep#_C}hqPub=c{jN!!tkY?jRHpl7dvH9I+KN9U@zaj@_@L>FVT! z#s%{se~Ni^mCG-Rhx8X-WHtvH05M~ufelYl$mOTjyZKG?YB`9xPP4(`UABzigx@}P zx#VK5eamN4UrR86$5F6e&SUaeN=oV17uPL#wg-%DmY^c`C&m!Q9VJyXK0--p_PIU=+Kx zmjoa@-=Nj|wsEk-1?S7QCR&zRV$?>Su5B>RJ(~B)tc^kNki!WuYNokJLe=ZhpUOgo zoD|$dr0u@kLz-jr&{x1+J9Z7rCW9}iSxY~=_R9^T5mydzP;O=4i}sunZi+4l=9G*) zrrEF-q?HX9D0He70{ThefeZ@x7Ney=QQfwaLuk^WQ-3ncZC_W<(aOvsLv`{M%J8C#&0)DKggt)pc$1T1l;htdwE?Uw{Ja&=!PUs(^i6Ok!L zuZqFrkW@WG2gr3p!I4AYy+i@UI*JUk5f}H(nbJAzdvPEl5=5~rl8$-^wX%m>u4*`P z=SvC+CPOVMq`>;OaSyEOHxdL=%~1-eZ@l{kTvjAz9AdVWvnU#fxA&?3xE`6d;?W#v zB(1nM6gQZ8(1}HuSyZ(kLpX7j^;u1W7cQ26dG%^%J?NLI%ct!D{ETHMA49c@PIpsA z3ei`3_z+)j92h8s`ZhP~Y!AF5&O6mwYHxMcMblRtHws|vjq1`dy8WBQOl+(5yum7& zF-fpcUJ?uoQ-}aTZ$G*VYU>qiBW=q?4GAtF?sQ0AzOswu^sPC#$VOwgFkU`I&oCZ& zsf()w4VfIdtb&I#W?!lcs+Y4#!jPaoS+-yDJtnMlQ&-TlSZ1uDuT`+79ikEu@ye*u ziXfw`r%+~GF~w~kia3vi=UpT?l4ENUHx){Z=WW>4+qe$3aBpeIY7QmWxvrVzcrTIu z*kHGGNfE)=_O1gP_6(mI&*r>)Pz>mM^a#Ml$Q(Z=`Ey)gs5Vx{nZ(T{Wt*|B@?18r z@lbSe*5penR=5n9+iUfU;YF7cchI(EQryoMBYkS7IefomlSL0Q-mbxKr%U_kU$F%{ z9BM`sj{(|T*i9+DRuV0)l0Pf%kRk6Lgyo#b#rj0yyXJDU3YP4Yc0LO@^u5Uyb*w)l z%GF-9N6Wc)(s*|hb`4};JO|ysGL*u1c7Fr&)hJ(|B51SHnX(z`Tv>o%9QG300#@xm-fZxBeTU&?4YipC>i@Vu= zJ4&>a#jh%}gB+tgc)x823(D|>0L|0lh|Dv}V2Ru_W)H3kCgX^!U4M^pMT`d*g;rnt z*b3n3Z^lQU#y4Og&&N_#i{kR6hxxG##F;|u0qOj;4{T2tSI@Ah2TsHI6V`&p?MP{i z%A0b}4fE84_5tg2yVptp=8GE?VMJkc?r&!Z!5qpPnvIk+ld25Bt{nx5!1g8FfQU>--}XO3eO#=+SfUT4}3lta z*MGb=z2HkW!ahf^_u3SO16DXoFj{ZY6LX4ow7Rl9iz_selkNny=q+a`7WZy)f?x(~ z)OsgW8c+&yaC^ZwjP^4tk?&f__yZ)V}>{ zs|2=YAymy$xC#ffW+4y_Pz2_X3VN<*j8$eolJQUku$09aB9>dx46Cu0{Gpn!mlEGt zGtL+)*FczOyx}D|z`bC6bL8?sfcd@?=BRWM^Z}-bJl=eSz#VgpnOH1G$>{u!?nl@5 zl3`3q#6cBzP^SQlm^UJnhGvp#+6P67lD$>en2~?_#TP8ZBlR|KkcG$IK+o=>kx_j; zy~<`vmFO?hr{43Sw|8$|Q7u z8XB^31+y5+8MV^+|6EFBS*tJD_kgJiBg*?h-8&`?j1RExrlaju^GeG;uZDi)$#lVo zuri5v3G9r*1L8$~++zoJ1EVz1S4KjJ@WZLOuH^IS0UsWZ8Bm%vh3Q91HdTtzS@({@ zF-E}M#3RVVU_4=@-^ig)+SSLN;MC+CDey^tP|{u=opddN97X~v^}5u?0?C^M6SfG) zG!JUTgWDt4C6pIPtx*{IhIIy$Lr^OuLQW9Vj;1+LPFgs`RRgK2hMzS9sn3*pNwS){ zSCnBDYSq<`8Y>8?qo^&}%NNm-6b)7xg%Eisnr2Y#8T;Xy`-QHIkG5t@k*DT+Byaacg+2W;nK?L9IqW&-tOPj`=tB<~p!_eZYAwD{W_7Z=624jNvS= zpgsxO-li7u4&;3u&|$RE($(FxSrF|Wx*=IQf_ zIMStB5pf56TX`}$D0y!j<_QTy!eia!lm~>_^_P7z#Q9FuQb!g#Ue1&=4Y2XXSp8=? z%?loIcnDSK&iupUyGMSElT%DWgo*iwkL-)JHjinxKTMD8%IQ;I()b@8WylxbH?=qDu_ zSvgVA9oKs=Jn6rg)hm`Qu4>x0EzH$yyH?QEY|-lVVej4W_J;s%2YvsgwXcq>jbLd}p zJ=N7!U8Z{b&ZTlc&MkdLg00UiVdj{YCL`(gUM+mzyh z^sg<;no3^F%H@C59m(GZUGQlR?G(g>BYp<~MT$g|JttOQl45cWxk_{i#qA#y+764? z+%C9wgFXac(zKp{9ZODQD66{NC*bBPi z34YuVm+=#8jL*opFbwV#nu0MR$R%gw_KO6Dah<|Ypj3ui8v6;7n{Gk1BZul z3d59?BWP7&!`1sFOy*AXR>FhGxjV_*`QFt|0F3L!ZhubW*_sgmkFqW64epuky0yop zPCg_c0b-mrt68^+sVVH91kkTO%~T7`%N26&GRKveuVEI= zmCzaLX%;}Em}_=qhEnv;+Mg<$fBqy2$*MU8@PnPyW(o(QAxog8F9`OYK6~j;A!*Q$PNrOgo0mlN@nqT|ts52e@VpPJPh!jQPsV9(|ws8JaAL1vD< zNlrpZ?nAT6)2Gr16Zj*`EF-FA_ONH77?vRIUS5l`g?MD9>`3Ba7_rZZOkVlSlSR8k z+lSG6!; zcJ_esm{e)Uw^{ibq^V%MU0`yX!On{^u?XXShH*Vcx%Sc}F-~p_?#AqD=?I!Zq zaor~qFUZ-$iK9Ia@OEhh1o(~6xsTJm@)%MMdTdw4B)fb%qw5miD*E8MzwC0Dk7(P1X$&L^c1K~^;3SF#rx@rwCfQs+iNkIb ze~SwX(-?-lX#pMr6NfUd6X>jwos^&`t1Bx}HIVWttNyhU#)*M|xf%7;+>1mV=(Xdp z9ota*xz@?a+JkMTkf9}-g%#y!j)XkW^nt{xodG&Yqc%%i4Lx+qV0I%`HD-%9CKgjQ z<&*>H@&-EFlZglMwm9Sg#18&>5vlaif{c`3Q4gx9!b?8XY_+L$yNI|H3^Wl4wyh>w zPT}ZGR(4hu?1Kd+GNxH2Calffm1kmdy){|_k6jU*7z^#{b7cr@u4E|#gcY+$6^1B$ zHf1(nFk`E@s6HXO3o25pTNpl=z_n?6bq1$APF)}@xwyk>XaCVzsRG-VCh>$ZCtPb1 zm??T?J(nHgAXQ)5-#{&=VuQAn%j%1ulq{mwK~G6}u+r!QNvSNWRFc1{@i|XbBzC2L zMXVrIfEJc|EZ;7GV8JGVG|fan_8tqjIEO2;DriSiy~D{lch&9oO?dkc7tPKW6er-u@e*~v%_%reN5dC_D;|$ zQhab|TP{jU=vA;+Zu{2MYV*KF;o!c0iqaRjXl`47Q0>iK1u3SzZ75C-OOSBBj`~ed zBisHf*q4ojIOUg_x-#g(Zq{F0>g>BM<;ysn-t*4bb6NJid%#R|$;I}{*eZgOmI&+A zIKDhQ(L70$FCbSZtu{E+zV+%>$b+fhGf{zC+TOCTjfww!Fv2~DJ9>6(10(p1Dk0`B zsnHH%=YjKe#5qyaCM_=yek#_(bE*sM=Q1Wt??M=byCHIykwSCkl!2FY%MwVT@={eJ zAbU=&amq=xMsJ5`SsTL%{5=2+UkS<@Ava_M@wi2(P?v-VX=i=KL$s2o+uZgb>!OQo zR;+FCNiL4>K~k@CYPQQUvyYz*ys8OOq8gPj_Fd!)c+Y}>ZncW+E-on|h6{0nh1KIi zm_WdGOKPR?}>&1BMetlu)j80)l-SD7vZn z#C^;~$wd%5$X;l6<{&W>0n12Ms(=>IX>|RZ@}cdGyH)6`6Og+^N_2|ldE=TIEJ+1` zvgs+sw%meQ0cZ{YEXjdsVN!m9W&TaaB0RLRWb~YnfCKgcElNS+gfeFrR|(2MNksr; zT^p*pnMSs4ctMpqi?dF>{AMS2HF5@R&vnJzXo_Ge0n3ZzVa+kA1udgX3buq@YovQ$ z(KsgzAEAO4j894n>l$zB2lqMn71kF%fgR>oz20o-_!yW>z>{$N3gzm(!GU!bgC_st zauGtKQ1(s8R6Vqby7Jg^@T1s}up%F*%D_H5LLqoFJ%!x1>q)GW(bSE2WS+93SQ)No zt5R#Ww=VL9t@UzN%$%WrLQ|Z~pz1@`R|&nHEYXFjSTwHU9VrC|t|WUe_mxbmDLm@| zEgY=RUL|BOMk%1d<5WYF&SGdI$++yp$<~nv{nXL$OX+D$<0;Rk+C-bH|^NiZz79}qH`5!&+RdOCvh3JvfDJ&^qz$3f)KB% z8C};kqdP0jzN=b>-`JjzF0zkH57s%N7#*e{rnE(}{B zu;dk-YXp=_dmk!J&G{KAt9nRvy@j5rj!TK(w?5!Up9M(z&#sCdRR{OHoqM_;bhz0v zMPagfa8o`Q*~IDI?$tm!4o|jI_XTKSmYe5JzuXS-&41yoD#?iXPI#B;UUVU#Q6BWn z3;r--+-0>lo`hgi*%R6XKJJs?^gVA6{ zPw*lT8k=CUC9kV-sWloFDw>Rp6p><`Cf zY)drA>>g2jEf>G(ME$aIgW77w=;opBPVD%wnoB5V2R$W+Uz|~)&9^S|izvCSSTNXm z6ea3^DN0`de^hPwrO4GUT}pm$OdcztfF*+1^$_v~e{%Z;uo(jRgrABT>pdLwTgdnP zARz(I*5bc>`TVk?WOR0v5~yh#I#hdwwB+7HqExlsOVE``nMRyO7<({MW)7nCB6oK` zVdv`3E!%Cm*vs< zcn!mHqz=l->G`c`2WG434LgYF2(t4jMd}RBJrt5KfYDz z%V6nFV3x?X6XC~as30L=HQIuME=^XWSI+Oi$@r4DugVzRKT~IDVPX*7b)Y{?K`Yy{ z<0x0CoGhR*L9M~V%J|A(+)k)IlY1Pyfwp+3Gh2-@o47(5U^Moo6oDd=Bq}Q%xR($@ zB$z18mtkR%AavZOuo9d;m-U6!C~w!=(Onpc7^u)~DuTq{niWeVkP&O$xq#JAb(|Aw ztL8`(bO(MB#%~~?KO;9x$;qNJEbb-AF}$ zal~0kAiW`F1EV&87M%$VVL6u--Lnm0kcV}eojdP!f<80VIHCU~^ce;+df>7d#?o@> zdxCj=0W*&pO1Y$ylFF2OdeyWFhhY~@;n<|qy1C+ij+e8s90u<(E8dfjkV zodJ$C6~!4;AiM;Bl6#`Rls%y3r#pjrt z8?l=Yfl+1z8_&bH`TeN2z!Brl%g9cXLm>o6!%0Em#puCVj> z9=!r;6G%gifeC;0*7fLl#9;JvwZSoDK$k3 zMwQW~Y=rgWzz(8#M2j5ji9p*__5CP&ISS?!qfa@-2Bm_RN=x?rVnEc7Nm z0`rQ4TeIH{6mLZjt$MS{%%}X5;r=B?XjNjC5y@&J`Iqq!FCRMow|{S`I^V-(@nID%CS9a znk86^K0X1^NN}qE9`@Hx)|e94>5rDzx4+Et|J!;L^Y6~>f88T!U3Y<^mcYoP6wbcR z(rDiH>ug7XBL;_KLT^a2B-?LwbSmdLQ~Pp^BWX_j<`SgweNd;yTEafk>%bs4J?5?C zgz{65Ei1>SyZaN=X6CBX?v*e_)Vu?6hvIjf2WTb!`HGcP6;zYuxeV*lwMsTFv~T0B z@JuJBaIE{9roO8cDwhwfsBO54tad6IQ6bL~{cEzeRrU2!j`p%YfqT=*N3m*mh83;C zhI)MGar4!e9(yhk2;!yWkRTCR7=m$~h-!)OcNFr(u&SA3DkcuRHxy-kv)Aa71>upS z%$=fU620ib=NJljM3O=F{nxP(V( zMrMkR68B=1Me*Pq4@H4{%A)efbrzF{vFik`#blI!mNaD&-y@BMhbi};Q~jjm9k%re zcm(+i&*FZIz?26C0l@(OM|qa<|LzM^u!K-NNujC4UM5zFXU$H25EXD%BQKTgy)=gT$n>DM2g)61I#z&)DYb3bQY&O=! z-}&_JdEZDMAU&21LP-*%&LGxaFLXtI(R#8ncukS2XvcBJp}$O7?Se7!jgz@lal$P1 z!2~tWTp2<2g6G6p)EYo;vE6h+eth7qU^^1jTz+TatGG{{yCtnSw1DHOHG3Glp z|4>ERG2gGsn?3?~bpwb!>;{9@gjTa(WVLB*oYa6wFzlIq77I)rc4qX1xlyKUbDNfv zqg>%*YtHybJ$>z8x=NGYq7PD8^Xx?kv~6vGrXSB*6=lJ%RgBo?2YpLOOyFz}$eh+# zb4*|~txwtJ&C6OK1+wT$BtUS05<5;>fcIf1feJh<7COtCSq6X-I+clvqSbEgpe~X+ z(~!3$5b;$JLM20jN)I7*E`E}ssLY*GA3mUck6Y&fDKCGZP+_cWzEE6Gd{$jge`{zG zE0_SEyd+Z2F7C=lrEI@j)KZ*8_;7=ue;VH`wq>-K-G3oEB6OgVQsyJ0=pI~8`KI#~ zfTPK;Ih5mGq6c=||TW|wU zL5~E4nW!r(SG>>&!?4YJC_eXB__UvAtqmjXtRQfO)9o^boYQ1=2*8M+)4aYwuV9Oc zl%Hq-edzqacMyC{g7?O_c*&y#U0$STe$p?jEo_z8;9VU-Sd=CDS#mOVPI%UfqiB|K z?@rhgYVbaF(rWPX*GMcXi!$yv!Vw49JX&~PQUH3FMbW!ec*A^vp}uVC+=B;RlV?)f zeJeIz4=(kiE78SX%yal|yhRBKdI@>Cl!Rv#Y+|@3BE zDe-}?cZaeAs+&iNG@!CXsu86T1gj9mc=)CST(Leu@v_W-@T@YK-k5}aK4Oo0hYfxB z-cxZ}z3~BmsP*E+`uPF?jvNp|1b0U39u9!}1QM|bU4_XnA7}Xa40=~`Mp}4qLvJn2nrW+arrV8u?=}4EU7nX zp%iyj1c+EVbXaK1IJ1~}?kDc%5=kAM28|gr(Gx_a*pp$rG0|8;)C~fjk4>4o0$%(R z9BX-{&q$8j2DzLLYPY_o;5=L%&N+ctW|*$>0R-X?g&+|0-gftr8|k)mH-PAq(lCV3 ztJA-9Vo@x@x9g+79#p+wDeOfJ4d8i3DlU8u_f~(?n|z$+#$J{ zj6ylhL$o=MK$|+2zrY2nS_2-mSmNuXA z!@nOGzrl1L5-=hg!XZfN&pwrp`-IT#SdQLL3stK^$W$enn~p6SW2Ht}>&bv(Az>(` z6MSuAM`1iUr!j)VUxAtTg^@ur^jt`*Ng)F>Msvt+?k-f3K*~p;E}z8i3wgRz*5Gl2 zs$W!CcfIYh#{f%R8jb(fZw*tNTf8>tGN!W=3XV$ zw?Z#HU}`~%Et#3oqKuEnE8-i8dvnGIiM<~!#QH?D$P3ygiiAmE5Agw7d#5=A*u{Q? z1}t{eaq%*-Ji861XD)m{xqXSpdRk8@Hgft|JdA+)@J#{8T8*?BjnrW_X>l};?_~QW zmLR;&Fp@{d7R>`D%iV3Iz}Xi|mahR{ijgZ8J3*v0nHxXZLeCSTm91hoX2S^I$Vtj; z0oxBMI?gMm$@9)|3A355BDdK{OmTubQFT%=jc5a@;9gG=aOV3#&b77?b7uMF%(X(Q zvr3731Z+=T-)4HB_BQ(wJ@?(UI(`Ao*-3J}DlD5drn*lXIY}x!OIn0vB%JgSK`ALd zGwcN2wR08i?lNm(sw>PiV=dQp{On`)Md@wB>-(5ZnY2zk*3hP~x{YuB<0q6zfjrTTZEpd@ z2$(#ijhK%kfU#15B*(1uPWcfS>0%HX5{)|uZtvycKxPCjCYhR9F_+sw^+Tm$%H91H zY%|#Anz1mYKh(hj?r9c5N8?<~d&r$OOnzV(;An?@ZrO!>4nbb7je#4Ho{1shqt zOnSsqiQ?-_mXzI4CCOB|q|+P~n=RfK^P`KDvgWswContWGsUhZecwK}x!aAXx$jTP<*X%@!JV#3PG|G zba2gi+eKauc0k2S9dChJe=H}N%9!~w?lt)J zLk_2RQQ?W<#2lT6nODcU6iNA8m4?xDZ!%}ok5~*4NTc7xomA?$`?uqnXmg61a*aF= zo2%S|9eee+hHenw&^@fkcJqlw&x8xAl7ygk4cPE=vzwdgUtO&#`|lEBi+qHy9`;d& z(p2CGbvqBXiQ%XUBTF&$oUty797hPWqO1(z9z;dwe;!rS(#(Hf$Pu>XYClB|w`-@XL)nK7yYQpk!|fOH zkv-3i8+|^%p{`w0Hz7ez&D$|OS^zYLT492=;)nKNYE|SNRwz`5(*1zf&;T5ME~q(Z z_l{LByWe9f+aZmgr&IYtC3i1<(X4`d7Rn;AidVyIOg<;@z@1NCh)$S`GMK?sMUE(= zCis0y$eVBl=%Z92cl?p{FJB`Q^)4);PHz=%RNJ0e@wAh|C_bp|9CA*fZ+{p8fl%WM zPvo^A?iA5uR7`3I=EpOoeca*L%>+v)Hr{>vjyq2r`~KG)rjEM|^TkKK-t8~-`u`GU z{p+p~F|e{Qu(x&j<6KNp`t4lwoq97DKZFP{No05LhzAQmfr4g~I+|@S^lo=2&MX`* z!|iW%ol+~_Tdy4wbrH)_b~)4#%F6#JY`Qd8eV>}Yn^Njc-YQy1GBoeDIXG{3Fu!oO zmZt6X{D_XZb-N`wSjMLYO&FFNZjBo^P=_0+oC(Z=eua}wkfF=hZ>OW#ETCiX{6g*_ zsC%gWs5Uq`Sjhi1bwh+qjtXTvumtCEfHBNa1 zRh_F#7bB$@MpVLpvD62!y{fVjl@ulyDgm!CW2CRU;N{|<)%*!Q%?X8=ec85sjUPG* zXX!T2^`=ju!ZM^1?aWK8R+)2QT4TH~6x04??L}(D&ZUd{(8|jS7b$jthyCXo;Aeb= z6@Mf4bL6qPnYXH@Z*n%lIccb0(E+K&Nh5=tQZxn&YP0Vl zd*tdOd23tJEoJYIf)yO#Qt5KFGjkG1a1xO_Y{b z8DNC;3sK-oKC3>pj{|4WG6gP!<^#?S=O0I=x!}Y*aY)wI$ z0l5?P;edDTuSYJQ5r`#X4BWR9Ov})((}zBT?mQw0jdTSmS|&;q_{11G;KfgXHw>ZC zCV&;tx8$E!!PRl@;Uk)7K$pG^2fJ416)=kbvA+BT3Ol{HI8dg7I(cZVv(~Z zL=ovJu-k;ml#2=qM$9?u(lO(r_va zyH$Erw7mk_k7v*6YAlAx1(1R$t3aygdGN`V8GNpeh6!d7q+vJ+Y0Th0<;>+}ag_31 zGOQkfdzd$7u6hblGG~Q}=`wi3&lBRn2o3hNLN~b7MY)cgqA-zHZWz#M=+pTgRX&9F zyiB*+mGp4n%DLWkP1*?&_uD-$Qe~S&i@Nsr9~xF6^kCk3g}k=~tZz@}zvdiOA@Qgr zz3v>G_`s^L#8|1Pwe%?XM(l~m#xLB4ZGc6{QgBPG{1*jyOK!uBk;$%mWN))0y}+FG zJ^kzHJ(_=U{Fxpkr>XtD|T3M>XDY zWfafBGRtXm)fZp|S%oMXaay#>?P$DT>q=0yhU;+Huc`HmB^Z<5M#UniYqO8xt>@jwn3QmqoYn!P2_ zDTXTO%{+zd_((T6N9waMmbkB`Z;@oY0y^>yU5v}s2H`XO<)(SF;mT$ z&J6pergXLI7%7U?=QRD&x1^?O4VWHh8yqy8`C6f$>65u|wqB5=o{;8dnH!Dhe}po82I*UH&qx7j7O2&(4R-3k#Se7c((4iuTA1{D95mlZWIjK4-S zk#O1JQP_^5Q-5*Fvsytiu@i$8bC?O)n3~I`aOXL5i%yEZvpoL>$$21_=UnAA6w)8KKoS$iH7)*G;WgaKHIgvbR&YyLHS% zk;@TY;34iz%5B=g+ggOXTh8_jN_qEZrpMs9s@HINTb$x6$ex>OXyd|(2Luvkto?R( zk<4LlL7=jR&|@!G4MXUb$`-hTv|Rn*TiHit=mt)>Thq{kfqo+&x~akn1rj9Dyo7eG zuTj|*oc-UhT|b|}qWS2rFeES-H8kaJ2(l0$j4&+1qw@||Hv(5D9(RqHs|D=tJ=-$3*S7b3d1x{z<3!&I8*nUso2BSRkO?@A>3|*KJ=b&7b zs;lojd&K~XfhxE?i+!G00)_BL9CAPP40PC~u93b&B2F)mt&!-+uFTWR807di;>K?M zhhG~=P#QMfxI8NSB7b>}F8O!&`@j7nX<}z@VEM1yu~-=?i8fkv&$5ZhiM&%nXGBit zc>GP;qg4|?wx9PZ?~vM!JpEWEW8sYz?(MUCa=N_0*4t+6lhzyeMw()oArRr|km2x> zz7nf5t{`zLlu)avppnGUM0)?z6)Gn1q0k;woAmPD?)O`M8%sfmt+24kF>rlG2Ty zJXRnDqJmn;M=N@MNJ~EU1Q5dJ7l{#7!o!b>75P%` z>!nQ(#Z(Ot&cCB?cG?YGsC*m;n!Zgje;iJ!oWktuULxg6Ui^(JBQ-~Pu_1ifY%0(Q zz+fV6tSQTbsx%f=BBre19Xp^P+k=Hvg&sHREIfo295-HBK^wx>7ju-Xb0D7wL{o8; zkhzZ1seR3aV%D^uHQec6lwg0N0(d25LG}Ue*bJhUV$jrHcAzeQ8?KGNTr@(zQcG*N z!NO)C-DIuT1o66xYbj)j!M?aC7TuM;<%JRYfD8AOX{-RQ`k+n%nF30UbnQCuO>5{| z8TVD83hhBSN?YpSq31KykOwohXf_GDvCSVI5Yz>e;1c<$?XQYHpoC{8gzEDKl)MXI z^qVs2pq)%MxjTxfr)z6xb82n>ptYgX5kg3FWU@IcxW5)rcSPh0=R|B!mHpokQqI&0fvh;ma@T4KX3O^tWgMaqBp3a$8kqmDKCks79(`svD3tt za-)04HKZy!$=|u$ce=i2=v+vGTF9sUvT;XVGPy)fe6(L0w>tVw|s!z>YJUs{?bu8l~JtmQAh~P@Vmqm6zF8-9VSf zJn@e>xk~j@O|&utHH|(x-H}a)*XajMHoBHz^;N)YL6!I@UFT>N7EJyoXUa8+`1~JD zq|<-a^}+DF3ZWonHO7nRkyLY)Kj&Wsrk)tb|E^t1ui6_KDo7ZgkOZ757s_>(^;K7) zp2)p%yUa=;*y?*h!47Y{=5YT0IzF~D6lgVua*oA|&4JH%H$y|(AiKFnku6#~;-d@E z2cGb1oZUKD20N4{#wK4g!& z65sTf85#K4E_FN3n={?;?L6BWEgp*w?d4MgA6hYBvEG-R-{nJb-49CsDa zWvHJ=clIjSGw-lF94w3g*-Bla#`Su{l}rWzp&Rd7E4pl6ZXxt#WXlMecFw&TF@I;0 z84RxK61o*nND^Ul)1{Wz5!Zn}nvo>kQTn~$qftB=1io)y%()>t*?CR+Tcav(qs$kT=jX zFmW`{7uB)UH~-h^=MgR=@th8^gRIigLP@rGF{=T+eJvP2P;pwE22VqPZZC> z;bsfMFan8TA-<~3YX;86a2Kn)<8yeB57zN5o)D0Lu)>7M3-X;vusl>Hz*&vzDom{~ zkqbsLJv|Muu(m?kbk&&BNU6hM-$i2EItbp@4b7Jyn%j$IC z)>FKW;Db!6JeXMednrAwkEUTO9Sp1(GRzpdvWaND0m&^Tilc7>!_bp0Fp8=Kw8@MW zXScx?C{l9Aw6${bf=QhgBLT1PgYH?nm$$ce+H}PT0qC^bd@K#zzBt>@GaF!iGmTPU z+;%WMwK9Hly!IYDno=KeaJpWm?4B9tFhMWM(KT zXQ1|S3%?BlE?2C0=|^%X*Hm-=c*k-LM}^ZzbpwP)d_HFWY!%zkzsv1()5F8d9kixX zEZ8PkuQji{dj9D7q4MZ93kB3^pWD8v61xhfoH^`aK7Xu(Y+=b3r%%JW;W>YI>cXO# znvyWoRxy{saYZ9?IkH#fijy=Q2~}Oe&2WXZ$=X>}p-*n$#9+R5Sx6g4!%$RckD3*< zkyqPTW##Gze}M=@0f*Gy66y)P#up3ivJZ4JP{3z(pI+z$%FRQtvY&yeC1bEl2aC~P z{VHJN)sb))9|@-Pmn3EQYm)v#I{{-IOQRn-_IL7WnCTUO?|1M-oPTsXLVqFn3KjGv zsOutWo8z7#i#hW^lgrWbTXGvcKbU7*^bFw_hKo11t`8vAp*FxZC^CSa87>g*!c2#F z17MhF-mYwoW26D&#K;#0DDzr@vdQXwUS4*m?CP@uU z`GmM7t(f=M5=|Q1)S@5OS7%_`5{T0#4NOvU+$nDBbmJwBIM6Cp63OyU=-OzNMxnGh zbZfQ|E$gbRe2rsfXARDB?PXIQ#Ok2<7;6iZJFKt5_lp8o>>s|mRHpYMprgAQ7fczk z^5Q|=A^N@(p$^WVh4acD`L(Bn8*_Qc-6QP+{*t;R|AD&v4kqUMkE)rWiP3NL^pl&j zd_1qX<}|;eU&P7d&x?P|5_^^eb1di=qajDk5|lWOeB$Scw)(97IbO5K zv+`_l>f>f{j(Q`kaQQcEiw8=S-3{fmK@pivh40u=Oe8Ucv@V z(Yw#DQ@6AY={t2WU39f6gJLz~v$!o+AuK6($Wbv<QSPxnC)*b&E*}?2fZ$BW(X8Ao0Jk{nI;zAE&~b3+49Vk;Zc{ARx+5 zrt+HOZ%pN1TE-vfLi!GRI`)rW{;2)>pXk3=9P+I6krXk{f2;8M$0Nr3v*fU|e*E(v z7})JC;{3PAHQ&R6fG9q}Gv)uM*Zk)*U=!8CY?li)E zlxPZ%(nbCW9GuiYyWl^^XW1dKzkif>ZIC~1<^sk4g0KImYtiWGm>XE?>)6r={QgDA z(ZKRQtQAfw7^d|RD-i+&MEnUBs_IW+{httdT0iYaTs8K4c{6+I0Su_2g<8pEobqqbOR~ziN+LM1g=h{F2UVlB|Y<2#l z^n4|EK!WvnvKiq0h{~b+PptOOQOi^kZDAh;lndmKH14vgA?_DhO zl&|c5`XKxzs7%<()a6SQFaQIp9KS%n$Ej`l{ zBwxS3tyKIu#P@y8pGqOL(EqjD{f}7Rcbuktg2fj8clxIPIPUi?XrJn)uu(tPz4}Ll z?|X{AdV(My_qQ6`{+mMjUBkhrQ(ue!xdx>_B79%RUib+DUdlh!#_&hX@9UO76-JcB z|6INNe>0Z8D+l~kV=5~BCn}`>i1&Rd(xoMEJhU z2L02w*Z4El9)BGF`{D;rSJ2S^bEP|eMEE{Y`l%@yF!Zw}6@J9{K7;ayRgC>y0`|Wt z65pjMy?%lKHT`$`zYoiMdQ@p_|D6EVAIJSZM&{|>iro8|5WgSC|K2D6|1g9bB@Lz5x#e1JiRf}zWHhY(2pSB zU+s%L0cpMc$2=tec9rnmjW@#+P}KXM@*(^P@cor3$rAv(hyTxObXf^-h+qDJ;qhaN z`iq77I3CFV15ir?1PTBE2nYb?qIpR}G!9OSJpcd)P5}S~0000|E_8TwrG43w+&Hr3 z`~3=iz&r$(*dDc1b;(95=_=JFvmP4@;{s-~D-G3i!1RU-Tl3CqmZHh{s z12_P8hXZhe?R9)rT-(d5qO49$QHxW1eYN?yZ#MZx{_nq9^1Qo`9*~59$G-b9m2ztO z?s6)-aqKRhkcNa?ce~$C;yQ}nV=@-=vjz3$A!K;!+v}fBKECQL;+$I}C&uj}xUsu= z(4GUSs&Q$D7%(XA=uwa2D*CoMRo%5|`%5vl-Sx!&QNi^uUrw=5PFwN3((}5TxSk~H z_S9X)sp!>^GK?z5xE15mDd8yfEG6YA!cmH`>t9uEU)|3|f0FF_O)q`p=`a* z_I>gE>ehFUy%>hmaBHu!J5Gc6*IisIVc^2U$FYA^RI2hfMgOk-E=S2~WFkkWVnFXl zad}fze@dOdUu%!88SH1J!e5`nMR?qf!9BG928fbF+|KRzFg~9F?!e(f$ew|GElLVZ zc_2b1JnF0XiDk<;WY`f$2J)?~AH|4(1p(^u4{Iz*zrO3c+q>=u#*vnOD4v~flYkxR z){o+PS5168Ci+qYOFG+Z?f#}2kHi5s0#id&Y~J$ zpU<>-I>rkBRP>A}L{BwV*&{c8MDaB`l$Q7&h507R2dQ4w6P18Cgiqf^-<-Q2oJt(Y zFi&Wung~lq?{nX2ANclM41>1`GIW2m;s?TzemY%bh12t7gNF2bJ3haC>ZGRjsxV}w z(5}v+AK$gbxqCG2{hRFaTZk7M7XMa97>4B~6$uLtORO6f6uKq>tyRsKzloy$Ag+(& zlf&dS!bml1Mht@Oy^r17?s7YeQ7BJBdq;q-EU6A|D(U9U)A5- zux2rcQfd#&A*{#E2c2Dte~a_!M_c>nNdo%0?0Tu6XF0pG(*Up)6DG)6g#{iM;P2v5 z1|r{CS1YzG;Xd}onZ@rI{O4|HqZQ-~0SUdwkk7?coFAmcqFF3WF!D=#lPVQXOBpE- zi9|X{KYzFs=d%YLF$gNiCSxB%<=AAvy;Q|T^u-(L3ES(VLu?Ni@wMn>r0}8e6>X0Z z3@nG#^tC;MB1-)DAKetxtH;2wswYwXS$02BhZP7R>WB%$nx5KoeL4pNm?XfiRQM~0 zuAf#8N|YUbd@_b{stS)v>nJMFgS3j_0z2HKCBdPB4g_#3>KYDZDhQ-6>h|vab9#&* zPB+n40_qm&B!^VtKk#H}v4Esy=OII{Kg=M>^=_f2FF#lt20O}uKMf$VPZD61m5R~c zSJR?LR=D5er*fr%%sPRc*PYMBZIC7{C%NnRP7GDw-uyaB!kdD^gF2gI001MI<0r4H zpnK{AdTw0W@10z7df!l22&IJWyYp)m02Ct_pt|6ZzqOA~XZe3nbIBud)wltld%1e- zpFLp51Kt(=pB}VFpobsrSUr7xx?f6MVU3_@)v02nVE8VVb__Kj=q){}@2`Uxe*u$w zvga`$L<7|1z=OU79hn??l#Bv;fZBy9+0#tiTf>&!hq1f-E=}aIU=~;#Fxl6lDemX- zzwe@d{teC=dr)hwBd^cBXhh$O`ZIDUm?2n031ZZ$S|)_?Y6XW^ z+F#(Aw(w#1=pA67>GA=)P6Fghar^pw0|oElv!7;0LfzXO0*syq;iR9y@DFjjpx-WXI%tjla*76g&ecWZbIZkwBZLdal7j>z0k`@(IgiU# z=j&_r1ng-C>ap7czd!>`$m3v1lECojrZ&L11xbo9YWG`3Mxjfu^9bx)u<=oYuGHt! zbT7S15G1T9DbZurq@mDqCKLU4y>a&hqE4&fB5XxT=8D>m;1ob!%~TATTneoN6JvQ0Pr7Rj>?DeQ7|rK_B|4 zE((Lx0z<;bNBo#s8yp};EvHnQBInoTaT)x^ZM}OM6jQI4@Rnf%0o{++!|N(=I=g)c zu#>B=Vw;8laAy&BhhPW?Y3pI|x8K00Em}+z;lr!wr_*Is5!$5B2^eWE z>=Jbk31i&h{;1|qsZn3LAK1cS1NFY$$MzaJ z_Ctmt*exD%j0lBkHu!m@2M(YI)ZXyx^Z9LY1KZv^^xPGpk-MK7!zqQQ84%LPbkb?$JW(-{~px#?`2oEzH zwgNu=DAx(5bnj4i5b&i_uJ>=!ImvJzl+r+u*;gWJqH1h6hmk! zU@Y&qTFn)$+LrkaHl;HVZQci=0*w!CBdX^Lbm|T$)^|Mv2jL1R;)f1=Ur#AtzVr7{ z%qP8!@Ef&i>9 zLM1j)Tu|O|gK@uiq3=C_iS*x}RB-nxa0NT#Qc9`kI*Zlj^+=sRiAyQ!lME8AE|qS3 zY#y!7TTlNiJ!ums=`CT&vw!<86>pG#tY z?GeeWB~SPMta%=Im~!JUVUjn}1xB$A=wwEP}^(;h!|{Nv}Oi)Ahm%YOOcczGU-4 zcG%t|nWeW^y^j^EJAD}$Rh`YUBUR?>NT@2P_Ez5`&GXi#^#s26E`%%%6E z+*?_VJ8lT@L;HADFHntFJzREPgQwGtJM&mUByATfnN3&SgSIs*iMUhJ%{(!#Nog|6 zG?5A0KWVy}i90CG)>3f~rTJPW>7wl{(+C<&wDY5=322Um!>0!;@XYBBKUPNTAMf$w z9*Pew-eiff!+E4IwXH2!a1nqnFPJCN@+H);o6;)Ijnr1JV4zAwK(P`rgO)ZS@X`*0 zSq3>swuwQAmSqV8HHV1Lr}EL`pz$oWKg$--VUsdwB#-{!rg2;E?vYo&3~HxaluUgV zk!!z-gQPnIr0a@lIyc4qFRx zlRYSZrLf#)9=iqDe8XXN^$CO}QCJ3HX%q(9l4nuW4i=V2VX(*ZZ5#$G-9=$=Ome8F zU0+-uy>aJI9j7IycE7wX=Ep^RsEB#N5F%xlb5K-l#bD_yme*034GJQnh}AqKR}&@9 zPbu5YdSY1RHin9kZAggL5iFvF}@GTn&NA_Oi%B?_FT72vel+T-EcVEeXEW78m!oz~dQF`aD? zUK*)!QsTKfQ|uNHccxaX&Gs}(F3cKxjuj~523xLuB~1R?tBY1>1=w3mgot;vI}{Wj zbtWkm$quecDqhnA*ppZ~)Ju2zdUX2?b9jFWdvrSw1Rrk?ws%A@W{OGJz};M3oNrGB zH!&XFHpDXP92iH6EqZ$MNWBzc=77+JrPz=Ig4u7ftvkCM@uS;?Si|c>39%8X*OLsv z=$-SIs2?+Ig_t;Jh8Z?POlF5J!zSpCT+E^U>E9lTjY;dc?u<2VBEz<&GoJM|9j2sk z)G};X_DD{h!)phj)Acb4n-e6NeT^2Y$A)lBj265)essqT9_L=Mmg8B=#W~YtY^{ir zG8AmEfD#@-cnUUIPpOKVxeJAGu*G_geM^;X54Kp!;+ljFma;O2g{_vda)yO%*0Y{O zQJ>qZU`W_rJ?X5HA1NcphUys?X?AzUwsUNrkRnZh60l`@!k}^!83r~`z_^#H{R}6r z)h;x1j(CJAXGeDk&XGf=uMS&vj6v%P1cf;yy$qoS{+5QL+hyW;-ThkWYxW3hA7|+) z#>Sh3cZl;;a2*r!I75@-)qU}3a}X%EnCD7&b`w!@Ny+BL;FF(Du_xTDA%)A9YMy~^ zt2nwNbi>d`pVPwD&AF;Q?mok#+f=g@bP|c)|2?|RwFP*1NN{v}YnGA=F_AZZ6RG2|L+74RuO^83;bV279*wN(f)%L1mzOeA! z93z0*l&a}64YP?;DvRrtU#b2)UB>=whRBdozkL&sz&52CB_{pM^ApNfSquL1Ifj$+ z9DNTM1JCB*W2dgk)h*jhCvm9{!InwM)|0jolCc*?v>i`yhbO8AIRMjJ(y4b_n4;hC zWNJ9f!DEd-t|h_77ctT}Z4Il-C|D&bS5U7kv*MZ4*+bC2P2zd=3wTNDd4lpPX(T|! zTlH4QRUM^2dRntcqdOKUZ;~93c1*(9)wIDkXO9VEThqRq%MtK=@6%I%Ua^u3oO|lG z93a{6>QFfuQ){)qD!r$=;7(!8Oed>Uunyu`!K4ch|@1Hph^`7??R70BF>D#>OZGHJ!07&2g``KnJPL?OPp@Ftsz* zwz?!F6k~y5Q7%qr1Zd7Fho&o~M0orFj>ZgPZze z0!TEUoq&@Op=FFMnxH@hm(88*45t2U0CJ{ymv>4TV}KJw%|1;l&h_l9nK8D=rdfCf zV~G=^kHp#;V~^@2yPfV)Vya;b5>c3X7?U)~`1gKbYhmoscU&=DLCV&}7@(&HaWEn> z=H`i$pPsFnu{l!0oCJ*35kBoJY zA>n3W>i6&+6zmsz5Hb{-uC6UP_+*J^g>#Y?ED zT5MQ6cZytsdbilv=DA_TTWp3)uZ5(33ww#f>hqSj(n)*HQ1rn#v+eM>=R8;Mv*}^xJP`!(G8*ov@$bPv`X?d_% z2IEg#rG8U-qDh9HW-4`cil2{n8y+?kernq#1fv$nCI#e_=JoCL1GH|J@^Fn*;PyM&^GMrt1`$k z*S9f8$lOU{?e^m5n9^XTJSKATSG(Q#xf1kX^!7YWrLcN(x=213Q|+-PWXolUW~97) zk!NHk#O)%H?WkQyV-K%wim$m6&R-o+yG{I6bbqBu?Y8qB5gr#QIb+>=dIsgmF^;yj9c0c5^rcbg$!SVtQ4j3|6FfXk-=vyOl^xpZZ-`c)qP+@GC{yF9?>b+Q zo%ln9UD5m65)K3}TGMxiH4F+t1cK;x{T#!ds1OK#{Xq94E=BLFV3f5ngu0naYalMe zxK6)X3j{hu5YorrOAp&~FtWDOx6uZ}XGYlO=IES6Jlwe-0DV0=Jb6{m?cSV!?oV0u zW3L7()BI~NCb?HUd)c1)t35Q(fBhksjlL}3`FdUu^|!vb-Gu()NvM50H;|=}=6RjW zOc&$y4t%6kSL`3iKJ$Mr;GgX`rhM1C{xKnoJy-P_!O6uCm|KdF{T1=R4cC(kNEgd$}7Y z^OY1Y{3d*WXs*;+R9z1;v3jVx+oOk>4I-!W*eYB{+f~YM-NozaMu4Z`JJ?|{yC_in zlu=R(koAPr$7lLpU@td#csFsD&gZz?q~fb>mCN*b0Igxk3N+qX(!|X?(cT#!IPG0C z&$-%9#^IjXZ|8Y8`z1KS+b!_G`z60{k`IgTLxY8(N=l zmbswJDrPGNqMB(4RokS~{hwM{-1DXdUNk$vKeP6I3=q`53;!JWd#5yLB1oLlJ_WXu z!#}GJgZM{Im!6)>z6D+9e5U&ji0%p3X>IeR1I{9IGKH3rJ3VNxP3Jq`=^{-}l9TlJ zw!04~JyVP8Xzry9-EKF|Dz7K;TG7D2XTJ6f{vFKqS>+!L{)>RR>JmQE0k3bQ6HBcx z3p@Y#S#w|e=fe;<4k!7gt!pqZr%reDjrzB&e`}syGwd> zi(F%k&qn^;32;*%GZ_Z$$K)6qXJ)fJZ9MLKwvMqlPj)C{=peK@6fu}`2UExt${`jh zcqk6OJErWfDFN7b*^XcstKPUl)pXCJO__{ybXi1B!LfuP$@~_qcGf0eB;%%S|?^Hy75iZSG{|#S2@{Z#gt{Ql`eyi zK#Y~<@IeRNRqB<&-3P6Eqy&E-@8*4HHG;$nVo9w*{hVd_zl=za8|E#3cmz4fzC1t*(jFuER z35s@5{uhe?J!3S{eyR|?BVp!2xAKx}&S^||{QZV}v}PnT4DHubu? zTg&#?CS+uD3=Ga=V7Mc#k+Dt!Th3aXFsCYW#)_C^2ioKJtMI3ANvxR%!i3kHP|1!M zZ;{+P!bzjD;@2E$EGXtex< z*o9dpf}5bK^L;um%iMZ`5{6cWod8FSAi%i^A84fK5_7QJ;I;0|MV=67lML-;8-4_a zQ>ylGJeAl6xb4BCh#iE>IHGPzXb3ch4T}$zA1eM7A$e?|_-N1CqXKnj_eMQ7&~>@8 z>3X6bfpSM;#IQ+$f(NrM-1G8yv4E#XHJa8$X)ep5l#!V(!?DuM3s};%tIu0|abEC zFt8Z6k^;*v4>eYDJIi4FJm~EN*^Z_Wy->lu-bp&u)4A>D;Nqlt##49i0VP>MxwO~& zC;%y)CH?67dO(t8D;P+!dLzKAI`Al6I_z-$TBD~OSJM1}v8EL(Y39$KSFYvhy-m-nR`T@b zwWrmDrd|p(V|?p7^G2L`QBdu^c%pb2ksr7Q7h*%d)0Dr!>SPjH;q4~p@QZI#7U<#h z1&OQl$8D_xu5g#&Dunb8_S14c+idTG;F*G0R=SquzjU^D(Qrs(cSFpVe}gwf_AW?X z&ku#>`fQdR3cp)T*YRgC0KJf=GmIv+^D;d8Quk|1ZLfn)mBoE>cxeG9_xcICwdDAh z3ejID1|3|yxRkJm%k}*4#kp1a3zhnQFdFCTFBcPvQ?D(@n3vWXeK%xSj96dHC@1ni zt^R~&xH^-KW>LoBp`6 z?a4we1GY=h(+B@PiX!YF!JTw?xZ!*JehJ@qw|CO_*?c|CIRMTZb;IRCBaW-^xFrQ) zt!PfUio~?3!o=yCZ*|wO&R^kLRxh&N_=^Y_zQFwOo8b&4TTMB=>FVdi6Pp(iQ%B4< z>xp1yDL^E=%zRsb)mGtNH&{b`XD;3KEzQ%HazSIWmvS@D&0osRJ$JjB`5J(D=D1t#sA^~&&ZN&(k36Ym%0J?MR!FJf@>wsJ@7T?FKx9^iXeS`gw* z*A?_NEQNU2cq!r7t@n|dNC#lOMLn4Nt9{)s=tFz;HK~2QZG|1SUGJ&Qj7Dl+Z$#F7 z%&R_cWNa2_;JCIt~~+OGHK(ZWbmx9dG0DHQekdQZleL}goV|3Qf=v6Sh)^~y|3 zLrq<;nYJht5o}+qV5R`lMaLH_*c9}=cL!s#m}0%fEX+UK_4CET%(GoTf7p^9^i@>8 zfc4XWEkHe2Ir^subBq}D(RRt1Pg>(j{l#X%=*ETpy)<}#q=`@`z zp2URi0hscxury2uSSWxeUSZEEip_;@J%qq&)Lme7V`&Hd+{ow8rR#fW2cMv#3ar&kPZ-xu5JN7B!H9?=C_(F#|+>7EgWWZtGAi>YCy#u2$+pcz&ph z1#uaFB*~&#lNNF$UJXez|435m-(KIxPW?QKQA{4)uf>Utvt|5Jx1&pT*F0k3f22fg zZ>7Yl88mL*j_4UjLhgWgyC{cLM|&boqb)iRr_Z4A))nzpf23Koh9lE_g2pw_=I^5w z6toEhj612MO`x1mrjm|*ghDE#J+ObFdY4>>ENgd3bb(e&yhce(B2GFzbm!Ku4ofl* z%}~D@O$`*QSvV}rrTv6$)uU_tN+|y*{jWAAc+@~5mnaoVfWEtv$uZk4zrj<2? z=zo-+fnxyQcdJ{1B{(kIvSo(rtsMyhB0Ok}I}!rKNqjq(J6-*w4i2XFs<#8)Om7Di z?hcL@6!AqR^dr^T6HmWX3R-TK%On3z=a0TtDbHWK$49XG+AP;j$V#3IXhFF=fN=3Y zEpmMikcn$WShVcg%v8rrAIqwPsCW`t9(P;-no6qWUS~=OI$%%c?6pOZy_`LnyVn#I zc+CB>?VBRpri-U8&y0vlXPN!7!~W0?qb|Xm4SMPtMH<5SVZS^*O&q8Bp1eFcIda%h z%buC(-DNj7*RRX2h3nI5*`Pn$t23ZgY?l29pq+jTFWt~3ESvTheIY)qcE4P$IV1^m zpjx&+&tkk#wQO|6PcFC4Qci!rsyLy&g6Vm`?6qdMArH$w>nnVPOSN&?D@=QWc53_G zy@llKh064{=gID9T1#rx?i0}uMo4ht3S^SKz+s{za^bJNV?&|)#!aOj2or2{L$m?Vo>+z)J%{z!7J^y4BHmtJs;MMF;kvRqt|8&Puc}zXA}L>0`2ref*qZL9iC$Ix0-De9s>B)^ zN$;wfH8i}asyAy`;ek(`tme@A(p6l&lA2E*s-lGFiRKc!Nb-y~=bKMsbxP&yC+IlSaL}%AWb0uX>eH<8-fjl}*Poz3Nq_ z9rlY@W!QXTkyvHm^Qm28m7y<2WB#t#R-sVBS)T3QHTX+ve0bV>^O_k$0-4jxPH%`~{KggKNM~2DFSVju? z>TW(Mz&oZd;X~s}W`^*a{2`aD{xIn<cXFJM;A%=un(;)A6gK2A<7>W6 z?}3Fjkj+dDj)G#OY{vaNPG}|BT(7OqX>4XD#P#Wn&0L$;WimFn3$$gTuEnG7F=+27 z!$WOP1j1g&g9|{oJUm+%zY&fIo&!7vmlimPNa9Pgjf2=+&1N@4KnJ+Zei4fj0-M7! zgCy}a$3+s&+-r&%QrMBrOh?Y9R5sNz5%pNTl7ah8tmV<(YgST8A11-cG*A7#Bi)h& zd99en5>i5-{+%kp$qQ?SW3Q0^UW?Ipo`F%x4t3q-r;NszxC0iS-opU)5e(tOP;R`A|m z;oeXZB$Y-uzN)ZIP+x)|{c|wm7YuA}=<8MZFr^_04o+96#3jL*)B0?&6+k-1ev_DS=)vs=p9Ae_-xj^Jv}y|WwT~(`E%1+Hf!v5;W6hevK8hZ zNhwUS6;2?UADCn-+yKe*OR^P)A5Zj4vK6LJli-qUg|SbOvpck>UNc*;`bak~Sowfd zV!^DVy?oYSXT~j`wNtLw@>$bl(lV2L))?nAGLwAP5J@s-lF!;5 zqk{RYvCXAmCi$$TVULi{S{T-HPn)%@6~>Xz+E_f{Gs$PIYVPD9$!ARqrFka#tYs}` zcqTbxVbNW4rcr+58^6eNVA?^@bd#NF4`rcUcHM^m^M4IXZw&dN{C@_fKWp^A{O=6> z&cW|3_`L(a_u%&d{62!;1^8Wp-xc^>gWm%DZv5|L1AYUUlN9_0@+Uz41jvnDXFwCn z+D-y7^j-x7K|&D-z4t28i=Ze35QNY|?~u?z6l^F+N2MxF5Dp*^q^NYHcaUB~lMY|F zUe7t6>-Bz<&F;+X`#kgPyEE^vnVodNJ~bN(G^2+;B7C3#+J zLQO8WX#9OB6Q0`wH|lC~C=)q>Q;{nQ#nQMJOLNg2a-30X{=C^1JqYtZBq zen9=K=#lTMFZ4+B$eqiTy0`0%o;9lVvIY;euxk0p=IdR!72CZIafo` z)fDo;#sjinSMFqnzH^Imj)MQ;?3Ix*?h;qcis$VUl&mL_a^bL{hLIv~Hmugacfhqb zuIFStYyxsxZ9lqx2~t;)beIYaz>avl1!)5akIXg9vcaBj9A4%fo821T@=)DS-s|-r zHwwQ_Tb5g7d$s9cc7BllA!Xbn`R95Z6+Nq12S#C7Qzy<%0yP$qlLo6g*kR2O|6M_A z7aHd`w@DB7q0g1gClv6Ww)f<}S%bxBhtdsNuwWSsI(U4{TMTtIX7iz0mnqg|hEu^E zz1EI<=?tn;#aFgzVk3Fwt29-$eYb4I=#{b3vHH;PNwKdl4gtwa)XQ4F&R@EQhIBb{ z>1WEd!zhJgJm1LM94w!-;5)yq<>qL%jb)E@(NU>#l;&U#vl_XciJDOz2?)c)> zg7gG&({WpTMb=W)ta<>ctZgG1-d;@(Nk*f=W}0L(F!)jY6Hu1N;~ELFVimZW_Qmk~ z!gPj*oO4$#hxQ**$XX)k+isF$+Wjm+X&&_#eaBB7UjI>ds1;D18u5^wY7S9$!oH+( zEv5aP^Ci`uuKJ=*PhrpHhgU4Vy6{R;e>0wQgx`W}9fzU@Gva)SYSfnByMg*+7bC@_ zRNtlBrKD+B-%w}pT6hsN`d~72*iq(P(~z7YYr!P+ysN`pkU1V*2~VP-;hs-%r4D9V z+?FnDQg~I6=;e9540YS>mOof$-0zsVw+Z$RT%6CQ!7mrICIe*GJ^5yWS|_2=?u7`p zarF>z=9nuu1OCuqQ~)rpbg``JYm=_@&(C(RajNP_rccmSgd`D8cq+7;jW({ZtyGk* z#yIiW5*_U1sA%#dM{1>G58ey=(->gh#M89-@*K$wQfXqIULm^EMALSchrr*^GK+Dr z=M%c$PH|ZzW5@M@aQ;r^HH;G)5{bTi3>mUoYCAQil@RXaGbnr91T9uP$oy)sqIUa| z5m@{q!@-?_X331`slE#Hb-a=ezr981!PQyB<0Ow5yHRO287eiqS(T znG|~?mrtnc(sT8Pv&A9SSFX_V*co$E6;fic#=T?Y1@w|BSqrGKzNq%4Z|sHM!qCWI z1^V}6rOkJAL#OTQ4@2w4UsHoCZXGfT4nDrA5uGFn;Z$PHQAS_k;OY1X1cHrHyzo3_ zPlmcTNDQyn`!Xu_H2OtI1S$Q)JM6)AS<%MG{aTk zatxNTXPYzAOFw`A z{_~tfH7PskOZ)A~x@0LjWYZ1IjS*6UMa+q&WNnurbLFqJB>cZ7pP0S#7dZ*5lou8< z4!zPjvOJ|K*n_a*^2awlA=cFrG-qFN+7!o?(485;X$I>}Cc*R-4d zRZ6oPMy5gpi@2TSLLVo1(J&h4?{%+Cy~#Q5VtPxy zOKjj1DasOLEf%km^F?%JiLqIY=EHmXiQx^+x=SMWs@9`Z1$(D7rG<^Aq?=@fa^M!H z&zX0ju&`?j;az z>nwwH7hHq|^!=<^#Kt(Amk-i+Lq_P2u8&&8zYrzp;-#Q;3Bel+suMbmZ@zbJ{SZtp8m^`YxAqiV4--%P*Id4( zHfBc2g*t`2H*fU@ih694 zM_u*Ar(!hZg5K$X^*YiU#vFrxq>DkiHe6Pe0;POg%Xo_y=LKP2CX?)E8IyF|ou{SM zHvB40RxiJsO6E15meBWDL^9k&-11=xi18&${B&Rd@70TT?T{V6p{qnHd`uoGX~N>I z)=4a8pcERv64lhK=DdLDEJ|4n{^#03qk(GAwT$H4+aK<&9em>(P`~$q{fdpo1~5(c zo~I#$+bN&6|Df5eK5?myH3o$ncE&8%29Ny(Aw~VwR2=F#)?mTLGEki(mdP4ja;Ls) zYN{j7Wl2Y@`dw~viRyaY<5qEAn@a4LLcZ&?MBKdPl*SkyN=!jA<3xFw$?m}CqroX? z8FrJbUl-Kj!$hp-JjEx-cGM+QeptK_rd%4CeZ!&U#`Z*nLwnh>%7E31@Wr7p{#J9f z$VahQFGH>c1RwoOVrS-r1-u|IW_YO+ld$b+C53`` z;e|_uK@^N~=SD45`Lxnh;K*GAm=$(Va8heyD|y0hvIM$ZY~4Z5mRo&m*x<#LL2}D- z`@4sJy%IYo+4{az;K3GM`Y1ehv_9s_NLg0!)=>wI_8b5$ANHE+!Ul|!&eh`*`or}x zd|4ErD+9&*WHBkpLR=p&xjSac;&X7MaK|+i%6P=z(4*Et zUi#)k*hXF3sd78wQ_l1%$BSrH1f@TMm)&^5407CU%Ea+uvz<^gqwUB;3Tg;--mo9I0jOX-ZiQcZ3rUqE~+Vy;RC0F+O z3}f%D0gE{19S)%GX;k%gOs+&zaGcF2L4BHL%EL&KF?Y4Z&s>oQdt#NBygttYD@$jTE0w1DJZhgpa7jL;TvHGF83J`ZCM*^#RR%UwhB>;ba( z@D?z5iPPkkcNNe)Cue0`p*WD@BTGms>pu>qXm|Wg6;esie!Sud$AeRX8HImm>j0bd ziYK6taKJt>8wxlBLmz=3{H=28vKsgSYa9}HC*+9pK^^|)GsP3Ck8sew78{E2uS#sH z;a_FYrm5ly(MLFNe=0QVufkqiNd@72-kGaZjv>T`!>u8FzL~MOsrfdBqy}>WfLP8gj>aWVStBp` z0ktph$?5KfF%w*4y2`D55xMH_duT{P)&a6NCC=6Jpt}6J){WquP%4vUi!0LC#v>?a zYHW4r#k{EUi}e?fPDBLgblAc%K1~D?adL}<<3WIKtmr5*Fe&cS)2g1C_n#C$n+nV1 z-rY3bR?L1C($`OY)hjlkis*k~@kENB0RFASL~5WnCS!ZB;j50?I)w2^ zya)eOI+jwMwTAJtP*zgfrpf$ErfKXFgMmbR#jLvY*w=feQtF;TF7s0C?uvd2NB(Qu zwlbbmmXmGHW+tA&##%n+9L(MP$cwX{@mA3S z*dHb3&x+Yu^WoVmJ#gz<4$C6xgzdK#LFS4{>)Qk-TbSjm zb)9aLeL5=IsH5>6!+KLlEwxw|6uRKEL6p!CFd0A|igIL4?~qi?W;H0`J66|Bye6w_Xh#K(4rzUNxE zR|N#*@FeK-*S|K1Fn^8ru3@K+yJj1d)SXuGo}uNIL)pB>Zni}%_<8C4aeQPRKxr|n zBvB6LhZY@42&jc2zc>fnL3;<{cCS-h+w0#wnI6?N+NWI4DZoM*ka=M;pyIww7LkQw z!(-qZ+KNC_3wBa?o*!uyHk2Cm3^ClKttuRrZuaSr=q;YC)m~_WPe^(GVJxjja4$tm zt=_Ri=dM`1__@+~FgXu)*Htdyw0`f!h-f zhL4WlKa*$g0Yj5|CSY`pfi+%caZR`#!*0WU@-7s8B(PObQ|!RwzRr(;iYh3dJ9a!Y z>TSLj%y;ss21SEcVLDeu3FVSteTCBC$kupF=F-hA%Ij6hQId1@ zN!-aQ5fT@vz;|4s?$?2$Qw`7a+riO|k^F}6G>uW9FM&+>TDaNdt3AZ%aPLqFbgy+U z@gzGSI{Z~Y%9@rLvm{kKX==4iy!HeE`pcYksZ!0@&3j%sd6NB62a6g~$ch1p)Rk7^ zw-}Yot0fCA0!@tk8P%U?@z3~~=Ofybj{*D8M|IC;Ugb}XnFPk$K2aWCcw;cGwf_uWz-b=G)GkB;lDp3CTF-1beei;o- z%=p>|p%w2k-B7zyO|H*HK~rn@!4hidWCd|~b73$vb={#$41zr*2v&Iu!>kh>Ma~jn zlhx_(b=Avkvs<5Ewnx3qBrU+>%xg1PtuEoES9?!ALVOSh(;%OaJ8pp1c4FHu z=R`)@y%Yx_iM&kd=)BT6En*HDS=g<04O%ke*M*KN~6xciG~GiSC5?hu#5kCH*J zn~t+5ZW0vIix80u!1SmNEQC7;in8-#t)Grxwa6++*hF;gV%5~Rcos|sX$Z*fNVrz} zKk6!|tTfbnwO1iIBJudP4goI%z`s^&&)`;T;}&QGKxZdhg5dsE9v-%y9xyz>e>Xc@)NO^Zar((< z=^tG9I3oua#BXiRh@24C-&+HMXz;!-BL5W?&Jvd>0LMyaS9etC;$LcbpU|p-vnouvXC49jRF@=kgm2a zaHI>|)gI|$E8yy4_d8|8f6|^Qv!eX2%-hPz>lcp{(2>qQg9Cg80swzK(wUxnKLfwx z1$>>Ie%ChXPi?=T`q?Z0;SI9W42m=y1dMC_;-Ap7*1P@*{mBJzYrFrY{b3qWg&w<194kB-L~>XAYH7S;J1;^u2wF%{I8@; zT1H2h;}|;$|H&vs_mdP?TX$!KhX;-Zj&Qkygu5fXTx@>D*eilk>cw!tanXFBO{se}u)~fqr)Fz!~T)Nd6u2`^a{LgPeuT-ywc(gzYBqdjQqf U0-rk*OpE&|;B3@zHvoYD10>zvIRF3v diff --git a/wear/libs/wearpreferenceactivity-0.5.0.aar b/wear/libs/wearpreferenceactivity-0.5.0.aar deleted file mode 100644 index 66b3cad816ca298c74a9f5c4d8c11fb1bfde068b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30815 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
    _-*d@4aR*`-ymGUIZefFFP|nzdXHn0vf$#)e zZ)W%~?wm}*re^MFo+1$$0Qd9VFsFd=1*#!GV(S4M6{3VcQ4gJZC-|#9`C&zfH$oBo zxGcx8ySLi8pA5S$9`j=kSxrBsWXVk%&rN%x@LuA(t;q+DmMAhju*}MIb4$mh+RiiH z5&ubM`)4=flD{Or0{M?UmVc7@-w%HCKH9GeKtVy7K-sxLxw%0pNI=!?eJm6msr{VF zQImi=zg-$C3Mg7?St?rUI#L@wN}6h#N|NcW8EO)ffbv`II?DMtnCf!bT}q1iKzD;; zkbpV{Yjg6w>QG0(!SUexeXkOo|ts0Gk10e);aY}wtdihQTETv3mV)>5BCMgsc zm>3ud3YHO=06Jy@FoIm5L$DD_0*`19u)-GR1O4`I_vxbVI&We~P2>lLdHLPq#u&mbV|Cin%c zndTb0kht^!fGjWt$rLa7OX{#ODikEwbm*}NyXoL1Qi~ooq1@PmG7N}8OOwa?k|STt z!ZPDPulnN^-p;wX53O47XZpqFdXR|?-pn;yi&ZhrZT*o7E)m<3Kw2=(mB`#dhdVBC1V6{7Cfzcw1~yy7@Lu$11n}u=IB?63 ziL*|PWs>d$;11`MaWl~~>8VjR=FQ2bOJUjU@y}ixb%fCdIXIU==rGz*!GhaZwpK)j zZ8>dq6i$0`8RqjAInb{dEH`)x1Jexd_~QATC?ae-->63Z)HUX)A>#e4Cc$N3#v8sk z&i0k|{gsOxhBX3wZHg(pYjR4Dr$KBq$+$x|1%cNtu-XdiC5HsgbI+o`k=|E#^_GIc z>P$RetCsbFD0^FEPZC3rdF%7a91~lx`bB)O{zV=#bGEq8;dKaN30XoJd=wrLZ*9ql zxDo(=iQ6+0687B~H_RcG#PdW!498u<{35EVQ{|3VTfn(UDcgRZ9@wZ1hrp54VwCx< zwO&kSsvbX+#Khb=sPHDDBwcE-JjvL?eoW~L2`ENNQ5C10gd=*s`uc_D6a>~khgTSt zq)D;8CB-*xe;0&&!yN=4cvP9l!2VcSO@*FnqZZ^J4>UVp6ahVWQt95MPIP?*t-db`c53YCxveRpM z+E0P&OAcPbBveefDvWRtC4@G9NqTm>Km<1T{%u0X1}P7`1-RS)lfw(-(UpMi`!pYU z0XHmmHFbM{u`43kf)r!jA(XVW7<&v%KdUlRUAy3US?oyzQ!Dh>o-PC*mlzY?uIM{S z3a?D>-)yYb@b0>}cwatW%{zvHZcadykS-~+hMZM9xF#8vEG|1q4!bx>4(mLgMA(#} zP;^1%%nx5WeFc45q-U`75i=LT-xqzNT)yzCB0PyF2);?KS#ztsj&5gbG&Br4_x_&y zV+>`i3IeZ+dMVSrZR*caqR~0*bW)(b9yr>yHMH@a=*trd&v_#_yAoK$fd;>R*MgA} z7{YaNb*KwT2nh~xV1f(El2*=Ar(u3UUB^X%Pxr4XL1N3o>*!&mzBmqp=*W6PG@|Rd zOXl{h5q+HCo01cRo}|h(33ZnENtXjM_`#z$@?m!^*gahy$uULt2M}(G+kd+oNl6F{ z6odi+S^fqBLiK+lVE+;<&Da0BBKb)DTAEvN_WEe|S5v&nj=@1qNlA0|_?_12_uS)c`1$r8F9?c1 zq=@ohtT8kU1D1hU3>|-$J4)sOmi}@-&ctw72{Vn3vQ9}70At96^83R>c*q#SHsd%O zH(!6hxf@JgJAci=~2ZFwB1e!Jo;VRZa30XPDh$^jZ;*wN`G!OGGCgK!A%5u<1 zLq^jkdmU_}EaT8(Bq&!cwQGBQ-WD-a%o9S*+e!nMui1lVS|?t19^#k z6Q!Y7#tiG;bI}P^R<1FHJ6HXM!J`^Md3FxU(QZoDCQo~6%!zD+RWqe1={r|e-kz8k za^3yTd1O1x@GvWL_C_mg&Zr}X$}58HTS!BU{fCNAOIMgxRm2&OFnV`KT;aQu*n!#3pPKQexbCQou%JGNkD8 z`ghG;OIq==GQ>^g2+s+}O3v*-t-f#K>c0F>mXlNRESq#%+ICue)5GFz`W&|9>YySz zLUefsmX|gP&*F05)8yw5dJ{02EHwdbmsu0Js3LS4L{~mP}h_EU)WO!%1E!ti~sn#{|OD1N;J0SP*tAwj@C@bWW z*5kZmJa8Mt=@d9^S$N2t9O>!Q4rf^(fp`)WVTXWpmLFpvUmtZC-yU@%-wm}3+>N%G z*gG}n5Oq7*AWt?NH2|wOV1HMh_E#ub2Ic#o3kM3(K?xtkkRh@fkNSm3w5e%R$6_;? z`HrBEs+J41JWfDzqr9sa=b_T`bHudMT;mAmmxBnb@Zh2vggrGFX&ihpmJ8&rW*7IJ zbtZ7#hnIF=q;aq`-nE$RbRK;nOq?xFcNCpx_oXRTX%K5APKY;<9;}4gRjER%t-R;b z;^wmL<<#!c#ZX-ih3}8uvjwlrJ7Sz3$R3wuV8_ISq%lk0`>oKC`HA@|eV>~-g5&k- z#30=unHmf^Hp3#wNtgH&#=rvETr_dVl;4FcLRk!~zchT7H`GIipRLdFAY%J#euaSL z$9&}TZ}+fW9@>Ps09nTGHPga0#qZ?+fr8(lcD03wpXhY5&^g+6Iog`&D1MbxU4E(b znhL2eU-Dk6AL}XpjzfP4dD(;kF)B<>e!{dG)|Qx+wdT%(-V(#=3%<6#o6R=>;4NmW zdM0~g{9wmtOoww>%h#QLWkax7_ePOqD8JZ_S}|A)o!Nv`^z=OjKa3{{jWW}>7N1Bq z47sJnD#*L&EifS85RO@@<90nOE5BHoQksd=2BR3!!st@-0E(-@lesUUQeI#>_9CR7 z+4^JJWa@aFV4}Of%i)oQrjhmAWgNOMWUzkC<;~NLUn(xjV@ua!)OO!tLWfvKyJ`9E?ix<-v$~od>uN0{pd&BrSD9wiP z+xyTM>TX1^uW-|5#4s45At_>dSWD>XC-jDqpT4cu@Vk$MP+h@ev^y>JA3tH<+J%fX z$&z#kL-B#FT&Ha5`eh%?^jI#X^z56%K^WJ`x_q7-E5fWaIIKW_f&EV?~rL zyNc!~d$&Lb6YyhKS|kEP>j|Kkjr&dVzrFXWZ(g@K!#!=%trR1%&o{2w&7z(p8FS$XnBV|W zAEL2nZCmlS=c@H&&2nY+d!_bsGqAU}jOaF*$2>VVCZ+uB+-pzhoM(RV>L7iJKFxpQ zR>y-$)QX>Q3oUZr4|O9R>d1D5tRs>)5(8OJC$OFl&n;XnJ;Kb@hC%XIxC>hvyL5_M zv=&i_x6A^qqbiopGea*3;!1cntRlTmZ!4~AA&hi#DL^i1vtmrsX5YCs*r$7!!#s4f znWfi@=}q77S&rO$T@9&Oa;4m@vAp%aqkxkUC1jbLaanVHikl#Z%vN6CkcLfV-$yoL z8cL_>6UhHMD049P{FMv{0hIg)ZR-e5BjEyRaUUCW86A}K#HJ^tjH{ypoA8*ef=gKw z2H!pmbXPba6zwUgaE9$#_1q-p1Sq}yxZ1PFmrOpQ*zX{?J|f%}$loY}-iu}Sm&-xF z=A0OE&78TzAIj?=m8sJ(tHIX#*^7#D4uvrx<;4idy=71qq9iT;Iq=Q2J|8 zhy{yW(w7zaWQ@H~JlO9Y;n8G3-HyW@#-dtnEe6-=*oxp4%seYij4I=BwialbeiiD> zt@P#eIk@DK(?TwhV$(H`qeA8=r4B!`hIP~k;p#(fYoa5wB233c*ZO919!qFh`5HBA zF1BYgU))Tl1p7#}$kYLcI!774)xudI#1$q@Ynm1|-I@y%hDKEmc(N^5nVB@6IRY}D1p+Fc zadkCc01BUlQ~5!o_d-meEb=jfZuzztO&ny zj?n7L6KI#CceFF^rIY|mLm|Du8-wdimJ>m<9NYZUjy?EO! z5ey+^^H!NKL*AxhG}=Ca+MtTS-vTz;!&dhI=b#H$-6P?c#*v*{%!;H8JyCWx1}LU_ z?rMZW`B1sm$E~DkJUE&&QNE}Jq_v6h8XwE7|4up$JZvi{n(S?#Hx?%THZ*WkIo!$}{u;Ff-+mjN&%**! zgevNb%G7z7WT`tB50O=ksd_E19Y+!P;DQ3Wo@O86S{ILV4;S z_O!b0L+p5u*tS}7Dhq2@GuvBOroXSjDgI6rlLfVWF)Sju878|$Mf)+JOUK8EZqIIuAa|_oSeQ!Rr72a zr`5{N(?t?|s+N*$L)x7kKAaWRZW+r`1FnF}8~8P_DT7Ae^4D!i^ZYI~8Ka>Q6{o|N zt`A$uNs@BW3=D0uGod8yqQ=q+<7UM`^^O|mm6tZ#SNqLokx6~=yB)hf?hr(#P&h6p zp~1>5{9NKA0IO=;kE?#P&&`yP+K44oCkvyfdl8?|sz(gYqIcmS8n!CyJbx$j4p(vF zf0c<#?#=`qx@Teb1~87pO>M@#7xdXQA-5@%2jXoFOB{Mzt9ZT3rK*mRuziG;u|sOM zSK;)F^rZ_3_U*Z<-n#gd+k7it8xp^bVv>jF9a6A&y-ko?t2SX|FKDM8oI@!Zep^iG@$&9Gz@n-FWov?ea-_*?xy{NIqFph;wP2S(tBIs zlh{nw9T!s=weJmcpNFO5o!e35{1~`?#p9fA!q6+vrFI$DwYGUF7__sUvnX#2$lS^O zNxWloS(*rxGt23*Mf$Rry&3N)hx27c1NPw)_Hz&x=cK)RyEz=?jkLB0NpkThw?j{x zEiKp*oJoujfJyPdy|yv=8I$pLoRKN%wK>K0UMWF9?&4ITuHIMWg){o(pSy1iK*4!K z5)WdHN#>1|!ik+~4lX9E85_R#Y0#yz7d$d{E|`~SUg z*~wwY1I^I4jJBNcuhIb}1cr zJ?kWFTk@XXi8Z0jz6XMEh-peN4kMnuUY!EOxo<0-EwLEsVwgEQVm~BlM1| zcM($RG9(+~{;-&Y5ujxqwe3X5d2W4*J#!Tuhwb9W;u^zeNmFXgEe3CWz#;aFJeH?; zLEA3QMpHvO&Ttu}?gnt8B#0TXaCETvf2Uw~-ug=aPNtsFN81j>}3U6F#N|lAc z4KaAn{%*G2J!+gsBKFR&69H}uRnZoW^hf~f7B-RQ7h)s-8kiSEukU*- z4&Z4x9lh9(cJ|*0oxr$|7PpAzUJ zhtacGP#}zgyC$vT-_@R}ZB$itnDlF!`$>LCKG>Gt67Qb!(K3(VD&Z*bO!w1Uch0AR zK|E)Ova+mg&23{7!?x4@{p;h0-Wwab8O>~g3rz=QFY37e1%&{7#&(ApQ8442Fj}Y0 z#p(`&P!rH6{m)@cc+p++J+=ctP=y7x{rd`QlZ9dGr@@U z#DZowF11ONEY1+cNf2$DQQG~aGUO6iY^v@l-1e*Y#ssO8U*P<1D8yX=)sBBC^BgisHP(_YMh2U9jdlxGrhq8kcLqo zaeBc;_+o%XI@Fhgj%LxkUZg?~TgnPZ2D+s_EVocZ1N%}ceGQBLZGi%-cr|%6_$K(P zvm>(}Y9HvfOqf#KNh*qXyws{s#8Gufaa-{kDLvh)tByvCFqa+GfO`P-ufLmZc1%TO zo=M=EbQaNSG>7>^Yc=PU0YB|5$b*Y8aIRGD^8H*|$(6BCQecx?;_=B@j9EwYnTYt=MLjL_f6$E2XLMsy1`md?wOod#`RqI z9wT02q*Z9_rB^_3$R8%LPFdRpQul4UZANSwRm+ainH%aO&?s5Yr5{6YW-sOI;l^`% z0%FDclDtRs+n|mPi!#Dlnf-iTOklfj@uQOguCaKu6XP3l7j52`;v9I))C0f-4X3QD z?JhP~-s4oLOkf*^U37%5k(n!om8RH5O2;$I=WqFz->8OoQ|#P~i#xHD0?8`?x2}ZN zkzrq~7s5V3zQxAyZh4~16lHE%^zW!n6z@)nXB9+vKpy&5NP-B>!bu>Om)Qu^twuFV zyRkbypCFxUMo>4R*noXq38vQI(-*$A+DQenzy(?i#=jr&Mlv zkl4g+*NRZHk>q&{J{3s#d4Y$LG88OP){@A<>p|Xte1JXIPoA)!1HTLbWHh&Zl^#l@ zTVGs9Q*|t>3+iyfq3N(LUcsm3>1NT>RezsbzSPS4(_K7B?g38EWCknSB()cRM-9Nt zx8nv zgfKo!BRkpn;SCi|xFuJCN6@Wv>B5Dm%G(zS}HD$;sa=hN$F3CQZ?ep{;H?85<88W3U1O!r)v`C*KK| zhsWF+fmi*sqoZE=d zF(h&7qJK+X=b3+z#r8?ay#<~J#EJMpFruVx6&`%z>Ik>GjafyMapmR2~snGS26{etJS17tiOpJz3N-2mr&6?_wuG}i{}RPj$Gh~s%O?g z?HY1)C)97>y;isCi^}k|w)>w$Xuj<3-g?h+;XYmxmM?1$Te%TiQEvVyA+WL8`X0b5 zx}bP9gYKO^B)KsXHvDd%fIWTpFa(;VS%HwWr<6tMOU*$(79`{{M=tgilF9dMR( zJ5Zn?v#i7*wWXp%xCAQn81mW6*Zfwa{9J+pH&6w6~u8BoZYu~!@)-@|RCxHkEv-xiR}tjF z;m4>qi|zJkaAIL++u4cZ7ua?*CKpZ9e>@3ATSA$JD6v?%KF=DwK4x}+biJ^b@CR+| zmecEuff%K3_I%EbD#!C0Vx@KIbLDbf*$?~LEoSh-)WC6kGo!;uET}zrG*;W2w;-!* zFH?)JL$B%621@YkBZ}w?Fmo^}Nwra12VS`zY%-{mW)58RBX(9FKMC+RcyiN*XX#l( zp`VsH_^9H(gT*)2)InM>(rTWEh&H3Wh;m0m--g8sCi_$^$MdxO zcw79t)IH`d%DJU^jx$0UOFIH<$!+(AMAm$KZ|>0_la$Xv6&2O7mY5!t5@l^jXS3^m zp3t4wxf|_-0;V_F48JK(NV^x$jmbVSuNIXqzt7`h0kWVTmAePOH`lFSu91Jq$r_QM zV~n^088l_I!At;s?6P^pt>Xq}GSxyePi}e&?=xrj#`jp0GLqRWVr85}EWAm&70Hf& z%PUL^I*ykuz&bUx9%v53=p0$9+C)MmAa?kH3-6SRCo>;*+DZD%fT&ZnaI7|-*LE*G z9@Vapw(8WG!9t&Ot9qU{C$d6uQwb&NhtGy(z+Oc%bN?-X`+%R>SA*Nnh^aZI?bO*? z*@?dLy(<)_%lV*fZkSbSw@Jf6R)$qRuDkG;__=dw)?3JfIbpOPtUj1 zwr14M+k-L4!QoD|UN|)nn#zEtw#LZ@W82G;H1*kxpQlS|9SnCh69nZy02I#K4DklS zIL#cexB1!~&&`-0kBm-jIhZ+MeC_?CYQbJsiAjU$8ERm;=Z^d<2-i3nEQf5OJG&*W z8&lEWzZC7Ka8^FNG(fXrQz~#y5M{AhmWi%ZmS$GH`)-)pu(5$-N6Kub1KlG;F_NH# za*7xDMWiP??u%kUGsNd7Pj;Nuwc#;$XYsXIK30SKlb1BxHOe~4AKX@var(qt*0u6j z;U=A<^LdDL7Mcw6D54wDi{8l3k(QHh2+$$S@4meqys2}uU70l}cz~u=3eKtJw1{#0 z)6(`Pzc$3ZCzMGnHOAc$JBya4(}Z_cM>c-HbSgi`(2h4_#&X(@5+)9YHs{ehutLCv z2p3Kn&-M>K%XEHKL-mZ0rh(cIxaqj6(H=O?-ad>YB+&*2AmVk0B`8-c27vI#Gd`a- zJ^%@r4)7Tc#Df7}1R*?%UkFHVrz$DVndn^F%SaV{P9_uds6xwxu=OOa8`pfgCpC|v zBA94f71${yzc@n;Xarpk_5>2ITl$d_Ysf3unnHw&j7fm`MCM4;FfFAf9Nb*xH=JG)0?v)F8Joz4c7q*(!)D}l?8-*mDiNWLLnBqz0D;70Cdvyd4CAA^jpK;%x`57RO{f6SE|jA<)M+84)Bs^D{MN4i z_7wVOJwkpHkgw00TY)WI=U2!UyZ*t2J!Ph9zh3!iAl@#^nkZ$5%Jq3xe2wu*4wVz5 z!|f0C@D`-*{DViW+_WzB{eAwWkc@ZeJGy=ksAyfSg6{em|L52$(qrldI-{RHFfo|j z;45k?C%kz>KKXS)+e-|uiU%HEP%)ULW`6veZiDnq3xEnwZBmLi#oO564+^6hRAF$I zIH4F&2i9-z%!$TD`%wjMRs<>jc+=V(ksvATH+-fPqaDF_(EPvdQp~Bo-VWvy3#}&A z5q7BNnm<#Y;heVnK3*XDn)dBgQ8rWl=k5+$5fN>(6Q$}MT;n%PnrU3rd0hjS> zxUmVqa{M`Wq~mk(Z%RC%`jEm|Teu?Z@V&QPqSspo`>8JjCWJWK%_-X;IAbB^_l%94 zz)>%Xh294H5wNQ5DD(mNmXtIva*S1%(x4&Rm1%@P*}~#xrY9neC#LnPIE>&5u2Aw! zmwAyyG;0^S6CXlVl-E{8R(Frj50=@YOyNX9+cR;HmhA?yMaKtP*ee{M=c$4eH0(L~ zp%}~_M;E60#>YmbOOC4U;2-ZgDgDrS3RI?gQnt!f$F{s;Ur&{NKX*2 zi{7YfFrFhjCo$}UEnQEQZj7yeLA&lI{#C!SbS3+<9B54plxq%h%-vZ8h6 zQ=0OGaKdS4fN5vA6}9CtDk?Bl+hkGM-GnZ=NzN$ivS#8+ve8FPsJQi6ZvWbGDdQBj z?XDEp@X%F*b!tw~AU?w;X#b%pjerma{_KMbc@+Z%w|mUo=i~Gd0vCXXaFw$hBA5KB z_pPT}BJwR|KmzJ3RkcQfoU08o+nBR~Fv2`jzM&^;kD6LP&A1<}S}1SIx%)I$AcwCCBRs zQ{Ttu-S;3_P#f0gRCDah=?T)^u&W2Dm;uEbAB!arxB#0oufSY}Pug_P-P$XwgqW2O zG@k__2)MvY7Y~r4`cL^sEG~E*wh!=$AD_((_O9q1wvPzLw0GUH*B|qWfk>k~`i()K z)A8z0L{|b$!$d@TK2#O~A$^ocxVh|eJ_U+T#iD>N=nvp`@^Ah5^sYpn)b9uw)i1+I zPOfC0_xlKt3(xf$q3MK>r`umgJ|1d6*EbQJ?}lT^$QEG-KA=5PY|x?s%WTGQkvY?&(*p)<9XrVznLpP(k@68>F$-70B7!J^Vi& z6_zpV#neYfkqo^1$8D|STPUj02vt)C#g7!q14)Iwm0k$Vl@B&v4FZ}g2XCxAw5pPi zwsk-ANWc`rbYls6^Ag!v)!b<8M}w9I%Vmim!xQs(9F7vgij4?!CLj%kw2y`J9PK9q zkB&Y`N8y&+E*=*~E8=h)P%k4C&`7Dv!&M8%qGVi&KRuG%2syoDp4yfotb1(As2G10 z>M`by1VKFJI;i-E63O;_2oUVEb2eEJR>Tvg#B=bd8WmaA`+)pvUwK)$O2VhfEA(Yu{^F48HiRi)vNj6FtA08} zxXZe&b7d%dijZ0dM;HRn;qwdM9_Y-FBHm8b(+*#uSdBbG@QbFZmxK@rFB&V479rlTe9jw+0qgN12f5R zg`4%fsp2W4f5=-xG53BLWb9`*j+9rx7=HqF?tz-suM9uH>#=o6Zeo`~?EsdsIJT(6 ziEdk@g=^R^K3%xP`RQNjbxI^CM=G8@!Y$6<>s!L*DL35s!-+78Iar{XGl6Yl={~0H zBZLN|@CkyWm23oE00lD3V*1Z0g^e$iiL{cO?hBh_6Pi(Wcgb*s9y}&|(M8@7$MGJ4 z2K0)&yS^_A{0M!xWGUfodaXumQ)!_@;5aPh3b#=4Kx=I}&Ye4UW>ye9x>4X#PGU1e zglS9byX{k&#OPTkUn$E2Sun)Of_&#}cIhU4FB0<#@#cSF#{Kx_L>Y%dTD^t{x6D>} zH&-g{a(X(}S|N_dClS&?rudCiT|So@Hvn25P4i`CuYG|e zVH|e7bLGW2nOP_BrVX;bqK5AJ7Ub0^nK?;=*?OJ4nw@v2iGNCkq23Z4kGH;}IGzN# zFqc0tN=Iok@Lj$k-CA&&?pv*1bpUPqx7kLP)-|)5-sC6>>nEdqkhngP2S6@d6 z6Tm2($+n>gzN<2tKHf_Oo_oeJ5)NA=Ukjz0yh67~`<8>Ott|OfxCr_FETY>c^cYt@ z>ErT0eZd$j1ep_A&xqoMD_(lrh$fpyqn5aJbzA1LFY^qgfG{NPccy{N|DOHe*%hwU zMW+-P`!8e99wp?1(IJ=P_#PUc#)4_8! zmJj1wTN}|?CR=J!uxqk!cY1UgDy9?ma5PDGznHCMqt%SW8g?Ipa_+1O>I22;!Gs+Q zgkkq~*-{i1EL`9_qwQ^SwP15i6nr``#%cj;AO;Nf7uHRGn(~)T)2FG5d$+sJtY$1N z+Yq$nyKNUn?-P;+uyCrHlJaVjRIY#QA$l9IXB&+%6@&=u5vHa|ydaTV=wK%5TlJz-cfj0x?A+q<)Hjz{ zM82aOiLSO^r_}@>;Jsd8>MQ)4Nf)GKE<(FTSytG6v79>kxh8JcsmKxU@PWBF1$uY` zylAC-X9?(D@+aa;Z-TFVr{zYvlyGQFyZ6XkWPn$b*qP~X&dI3;w^*z1--YiF*OqLvYB_*fAK&4X86wyi=|O;31hsqF#@ zwF=r~w}$#akEC|;tFQX3A$UC4Lk>F=$jk4K1>K#C8dNO2TkRvwKSc@H#(%OzQPO+r5nMjkSxW6UpgVnENw2zOD?ps-7VzUDyUBo1z0kw*~I zpj@rR!rzp92(ew2tS*;QwTAQu_kRIR7 zk`WRjD)4>-tE{OfX~X@=#=gAE`(s?!i__1{f;rptw=hRj+0z1{YCBg`v52kt2QiS& zzTtSP-9{K9@&2mil-NKdw@#VBE8CKd83!xc+|fJO&T35H)uwJtemD~R!O?rj>A(v~ zFfJ5|47I>DGH(WCUX1V@=t0@wJyOA@5CaCm>xA5=(V2WmNp4M-<>}$^fP;hnbJyi) z>>|~nRy8qyF*(x?V===0f)P3da?SvSeH0=637xnPcf9Le2v;QxJA-QYt_m^#!@z;} zjAGC1y=`u%T@c>$Oc3<$3ESy74h1AfTyr;qK^Q^#B%EBFT(CrNH;q6p>hRLRb)@T) zbsHfR#=`aiL9XLuM<3FQlz|<0Z1zjd8?R@+Oqc8pS2OFMyo=TQ5mt_62;m;HYd#YA zBb_cQ#^a95tLWOk1chkvi}1~p?Cj>~4(v8h8M@ViMKA3xqjkQbH5 z;nba7RMgF-!Y~_Tw_J#`h4vu$J%zIqg^}#<#<-}Ft;73q+!Y2k6NOz)&7N&F+fay5 zHl9Y|I{Pv_mTbA0S5W?-rmUJe;nU` z*ZJK?>$i@jo|}!+|8#|x(=^U+dmLW?0C4}QYHM#~Y-Dd_ZD6Ep=4fQ~yJ^{=^0@Un z9efAa2yY9BdtxexFc!GVMvs{<5IeHi8ZJz_hNRFlP;1@3rw%Llj}zXn{?^ z6O|joT*wN0V~{cPJz@MK?{A=G6?7&M_-{fAgW84|16sQbCh<%7QX@P{_MMEYjqVsc ztcVtu+C7f^sNto-j#b~{qLpJY!!Jb=uObjB=Z-|8s&#dNs>I;dgYFZ3TFKt@luU&1 z4!lS-xfkl4^$fOIj?e?6G`sFi711DX@(g0KSApoSSlrHl5_=b$*fhS+yL1u9bi1~3 zhJu;oxzJpuhkyO(^7l64ctB<$OdRvBcU()+w5o2m=JfFu-N;TbsP~6tu6bW!b^7eG z$)Dy!^r+7EmAO&8~qjvQi3M$yeK4;aIg6S<5 z-)m({f;EvC92vv-!8n&SY13n_c7sJ~A?TkmfZcE_-E+x5&7+eUl|@g%^2mw&#;W{| z@a@Y%XrM({S(Kxu(u4)hXNVU|D2;@eDkXc&&HPf6nzwJ13{uUtR8o zfd99#V`=tx!#hPu$pJd}E~t+X%qybF3PQp{Z4_ZHS9nhxNtUe5FSmr^F4{hwCrxcA zPNYNxNK|WnyilG_<1O45N=;=`j}9{qFR*|5@;`+P zXFW@&{}5fun5Vtkf4QCFSI9v5J7oN=`q#^UMG7Tpi;Z9H4S%S%P;hgs1>=tGIe|m? z@!I0)oUr|0hJN80e zF_7(Fs#g4RoY9Ya@gR7?5JY`1g@W=Ix#U6SFU?d9wKWGRk{@45P`p961g5L~&#_&{ zps;Fo>ASC()!t7m?JzPK=~Y1nef)cDz%l6-gP_EX4N872HIUW(Kp=MMbIr!SimK6e zANdA6G=JVfB`Sztk|@raf{~K_EeH)(g-VjCG8XO;ougXq{d$~mdl8?70a=U^eoU+r zbXEg>wV7lN#;+a4>o{~V3BOMO%+X)vT-+~eW*E7Up5aLZGZ8g?my$PgUZ@5iVj;3Z zDm<;(rkD>)4)CI+lhw-t`JKZ*S|E)ESK89iJe%#{sQ&Bfeo2wD`>&swz#-nJdsyyu z5;(rRMzmaHO2V)@aGOnvv5vZPjU8HtRHuw*Fgc(?%zvZM5_y%+2kYIE*;$*=^7rrIr0thMq1nYcIoVg#Y_b?)}exBofv^ z@6IFaxkHMXy+-Aawp_!~$D&nlbH7iENyhqepq6BsTInn$Tv+0@Tk57!vCh{)9iMGmhMot`{5nK9(7`%)E7;v@e^SPrMH? zIDcr29iD=ow>0jiYb+*FKd+9}qJX6dc+9DktMkflzEa)K&OO%APON^mXC8OGy%3L^ zGY3?uS~$q0q0mfn7qc-xR*#sB%a|3ih7@5vTkS_E*KB0Q2Qt3x5~dL z)$d*ZOW*;1^1qn>&0zn8{K;Vd1uF2vv-lhG|FDz4QUBWTZ!Y(j{NAvp Date: Thu, 27 Oct 2022 16:41:07 +0200 Subject: [PATCH 44/77] replace iconify module with aar --- app/build.gradle | 5 +- combo/build.gradle | 3 +- dana/build.gradle | 3 +- diaconn/build.gradle | 3 +- iconify/.gitignore | 1 - iconify/build.gradle | 20 - iconify/consumer-rules.pro | 0 iconify/proguard-rules.pro | 21 - iconify/src/main/AndroidManifest.xml | 4 - .../iconify/android-iconify-fontawesome.ttf | Bin 142072 -> 0 bytes .../java/com/joanzapata/iconify/Icon.java | 14 - .../iconify/IconFontDescriptor.java | 17 - .../java/com/joanzapata/iconify/Iconify.java | 111 --- .../iconify/fonts/FontAwesomeIcons.java | 716 ------------------ .../iconify/fonts/FontAwesomeModule.java | 17 - .../iconify/internal/CustomTypefaceSpan.java | 88 --- .../internal/HasOnViewAttachListener.java | 82 -- .../internal/IconFontDescriptorWrapper.java | 49 -- .../iconify/internal/ParsingUtil.java | 217 ------ .../joanzapata/iconify/widget/IconButton.java | 55 -- .../iconify/widget/IconTextView.java | 54 -- .../iconify/widget/IconToggleButton.java | 55 -- libs/iconify.aar | Bin 0 -> 126846 bytes medtronic/build.gradle | 3 +- omnipod-common/build.gradle | 3 +- omnipod-dash/build.gradle | 3 +- omnipod-eros/build.gradle | 3 +- settings.gradle | 4 +- 28 files changed, 18 insertions(+), 1533 deletions(-) delete mode 100644 iconify/.gitignore delete mode 100644 iconify/build.gradle delete mode 100644 iconify/consumer-rules.pro delete mode 100644 iconify/proguard-rules.pro delete mode 100644 iconify/src/main/AndroidManifest.xml delete mode 100644 iconify/src/main/assets/iconify/android-iconify-fontawesome.ttf delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/Icon.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/IconFontDescriptor.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/Iconify.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java delete mode 100644 iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java create mode 100644 libs/iconify.aar diff --git a/app/build.gradle b/app/build.gradle index 82ecb4b85d..7b3fe324dc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -169,11 +169,12 @@ allprojects { dependencies { wearApp project(':wear') + // in order to use internet's versions you'd need to enable Jetifier again // https://github.com/nightscout/graphview.git - // in order to use internet's version you'd need to enable Jetifier again implementation(files("${rootProject.rootDir}/libs/graphview.aar")) + // https://github.com/nightscout/iconify.git + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - implementation project(':iconify') implementation project(':shared') implementation project(':core') implementation project(':automation') diff --git a/combo/build.gradle b/combo/build.gradle index e20cc0fc66..b76bc9ab23 100644 --- a/combo/build.gradle +++ b/combo/build.gradle @@ -13,7 +13,8 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':shared') - implementation project(':iconify') } \ No newline at end of file diff --git a/dana/build.gradle b/dana/build.gradle index 5a166b3ab2..35f9454dab 100644 --- a/dana/build.gradle +++ b/dana/build.gradle @@ -23,9 +23,10 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':shared') - implementation project(':iconify') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/diaconn/build.gradle b/diaconn/build.gradle index 64ac7fee1f..2c512646e3 100644 --- a/diaconn/build.gradle +++ b/diaconn/build.gradle @@ -23,9 +23,10 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':shared') - implementation project(':iconify') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/iconify/.gitignore b/iconify/.gitignore deleted file mode 100644 index 42afabfd2a..0000000000 --- a/iconify/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/iconify/build.gradle b/iconify/build.gradle deleted file mode 100644 index 3166680705..0000000000 --- a/iconify/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-kapt' -apply plugin: 'kotlin-allopen' -apply plugin: 'com.hiya.jacoco-android' -apply plugin: 'kotlinx-serialization' - -apply from: "${project.rootDir}/core/android_dependencies.gradle" -apply from: "${project.rootDir}/core/android_module_dependencies.gradle" -apply from: "${project.rootDir}/core/test_dependencies.gradle" -apply from: "${project.rootDir}/core/jacoco_global.gradle" - -android { - - namespace 'com.joanzapata.iconify' -} - -dependencies { - api "androidx.core:core-ktx:$core_version" -} \ No newline at end of file diff --git a/iconify/consumer-rules.pro b/iconify/consumer-rules.pro deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/iconify/proguard-rules.pro b/iconify/proguard-rules.pro deleted file mode 100644 index 481bb43481..0000000000 --- a/iconify/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/iconify/src/main/AndroidManifest.xml b/iconify/src/main/AndroidManifest.xml deleted file mode 100644 index a5918e68ab..0000000000 --- a/iconify/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/iconify/src/main/assets/iconify/android-iconify-fontawesome.ttf b/iconify/src/main/assets/iconify/android-iconify-fontawesome.ttf deleted file mode 100644 index 26dea7951a73079223b50653c455c5adf46a4648..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142072 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 +|+&Vdls@0SAya!8#E9iVniRwHu0GY;H*n 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�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%0D0!#Bo^>xe$Z4SmykflG_VnkLvLv4@e#4_y4Q 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 iconFontDescriptors = new ArrayList(); - - /** - * Add support for a new icon font. - * @param iconFontDescriptor The IconDescriptor holding the ttf file reference and its mappings. - * @return An initializer instance for chain calls. - */ - public static IconifyInitializer with(IconFontDescriptor iconFontDescriptor) { - return new IconifyInitializer(iconFontDescriptor); - } - - /** - * Replace "{}" tags in the given text views with actual icons, requesting the IconFontDescriptors - * one after the others.

    - * This is a one time call. If you call {@link TextView#setText(CharSequence)} after this, - * you'll need to call it again. - * @param textViews The TextView(s) to enhance. - */ - public static void addIcons(TextView... textViews) { - for (TextView textView : textViews) { - if (textView == null) continue; - textView.setText(compute(textView.getContext(), textView.getText(), textView)); - } - } - - private static void addIconFontDescriptor(IconFontDescriptor iconFontDescriptor) { - - // Prevent duplicates - for (IconFontDescriptorWrapper wrapper : iconFontDescriptors) { - if (wrapper.getIconFontDescriptor().ttfFileName() - .equals(iconFontDescriptor.ttfFileName())) { - return; - } - } - - // Add to the list - iconFontDescriptors.add(new IconFontDescriptorWrapper(iconFontDescriptor)); - - } - - public static CharSequence compute(Context context, CharSequence text) { - return compute(context, text, null); - } - - public static CharSequence compute(Context context, CharSequence text, TextView target) { - return ParsingUtil.parse(context, iconFontDescriptors, text, target); - } - - /** - * Allows chain calls on {@link Iconify#with(IconFontDescriptor)}. - */ - public static class IconifyInitializer { - - public IconifyInitializer(IconFontDescriptor iconFontDescriptor) { - Iconify.addIconFontDescriptor(iconFontDescriptor); - } - - /** - * Add support for a new icon font. - * @param iconFontDescriptor The IconDescriptor holding the ttf file reference and its mappings. - * @return An initializer instance for chain calls. - */ - public IconifyInitializer with(IconFontDescriptor iconFontDescriptor) { - Iconify.addIconFontDescriptor(iconFontDescriptor); - return this; - } - } - - /** - * Finds the Typeface to apply for a given icon. - * @param icon The icon for which you need the typeface. - * @return The font descriptor which contains info about the typeface to apply, or null - * if the icon cannot be found. In that case, check that you properly added the modules - * using {@link #with(IconFontDescriptor)}} prior to calling this method. - */ - public static IconFontDescriptorWrapper findTypefaceOf(Icon icon) { - for (IconFontDescriptorWrapper iconFontDescriptor : iconFontDescriptors) { - if (iconFontDescriptor.hasIcon(icon)) { - return iconFontDescriptor; - } - } - return null; - } - - - /** - * Retrieve an icon from a key, - * @return The icon, or null if no icon matches the key. - */ - public static Icon findIconForKey(String iconKey) { - for (int i = 0, iconFontDescriptorsSize = iconFontDescriptors.size(); i < iconFontDescriptorsSize; i++) { - IconFontDescriptorWrapper iconFontDescriptor = iconFontDescriptors.get(i); - Icon icon = iconFontDescriptor.getIcon(iconKey); - if (icon != null) return icon; - } - return null; - } -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java b/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java deleted file mode 100644 index 16202e243c..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeIcons.java +++ /dev/null @@ -1,716 +0,0 @@ -package com.joanzapata.iconify.fonts; - -import com.joanzapata.iconify.Icon; - -public enum FontAwesomeIcons implements Icon { - fa_glass('\uf000'), - fa_music('\uf001'), - fa_search('\uf002'), - fa_envelope_o('\uf003'), - fa_heart('\uf004'), - fa_star('\uf005'), - fa_star_o('\uf006'), - fa_user('\uf007'), - fa_film('\uf008'), - fa_th_large('\uf009'), - fa_th('\uf00a'), - fa_th_list('\uf00b'), - fa_check('\uf00c'), - fa_remove('\uf00d'), - fa_close('\uf00d'), - fa_times('\uf00d'), - fa_search_plus('\uf00e'), - fa_search_minus('\uf010'), - fa_power_off('\uf011'), - fa_signal('\uf012'), - fa_gear('\uf013'), - fa_cog('\uf013'), - fa_trash_o('\uf014'), - fa_home('\uf015'), - fa_file_o('\uf016'), - fa_clock_o('\uf017'), - fa_road('\uf018'), - fa_download('\uf019'), - fa_arrow_circle_o_down('\uf01a'), - fa_arrow_circle_o_up('\uf01b'), - fa_inbox('\uf01c'), - fa_play_circle_o('\uf01d'), - fa_rotate_right('\uf01e'), - fa_repeat('\uf01e'), - fa_refresh('\uf021'), - fa_list_alt('\uf022'), - fa_lock('\uf023'), - fa_flag('\uf024'), - fa_headphones('\uf025'), - fa_volume_off('\uf026'), - fa_volume_down('\uf027'), - fa_volume_up('\uf028'), - fa_qrcode('\uf029'), - fa_barcode('\uf02a'), - fa_tag('\uf02b'), - fa_tags('\uf02c'), - fa_book('\uf02d'), - fa_bookmark('\uf02e'), - fa_print('\uf02f'), - fa_camera('\uf030'), - fa_font('\uf031'), - fa_bold('\uf032'), - fa_italic('\uf033'), - fa_text_height('\uf034'), - fa_text_width('\uf035'), - fa_align_left('\uf036'), - fa_align_center('\uf037'), - fa_align_right('\uf038'), - fa_align_justify('\uf039'), - fa_list('\uf03a'), - fa_dedent('\uf03b'), - fa_outdent('\uf03b'), - fa_indent('\uf03c'), - fa_video_camera('\uf03d'), - fa_photo('\uf03e'), - fa_image('\uf03e'), - fa_picture_o('\uf03e'), - fa_pencil('\uf040'), - fa_map_marker('\uf041'), - fa_adjust('\uf042'), - fa_tint('\uf043'), - fa_edit('\uf044'), - fa_pencil_square_o('\uf044'), - fa_share_square_o('\uf045'), - fa_check_square_o('\uf046'), - fa_arrows('\uf047'), - fa_step_backward('\uf048'), - fa_fast_backward('\uf049'), - fa_backward('\uf04a'), - fa_play('\uf04b'), - fa_pause('\uf04c'), - fa_stop('\uf04d'), - fa_forward('\uf04e'), - fa_fast_forward('\uf050'), - fa_step_forward('\uf051'), - fa_eject('\uf052'), - fa_chevron_left('\uf053'), - fa_chevron_right('\uf054'), - fa_plus_circle('\uf055'), - fa_minus_circle('\uf056'), - fa_times_circle('\uf057'), - fa_check_circle('\uf058'), - fa_question_circle('\uf059'), - fa_info_circle('\uf05a'), - fa_crosshairs('\uf05b'), - fa_times_circle_o('\uf05c'), - fa_check_circle_o('\uf05d'), - fa_ban('\uf05e'), - fa_arrow_left('\uf060'), - fa_arrow_right('\uf061'), - fa_arrow_up('\uf062'), - fa_arrow_down('\uf063'), - fa_mail_forward('\uf064'), - fa_share('\uf064'), - fa_expand('\uf065'), - fa_compress('\uf066'), - fa_plus('\uf067'), - fa_minus('\uf068'), - fa_asterisk('\uf069'), - fa_exclamation_circle('\uf06a'), - fa_gift('\uf06b'), - fa_leaf('\uf06c'), - fa_fire('\uf06d'), - fa_eye('\uf06e'), - fa_eye_slash('\uf070'), - fa_warning('\uf071'), - fa_exclamation_triangle('\uf071'), - fa_plane('\uf072'), - fa_calendar('\uf073'), - fa_random('\uf074'), - fa_comment('\uf075'), - fa_magnet('\uf076'), - fa_chevron_up('\uf077'), - fa_chevron_down('\uf078'), - fa_retweet('\uf079'), - fa_shopping_cart('\uf07a'), - fa_folder('\uf07b'), - fa_folder_open('\uf07c'), - fa_arrows_v('\uf07d'), - fa_arrows_h('\uf07e'), - fa_bar_chart_o('\uf080'), - fa_bar_chart('\uf080'), - fa_twitter_square('\uf081'), - fa_facebook_square('\uf082'), - fa_camera_retro('\uf083'), - fa_key('\uf084'), - fa_gears('\uf085'), - fa_cogs('\uf085'), - fa_comments('\uf086'), - fa_thumbs_o_up('\uf087'), - fa_thumbs_o_down('\uf088'), - fa_star_half('\uf089'), - fa_heart_o('\uf08a'), - fa_sign_out('\uf08b'), - fa_linkedin_square('\uf08c'), - fa_thumb_tack('\uf08d'), - fa_external_link('\uf08e'), - fa_sign_in('\uf090'), - fa_trophy('\uf091'), - fa_github_square('\uf092'), - fa_upload('\uf093'), - fa_lemon_o('\uf094'), - fa_phone('\uf095'), - fa_square_o('\uf096'), - fa_bookmark_o('\uf097'), - fa_phone_square('\uf098'), - fa_twitter('\uf099'), - fa_facebook_f('\uf09a'), - fa_facebook('\uf09a'), - fa_github('\uf09b'), - fa_unlock('\uf09c'), - fa_credit_card('\uf09d'), - fa_feed('\uf09e'), - fa_rss('\uf09e'), - fa_hdd_o('\uf0a0'), - fa_bullhorn('\uf0a1'), - fa_bell('\uf0f3'), - fa_certificate('\uf0a3'), - fa_hand_o_right('\uf0a4'), - fa_hand_o_left('\uf0a5'), - fa_hand_o_up('\uf0a6'), - fa_hand_o_down('\uf0a7'), - fa_arrow_circle_left('\uf0a8'), - fa_arrow_circle_right('\uf0a9'), - fa_arrow_circle_up('\uf0aa'), - fa_arrow_circle_down('\uf0ab'), - fa_globe('\uf0ac'), - fa_wrench('\uf0ad'), - fa_tasks('\uf0ae'), - fa_filter('\uf0b0'), - fa_briefcase('\uf0b1'), - fa_arrows_alt('\uf0b2'), - fa_group('\uf0c0'), - fa_users('\uf0c0'), - fa_chain('\uf0c1'), - fa_link('\uf0c1'), - fa_cloud('\uf0c2'), - fa_flask('\uf0c3'), - fa_cut('\uf0c4'), - fa_scissors('\uf0c4'), - fa_copy('\uf0c5'), - fa_files_o('\uf0c5'), - fa_paperclip('\uf0c6'), - fa_save('\uf0c7'), - fa_floppy_o('\uf0c7'), - fa_square('\uf0c8'), - fa_navicon('\uf0c9'), - fa_reorder('\uf0c9'), - fa_bars('\uf0c9'), - fa_list_ul('\uf0ca'), - fa_list_ol('\uf0cb'), - fa_strikethrough('\uf0cc'), - fa_underline('\uf0cd'), - fa_table('\uf0ce'), - fa_magic('\uf0d0'), - fa_truck('\uf0d1'), - fa_pinterest('\uf0d2'), - fa_pinterest_square('\uf0d3'), - fa_google_plus_square('\uf0d4'), - fa_google_plus('\uf0d5'), - fa_money('\uf0d6'), - fa_caret_down('\uf0d7'), - fa_caret_up('\uf0d8'), - fa_caret_left('\uf0d9'), - fa_caret_right('\uf0da'), - fa_columns('\uf0db'), - fa_unsorted('\uf0dc'), - fa_sort('\uf0dc'), - fa_sort_down('\uf0dd'), - fa_sort_desc('\uf0dd'), - fa_sort_up('\uf0de'), - fa_sort_asc('\uf0de'), - fa_envelope('\uf0e0'), - fa_linkedin('\uf0e1'), - fa_rotate_left('\uf0e2'), - fa_undo('\uf0e2'), - fa_legal('\uf0e3'), - fa_gavel('\uf0e3'), - fa_dashboard('\uf0e4'), - fa_tachometer('\uf0e4'), - fa_comment_o('\uf0e5'), - fa_comments_o('\uf0e6'), - fa_flash('\uf0e7'), - fa_bolt('\uf0e7'), - fa_sitemap('\uf0e8'), - fa_umbrella('\uf0e9'), - fa_paste('\uf0ea'), - fa_clipboard('\uf0ea'), - fa_lightbulb_o('\uf0eb'), - fa_exchange('\uf0ec'), - fa_cloud_download('\uf0ed'), - fa_cloud_upload('\uf0ee'), - fa_user_md('\uf0f0'), - fa_stethoscope('\uf0f1'), - fa_suitcase('\uf0f2'), - fa_bell_o('\uf0a2'), - fa_coffee('\uf0f4'), - fa_cutlery('\uf0f5'), - fa_file_text_o('\uf0f6'), - fa_building_o('\uf0f7'), - fa_hospital_o('\uf0f8'), - fa_ambulance('\uf0f9'), - fa_medkit('\uf0fa'), - fa_fighter_jet('\uf0fb'), - fa_beer('\uf0fc'), - fa_h_square('\uf0fd'), - fa_plus_square('\uf0fe'), - fa_angle_double_left('\uf100'), - fa_angle_double_right('\uf101'), - fa_angle_double_up('\uf102'), - fa_angle_double_down('\uf103'), - fa_angle_left('\uf104'), - fa_angle_right('\uf105'), - fa_angle_up('\uf106'), - fa_angle_down('\uf107'), - fa_desktop('\uf108'), - fa_laptop('\uf109'), - fa_tablet('\uf10a'), - fa_mobile_phone('\uf10b'), - fa_mobile('\uf10b'), - fa_circle_o('\uf10c'), - fa_quote_left('\uf10d'), - fa_quote_right('\uf10e'), - fa_spinner('\uf110'), - fa_circle('\uf111'), - fa_mail_reply('\uf112'), - fa_reply('\uf112'), - fa_github_alt('\uf113'), - fa_folder_o('\uf114'), - fa_folder_open_o('\uf115'), - fa_smile_o('\uf118'), - fa_frown_o('\uf119'), - fa_meh_o('\uf11a'), - fa_gamepad('\uf11b'), - fa_keyboard_o('\uf11c'), - fa_flag_o('\uf11d'), - fa_flag_checkered('\uf11e'), - fa_terminal('\uf120'), - fa_code('\uf121'), - fa_mail_reply_all('\uf122'), - fa_reply_all('\uf122'), - fa_star_half_empty('\uf123'), - fa_star_half_full('\uf123'), - fa_star_half_o('\uf123'), - fa_location_arrow('\uf124'), - fa_crop('\uf125'), - fa_code_fork('\uf126'), - fa_unlink('\uf127'), - fa_chain_broken('\uf127'), - fa_question('\uf128'), - fa_info('\uf129'), - fa_exclamation('\uf12a'), - fa_superscript('\uf12b'), - fa_subscript('\uf12c'), - fa_eraser('\uf12d'), - fa_puzzle_piece('\uf12e'), - fa_microphone('\uf130'), - fa_microphone_slash('\uf131'), - fa_shield('\uf132'), - fa_calendar_o('\uf133'), - fa_fire_extinguisher('\uf134'), - fa_rocket('\uf135'), - fa_maxcdn('\uf136'), - fa_chevron_circle_left('\uf137'), - fa_chevron_circle_right('\uf138'), - fa_chevron_circle_up('\uf139'), - fa_chevron_circle_down('\uf13a'), - fa_html5('\uf13b'), - fa_css3('\uf13c'), - fa_anchor('\uf13d'), - fa_unlock_alt('\uf13e'), - fa_bullseye('\uf140'), - fa_ellipsis_h('\uf141'), - fa_ellipsis_v('\uf142'), - fa_rss_square('\uf143'), - fa_play_circle('\uf144'), - fa_ticket('\uf145'), - fa_minus_square('\uf146'), - fa_minus_square_o('\uf147'), - fa_level_up('\uf148'), - fa_level_down('\uf149'), - fa_check_square('\uf14a'), - fa_pencil_square('\uf14b'), - fa_external_link_square('\uf14c'), - fa_share_square('\uf14d'), - fa_compass('\uf14e'), - fa_toggle_down('\uf150'), - fa_caret_square_o_down('\uf150'), - fa_toggle_up('\uf151'), - fa_caret_square_o_up('\uf151'), - fa_toggle_right('\uf152'), - fa_caret_square_o_right('\uf152'), - fa_euro('\uf153'), - fa_eur('\uf153'), - fa_gbp('\uf154'), - fa_dollar('\uf155'), - fa_usd('\uf155'), - fa_rupee('\uf156'), - fa_inr('\uf156'), - fa_cny('\uf157'), - fa_rmb('\uf157'), - fa_yen('\uf157'), - fa_jpy('\uf157'), - fa_ruble('\uf158'), - fa_rouble('\uf158'), - fa_rub('\uf158'), - fa_won('\uf159'), - fa_krw('\uf159'), - fa_bitcoin('\uf15a'), - fa_btc('\uf15a'), - fa_file('\uf15b'), - fa_file_text('\uf15c'), - fa_sort_alpha_asc('\uf15d'), - fa_sort_alpha_desc('\uf15e'), - fa_sort_amount_asc('\uf160'), - fa_sort_amount_desc('\uf161'), - fa_sort_numeric_asc('\uf162'), - fa_sort_numeric_desc('\uf163'), - fa_thumbs_up('\uf164'), - fa_thumbs_down('\uf165'), - fa_youtube_square('\uf166'), - fa_youtube('\uf167'), - fa_xing('\uf168'), - fa_xing_square('\uf169'), - fa_youtube_play('\uf16a'), - fa_dropbox('\uf16b'), - fa_stack_overflow('\uf16c'), - fa_instagram('\uf16d'), - fa_flickr('\uf16e'), - fa_adn('\uf170'), - fa_bitbucket('\uf171'), - fa_bitbucket_square('\uf172'), - fa_tumblr('\uf173'), - fa_tumblr_square('\uf174'), - fa_long_arrow_down('\uf175'), - fa_long_arrow_up('\uf176'), - fa_long_arrow_left('\uf177'), - fa_long_arrow_right('\uf178'), - fa_apple('\uf179'), - fa_windows('\uf17a'), - fa_android('\uf17b'), - fa_linux('\uf17c'), - fa_dribbble('\uf17d'), - fa_skype('\uf17e'), - fa_foursquare('\uf180'), - fa_trello('\uf181'), - fa_female('\uf182'), - fa_male('\uf183'), - fa_gittip('\uf184'), - fa_gratipay('\uf184'), - fa_sun_o('\uf185'), - fa_moon_o('\uf186'), - fa_archive('\uf187'), - fa_bug('\uf188'), - fa_vk('\uf189'), - fa_weibo('\uf18a'), - fa_renren('\uf18b'), - fa_pagelines('\uf18c'), - fa_stack_exchange('\uf18d'), - fa_arrow_circle_o_right('\uf18e'), - fa_arrow_circle_o_left('\uf190'), - fa_toggle_left('\uf191'), - fa_caret_square_o_left('\uf191'), - fa_dot_circle_o('\uf192'), - fa_wheelchair('\uf193'), - fa_vimeo_square('\uf194'), - fa_turkish_lira('\uf195'), - fa_try('\uf195'), - fa_plus_square_o('\uf196'), - fa_space_shuttle('\uf197'), - fa_slack('\uf198'), - fa_envelope_square('\uf199'), - fa_wordpress('\uf19a'), - fa_openid('\uf19b'), - fa_institution('\uf19c'), - fa_bank('\uf19c'), - fa_university('\uf19c'), - fa_mortar_board('\uf19d'), - fa_graduation_cap('\uf19d'), - fa_yahoo('\uf19e'), - fa_google('\uf1a0'), - fa_reddit('\uf1a1'), - fa_reddit_square('\uf1a2'), - fa_stumbleupon_circle('\uf1a3'), - fa_stumbleupon('\uf1a4'), - fa_delicious('\uf1a5'), - fa_digg('\uf1a6'), - fa_pied_piper('\uf1a7'), - fa_pied_piper_alt('\uf1a8'), - fa_drupal('\uf1a9'), - fa_joomla('\uf1aa'), - fa_language('\uf1ab'), - fa_fax('\uf1ac'), - fa_building('\uf1ad'), - fa_child('\uf1ae'), - fa_paw('\uf1b0'), - fa_spoon('\uf1b1'), - fa_cube('\uf1b2'), - fa_cubes('\uf1b3'), - fa_behance('\uf1b4'), - fa_behance_square('\uf1b5'), - fa_steam('\uf1b6'), - fa_steam_square('\uf1b7'), - fa_recycle('\uf1b8'), - fa_automobile('\uf1b9'), - fa_car('\uf1b9'), - fa_cab('\uf1ba'), - fa_taxi('\uf1ba'), - fa_tree('\uf1bb'), - fa_spotify('\uf1bc'), - fa_deviantart('\uf1bd'), - fa_soundcloud('\uf1be'), - fa_database('\uf1c0'), - fa_file_pdf_o('\uf1c1'), - fa_file_word_o('\uf1c2'), - fa_file_excel_o('\uf1c3'), - fa_file_powerpoint_o('\uf1c4'), - fa_file_photo_o('\uf1c5'), - fa_file_picture_o('\uf1c5'), - fa_file_image_o('\uf1c5'), - fa_file_zip_o('\uf1c6'), - fa_file_archive_o('\uf1c6'), - fa_file_sound_o('\uf1c7'), - fa_file_audio_o('\uf1c7'), - fa_file_movie_o('\uf1c8'), - fa_file_video_o('\uf1c8'), - fa_file_code_o('\uf1c9'), - fa_vine('\uf1ca'), - fa_codepen('\uf1cb'), - fa_jsfiddle('\uf1cc'), - fa_life_bouy('\uf1cd'), - fa_life_buoy('\uf1cd'), - fa_life_saver('\uf1cd'), - fa_support('\uf1cd'), - fa_life_ring('\uf1cd'), - fa_circle_o_notch('\uf1ce'), - fa_ra('\uf1d0'), - fa_rebel('\uf1d0'), - fa_ge('\uf1d1'), - fa_empire('\uf1d1'), - fa_git_square('\uf1d2'), - fa_git('\uf1d3'), - fa_y_combinator_square('\uf1d4'), - fa_yc_square('\uf1d4'), - fa_hacker_news('\uf1d4'), - fa_tencent_weibo('\uf1d5'), - fa_qq('\uf1d6'), - fa_wechat('\uf1d7'), - fa_weixin('\uf1d7'), - fa_send('\uf1d8'), - fa_paper_plane('\uf1d8'), - fa_send_o('\uf1d9'), - fa_paper_plane_o('\uf1d9'), - fa_history('\uf1da'), - fa_circle_thin('\uf1db'), - fa_header('\uf1dc'), - fa_paragraph('\uf1dd'), - fa_sliders('\uf1de'), - fa_share_alt('\uf1e0'), - fa_share_alt_square('\uf1e1'), - fa_bomb('\uf1e2'), - fa_soccer_ball_o('\uf1e3'), - fa_futbol_o('\uf1e3'), - fa_tty('\uf1e4'), - fa_binoculars('\uf1e5'), - fa_plug('\uf1e6'), - fa_slideshare('\uf1e7'), - fa_twitch('\uf1e8'), - fa_yelp('\uf1e9'), - fa_newspaper_o('\uf1ea'), - fa_wifi('\uf1eb'), - fa_calculator('\uf1ec'), - fa_paypal('\uf1ed'), - fa_google_wallet('\uf1ee'), - fa_cc_visa('\uf1f0'), - fa_cc_mastercard('\uf1f1'), - fa_cc_discover('\uf1f2'), - fa_cc_amex('\uf1f3'), - fa_cc_paypal('\uf1f4'), - fa_cc_stripe('\uf1f5'), - fa_bell_slash('\uf1f6'), - fa_bell_slash_o('\uf1f7'), - fa_trash('\uf1f8'), - fa_copyright('\uf1f9'), - fa_at('\uf1fa'), - fa_eyedropper('\uf1fb'), - fa_paint_brush('\uf1fc'), - fa_birthday_cake('\uf1fd'), - fa_area_chart('\uf1fe'), - fa_pie_chart('\uf200'), - fa_line_chart('\uf201'), - fa_lastfm('\uf202'), - fa_lastfm_square('\uf203'), - fa_toggle_off('\uf204'), - fa_toggle_on('\uf205'), - fa_bicycle('\uf206'), - fa_bus('\uf207'), - fa_ioxhost('\uf208'), - fa_angellist('\uf209'), - fa_cc('\uf20a'), - fa_shekel('\uf20b'), - fa_sheqel('\uf20b'), - fa_ils('\uf20b'), - fa_meanpath('\uf20c'), - fa_buysellads('\uf20d'), - fa_connectdevelop('\uf20e'), - fa_dashcube('\uf210'), - fa_forumbee('\uf211'), - fa_leanpub('\uf212'), - fa_sellsy('\uf213'), - fa_shirtsinbulk('\uf214'), - fa_simplybuilt('\uf215'), - fa_skyatlas('\uf216'), - fa_cart_plus('\uf217'), - fa_cart_arrow_down('\uf218'), - fa_diamond('\uf219'), - fa_ship('\uf21a'), - fa_user_secret('\uf21b'), - fa_motorcycle('\uf21c'), - fa_street_view('\uf21d'), - fa_heartbeat('\uf21e'), - fa_venus('\uf221'), - fa_mars('\uf222'), - fa_mercury('\uf223'), - fa_intersex('\uf224'), - fa_transgender('\uf224'), - fa_transgender_alt('\uf225'), - fa_venus_double('\uf226'), - fa_mars_double('\uf227'), - fa_venus_mars('\uf228'), - fa_mars_stroke('\uf229'), - fa_mars_stroke_v('\uf22a'), - fa_mars_stroke_h('\uf22b'), - fa_neuter('\uf22c'), - fa_genderless('\uf22d'), - fa_facebook_official('\uf230'), - fa_pinterest_p('\uf231'), - fa_whatsapp('\uf232'), - fa_server('\uf233'), - fa_user_plus('\uf234'), - fa_user_times('\uf235'), - fa_hotel('\uf236'), - fa_bed('\uf236'), - fa_viacoin('\uf237'), - fa_train('\uf238'), - fa_subway('\uf239'), - fa_medium('\uf23a'), - fa_yc('\uf23b'), - fa_y_combinator('\uf23b'), - fa_optin_monster('\uf23c'), - fa_opencart('\uf23d'), - fa_expeditedssl('\uf23e'), - fa_battery_4('\uf240'), - fa_battery_full('\uf240'), - fa_battery_3('\uf241'), - fa_battery_three_quarters('\uf241'), - fa_battery_2('\uf242'), - fa_battery_half('\uf242'), - fa_battery_1('\uf243'), - fa_battery_quarter('\uf243'), - fa_battery_0('\uf244'), - fa_battery_empty('\uf244'), - fa_mouse_pointer('\uf245'), - fa_i_cursor('\uf246'), - fa_object_group('\uf247'), - fa_object_ungroup('\uf248'), - fa_sticky_note('\uf249'), - fa_sticky_note_o('\uf24a'), - fa_cc_jcb('\uf24b'), - fa_cc_diners_club('\uf24c'), - fa_clone('\uf24d'), - fa_balance_scale('\uf24e'), - fa_hourglass_o('\uf250'), - fa_hourglass_1('\uf251'), - fa_hourglass_start('\uf251'), - fa_hourglass_2('\uf252'), - fa_hourglass_half('\uf252'), - fa_hourglass_3('\uf253'), - fa_hourglass_end('\uf253'), - fa_hourglass('\uf254'), - fa_hand_grab_o('\uf255'), - fa_hand_rock_o('\uf255'), - fa_hand_stop_o('\uf256'), - fa_hand_paper_o('\uf256'), - fa_hand_scissors_o('\uf257'), - fa_hand_lizard_o('\uf258'), - fa_hand_spock_o('\uf259'), - fa_hand_pointer_o('\uf25a'), - fa_hand_peace_o('\uf25b'), - fa_trademark('\uf25c'), - fa_registered('\uf25d'), - fa_creative_commons('\uf25e'), - fa_gg('\uf260'), - fa_gg_circle('\uf261'), - fa_tripadvisor('\uf262'), - fa_odnoklassniki('\uf263'), - fa_odnoklassniki_square('\uf264'), - fa_get_pocket('\uf265'), - fa_wikipedia_w('\uf266'), - fa_safari('\uf267'), - fa_chrome('\uf268'), - fa_firefox('\uf269'), - fa_opera('\uf26a'), - fa_internet_explorer('\uf26b'), - fa_tv('\uf26c'), - fa_television('\uf26c'), - fa_contao('\uf26d'), - fa_500px('\uf26e'), - fa_amazon('\uf270'), - fa_calendar_plus_o('\uf271'), - fa_calendar_minus_o('\uf272'), - fa_calendar_times_o('\uf273'), - fa_calendar_check_o('\uf274'), - fa_industry('\uf275'), - fa_map_pin('\uf276'), - fa_map_signs('\uf277'), - fa_map_o('\uf278'), - fa_map('\uf279'), - fa_commenting('\uf27a'), - fa_commenting_o('\uf27b'), - fa_houzz('\uf27c'), - fa_vimeo('\uf27d'), - fa_black_tie('\uf27e'), - fa_fonticons('\uf280'), - fa_reddit_alien('\uf281'), - fa_edge('\uf282'), - fa_credit_card_alt('\uf283'), - fa_codiepie('\uf284'), - fa_modx('\uf285'), - fa_fort_awesome('\uf286'), - fa_usb('\uf287'), - fa_product_hunt('\uf288'), - fa_mixcloud('\uf289'), - fa_scribd('\uf28a'), - fa_pause_circle('\uf28b'), - fa_pause_circle_o('\uf28c'), - fa_stop_circle('\uf28d'), - fa_stop_circle_o('\uf28e'), - fa_shopping_bag('\uf290'), - fa_shopping_basket('\uf291'), - fa_hashtag('\uf292'), - fa_bluetooth('\uf293'), - fa_bluetooth_b('\uf294'), - fa_percent('\uf295'); - - char character; - - FontAwesomeIcons(char character) { - this.character = character; - } - - @Override - public String key() { - return name().replace('_', '-'); - } - - @Override - public char character() { - return character; - } -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java b/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java deleted file mode 100644 index 0f2dfce4d4..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/fonts/FontAwesomeModule.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.joanzapata.iconify.fonts; - -import com.joanzapata.iconify.Icon; -import com.joanzapata.iconify.IconFontDescriptor; - -public class FontAwesomeModule implements IconFontDescriptor { - - @Override - public String ttfFileName() { - return "iconify/android-iconify-fontawesome.ttf"; - } - - @Override - public Icon[] characters() { - return FontAwesomeIcons.values(); - } -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java b/iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java deleted file mode 100644 index a07bb49ef3..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/internal/CustomTypefaceSpan.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.joanzapata.iconify.internal; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.text.style.ReplacementSpan; -import com.joanzapata.iconify.Icon; - -public class CustomTypefaceSpan extends ReplacementSpan { - private static final int ROTATION_DURATION = 2000; - private static final Rect TEXT_BOUNDS = new Rect(); - private static final Paint LOCAL_PAINT = new Paint(); - private static final float BASELINE_RATIO = 1 / 7f; - - private final String icon; - private final Typeface type; - private final float iconSizePx; - private final float iconSizeRatio; - private final int iconColor; - private final boolean rotate; - private final boolean baselineAligned; - private final long rotationStartTime; - - public CustomTypefaceSpan(Icon icon, Typeface type, - float iconSizePx, float iconSizeRatio, int iconColor, - boolean rotate, boolean baselineAligned) { - this.rotate = rotate; - this.baselineAligned = baselineAligned; - this.icon = String.valueOf(icon.character()); - this.type = type; - this.iconSizePx = iconSizePx; - this.iconSizeRatio = iconSizeRatio; - this.iconColor = iconColor; - this.rotationStartTime = System.currentTimeMillis(); - } - - @Override - public int getSize(Paint paint, CharSequence text, - int start, int end, Paint.FontMetricsInt fm) { - LOCAL_PAINT.set(paint); - applyCustomTypeFace(LOCAL_PAINT, type); - LOCAL_PAINT.getTextBounds(icon, 0, 1, TEXT_BOUNDS); - if (fm != null) { - float baselineRatio = baselineAligned ? 0 : BASELINE_RATIO; - fm.descent = (int) (TEXT_BOUNDS.height() * baselineRatio); - fm.ascent = -(TEXT_BOUNDS.height() - fm.descent); - fm.top = fm.ascent; - fm.bottom = fm.descent; - } - return TEXT_BOUNDS.width(); - } - - @Override - public void draw(Canvas canvas, CharSequence text, - int start, int end, float x, int top, int y, - int bottom, Paint paint) { - applyCustomTypeFace(paint, type); - paint.getTextBounds(icon, 0, 1, TEXT_BOUNDS); - canvas.save(); - float baselineRatio = baselineAligned ? 0f : BASELINE_RATIO; - if (rotate) { - float rotation = (System.currentTimeMillis() - rotationStartTime) / (float) ROTATION_DURATION * 360f; - float centerX = x + TEXT_BOUNDS.width() / 2f; - float centerY = y - TEXT_BOUNDS.height() / 2f + TEXT_BOUNDS.height() * baselineRatio; - canvas.rotate(rotation, centerX, centerY); - } - - canvas.drawText(icon, - x - TEXT_BOUNDS.left, - y - TEXT_BOUNDS.bottom + TEXT_BOUNDS.height() * baselineRatio, paint); - canvas.restore(); - } - - public boolean isAnimated() { - return rotate; - } - - private void applyCustomTypeFace(Paint paint, Typeface tf) { - paint.setFakeBoldText(false); - paint.setTextSkewX(0f); - paint.setTypeface(tf); - if (rotate) paint.clearShadowLayer(); - if (iconSizeRatio > 0) paint.setTextSize(paint.getTextSize() * iconSizeRatio); - else if (iconSizePx > 0) paint.setTextSize(iconSizePx); - if (iconColor < Integer.MAX_VALUE) paint.setColor(iconColor); - } -} \ No newline at end of file diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java b/iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java deleted file mode 100644 index 773c2a6949..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/internal/HasOnViewAttachListener.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.joanzapata.iconify.internal; - -import android.widget.TextView; - -import androidx.core.view.ViewCompat; - -/** - * Any TextView subclass that wishes to call {@link com.joanzapata.iconify.Iconify#addIcons(TextView...)} on it - * needs to implement this interface if it ever want to use spinning icons. - *
    - * IconTextView, IconButton and IconToggleButton already implement it, but if you need to implement it - * yourself, please use {@link com.joanzapata.iconify.internal.HasOnViewAttachListener.HasOnViewAttachListenerDelegate} - * to help you. - */ -public interface HasOnViewAttachListener { - void setOnViewAttachListener(OnViewAttachListener listener); - - interface OnViewAttachListener { - void onAttach(); - - void onDetach(); - } - - /** - * Helper class to implement {@link HasOnViewAttachListener}. - * Usual implementation should look like this: - *

    -     * {@code
    -     * class MyClass extends TextView implements HasOnViewAttachListener {
    -     *
    -     *       private HasOnViewAttachListenerDelegate delegate
    -     *
    -     *       @Override
    -     *       public void setOnViewAttachListener(OnViewAttachListener listener) {
    -     *          if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this);
    -     *          delegate.setOnViewAttachListener(listener);
    -     *       }
    -     *
    -     *       @Override
    -     *       protected void onAttachedToWindow() {
    -     *          super.onAttachedToWindow();
    -     *          delegate.onAttachedToWindow();
    -     *       }
    -     *
    -     *       @Override
    -     *       protected void onDetachedFromWindow() {
    -     *          super.onDetachedFromWindow();
    -     *          delegate.onDetachedFromWindow();
    -     *      }
    -     *
    -     *  }
    -     * }
    -     * 
    - */ - class HasOnViewAttachListenerDelegate { - - private final TextView view; - private OnViewAttachListener listener; - - public HasOnViewAttachListenerDelegate(TextView view) { - this.view = view; - } - - public void setOnViewAttachListener(OnViewAttachListener listener) { - if (this.listener != null) - this.listener.onDetach(); - this.listener = listener; - if (ViewCompat.isAttachedToWindow(view) && listener != null) { - listener.onAttach(); - } - } - - public void onAttachedToWindow() { - if (listener != null) listener.onAttach(); - } - - public void onDetachedFromWindow() { - if (listener != null) listener.onDetach(); - } - - } -} \ No newline at end of file diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java b/iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java deleted file mode 100644 index b7e1d0045b..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/internal/IconFontDescriptorWrapper.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.joanzapata.iconify.internal; - -import android.content.Context; -import android.graphics.Typeface; -import com.joanzapata.iconify.Icon; -import com.joanzapata.iconify.IconFontDescriptor; - -import java.util.HashMap; -import java.util.Map; - -public class IconFontDescriptorWrapper { - - private final IconFontDescriptor iconFontDescriptor; - - private final Map iconsByKey; - - private Typeface cachedTypeface; - - public IconFontDescriptorWrapper(IconFontDescriptor iconFontDescriptor) { - this.iconFontDescriptor = iconFontDescriptor; - iconsByKey = new HashMap(); - Icon[] characters = iconFontDescriptor.characters(); - for (int i = 0, charactersLength = characters.length; i < charactersLength; i++) { - Icon icon = characters[i]; - iconsByKey.put(icon.key(), icon); - } - } - - public Icon getIcon(String key) { - return iconsByKey.get(key); - } - - public IconFontDescriptor getIconFontDescriptor() { - return iconFontDescriptor; - } - - public Typeface getTypeface(Context context) { - if (cachedTypeface != null) return cachedTypeface; - synchronized (this) { - if (cachedTypeface != null) return cachedTypeface; - cachedTypeface = Typeface.createFromAsset(context.getAssets(), iconFontDescriptor.ttfFileName()); - return cachedTypeface; - } - } - - public boolean hasIcon(Icon icon) { - return iconsByKey.values().contains(icon); - } -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java b/iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java deleted file mode 100644 index 574e7bbedf..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/internal/ParsingUtil.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.joanzapata.iconify.internal; - -import java.util.List; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Color; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.util.TypedValue; -import android.widget.TextView; - -import androidx.core.view.ViewCompat; - -import com.joanzapata.iconify.Icon; -import com.joanzapata.iconify.internal.HasOnViewAttachListener.OnViewAttachListener; - -public final class ParsingUtil { - - private static final String ANDROID_PACKAGE_NAME = "android"; - - // Prevents instantiation - private ParsingUtil() {} - - public static CharSequence parse( - Context context, - List iconFontDescriptors, - CharSequence text, - final TextView target) { - context = context.getApplicationContext(); - - // Don't do anything related to iconify if text is null - if (text == null) return text; - - // Analyse the text and replace {} blocks with the appropriate character - // Retain all transformations in the accumulator - final SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(text); - recursivePrepareSpannableIndexes(context, - text.toString(), spannableBuilder, - iconFontDescriptors, 0); - boolean isAnimated = hasAnimatedSpans(spannableBuilder); - - // If animated, periodically invalidate the TextView so that the - // CustomTypefaceSpan can redraw itself - if (isAnimated) { - if (target == null) - throw new IllegalArgumentException("You can't use \"spin\" without providing the target TextView."); - if (!(target instanceof HasOnViewAttachListener)) - throw new IllegalArgumentException(target.getClass().getSimpleName() + " does not implement " + - "HasOnViewAttachListener. Please use IconTextView, IconButton or IconToggleButton."); - - ((HasOnViewAttachListener) target).setOnViewAttachListener(new OnViewAttachListener() { - boolean isAttached = false; - - @Override - public void onAttach() { - isAttached = true; - ViewCompat.postOnAnimation(target, new Runnable() { - @Override - public void run() { - if (isAttached) { - target.invalidate(); - ViewCompat.postOnAnimation(target, this); - } - } - }); - } - - @Override - public void onDetach() { - isAttached = false; - } - }); - - } else if (target instanceof HasOnViewAttachListener) { - ((HasOnViewAttachListener) target).setOnViewAttachListener(null); - } - - return spannableBuilder; - } - - private static boolean hasAnimatedSpans(SpannableStringBuilder spannableBuilder) { - CustomTypefaceSpan[] spans = spannableBuilder.getSpans(0, spannableBuilder.length(), CustomTypefaceSpan.class); - for (CustomTypefaceSpan span : spans) { - if (span.isAnimated()) - return true; - } - return false; - } - - private static void recursivePrepareSpannableIndexes( - Context context, - String fullText, - SpannableStringBuilder text, - List iconFontDescriptors, - int start) { - - // Try to find a {...} in the string and extract expression from it - String stringText = text.toString(); - int startIndex = stringText.indexOf("{", start); - if (startIndex == -1) return; - int endIndex = stringText.indexOf("}", startIndex) + 1; - if (endIndex == -1) return; - String expression = stringText.substring(startIndex + 1, endIndex - 1); - - // Split the expression and retrieve the icon key - String[] strokes = expression.split(" "); - String key = strokes[0]; - - // Loop through the descriptors to find a key match - IconFontDescriptorWrapper iconFontDescriptor = null; - Icon icon = null; - for (int i = 0; i < iconFontDescriptors.size(); i++) { - iconFontDescriptor = iconFontDescriptors.get(i); - icon = iconFontDescriptor.getIcon(key); - if (icon != null) break; - } - - // If no match, ignore and continue - if (icon == null) { - recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, endIndex); - return; - } - - // See if any more stroke within {} should be applied - float iconSizePx = -1; - int iconColor = Integer.MAX_VALUE; - float iconSizeRatio = -1; - boolean spin = false; - boolean baselineAligned = false; - for (int i = 1; i < strokes.length; i++) { - String stroke = strokes[i]; - - // Look for "spin" - if (stroke.equalsIgnoreCase("spin")) { - spin = true; - } - - // Look for "baseline" - else if (stroke.equalsIgnoreCase("baseline")) { - baselineAligned = true; - } - - // Look for an icon size - else if (stroke.matches("([0-9]*(\\.[0-9]*)?)dp")) { - iconSizePx = dpToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2))); - } else if (stroke.matches("([0-9]*(\\.[0-9]*)?)sp")) { - iconSizePx = spToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2))); - } else if (stroke.matches("([0-9]*)px")) { - iconSizePx = Integer.valueOf(stroke.substring(0, stroke.length() - 2)); - } else if (stroke.matches("@dimen/(.*)")) { - iconSizePx = getPxFromDimen(context, context.getPackageName(), stroke.substring(7)); - if (iconSizePx < 0) - throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); - } else if (stroke.matches("@android:dimen/(.*)")) { - iconSizePx = getPxFromDimen(context, ANDROID_PACKAGE_NAME, stroke.substring(15)); - if (iconSizePx < 0) - throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); - } else if (stroke.matches("([0-9]*(\\.[0-9]*)?)%")) { - iconSizeRatio = Float.valueOf(stroke.substring(0, stroke.length() - 1)) / 100f; - } - - // Look for an icon color - else if (stroke.matches("#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})")) { - iconColor = Color.parseColor(stroke); - } else if (stroke.matches("@color/(.*)")) { - iconColor = getColorFromResource(context, context.getPackageName(), stroke.substring(7)); - if (iconColor == Integer.MAX_VALUE) - throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); - } else if (stroke.matches("@android:color/(.*)")) { - iconColor = getColorFromResource(context, ANDROID_PACKAGE_NAME, stroke.substring(15)); - if (iconColor == Integer.MAX_VALUE) - throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\""); - } else { - throw new IllegalArgumentException("Unknown expression " + stroke + " in \"" + fullText + "\""); - } - } - - // Replace the character and apply the typeface - text = text.replace(startIndex, endIndex, "" + icon.character()); - text.setSpan(new CustomTypefaceSpan(icon, - iconFontDescriptor.getTypeface(context), - iconSizePx, iconSizeRatio, iconColor, spin, baselineAligned), - startIndex, startIndex + 1, - Spanned.SPAN_INCLUSIVE_EXCLUSIVE); - recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, startIndex); - } - - public static float getPxFromDimen(Context context, String packageName, String resName) { - Resources resources = context.getResources(); - int resId = resources.getIdentifier( - resName, "dimen", - packageName); - if (resId <= 0) return -1; - return resources.getDimension(resId); - } - - public static int getColorFromResource(Context context, String packageName, String resName) { - Resources resources = context.getResources(); - int resId = resources.getIdentifier( - resName, "color", - packageName); - if (resId <= 0) return Integer.MAX_VALUE; - return resources.getColor(resId); - } - - public static float dpToPx(Context context, float dp) { - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, - context.getResources().getDisplayMetrics()); - } - - public static float spToPx(Context context, float sp) { - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, - context.getResources().getDisplayMetrics()); - } - -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java b/iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java deleted file mode 100644 index 8f5ee12ecf..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/widget/IconButton.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.joanzapata.iconify.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.Button; -import com.joanzapata.iconify.Iconify; -import com.joanzapata.iconify.internal.HasOnViewAttachListener; - -public class IconButton extends Button implements HasOnViewAttachListener { - - private HasOnViewAttachListenerDelegate delegate; - - public IconButton(Context context) { - super(context); - init(); - } - - public IconButton(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public IconButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - private void init() { - setTransformationMethod(null); - } - - @Override - public void setText(CharSequence text, BufferType type) { - super.setText(Iconify.compute(getContext(), text, this), type); - } - - - @Override - public void setOnViewAttachListener(HasOnViewAttachListener.OnViewAttachListener listener) { - if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this); - delegate.setOnViewAttachListener(listener); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - delegate.onAttachedToWindow(); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - delegate.onDetachedFromWindow(); - } -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java b/iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java deleted file mode 100644 index 00a3b04c54..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/widget/IconTextView.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.joanzapata.iconify.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.TextView; -import com.joanzapata.iconify.Iconify; -import com.joanzapata.iconify.internal.HasOnViewAttachListener; - -public class IconTextView extends TextView implements HasOnViewAttachListener { - - private HasOnViewAttachListenerDelegate delegate; - - public IconTextView(Context context) { - super(context); - init(); - } - - public IconTextView(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public IconTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - private void init() { - setTransformationMethod(null); - } - - @Override - public void setText(CharSequence text, BufferType type) { - super.setText(Iconify.compute(getContext(), text, this), type); - } - - @Override - public void setOnViewAttachListener(OnViewAttachListener listener) { - if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this); - delegate.setOnViewAttachListener(listener); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - delegate.onAttachedToWindow(); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - delegate.onDetachedFromWindow(); - } -} diff --git a/iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java b/iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java deleted file mode 100644 index 4bdb9ed5fe..0000000000 --- a/iconify/src/main/java/com/joanzapata/iconify/widget/IconToggleButton.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.joanzapata.iconify.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.ToggleButton; -import com.joanzapata.iconify.Iconify; -import com.joanzapata.iconify.internal.HasOnViewAttachListener; - -public class IconToggleButton extends ToggleButton implements HasOnViewAttachListener { - - private HasOnViewAttachListenerDelegate delegate; - - public IconToggleButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - public IconToggleButton(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public IconToggleButton(Context context) { - super(context); - init(); - } - - private void init() { - setTransformationMethod(null); - } - - @Override - public void setText(CharSequence text, BufferType type) { - super.setText(Iconify.compute(getContext(), text, this), BufferType.NORMAL); - } - - @Override - public void setOnViewAttachListener(HasOnViewAttachListener.OnViewAttachListener listener) { - if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this); - delegate.setOnViewAttachListener(listener); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - delegate.onAttachedToWindow(); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - delegate.onDetachedFromWindow(); - } - -} diff --git a/libs/iconify.aar b/libs/iconify.aar new file mode 100644 index 0000000000000000000000000000000000000000..1247bf7f92650c7b349b347fa5280b195deb840c GIT binary patch literal 126846 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

    SFlevHLABJ}SVe&e& zV1nvCy;t2|GSvc-R#6OPQXx^J1Ia___4kbLUZp81(X8qof6w~iyOe@o#iiK;#6F6d zi_6ic&Dek~%*W8WAN@<%v<9^3{zCq-Y-ej^J6cmat_KSM01Gp-!2(&7A7Ue5j_i={ z2MfVp<%eXEZj;}T{|q|hkJih-Cp_xG^}V1Jvz*BvF~61nEWZf^`5*G%<)4Exdbj*@ z`5#~`62SFnZ26k_iRe*#DdoYq%>fJg3no||Q;Fg~8t_`|y~b)!+%>@7F)%d8N1J?^ zMV;`S&dh(Wfos;h2R=y2fy|?{w-*d%QZQ9>`#rZo*FpKnb@0g@nUg!{9hp77@S@{) z9zIMJ+FNWYejJ5H3+%v(>9x@q6Hw=VDkmN0Lp2ruzeKUbH0LsF>ixYh%AZ)T3b>fs zk_!2wCsKQ!cw$cq9IGsQsH~FwJhXN8i378@Zk^4XH+$>3@bZqX-S6xKrgT?F=6qKm z03Q41;fKF@7+!x*>6kI4_n?bD&u8CS@J*NqE=IAhNi-KJnvL!t)Idrv1-I;cWarLD z;3H&{<^555@6dhtnEJ2q+k0$JZ}$s5&J_Vi{og-PU>u|N8!RaE+>vYhzR~x&}V@@5eZ3K6)ci4 zvC}bnPX(#@yO!2JoJa>0Zm6ITq2- zVp+Gjru2e|OHvxm&G15ZK&z>%=XHKpX+X=Dm1;DBA8 zOW2@8gt|ALAmQI6v|YmOgC$oixFcy+YK(`%XfQGX!uf|AHjeoRSdLfP+C!t`43_i7 z5kghZoQi5t9iBH;vuIyG4HLDKu6feh8LqkY{+dvy%^2}}UV6({(a@x4O?S$DcNtih zsqXe~AM<-mmuW548-FYRec!TBb(GQAD>$IxMC01W0R4osyqp;eDu-FZZmEvgt!qU` zyluj{hNYeLi>&2yK(o!ou~sX`mslkykA!lTFUin+xPW149>61yAL3PI{H}=t&!|-dfQNBxO6m;_KMvd00;_IOWk6BLXbRcDxB!=kw zPh|ZuD41c>_@1iIM-FB5*4i10D3W3x>@!so=$^ zDee$7g;hWel=EfZgxWJiq6F2Y5EgU;ej3J9NfpbxWVNJlYJw~msX`3ru-e&8;dvLO z>X$4S-!^-8^yV9{-?Z_;DQo-uwJX+4-oC7{aaLgb0r|r+Pe(i+?4+kneFV^G79PKA z*9%^+&yRN4e|&WCT93!?A77E|j4s=>^CjlOwrSHk;-a3ras9e6w3%iMIbV2!-L1^Z z6tDy>g#Ad}!XIZA;6E-kv<l{p8-GTVo~*adH-&mH<0-i}?O6`WRf zH}O*}MN-@hw0@wdhB%p@7b2Xwj-eA(tt|^$TbWtO+G(u|S`V~VSG9tvktBR*U214$ zYW-y1VC1JPe|z~9-e};#A$-2Is=AdabKv_Z|K4b=lIK*nwpN3Os#>MYnn?1`c<;~3 zZ!!XJ0XHUI+_vq-#KlIQGwiFX+GpT+W9G)}Rn;vmXdcD#&bNf4!bJIzWMc&tpdL&H zUlRP00H#1{aBv|WRSJagxWjXJ{BEaPK?n)I?R2OSD;_`?s~FHpEJKo+E)-W)5qOYC zqkaM{t=m_90~R$Q!I_gei}~+K;Z;IvqVUl5zzFB z11|)u?ZBce5=_aEXvbObdoTe`kzUEg9%zfB2?mW<=wcH0j&DY6pK-!8-;QK;TppX< z(ZF+P*@$bzC^J>K5l#6V3DUB5fJVIB3kYbbfgWkcH)x0h55$E51jvLYP(Nsp3@Z(R z?~j{+2-PuCKy)_`&09H#;yj5pRz!~#!Y7Fa3)MQI%#Kk4{lcqx?f4-yxh;vzG)*b$SuW6qXXZd7TKfV@hb?FLjqeptbNij?wcL0IW`n z6#%!CX>h3Hg0)yAeW;)AL5UbXMGM ztFqI;Q)Uz$vosKJ8k?7a9K$jd5w?=C-lsLws%p3_2FN7H&5{19p_9IItHNDEb>R{yxpKnpyC0;6eSjkHOtWoZa> zkYO}}2ABnyu-YN-bOc=?O=x+kWlczQ==`3V1=4hD&E$$`Y1!RLDOpkNWOaT3(D1Dj z7Faw^Tg)5vYmFi_unh3iwBLGBz`1I?qq>?Ft-1@wcGc<`H1LTYUK6y3tmg^_1~&GD z$H)3B#!Y0AjIc7X*n~t4z0U29`$e~?6`(yNnyr$q>5R&jw(i(iec0>s(E<=mF0-3i z4J5#!ssIzMH*)eEps}#5MhAgeM{DrwhVm_<(^TR%m+Aa`H9PiPtF_~jF98Ua0_L^APAlJ!*Dw6tcoNlP>QxCsD^D>v1YLt3u|Ws=62kh4gd^h$)shpkYyQ;=7G@aGU(gO zwKQMSF}ACWyKkJhM&q=Vca)Y&fE~Zu;AI?_X-$zz+SF1Xadv6U8pvw-Mzd*3NW(=+ zIvr&|+Um8fUF;HrUOio9aY3kMfyw#{4No()j^hC|Cm0|O>Ma@oH~<(o&3*H*jHdyqIg?jVYV1?Ge z=tRH2+h=8Iqp6B>8ti&gmtfIyB^u5v&|FR9_^{=tjZ^(vr`cYHnXlKxyR6qVZhYyC z9o05a=B_&2wS4=gwJmQhte;#7p+ATkT_YLF*q|^kF=^NM$*iwFP=cyeqSsHIY$%U< z+!#wY+RzPTu-?01gfa&Q^_qEx)@~`AWU{O!Q^#^u@ zf{b|f`8yA!y&yur|JE-Tj@fX-(BIL74re{{&GcCpZ<%=EkJNJzL$4y_h zmVf#2w7<~j0C3&i(vRPEO^mnNWdA3R0z*l1Tz6@#igTduMWdAg3tt`$yHIVvc4`@3 zdqn6ufO&?a4IWzYS;DNn5XX_01H!|O<4x(T{h=KyBvl+?WmS;cutXHc3}ucU4x@xa!7je6Y7GwV^XKbwTUFGwj};@zL4!RSjhg(f_```_c^) zz`73)@9mq>eT{tLxeewXbqBC`2fWuXH(uk^J9*x0c3EaPeST-MHnBKT-m#&(ZAoiT zsIUvx%5c7LQISJ{zI;2ol`szK|9S4a#<2h~L) zm9ln(1i|udAe6qL0_$Kr!RfFo262o9nEWjVHA=@_fc_-NmfA8+j&cqJ93J17b`R|| zGUYb;cUX%H&Jg_{n`X2#9A|eo_~gGEwHkSuz1xtOK8HSkdD4Cd(>{Zl`3r~NZ$0rC zdO)wsRA$=SW<%Fjl?B~jbj!QsUs~+88oO1emE9%0);^uxn^@l8KlG^ui~|=B*Tbnk z4RNeewgL|Ywo04ju*|5Yo~Go4r4z^> zN^k6esh*AUASn%;`>nTQwLq2u z4kD4t?x-kK?yz8)*-}QTms8nm`}n>~s8Q8(6&5^^&%AT+dtAR1P1d{{V0Vv||oP8$qi*GDX4CW6Gb zmQ4_1c7k`q5(id?olP&f^_@@Oxpj%M0UH>z{Jzm7$nQU{^XeX#-xo|q`F%6PY9D`G z%Q9wAflh*o$F+X#*%c6_{}#4b=~(V9k!_U-{>SuY=OtegGV=?&9E>G37Jg*mA@1gHf?u zs8n#kxU^~uu2wz&h@#Us!vB3lOh~c-bpoy_{DRS$t)l_1nfmc5iSJYVYiZQfW}4iS@8M~j zz=s3yx!#a#u=7nx664}atTj1d#n@DIb$5$kddgbrlqA~n>t+QOByi0!wFiBXxivAKkx3FQKpk0p zOw_Ew2&h17Is7pu;uS%(?nNUbj!PBME?y9Nu)`NNXroV;EH0r3r~sRBw7ygpl|gch z917#bt+GUiKg4F!nKrxFHG8W@YZS_Oi%0N0QTwM2>t@&09qZq)9IX-uHpSWjMjaaaa5%QdTp&utjpO7<}ZwfwGDBXrnI8H{lSH$V-4k{JN_}`pJWnTKL13o`&OfyW%b5# zfz>Zt(_7(xX8D;*-DOX-_TDf_aD0AH*<9Uq&BcA~o!g&UzXdR<`!AiEyiPEnZU9@_ zI<^=EJ?c@-YvJ-`JDSkbQ5iaVjp*slF|2V`Z)S_zB{sO{Jl-`iCUWIXb)0Kjp?tBK z(oz!US0{Y1XswM|@2!x>B*qoM%%j25VrN9=oCjWf;ei9s`vcF*w`N{_;$Bd}#GZIH z^BAbO*S~Dp!f&p<_8YcMb`QyCt$Y_ap9K?tlc|zFd3Pl^JOuvY`HlRnqU%HQ!-Ysz zTZeToG!|DmiYEveXgn4mHXi`=dBt&>#c8%2#A6W_t^64QEpyNig>@qW{**bKWH0nC zTGqF6*{oKxWs`jPP08hwj)3Yl6;qZiTCrfRZ}ZESZSE+Exp@2JuH|zUBx|`zdsZxH zi~8&=W6-!KH#G{OX!kj-6)a~JH9T4)33c&B%P;DJ;kKFc=S^?1SR4(Ub6U^#tyhDe z^lWYO(t@W%r~63$7Pvws;GLs_s4><|-95L?8kjk~=HdZBL)uc-G{+%h_9)-<+t*{%x5}&z!vl zxF^itF8>o4x6hvdCY_{Cf+^_d%FfPt+qW0Unk7hDs#jxcMy36!2vJPi2EhH}$Pgz#X@retVr!K|Jp99}n*g>_3paV0B zDh#Ib$?q)f2pL|{ndXaGEW?kmHc%m#)uM!KS*$qz^gDvP(%3J_poUx-LPIZok60=m zef#D47WWtdewK~?5mOK!26wW`>KEVnMf|TQE?naNklR%ktG~>cBP_NFm;g8 zh*m(i5`>HsTN)&v&4(kUB>Lo#-kOE<6bMXLi4{4Z538Qbu#7>Uh*@TH_@$w&2sen9g*g9L`!HI`MGNx{{rnA@C+4xxE_ld_q2)MzXVHPwM3jvi8uYs+QQI=vk=bR1@D@$za7Ub%O|$7R=jt?nc0L~Vg%NoVlUZz+;l)iYqqH&I!a}7gHg^Z z_B~^%WrYP&9v}f@lnxR+t#;n1U4-(t!_I06(JVC0!?lX93|`f|7d#;_^7J%Z~UHf@0~ln-RU*cCq0?T%%o>h2oTZ;J+#oP z5PA_|XeuhGC`AQ{ir70A6x~?YwV?iR3%(ZI)!o(AwHF|Bc+a_a5(2V6-Ou~~2j<>W zZ#nmr=Q+>wd>;wt#RMu)gIqvIBeahvkhZ|ZL|IP|E?jhL3J+E0ouJ*ABZMS~FwRj4XNzO!TqIv$jsD?Iieg1C0tLVle^rv7>k;OtZD#6>} zBzT)>S28M()!3fQj1Pjt(IM#elEF&2L{W-_8Ow9QeuoA%fIb%tWmG^hmw7Ij0foa2 z!6)J%K(p*u)uSfgU&@WHC~VOr&}#|l=*q%oP2wh}v1()@Z{NIqHdAFsB5!|8%!q?{ zTsnpnj@@oFRgS65+duE1rLPaf=b_i&&m*g*c`EKQ+A7Az^Y5I0&|)TmJ7Ti-DqJ@P z%HqRit;v!GrKp)WADES0UK$Rx zS+kbfATQHlj)Rrs6AvFWw^9AFL_u$##l3kbHIkY}EuknLuV6taph?n#@F%Dd_caLj z#1ABSgT6R%YHt?JBQdql@+Pye2I6lEIX)gMp|TjfR6_z#6U56+oXYaYaXd(TX5hGK zLp@mh(!W_LtC8B7X7qVM4zK3Lj#A*}nR2^v_HhmnEMEM!j+aP|TAjnixhY z(c|7+gCt)9X8p$QdGw`I-+t&{6@9mZg`oNC9Xq~8htZAbFbRP%pc7PmdgYa$q8HI2 z^dbqt)E&F~_^Dtykn*8QN2ls6MVHeo^f-YW$beGMtAP|fg`{+{KegwX`CTIuN(*n- zxRic&!SVDO37eP2bUgUtJLte{c<7!5Ik4os8#fCNbLz<}KLu46JVXE5BecJs=xG5R z8}ySg;!hYQjM2cDb$|~ff}t2=W~$NGpP+00^an8c#0m5nh<#2!5J-P_!>ZeW@eShA zGi5lK-g(VW2W|HUPhPwC?=H3-)u6RYM>RU{_pIyJ&ldbNDXAb;M6C9WzDyVP#ehc_ z)eZWc!(C(hgHgJd?oDMoPRkwHDS+3cRR8}9NA@Y4Q6a&BpK(A!p_GW8ah6Ks8=w1$ zP@cpCT&mxp4Hbm zOG8!;!T&+!;~WRI1yY20!(-lCX8DH?38FT&0{^MOBf%lVgKu3rS6UziT>zjS{Qj4m zO|dtKIxT=FLJB@eK_b(@Y?j_!O(#gOn1I326IIo@*-2Fxoqc$6c_g=?X8ZFwf$KY0 z7sg|y<&LDURlXC}r>hhS_~H=oG6-L-(JcNFKUvjhH@rDctq#p7zg+io#)l01v9N|x zz(YovxaWmOmOq+h=I~PpL>{KI=!A!+;2)JwpoiYuk3KoJX3a6+*bnml{LZCMZu~!~ z)c@HyZs(Lnj|4Ttf7e%?K=<{M0-zi?j;;B_A69Mp2>txgrlMh!Is&3znK(}nn^7;- zDo7+uMCmdpD4>%)wunCia7?_sJ1Xx~v1z0$jAI!eUcmzwdn(AteRw5}bmb{BEhWk=yfLybrqqx!E zDFOEUKuN4A7Aas%mo+3q4P1MG=lddGM@_VDA2VWFlQzFU9 zk?eLC6bLml=b<^3?pEfzP*xtkdTtJ@N8d|YvMO_25tY@v_JIf1S}m$#@X5vb5*MC* z2zqfM1Kc&BmLj~MsB+>2Y%HUwQU$n>k#wN*)Fh{OF7H|H2-^27>lnGrZs6@;+ir5| ztXzKkGBEN&{^f|hx~+S08~W5>w;NWk?O3{`9pJ^(!N)&ZyWU`T@R!;gm$olm3LdzS zt08mL9bAf?EIhY>DI`9$Xr4ac>|J(dpcZid?wxzHh(3|H|^)(2tLvIrT75R+Xb~ zb1Euw2JY;QV=vL(Fzixr z)0=O;*#V8|e}Q4>DUxtAG~k?}=m;2kDf9QfY3J~8qOM%>gK%e6alV(5oV0Iq-d zG6Qc;j9Yg+T6fu9k6hMN|Mc-h)n&B#JSED8RHp_Qbzo#_A~~mvf$}-JwS1~1y(Rk? z59i^izwap=1V5kOzH%!2tc-gT&!?NHqtt8EG3tHlZ`41i&!{gcqPY}z(U^5Gt07mw z`iLf}i*o}Ljs`{Ji;_e&#M1*|Q3c%_MkKb$l8EPhfulC}Q`k_FLAW5ok`S3d1p6{` zLQR_!1ze~A<`7pUm@IX{8elYI;!av4>MRk3Rm`Q);SmaLEm z(y$_dN1}gEm33CPLt;cOx7MOlgTG4^M&8acW{Jke-67Lib($vtxYJa4U16e7-jK_7 zROcmf3`V&{8KJ}ZK2XK#IJHF1$rw&!(-*4OPt=ARYMeu*%B(Dt()80hM_#totM(~! zr5wy|>pQG2&C}7jKZTCOWp=083fEj(l|-kCE*TDPqkU!3Qie0O)jH6SE{Qx}$sc#i zv*|Sel7Ca_!p2q8hLz4wRJjs0+Q7aCj_#TU8CJ#yIH%HO4VXN(n(SuWC*)dplSx%p zWrViajI5#zcp;wkLav{a)H&(dzlU;kGO-tycNn zNryEYh6>G}Sff-U!2~>{8IbGp*b3~UWU_n*z$?(ysYZXuoUbe6n>Di7*gIdzrDbv% zALkT(qiwnFctI(fub}M2H%cif20*y7$m8nq82dM6 z#x&Vvg8k11GrJ)~f0k_I3zmw4TC+IH1eH1tcM?IjJPt|-@(WSFBN7>+|0Pf)qVBVx z^JU1a^|2D%?}RR!$nZzZwJh&i+O#prN);LoNWBZDN3zG|a>_j3V2%}9oW(Y^OlPJw z617aL<`s6ILMmtFX3!}&=es916q@q$9iv8raCvzcfLmsDml$-lElB{XhF1gH zTadl_*g^D<-z{ABd*JAqaM!veBa%+JG++o@91}*~5_GoORhA*cR<6JAJUa>(UL`xJ z)p$P8Ks5;U+rlP-n5#B(5(6eDYG~Sw2?ejj;HJ4kSO5|QA_fm0|0dA@Geox26J|ny z719Yek*K%;ZIEy#!RnT1i)!dl4Xh?gHMk;E(6h%?`@k4&_wX^RCk!za)GGHV0)fEX zfNRff&nfpR19O`K&b>W*ZrkH($g?+gt{&68OgZ{Kdd})GO-t2dpJ`C+5z4ss_TYcc zWTCNn7M$H|E2vlEjHbCl#%+6@^-qmeENdOJ8obrB*Oe?VHg>KVGpt)X_Q6`^UPWMT zFhB}IJ-K7kJaR|;&sBe9oCZJGn(0l3!ZW+ZteG;@k=Gy;nVY$xEBU|}#WKd+vRpCd z$@)>-WSD*PAK9O!>PRxFM=3i##A4dhS3Z1?+9^SOG+%vlEn;NNH$~ZjC@CSxYy>5)g z9gu@veW%sw0#3yeg=o$ETvz}xqg%lkz-u%ol^L9D49;nts(}n-##^4SySB-I7b>Jg z_fF1o9HW!ypoG?HebC3yasZS@7%5{TBOQ_w2#Uc;jmoT1(q@ef4?{++gggJ1lfLPn zjP$c~+zqdHr~m0*R7+Pp1=gL`se0;0S(U8?oD5GLdKf5n`Z*nDq*G`9@T25A6@W}! z1|(!bO}(;cfe}p+Y<2r_3y3}3P--0R39G0ps6EtO)RR>2z)sJAGgbC{xNkx~5MM~f z3vHQnzY_odyF4#~a(Q$hi|l8n$bmgs-ne^yUr*hX(lG1^cRBVt!s#plB@68QDz@)rRMQ#ncAD67HEJQ6oQ(I?D!2h6%^ZD_g}{8 z|MGkOmi}=e2+sfO_5QznK2}gzIU{PS^qzz4|KAU(-&*k80aAnf`26Ntfco$6B%y+~ zQ^G!%1Rv2LxYlofE%@j_@Z#`67Z08h@J56K{4c8Y{TF4=gD}FpX7a3->1DeF?vIjP zsAvZU>kIk&_3I9z_cPjc=zT|NyWryBssMeJNKhAf2 z@(C{esi;}kzn3E7>^cRB(MTfu5_ultMV>5}qK_4jSw7haqbJrBc;@qYaRza=5*SpP z*rEm^8Ix4O6FsdAj<0H7SBZ};msX;CN4GR@ZWIpSs+Bwr@B&-jY7vzH;%truJ2f_ZPm1K3i5$E~sp}Wf?vW-?wb;s`jRRi&wTc?O#l6ug+4C_{}zoScSYPV6qR3?jA#bef`UUzSjj!uvp;b>r>zD-~Zh?ERKGgBR6hLpkqV% zKt(>Fh(Mab*bp{QF~yRCsdOp{pH4TX8`;x-cRJ~)bEK1Qe?buTn(|DrH&`$kOor<| zTY?aRY06irLn*Bmq;!=&nhMvc0VS25rPOtzxi-GPRP_IG&Jr1Cu>s*ZSdck~`s3ue zShCxT=~Xe1dBA{hz)vYGy!ZeG=Q~MoBU*?SvhNOxp zKA4G){3#9CV^_U73#Jz>I}-=tH-C@*2UuGtK8O0yzhK9>D_7LqzjS%=sHLgK^nT`n zb?ATQb-tK>GMPYc0_mUM2K<#DZqvCIuZi4s__^UN*ZtX1zkcH59a)FgjJR}kxh?Yz z`}Zli`iN$3+@z^<390KV>N6bDv^l+mL zmVzBe+rj!3J=ZP>HH~h0_>NW6jy$^#${U7(TfnZ3se`v({$}-6is8je6o_e@4{Ff! z=S#rQ^?hG1TXJhoNq1RWjt;%>ROb}*$cZI$vzmv<4Oz;)ORSpIr`y>pM4+wKeAs$zP>I?yZr6dK{zIN@kucf!| zoNKqwZK-v;_cj|l3|T9O&ZXaeZ2gAE9^0_~vEAs0qiBTkg)M8Iw*DP#ZJVMp5xaiH zGe?1fag+Mjo_X%=ost~)p5~UMTk4Tk4yQj_{}`_S=%X8+ML(kFH$J*|`6Teb{vrtW zJOiZY2kJb&QHtNEo@&YXi6C32l*kDRrps~s(D8GdU{(E0M<9~GR&`&#F-M)S1tnGAm&yuBW?Mu+BhnAHW84UOum8&ft7G5HL%$tTxT7Au&zT>-g zAAjdY^c)DR0`KB<)H8GY_E&doCn()#$4b6p&r&MfFY_^vJVHPlqPc(|c*V?<$&R^Y zS_5dJ-5O7X0I@a#m^-6+(gHw22SPm2NMwn`iBq#&5T_*QK!PZ(v2je%o9G4&M3eB? zS8y7c7q;ddzM*DXk(*|o(?L$^Yr960I;t$@^+Ruz{{1+2?_bN(p~Cmji~Pri_OPYc zS7a%Id*0P6OscTI%G0Ru{sWY)+wne{yvN%yq*A8?yWDZ5A_Nwr>r76%EMPBf@=xNF zupDijH0=6$qm4!|%T}q=*IYI>{W-eH>7yBrJqQ+q`44DKCi>ADbj>qLFw^Z|puv=9 zjiZ;*u0X5L;5C`#dU_aG_~MtN(A9>q6KW_;o98(uZwBj0p()@bm?h?3@5TEwHJg|sQ?8$hNGV}d5v*6sjXHvMV$(t|w=qV9R zE=6A8)M@c?XAXLA#v`P`)aJ?LC6eUvlj8B*OPnMm)=BazC`)K2ut{uyzGs9erU$Yx ze{xcIKgv%As;eI(k8A)Dw_^$NW&=mj_byQ&6p!r5pbbTU+;2s_R=*seh%Ly2ou3NF zm&q|j;M7xm(DpLeiI1Oxot-5?-S(i>=d%X4>w-AE^ytHH^qAe*ZiRE}g9kwV93$_{ee*)t_QouJ znOBx;a7yiS6!tH|#_c((sMRO+tW)`buFyPuL?IV&xpSm}hAL(D#0vyLK=k{HzX?w$ zVdBq>qdCl9hj1vtCp-*=-mw5PV)J&m&~Z>`L7#y$I1KWcchXP0(KHwO$^{DHP!~Ah z0y-BSdpi8PMn*BqDK%bUiTC$PY8W+|noiB2mSAplJLX6CQ}WSMS7{1*o=}H z8%J?7lD6e&gSj7cKSp*2y@kZGH(@49II&Qo1kd)gnKSr=^e86S&tAkWbKB zOhKyTGPPO_R5BCDQ7BbXtyBf%3W-dukjc(`VK6{7)ajslyv+usGP7AG1-7GBt3nQq zMkrTIF`J=MWi+akT{y0m$P5OVL=85gkBmk+r-hhR(sJ@CJg<=A5ROX~({Y-C#}SoO zrUctw(P%W7BT%a~2F(n$T5Hk*r4ndOnm?-bHa(C?lu#~HNI5lRW*=J7_ivTnF{bN9 z;L^p)RvbF`4OGb0YI*vHZ{(_yJcT6Y5p;X0zOjPW74&_0tUEKBx-Q3MTY};*baLfqkovp<7WGy7ky9u2)exjbc~eAE;?c2-a+>PkE({c^9)%;`MD^{}95O~kiAkd%=PTnT3s_scmb z_`4(4?10#Y7|H%Cu{WrI5yAK#zcxN#%0dl*#Ed7ogrN5qj0HmmjwWS8Gh_P9kg2)rCD8Ip_RYM@DExNqsgZplppix->D`#X= z#;9emB+=lvs8kBK5tx;F8L@>|CXl^kOmsNds8QkP5#TA5VBHnFpowjc+DlzWaO_{CvI1G>_w1ZB$8dWIqvZKo+X(&pldO_;j^AQ<*oD$r?82^hI8JSShK zfpARsmFqihiG(%ALJ6c<*QG-aBD>}C@OXM{PA3BM({c0=EYdm-$ z#nF(V0ZXS29Bf4IcFw@uA&yJnbxW^idIyU>z}sm9zLOGmz!z11lU!pOWdW^?%(!;cWKP2j*+YF{DSl! zfdwe_o{kA_&Bfj+hl>2h8As=dCCq>kRiq5R`U*^{kLo3x9_>Bdm=^sF&kcG}Z!f8m z>LyhP(q#X$_V34#=S@&e0xEgTXJlhOXXb4D^>^?QFm4?XEQ1Bj=QtmW5~qSNLq5Y4 zQ4AzMy7GU0yHpBMaQg!3^&eg@HO@%2nY>2@-)Kx~&>#41|zGRIa9|P_0QT3(GDA$S zyGWmo{?>7N;hqrN-)aJSWHj>YE1=-D7YRptA!!!14E+RTvfs3P(W(Br03RWK|6cO` zK;8-DvWtBG1T}(SCjF*2t0oqsfM~oEyHdeq#be@V!OssM>g~j25tFx=K;Xr)Bs28u zAHPd#Q$!WC^ob{=G!EFLe^uj`RjdDcVLDo=(!i^rNmY|M|E3nfR|w)OefJ%{LJ(gG z$6S;ibEH;+3BUtgfK7yCAke?jjCnR48^Dx_&X94!MR*aB zb^Z&Sh#p0cKmR-(#i8%eqb)#-7q73c2CeBknKz$Dj{{ZuPCDxCd()U_?0eJerK322 z6To7$2+aA&zj0&V`(Wqck1l`Wi6Vc=&OwY`VWJh=%(EChuP-zhbk5HnzNxd z+YG&!g#XYyfNv_L*wwgSc8Yyc*sb$ta@%U_hIcHkS$i++EBO7|gP#HUKki)g zbUc*1?Dq1TkKTs9xI-k<3?zajiI7A~W#OYY#Obr*f=^b~j3;8wWPq>zQtco1 zqAmBm&~b0a3unH0!QptJ6V`!sV!~?~7pwHl7dks%a7d_&XbG!3NhMsBRJadqNk1nf zfZ)esW$6p|iI)@hYqBIK**_B$2yjlhNlz5{DS}UsRZX`1LopMhmz>=857di#Q13ss zy#U&eeSkj5_=BB|KKS4mXnz5w9wwRF{sEE?{}C+v+WkpB>iPR7(f#YDzk{y)PuyRl z?L;4($Mf31aU0ISJwC2aM2hifWCTSL!F(MMBX_c?nINVcaX}M^5RN2M2&e^{c+u3o zfWcf()Ku(}n)MmIa$fqEmsubUCrdr-@L`d;E!A3W$f2>T)bi~79JOk0sMWxOkkN2k zk0(SkrZ$ITPF@GkyS;`&&xDafO~%UM7A7mFI9sh!bMkP0TX92fk%I^HhiK8+Bk1tI zw!+;fz*;;~q|w={_U<|~G!oLfb=v6Wr88YlYq7^Bku1|S+U!M(v)oTUUa-XL2@KWg zmZ^t1ou#)NN#?r^9-TI}Zq>T(Iisp{Iu-5o)OY~0sJ2`bsRnhwF$F?BP!R#f{}~G6QOv*9H%*A#3dnW zJ7(Mk6TuMC*e2bQaC3e+G&7)CUVIZp+i zp8qzwb$+=sulC0Gb+zfgjxyQHrcW<(@f|)^T0S4$`gUop?)@8U^VWW*R{zsof26Fl zsAN(}QD@nadiOuo>d!oNM=Hh_&lggQrM ziRUo5`LL(7)G@RB67)~+{clO?fO2f!-DMFtu{~#OPWz;m+w1k;$mQSY>u+zFBqU94 zzP&;JwOszSzTx&}7_5Veu{rmY=9GHwe=B_-ntj+)Qt6m;N%u@gX{jgZ!5R1Dj8#B< zYrKY%C%a@7#;i%DvE7OATNEF1xFLWIW8z(QA zKHJ~a(&7&uYAuUYj$K)i7tCG~ZfMRu+0|+K5PAw$#b39z}qY%W5pBeFHdj*sDr4ui#AxPk`oL?B)fw7~cLiFm*t zi;ubh-&I02;Cbk%fIF=f_AnPxtB5xYpO^S0pvlTa0%T+e9>@h`7S^cscm=iO7-1q} z89BZ=0(?ZHJ`^Qt_5q`SY8BH(V_pI2p1|7UoT!nw*wPs?THoS22uIy{>-~EwDl68l zTLo19TZrIGImya7)UNN5fg+FH*@X>hkpnX6W{e`VZHjsDkw-|D6Sq->Z@XzNdq#M9@ zxGUsM0;PyYN9n81_t{!@mSTR7zmZeG3KGG=I7lR5WZNq!;x-a<6k;7NV8aNQlSFe@ z1QsHj%mVN+QLMnk2;H=_tuk62`zasTjVvA}YGbgmAzU?7yQByFdmsAl)?~fW%(8xC zv~1d=spjU?qc7l7iCh)TmM16g`^(B(fr>HoEb-O1q3y_G@<6*`{dd26d{brT2wzV7 zk^(%izu%{31NhF2DpMVwrY)Uo2piP=r8`#rW#6QIcpcPd)6;2~7Y(NGqPLrVZKkj10sJ z0N+n{RbzVd1py=6gK6dA0)Ff{;(f5F8(usa;2=Z#gD^NlT*6NfMF_GS(Oxl&pmSP* zVl}~rNOo>rU2ZmQjfU;{`Sx)1i()Ya-d_?TDWMYdqdRmD`s5C?&tog9ws*+V!_bE> zf|i#b24%H?mBZEtq9Q2D@keaitvLae427*_|KRj&&`wW9-g9^VGdf}v?*7vA>g zg#N%^PULB$ri|LYpv{lJs)_5Li3F%%;p4LBJAxHW_a)TYW9XB8_oLS?;ed3TT%+ZN zzq@MgvsaBAdDXLXryp+IM%*}~q%9Z@xi&2T{0;kn<5>E1zvA9WK>>|+pjQbt*Y#WE zR_RqTD4#kPSAQE{WoX@1u27ih5fYEq8)q$Edu%Tn(B$jt*IhfOzhWnRg&JxFI$T=- z&a))jg!)9vS|Gt^-v_S0Kyb)XICF3z^yDvOgVp$6FW`G^#q?xG`%IW6@eD%5bOIQm zkv5oJbcVYdTq1Du5R+AzW9oGw+f7yod8F zHg8_J)&qblke(b=0T9q8BVnth@JK=Ky*Xy9J3FrN5F9I3s+MUg3;Y&K!I6TTdvdH+ zZ*Hl^hb!9PGge&Drym)$TJa@w@6WYbefi}$)2pp4^jlIKmu+>s7`fcI3S427GmPAb zw(l^>CBW&n<#Ak&#pPnB(KH+ zb1;+X0Ib}6Ro}=}MmYzaE?b^}FJw8JVi0cQybN}PV0v;+Iomf7B8vB-jc`1hU|pbq zCBoPwwBNeW>c7@!TWIs$FnxVpa{Tx;i$Mf@Wc9Q4!<|VWu_|I`QdYm;%DixH@`K8W^kJv9_lJ4R0|@Cz+rPmDMEV&qI;n0Mix87@cM zJAy9M0|mEK8CSU*ni%GDXEL zWxUjI{cb}Nf-&qb%=lR9vhky4&&d8N2`9zsa zZj*P)-&a@^opQO%E}JOJ(yIl~lP>jxdWRnW-!qXEmE&SIxs1L!Vvy$@T4*hjv*FPj zy$bL^!FLV#g2~&SxVHZuz(sIhCnR~k0pw*W;w#&~5{@z<QU+_nH~B)K4)B@Ul0esk{{?-YV!SB$zRX+#7bC30ClKl@CxW+bQcuS4LIBcqIX5n z#p1ajOkOlO{emM1VbBiG{x`KiDvi)4v?+~r(e~|+0TrkQ%EQ~+qq=itf_9X$2Tu;@ zzYp@tiI!e0b!X7Naicw${x7P4t5ov25X_RRbS2FrTFL`~@|F?JC1~8a5~J}Y@r4KE ze;G^!gP^@rmcalUn3s5hW<&&j{Rx6dAz}stux{)?2=)eTK^wvo@+r;&|4HC&#VDT1 z@3wG#CkV_D$Rc3B{UN3|jq}sOQUNJ?o;jU_y?rT^SrqUhL771!<0hOOMLJh_W(V;_ zV&I6j5EBA;fePwtfEf^hBuCDYCz=9i@$Q~GP{k3n`*ARTUEv))yTNtA`8d7%b8vl- z>1vuEMBTVZ;X0wj5%4l8a($p_0j~NvxGsR-!FpCH`G?@^&PbID-iQXHA6&#gq>IIr zO{4J*pyi;?RlF363$a!7gEJK5j8vV{QlzjSjDBdS%U-(F^KU%xxXZ0I7!q z%(%9>D{AMBI> z_UvKlCXKy>%!D)XTDUJGt0g!RxK|18yL5bl*xnlxKnFY=5yA3w>U!wD{`&Npv7qq; zCYW2%(XH`(A!Nq76u*y*UtWU)NmZ{tWDm2Abi+wj;yc&I}^YKbns?YJMo^8w@ZMM>7 z+&$5NO?_{nn$`J=z{=NKrH*tbTTxz$E|=P~K}&g9MhD?7v{Qp#skZ=gf!gH)O_xPv zjzH0F$%zfg=2ej+|}KjfZ1>_T0%Dxlf;d{?(8{-mH;AOpFwU!L0l0B)rc2L78CJ zFUoRK=h;2jDIca;iLV;`^#lq}C%`+#&ifJiRoEc(=nUL>P!66LLm?u~PYYHWEQK(^ zbnb@}X1;M-9m2g#oxSIJw( zk8hEy^t*vpI&Vf^b#>luy;8nq=guv1B~H}H_8&N~Uq%W({l*(llY&G8POzB~_Am!a zq-v-U)F^5OwSc-556%mG!BPL^nP5VSXm)}hyn(dA75d zdc@$^MHA@}&2yXaf7D;U-wcn%Mou$~XBm_@yh_D9&Jw5`DM_>a411Pd7SpfvU zH^Kx$6fHzoP6l5HGk~B;VoN(0awnm2V%V~vCcbj4!}Hh$I-h5&R)(?7~RCiZvEppDNyNapZWcn;q#@C*f1 zrC^`nf)Y+(^2wfRz{T{V#0w5^py)0Ke`E<43=w1n!FwFd?0T2tu_3;9_za;GB zE%IQlang(#B~RJ{t1XM_uJfh2EEAX1w{efxO}|^y5{R-P%(-a_{UmKk#l@ z7xIpJ-kNh@$B7p{?i%I}UsXQl{l}hY($s8q>muny&z{Z89(?A}gPm&vxsSo;b+z|C zjlRSG9>29Hp>6%=#CMYgQzX@*-+17Q6Uk-5%+h#V za7;jOM#M(}9p!zjV4*?)C5)nKGG~gKh?==5JczqN0JDyCG!ZqKqZf`K?#ZjvB{ZX? zm8UnAE0XAY2ogYZyUw<9*cA@}HgIU}A-H!)`=$E;*jW^;42^9xnVS}G+7GWO&MPix zjB7w|s@C-5gT8lJ&CRLilAndHEX7CY4eXG~v*d}@AQV@%O+rl*8do_Hgd5ZA;U=wp z<&@dO%zmRQ%cHo?3s%pZ-(d9`O&(yC-V#qA?lLveFPsrB#tP#?JJ2>9rKfC^pDL!> zsD;!fY8Q0}b%gpO^$GPIa024{K$NV+1JPK#fbn_R{&$!c8W+P2&VXjWDB!yrB}pehYecL^fuQay}vhz|5}DbIJZn)NJ5<1Ykx; z5@|V1uLa3Ha4v^GBR8;XoZ!yg_QJ=A4|<4m^$p|#|F#%QzC9Y_S+rc19sbK~PTY{-k`EnSKa z8*X^~#xvIoX{+-i1@q?@MDkaYG_d8ojyf^R(2bzDA&k7cIYg_nbMq?_R!0L>^wW_@=9-PQB`;#fx?_>cK-s z^t&#M89APH$vww2W@NmipC$UG z!2O;Q9(nB+%EPDsU9fvJ1cd% zDu-Y4b&@yKoEkN=ZR*sf{7P4CEl6f3oJPCRY4K*4#Dl+Hf4UHy&DUe-U zQ&W%|42PTM%x=nIeyTlyUPAXE140syE!g+K{N3~C?*{O?p`8F@$#j>gQ<1SZWB5wcg}g7N-DozEB||B2sqBUz(_ z7&pL&3K{t4G2+inew<(+5lqfJ)}Fk@-fHzsc?#=OH{{<7!B8_}0_@Tb}9*L%Ii z5pPL&(<;BOxY+lVC3)Fp9%~>sV2y=0uJo6;-8gCO7Te|45gWJGa5);cQYW$dos*_r zGGi${c47MRwzlF#ymiruO3#q6vkH9ctPCzJMBluN|0*ki2Au`qsi)HK8e9ey2f@V7 zPN11Ep|2EZ%5c5(JD(=n+7j?kRaHSjVc`s*9&1)A0j#PjF9&P$@Sh3)O`DdN_ZYZ> zluUP;GJoae=<M6PE&zgXw1nV+5PdU2ipBDAA$gE>H9q4Klu%p)1PAqk@ZKzDB*1UJl0mG&$4Z3q zoI!MOkLhXg0ZqT45k89soW4lF5ukOLq0~Wz-ej|YsZqbvPf}0c-BR7d!&)GfG#j8E zDD_$sJ$5>XWs?*&ZEqMhYe>1HQqQP{@Zbe0+oIs+=drpGtTdDlI#f7HodxS#st*{1 zi*zWNUtYvEgj@u#2jn6jsG1Z)(K;TU8qVh6nFK2Mu%BCc-m<TwsBM zG2Y{k2=N^iF&@p8$oWN5ISr@%6|fSyC%kZYMWe-_lxcxcE|c%ut(CEG=@zD2s*;25 z(o7ZA@?TZ~T1*t(57Y|O1z8ync%KR1&I~>}Zz(4GAOmZ$hKf+b@Jc)p)33{^tEpSW zbr>(GF`^jmiwmo;ukRVhEMSp>pDXB8@9<$!*C<9L{l0>4XzNl;PX9dga^z|Jr z1x2;>A$O6p!>u3IHL@s*nUb!J`T|{bUT}C;VU{unY}2T+3gz<6yKSY~!ri;!qWtjC zWK6ncw?AuCv7P~9 zT2&^s&C{I~3^kV5TGVE(+p1rZ9mod0#a9@YO6UBa(SDa=B^P_} zJ<^*=1Cc%35F05G#xhxDfQi6}5Tvv?@gG&q5El>q8$@{VG82_}iK*(#<`R_L{q8OR zD6O_)Ox7GGDh2YNAC}vtqjBJAKGHG1D)jkt($e-)>AL4);C7q????MyEoq*=d)NGj zvc^4;Xcb2ISpQ5nd%PSk>dw@Y|}bV5(G{D1Yu81Yqxr+=a^$$5P1W)ls07jM zA-)BLDO4vSG5uN`c<|8hNI16N@1Hn8eEt3z65?Kqn|NV?)Wso`28YupL2nT!M=#1b zda+*JB|29S1cD&esA&y@WVlt+2x4k|4-`Z#X`ui~K(@c?e+bk6ULk`}whM>*nn$f! zF^YalxXoRGl9Iq(`aw9ud4eV)(G?(&K$Hl%LOTiNvf=&*|Ue`U!v7E z<`zG>bI;2~IgOl5M(6&TmdRi_xtjP<72bic?!Wp4AITkTs&GOtT5E zn4~Q3)LP2p72cK1kp%8Sz&acRB~HIU`f-Z*Nl+x+|)t`TXJB^ zZI5jE>(+5s2B8AT*p;l5g{xU>mZN-pT@gBn-tX5`|Kt&cO`0tQP(J(2R>9An;6D$H z2Y16$3)faHJT$F)?bhGx7T-TT3PH>hsT=>h2loT{Ekl!hsYIz@73rHTmXHm|LRBkU zG4(&GzlpAsK}E4rsgjNAB$ouGz;SFX8b6>{CCIpZ6p_uEw8VDDpaDeQPP}!nA)a`x z%m~$qFA5n50i&eh=#-D=%H{tfx5?+F?+nCVKT9Q30XT7$B4_$0W#qVMU@6{7%ye)#jH&n+wG8cM4**=lQT)9kqtYI0-E z`1IA6PCT+9H5%5(&-~cD&@}Xq==;gHzp;{yguH>e$rXOhdGg9!yb`aYuA%mc=+O}Y z-;!*e!l)32Q6VCxi(wwK3Lz2Hl@su_E*>Fl3{eB~4Ez(>8Bx`ViJcSr{W8K)r>Ok) zpu?5hn4RVHw-@BM`&~wJ$l}X&IfCt-LYB`fMDl$?k^F*oztdz2lOn&YA>`sJ-R()@ ztw8*jZ0|lp4J(a};2mBEAMAwxF_I!87l++qH<|2Ko5N|f@>;bC#~qnO90JK+A=63zIl_I>k_ZDTw=Ax_7`|Nw2W}Y4Hk3VX|NF#Dr(FDDNS@Iq-L9^fU#% z^UWttqwO)LOlc>e06H4_L63c}2 z86QX-#f+o62n9*7gc(tnR}vy#j|ad+MB5F#W z$tvY?SBXCWh8*8jF|V~bQsydFWL1n`-O=^n>_6^*WMrv*w8jZGqq8^saOJq`e?M>B zb#um*SLBr2y0(p67Od$QH@>M$oXRY>Ilp3F zqgJ=*AVZsT6!v^}MzIkX>&{yP#tHItq7xV@>EE{UnJ@_*5^+Kd0vat|@JxcBfhBEZ zHi~n8VgOE97~ov=BG~bJKlk~=G6oj=<2qpACx_&oA<_1AP&;j=GaRvlQ5Dk~&1In> zZK+YSo|sQFlOMd~>B$B~WzNzG%l00e+r7L%>N92g6Q#{L3--=E&$qxQ57fz30S8nm zpubR~@ehs5orY!YoVIJcQ>t-f+t~8P>k4B~=;S)<1*)5l}4|{OMyt@~y zGEOa@Sk@4-UkyJ!-w=V$$X`WVPa=D;b6j?n)wTScJs9uXFFJge8#l6IXnN=p0 z(JvKGw4kku)~~wy>Q!LV+-I+PhpcI7s(*E(NeEibRp>u;qVLfg==;u*SAn}OpbG}s z`%wadJ!Jvn-C^cw05hO&k6GS<`^+A=H}mLucLXSN>3-Vb`tu$}nD>eL1wIk$NDHQl zh%^d+=Nh8KEzy#(5sG5+9(XvDnGt~UiA{juqm9rDS$GP`B7VaXA+mgueuGm8uO_&S zjpETC%7h3IS~LPrqgTQ{%hB3lTaF&xvh3kIp4OLvB_IoB&6sCo*`r%3s~*(IO&X(5 z|KQ}KKng0+DYOHfYHO@T2lSqo&3$(tL8kzBWa+GJg32REfyc&tC@L&^3_vk)))A0u z%sS&fihe$N{a0gZZUm_m;_W=i% z0xt1nuq2owVsi)T&Kqp^%n3awm*Ct{7sz_~evl|yBFJgsdH#KU7vfIoN{CdFm~ol; ze%UP}%2l1iSf9CXzS+kPV}mXx=nDSBVMwP84u=7z4B&oJI8EV0$~s5(2(W{(!2XDA zo*5_x$!4Jvq|8pI8KqnW1#nT=;Rrj@6VrF5Vk1VxQsNO#>|P9BXvd_lTCH9uq?p!2w|iMCC@@2SVcfQ2_)( z(@!vc@La+^8S$s<{E>(sKIaEgb6*Y#)7Okg?>+DcI{uKE{u4>)TRt9y9@z5jgLA>M zh<~$g^ZV$nyM9CqW;{!Bx8OJ^zWWETYsOK31pcit8f}b@9XmSW^GB||`yur1BmLny z4}Al+_#$J*+=bryU^9@Pi1>vVDE?qG`td}B*gGiBQp^vTZ)?Z>e}#baO`G*Z<|NoM z7vNVT7)NFTeJ7y>r_sb>kE|;aqO~nJk=B(ED-plALE&N&5dqgogbByv#E6rFA&D>J z4h<7`rp&@4Y*U;wUl`MF+gf93Oh~fZnaC zTr;AGH?+;!;#HfoRKc=3ry+W)wc^zNzumGIf2UIPhh+h!GPhye_ztI*vuHJpqoFD* zIUztZ+hkG?92xJp$5SG0DOEZja^}XDj+x?ETjk8YqoZ~63lbZzP}LSx zPr0{m@8a%V?=hF7r;Omm`qIAcc4>|kavZ&NI+`G7!PNJCeLwgQU1L*QTC>`xC*x>; zcFpw%@4W}W+@fZEaZJIwyd@5vVIa@@9X6At;L0KHWiF)>%8x-#9UH!Hq}P*F&ebWs zA5KWjT4!r=Rj<{6WAoZ)rJvDBv>O&(KWo_Z|I6H$2S!ok`*&4$PtScH$t0P~WHK{3 zC&y%F5+KPWgd-$C2&bIkz9HO)2*Zs6id+gPW;oy+V9o3FT7eVRjYZ2y^2$-W&K`Z-)JXfD>kn1O}Jdrn7$$>VidI8ouFlr z_H?QRSPf!>eN5Y8AojqvQGJgs&FFh-!3*^Z+dtn5!dpMzjta>$b_Cky7HVPlAT15^ zeRE4knAmu{9N+pmsO{W?-_omDaq-TyG_%d3YzCJgn^8fzYna|#tGtLGEyO^iv0KdR zT2C&2oQa0|MKREO&1lk7l3q_rO~tnqWUlgWtw~L-+2pS>1@Y8#$UaDM^ndzrX4$)xWc9#@QI})7IH)F{;HCaDu27#{3UVwGH$Ls z?60cwqgf`?V>wmu&hEE&B|<;jyP+18aO!Hdw-c^jVnGoTN=x7+Z$$DCvyWFBRnWnN&;GA}XbMGRt=N@}vv(@%$lTq0d#sUR#Xq7xWOh?5~o z+Z+LMiLej`if@bWIAczLeE@YOdJcj*k3;|tiwj3f5IO~CkOdYHG&n$j_u)m3#mqW_ zKm&Y!!K^cq_bj@g&H@U6pbL5=E+=m>$)L-l;{_kE7z!Y6IIPJ){xxk0b9|@ThK``N1xL<0l*88m%!(qRcYY~wC)9%gTB({!G{4C(%Hw z0lv%`4P4)CVS!ot9xp|8Akf)*4F7TEg`2Ye0NDpN4&~uSQ#yz4kjaeLcvvd6Way1X zqa#VG1jD&>qf7>7@aaYz28;t7$kc%Oa%qyog#R2#5+yne9A=doJ;$YYz6GYCqgpnV zlgW8>J7mGDV8V-12wKmb({_xK@HNBd0y%msg!ZI@0J@*k;P9s=()^UWtxba}{YP}%lbE_xZA1wPGg^!dkmU`GeUMPb4v237+O6``lW z&!3_%J8wi^fRw-dWgwU<=WtzTMeb;1#r+bB%}+4t7}^cuodQ>Q0<+wco8gzB>B-HV zKW=`KyYNWJi&DLzs(g0b<}+Ycd-awVUf7cP7`UHcj3cABzesmB<9>GoBd1!o$$kvS zuw(**=Px{-{^AF`*aUjUB|h+k%Ot=AC4!l~7yTY(tTMg@nl3bg8IuN~>mx5Oo>b8c z1L)W?r~}ip)aWA=S~Z*f!`X+nA6W>7ylHBv;^(bFY3S^AV=sWIZ{1Wieo5pkx_LdtOeqWrmpq8mgFJoJPl7Z?I~ zx*hP@$<7TMb7#qd7f)zJ#c=}F+++z@gqcS+uRnM8&-?fP`RuvyI{ru-fL|Xz{562+ zzc-%0bKL_kw;ep#_VNSk=B{~U{OhMq{Sf@){@Xu!q-E*4w^zJ<{M75*>JDkyg#G&` zlyR3g%$wJ7Z&?)^8Mb@(uue8N&$(bh2D_8H?MQX!NMG@+`MfxvK90xe32}LdiU0F` z=&PQ)0Z=vMy9JmBFeUiI@C;5i<*P#QOjqF7(Y|SlrvS#0Hzkx=Mk7fU&l;h zrs7rod}cATj9G;#^#*1ub0f2xxs^G9sr7N@67CUX3&=(9eus%jmsxsWL5q-h5p_X{ z7a;guzj6_OpDFkYz81pIViK-#xneUd3Q}W(0W&$m^Ed@6L+;1ZXNgQd%J%>Y*{>FS7gV=r=Hrl>B%S2`<{L^{XET6t!#S#DQUq{XRu*-FgweX zQLDkT@=TdcZ8a;?f_{gDY2Sk$0*zJd(ave;13v4u*U-DmmhDgY-I7t@P-l2E$fa_4 zGcvr6g2~$c*z0Fb3A=1Y{V?NQ7hHKRlg5zJzqaEASDGd|rzN_<3BP|XGnSTm zuBb0E4Nz9GzJP*&5Uh|G);t$A4O9aH#r?;X5F>RJAjrn{R%{$uj&nqLF4?`H`gN%# z@}{7A92X=1GIR6Cgkn2UqpKg~1G zxJwNC@Mrho$)*7?1iG4u?E8;%ZP*K3!~=b}*MMX0Vhkj{jQ@GwMLiedJf3LER8m}8O#4v)bhgASL2r4xIXcw|mBZx9>-NAX3t7+nNkgGrHrH@=D5Q5zemZSPGI{yj}Q40vqLX5sZ z*U1=-9HT4HLx#v%;!FzP;<2cfxs7ST12oy57d#Xy`qytkQF!$iZ?42ZI+h%p>wH87 zsEI&z5*-Sxt~>N^eG-^lyq^p+f&o`@c>Ktb`hb4qNNoSb8wvDl{v+G-6GDaF(HU*0 z!{T93__WQad&iI%)31IGga8r4LAbq$5gLB!`W4?b#J920U}y{h7wBUxm-hj=M0gur z>LV|=qF2y|dhFTwtC4V45gIer|M-}$mHy01hH)5hNg6Z&L=`khJueM1%SL}oD&2RX8Q;H|HL!Oeq2$Q;$;xuzO z-)6C;&RuH2pS8MARi;?qk96F+INhF(S9D|p{<+@U?os_ie3);;bKK!%ByE$yki-rfBN*ooAP@a-x(Q=A(r_E@zWu_}Rb&@4Tj$^{{DV>4g>~KVseTBty33B=C z>c9z6YZZ*^lu4o7Qw{>LCt^){9Ju~dfT(N5U@-$c<`Do{iJ-tE0y$N1M6n#9rGh0J z=?p01;$K7J@T>62>EQ(2p=+9 zQ%tDv$gLk;&aDk)W`=5WFOxYO>|(eu--+ilKC&ys2s&S^RmV5%;<&gvFMw1tET_*T zXGZwq!sz|?+qywrMC-wSZd59Eezx@_$a$!f5nCKN17cf0Mo;6mln_*8C*rgZ0sWC} zU+&cy_M*S(#Zw*fR^oXmk=N^~uaRmhh8bQ+4}vWq3RL40)5d7|R;!zS0Bu@7;mD=G zT{%n>&O?$XIFL7QJj?m_E zQNB%Y!bNEMl_K=J8Om{nDGp)Tu@S04DTyG7C7P|c^)xP25mAADRNie zrf5%he3XzS+8*dwQ_Tz^XU|cF_gFRvxZ7{!k2H}0Lx_Nj^zT@vIEKiy$7*B!weol1 zpPQ6gV1HxfN8^~TZEAgFdqUmd#)4~yHkoZ*M_;>k25}?O9eESvTGZ78kzU==lvrCZ zF8?{7pnLo$c_Vcf^ayciU{jA>_t;<%j3WvM>^%#C|LsD+mAt-WrpziYlmpq^#ncBA zAv^KhI&VzWV|>|Bu=nVHSW2WBymr*TSPrCl(iHi!=54gi$I>-_a@1pb>H76ol_J^u zfrQ_Qk1(Z71yjc~(i0jplw6B+IDUbMkQRbRO*4ZBNsmO!7Sjodn-07{NA~1&pcvbU zBp8{NNRV>lKMy8Q48-&zH#*>X>-+-`oPP^=I``qJOY5@PhY!zQMn_h7<;GR3ZiJzy zNiLqI9_&Akpzj{i_8>)96QuJX-(Xs{%w#}+jJ&=XEZDpm?MFYC9shINePv>i;|V#Z z89rQtIzf~+l-<|%=i_B$-UhlP0%>mpnFeMuv*2274o{yYj3CMMc-f#hbh_evm^~Y( zCEB4t37x1|DuByqw%}4@g5=Z-(?y0z^3g_Y1Ckyst-jKnj(&LZ9dxY!iVOQ1q_Ug- zynW?|*U|Qq7_M)|6MLy6Vz|3Mz`xG$C&yW!e#8Iqc3hBbD=t9nfPTOZTvK9OoAO=w z3Djv#`{0aZ_OVY^ZU5T=jo1f6iJ^u}kuAe+sKw|`ZoiM-PIOw*Z0~?d*Xq6KN~eHl zL81#fi(POTN}}f*LvR^RWaj)z8R9ncZxJS{4n!+he0b)Hr`a;G@zKYg{S=qo zW2iGFW8E;#)ty!MG|0I7S)fVFST~jS#=l0JAy`bBU)g=2^}e#sc+*3n`^tLo5cQ=9 z?}=lk5NDPYdXApKZjQ-c97iwhlF7W72<;lyb37e(N_0PU>DR~AcX!FHIG}9z@SfxA zuv4P@sY|~w&cZH^jqXA1H_I|nT2+%*I6|3#| zMDd;142IXlh$bGV9v$JH;}Bla31M!1EH4zTTugNWxs))3pHG}^nJqql>@d_31B;5) zjj+&QKp)6bWchOW)98aJjsJx-0{7E$c|H!@5$etoT!=G_J`g>g7O5Z}haLhs@$wNJ zpBBH;`R!HXDyVw_e?jkQZM>kC= z@VIz->t*YDK zkDNn4CZ{Fa%uwSSo@-_wSa9a%IVD?BOVd*)Hx3PzdiLc`&uy$N=H+*$Py7Omw^hv< zxpzcGb$dnS$l@_`R?IDU@GOeFn%7vED@z^EY8vM+jO|OW#bvh*uO})9st6;Zhr|#L z@akC97iOkhiGXH^VgX?XHW7zb2%7aVm@tAzXP`_-?3>p6d8pGaDk$4JZBPARzz#}E zl_UuUjZ|7ZfX}EYouZU$nm2rXV#bUUUn6X+9{$5oOxA(r_0_9iM_(WM{Yf-s$AZLIDkrMuLqEZyf)6=p23)i3FWT zU%$S3@-}eb(LWx-F;o33QG75F)5k#fh&{Lz@QNkq@H=$)ii;{G*!6KN5UMwZUWC<` zA(zBn+E7~B(4Lg=ApUN@!Vq?9a)l{y%u3>mSL4MWIu-{a?w6nh|-NX{^J zx0c}kf#?)Aftw^Y4me_5BvkphDYlu!`(i5?!kJ1m*G)k$en!yqVF)y-36u!SIn5wKTB7R|8!0DB{AM;;a@a=K4wfp{zyyI01;I}#Om{xRMIX+&`{}~ z4!M)|$`cl_bdZ=)vz=y>PQJSH`S=x?Y==yxmR-3bQ>(C*SbDicOpm)Le*%N5GZ9A1k6tFn~^#L{|N16~>yL zBhFC+7zrNVyO?%N$mu2!3?009@Zd#$%x8B+Limv&m4yHy^Aw8=nThYg&|RNld$=3x zme4UX<#u6xCWqiKIb@`*dmMfrOIcqGcvNd`Mc)NMEt-jr;QyJRHi*7!Z3PVI57vVI zh*|KSgh8R!aBF8POAOE&!P&yYRgAuf-yvg-lh9|5&}TfSp;c8Ws=dzi>0_EdalSb+ z@9%i*l2&W(XftcImmcfD^Rn-$vLzfdruENm?F?^viho^`m8E%|e`*sO-ui5NE7h$8 zE)WQ&I38TWw{ykah--fzCVZdy&9wYk)F~Q@w6RE3IT|8TDA!DusEQT5NRkyve2AUZ z+=S`SN~$L%mB`1??Y6kOZL&#Xw#XpS@9uGtv04U1M>sk;NvA~xrZl5LZ3A6w2$~~* zy!7y%}O1z;6;6r2U`fv-RWDslA@JRUa%*D>>Cx0`56_P8ZMYNsG5 z5-|*6KnR$DFGGle(0HQ9nI&$#)DkM74FEHqJDbHAITuwTO|aF;;v#x45!bgCe{|R* zXQ6l+M~1ozK(>E8B|&fWJ-q5O+E@z#L2?Te2g%EMG6@t?&{x4$Qa~ZPr3wTS;YP(N zCV_kvz(##2N~zN*1jKKe2(lhdpd|o|K{RaLL)-CuYX3^cvoB+-e z$PD5>;WyFGQcypSTI!T|)U1#p$-oxTjjZ?0Y=D6Oxz)fT)(+*{CGX)mf|(*hIdPIK z9MvE%q3<|N#V(R7A>bDg?TCg(92FlBp<9h&D#0gGw?5eqL1PNeQ;FaMpznPN7V zsm5mH57}OrRnWdvHAb|0;cFnUCQDcR*rx_NDTs*5DpZM zGe<^5Ub2iW8uKiGyg@2SR;LIuMQWN&Wl42f^+tu@AE%JXG{azqJC#>?)hv`}%QYHH z4X9X>YBx!>Lo9t*7IFfgQdC%+wYH#q)~z=hb4nZ)N;neur}Z1133!2n5U_nLwR${m zq%Q6^C`qkTaEUHi`rpLQOKpKDhv8a)@b8WQjPXu z&SX`8n~G;keVQRQb&kSh*4nPTU~7~)45=wuX*H^3r%U4ta_Xg(81%fPzQ2K@KG{K`GTr4cxpkPHEGoLdb#tN`ircJf&18>yrjXu(}#g z_L_0Lb5p=KMrGlC|MIlsQzaIdE>q^o4FIx+(a;EIqKE1mq|&O;g$n?1EnJe?09cJC zM=eW-TIHMn^$Kj_$F0tB574plF}}d2om!V5OE#FRdCq4_u#ZcrlBt{y??Rp*osnSY zsx{L56lZa+#V};<-2HPuSeW0xU#%o-Vf#mlbc?QZ$v_ATa*~s?3n6=Cq*fC3nwgFB>D zRm4jrJkdW1WJaAq!9t)btCUH-Dpgu0E|bU>wRX@-h0;Gi;BSDi-$#|DOUg@jOyy({ zQ+9(zp;Cxj9JDQqy zM8=oR-+tro-vS;`_TJ7v-ZnL#%^9>{-O#6JrcIgDG|;Uaei)rTfj;`^`Ay4eY8(Z* zC|(-1so$78&YqYFhLzLh{2Z=jvi$K;(2CXwGx z1fa$<{@9b-F6oU`$YrC4(3_ub+43nU0ga%9*dhzBMqys6)!MaMaQ(bGXBu7Jr#VN6 zQq3_j>368}=4Uoj^E~?KJlo{9c7|hM=X~pyPtlvbzV^~JFqOhGPo+KcuLPRkje-prlMC8adH^gTIcVT zgh*4*Gy?noMS57gto{EfJrK`E|Ig9`8JRIvZn_sKpI&s{I#J_D-9 z!w^$vNwtl*qiWeL+(N3FW7BJLW76s5Ld6+$&R|t4v$B-R6g~LX=E*{t*trgSgO{)$ zugl@va&){w#Fl2sJ|EE^U^fx8DxJ}R?{<&G;q?3LejUE+N~qluz&>mUwT8nW6bhm5 zo14-1p%4g#!>ART+U91U4e{YN)D(`iwT1WY4Yxsi7_?BUSe!B0hL|RXT#9(nm+qPp zOc=_9q$52Qn|=pxqKcCJI=|E8!U>_=tT>fa=WSG8otRX7-6X|57KJ+)L=@15c?J+H zU9z1b!B>Z9BJA3UL$P6^z%+tea2F0w^!18waSVv*ux%$B{@6j($3ScmhPI$EB&~?N zz=*gxIAb_Z>GAy`UsS)u*q*uSnKzv?mP3%3OQ*@_a&%{vX!v#D3%4`BBN`Q6iThMi|_nDSoQB5!g|a z=vtc9*;G2X5j$#_M0pzt)qTtm1#Oie;EL^h5ZXG+{r3{rDN{r_5ByD@$bma0fXV|(`PPNyLQ3M>4kGrQ#U+0EiZ4{lN)BT zwPUKwLXFj|o=0Wi??a~ageNK~aq(~$@$|J;oJ_y~Ic;fFxZLm+?SPfsld;}UZTJn-@C=l}LR{$)poWP`WSi|7X&!~3i5 z0_r>OMD;s=y0__W^zJhcpbt;Zy#E_k(h~!V?J-xwb4$J#ZNCcN+2rgNVlz|BzHVHq zutC+)N_IB6kjfCAT-`xQJ%@(_+;?JrEiEy}CK4>_%nj`hJQ-B9w8VVEQMafrRw<#~ zgpbwFlry85g=8Ow?9dUMcU^q%H@@SG*WU353Lg>+!o~Kp#M2haR2V3>*f_qogQOMH zPUZ@spbU6iU6}>xEUcZ5Zm=n1pB*b+PY~b@OOH2SXo_AP+h?7nRN5ME&Fbs zG;ryRIh?*;&&`>!bYKT_Emtl?G$TYpY#2w`{!=$J5wE}>rM9v`gUYByTR@`koLalQ z+To~PUaQ#k_7l$t4u|l}6L0TQT+=mie>0yMid(G~3TAzb-Jx4OmR28hLtVlFKJ^9_ ztlxqAw8ciG?$oTwft$9+i-YjtOD!#z#4@2tZi+wiqD zF80KSQ3qN)Zys8VIuekXcyKH35w`+90img1+J;Ae*s|q^M>nJijx2}J^D%K>HJ^@0 z|FazC0*BG!AmY=|rVMJ)|%0$sG;P#yxiQp>q;7m`eayHuJc;1)4JaZ>D6Ik;#(*4dp?&I3rLb+%n^5Um2=TDrjh4F$!eW z&T5;!8%)_`8qj^t(}e4|h#_EHq*$Dy97r;V0WbnuGPqd$Q3(-ef*CK109hgltT-j} zfT+ZuctjCkk4~(%S5K@y><;iKHX-Tv5)W$6aX^xboBlh&(m7!hgc zw=ffheFx_aE8acbVo2x1)!s-m)DqFq$oE~$TfRDfZU$m}c^Tk5go%kSzn3U zEJ26JE*?jj=A*1i0xx07{8NN5B8M@w$p}2f=Os=RfOW+nsd-ZrcO*!TCRyq$%J~aX z-4f-%N5vw^Mi0*wojz7+si@^q$Gn3F=Pk(_GU4DnZ$4a(JMh5;W6*;WZ#icmibj=Ws=!nm+yk=2wjmv%h%q;3mR*|$lL&4g1)&U zlazZ|$pEh#y&m3OPR1}=F(41#;jdfoC_?Xf zD+YQmTo{-q9pTRztlJ%LdvraRNwM*8O9F8Pd*#3tpRABd@Q8MxE5S{RPPquaECDt& zIiko(J_qHfh^`7qwTJb!>EL`Ao{&|_hvdcSXh8L3+?R{ADo~!3Mi|Pi zZV6Lb)cMc5&Y?SrMwZjJG&k5+-5=gQefVs9L-UnZF#XOAtg6IqwL87Wbhq7Y%~R*~ zDb3PoTGL#UtL;{|a8%_@d6{ltiFkNqZdb)Dr!)&^&){TZ7*S>`&XB8D->d+ne~Q2* ztTVxiUjq&*#3VASa~9SuYRe^LECoaX_O{tS-Gbm#Ib`z=&g+0 zlDbmRk&y$RaFj@ANI79STV3F;kWII4VMB%Pa@nmL?va(lDUl(gYY<;tc5rTTQAVLT zD8F7tl`5og=%$V5BRgYu%-TNZFwsAM5*>x`&?)abgI<_)rIcJz3`;F@JiSR*14N2=I&Q0Y}#A_ zGR~w)H_68?n>_-J0ux8fUNBm|W0EZeInDW)0xqtb5=-LEvOoQwsb@xkGB{wCNbI6Qo0{zq_tX{@k)^83pdqCKGzA}O4En-ecxk_a-Imd&o#P@i<{kWp?%=$J&8a#} ztWrz^Ry^Yfs)q~;7B^t}RQ<5oWwJ_DTjbSV?A#&?byP_&&&sWQ1yiQF&^dK=mcNcm z%^RQ?ZP=|FoZ}xM%^P^(f_Gqr7rj^HSYPL7*H|i#ot``qJve5;K|EiA%k#bS4o(=7 zw}cR5)WO#VGi}F?R2G3oqt#ozU8~L2r=m}YJ<|r7^v2>!Fx#9ISvg>__iJb&v^Nrl zYFB<;``-h(U}SCM1oXPwJD{YDjC`3p(3}3cI3A4f7{@TlbPj2{Hs?;UnKzgP>grJt ze6I{_P~|%wx8EQFhZ^Xiv_Zs%xz3`p%2=MR3ZX)S!#;Fo^4F8I!~G5#iWB@2ba7hl}Qb^8>KHE(W^y1Xm_|`^t92nl6-U# zegE=`6)yuV$OBqx``{WU5p2~shaUZP$opugPOa5}h3IY)4}rr;O21>)#C@4^Hn8Gl z^nI`RP+hNxuq`p)`Iy#FZB(E*7$_h@et3}L<1k0*L|sxPo*@!-Fr>RU{=HyV6-}=* zBsl5N9JL}}qSq=oPGd~5xeWEwnufRrXtfHBR_a%2SZ$uaF@OI{FS1G;RGu%@{YKDz zFTd!yx-cX6Tz!B93g+nbjVcbRSWc!+ux)d~QW!;A(_o1SbuyJzni5=zbf zRw%CM8pRGw*Qi6%k3wB-LMv~lJSB{bvj`p;2+CMb&>{l@{)cUZ&_$YH%ZaAJ$PU`h zqEBH9Y>71CXV8Z1XMv*$g<%`n=p-IA7;#P~fuh04Yo9fNFwv643=xbof8oL4YVe`N%s1N#YV8O1yg1*ig%hq2blTQ#~ zlyPTp5b|Oezfuie!LR-|j_wSO4!<}KT)9T0B>UAL$rwHpr_;csMzvrLU`FB=8t$nT zAa=6KN7>5)RLL*Zl|n-is-GFP`9wB*HK0IjfIxH=+n}kW0>(Ib4GuMBPbWKqgrx&7 z&nbK{^i#GO2USiEcLv>_V9?_Za+`v~g27>(o+T|y@Q>TLq+$5dB`uu;jxAe$?4B== zahr}UUv>;XbbgBd`^*g&*R8vF!x{Dggx*1C(TaoSwl{pe^$5Crc#*6k4=g+Y?)Y;XxCy3+pASOv^}uBE%_U0!O+zdF z@G*d|FOQ)tupVgEU24Cyj#DgNG~w{Y70cefeR4z~&bS)zXF1Nd!FSs;cc9CMnx~gu zZ(ie?zT^;)-to+B*nP&5X540GburvwN*4`;Uzmb6;+x6X&71>lfM^UCEK%lnyaJ6f zmj?;gk(U+ukZc^LrG&A_2H1XR2l^Sv!D=8!2cO!!`KiqyPsORS@;%GW)dGdhrc57` z-v1o>DSZsKrUS*`HX)6dU63yy4_ zG;#ChiIXDtrQ~O3JCbWngJ~=(o2}*?`q73hV@Q0a+GIy|W`2s%rq)|IwbN?$B_~_; zYFh%1n7{;>3d*e-JGu7)iJ*oV?gDBfoJSVIC1k{O509w$5#IwP1(3{Lq1J7eXwCMk zwvg|dv}MwyEx;$w?3*rkuiLaTB_+LYrrey>f8;H`n~Th5nYrA2X6aCTmzm9HN_LOx zpEc+O^y3RJ03}?T2zkmP64Ru}&&DJ^S(=oUsn;j-NyhxXd46@t&4tkjmeq?VYW;Hi_Af!`5h#QvcD&~x zK#N5K9O!ira11E&WuSGAD3AK>mgA_>1w10Xqq-S#KeF@ccZfCPv`jMeir0pQ?br5gi|6ny@?%z(Jl7C0Z-E zAwT^Cv*Fz|_b~|i^*1>d*cVkM)l31QOZyBJOC6U~UkKo7^`O31@FoB|D&45)@NQ`_Ozq?B+qq{(IXIHz0iXK^z+zAUz21TUsCoB5um}p75&()| zMKK!ah#(z%#a*NZn5yJ)yE{U433%FaCW%>!XSI71C>~jTsyP8va4w@j;IVP}<6P2J zK{`EhC4e{-H5=2bAgL-1ndb)yHX(i}pc?SVOt*lp3#ckL!iz|iV^rdfDROxvj@Ug$ z1NL!8velhYjH8__Td{5D6c!y5R&Uug8QwI9O-<%heTRI!S&JtG5}+MC)6Ovl zGgJeP-HyIM0~Ykr54?T0La|hp^X>A$W+A!GH(IJuB=eT>rJ9|3ldmD$H@VhTUM9oK zCv-~BfXIo)z#eoC&ifBx7RDVkev1em07aP-~pp|86bkbikI7zGA^+)3!KYF0O5 zDa`*vKPjI00e*y2uoTLl@1HxgG)0j4Jdo>?2?f1M%1#-fD9=r=o#mhK#zSuR$U!H; z_{BrfeDv~$F6N_C(_{NNQ5^puE&<$gILhKm*gx_36r_S5ZbI+~{A^!bZ@>sCltMu7 zFM%GaEl|&2I{xAj^v$fg>p1SZx>>+@pa|S^c*mTT zH?BPV>MMs=ZC^Ei`)z#cqP-g?weQZ^-9Bl<-bD*m1L^+nK+WkVNJ|2%Ixn}P2i8}P zDh1O%{|lH_HnQplbSk<&(c*ghp2=nWOeHgr>br4>t5!U1A*sfRB>WaZy-ULC8N50n zKxPC6$IMcaP3jHMeLuqC3LJD%i-}^##t-*Tf3O(bSNa7yf8yEuKfm|eeBH!Xf$^z- zR)VKNvQ5KuJsO%by0C8Mz|OK50N<5YrjA*5+uA3+)4*l;9{=7gd;SE+mKN@P zdD5u6e%v~8IS`h$^t&I-`FS|{77sX6zzS<{TJ`diPk={8P8(Qo|KjZ(>&8qPIrx)p zZ^0oqzwknAuPrQydPWE?z%@@cO;?>6`V$YQ8H4HyJ++jGCz=sEpobBi^e_T6MeO9z zQWC134D2io*h$Vb*|$1H9+=pfLpaL!BBslX$Hl+lbXmyhvB5{q(?lj{{2%>#c3j*s z!19Ez&qI&fMD^6TSGn9by*#iq)2n8a^ac+4Y-Ll>_k}ez+*hCk8-^$O}yv z$O#j7R4j@voqcm~XU)@Zu(54xW82x-_{O&FY_zenv2EM7ZQHh!o9AWK@2&gZs@tcg zyU(2YboI=czh6grMbTqUp8cvjvb4n#`rGTqE z?!;Ky-}>6%B3rNtsVNiNUV&X+*FWCq+B=%$2$k~&%6O9;CNq2d561~mHR=maW~>|9 zTsu5$lK7z{58&%4H}VZJR;@CU1QxljdK)Y^tubS+WRfURRT89=*_qpY&IVC=$-PQt zp0*s{BB4iSZ{>??TimbC8A}w+sq}^r)YvUGvg=twl*VhoF|6__6O&Z$G>R2qZc8n! zQ!}e7XIB)1%C%Trh5PzL;UXQ+XHhfQoIT($peA1vTR==m@Zr<3bP`W-*_1Y)eZ#XSwz05n&fOZTf@E3K zKt+7hd{guu3*w-lR%qqx?u#=K!dRoZ!@{8nSJhA$6!ilHIOXe*BL~YBl&yH~Pezru zcwIb2gW}_cl|9cus?l)0f!8aiv6wx%I>rIndou8rnM4@k^NLvX`szTWcVQi8(}}1_ znia27iwypPIWASJHKupzVYBw^<(sS>%khjV2B)gCa?yOlI9;FjijC4Fd%#V($1#lRS7t{Tk>e_3a4*5*ei4BIIqC0$ z#kBE|l6F2G&h}A4Gl$p~EL7uOLnac?Vw+6*^OX_}DP zaY3fSQBjn`%oK8C^c^_ZFog`EZ(Xv|5Ku{r?>|zeF>P|6b z3_Y8b6uH3+^W5YX7YcmXr5D{|Ez8oOhC($d*Xti_=*PCGKk2C95um@zi2R_)L8*cs zk#%xiToL{N>{upZy8zSHFuV?PP zj?wFGzRGb2kty$vGEt1jvwU>oxuSXbpVG_cKC{p!te2wbJ|k8?T@Q@=&x&aZPY8e+>G5Q~)N8uELt;jJwP_G>aU$7fkNAJWB4*tc zikv`Z|8g7`U(NukP+^yzRX1>LdVoGiNMf+DJW{#NUbPms|{)ijP6CmkR&m<~-aL%nh%~amUA3X6Fu2 z$A>H{8Mcn!qFu>$d`;3HZ3mxjcqQ(a6Gd)zv`TFKE+;DXd)W-56*F-6D9b%?rYBBJ zfIvBzdtcXqzl>}D%8|cGtT}7z>MzA5+?ieJd(Dj~5ORzzV$qO2T+*^W$B7E*%3lR6 zr(rtr8sOC*mu2|Tcog}_!^dz`B|r3k`B9u*5apq=!r=UwfvHk1>O4urmxY3qO{8 zT>7RJCvN)#*wGZ=4MCU2SC-7+TkkG3*&<~mZa2NXY*u`4*?aDrw!lfmgCG_={8qzD z-DHr5ZUx{I>u6@@;l3026d^ZS7=ituMb1{@pEvBB8=)CY#OJ0{UP#JNnhk zkdN@BD#e(wQ=bkl2UFlJRpM&5=q%u1H`i2TGRgBmTOo!ubp6#!E8jbeg_bkR^$t4X zn<^ZEvEw67zrIrmnmKHKkKab+fNf+i7K#Tic7>waYP-C=K;`}yL4k`DID*;Vx$du- zZAFM=$LYX>41+J;L%aHIHg1RS=UI4K(Lp2*k4BfB*(}r*US1JR(|(G-a_0(jL1}|= z&Vrs1#M&oZYM3Zc4j2Gb;)7+*TAf|O7{@htYEbKC<4W|Z-VXz+TkhrloeM%|Sj0cZsJboQ`DEno zh@xnTvgrB3+i5xz7T-Yyfo`?6pk(u>>Vn@QC^9~X-Qb66XuNV^cLMOA;A71(@o+`n zzoeO#&JkLvS}KX{PWgEyC&?Y%sO63&NgE6tG$Lv9l7taBdEmZ#`#j6IDz$Kwl;&ZR zThTpdgesJOW>ZXhLTpsVvaMhzo?sE5 ztTRbo(u4f5y&h)2w-_lBJqhei@QB6h;QqE@xD<(_s=yaDp!B;%CT3%HHnyUA1TAcR zjXXNdGtGTt+5P}+Z#&Pcko0$W^!MQfJn%`3pWl9o7q%*3lP;JkArWt9bf_kx0@JV7 zs41aJz^8x!D>xOEEl?{nE+K&=X>1OyWq?Wj#`w0T=FIFj{xlfb)UE?1DK`Qd4W}Qm z7CbyoI8ME6ZvPw~h&U<$vlFm(?F$;6HgnGY$2jlJ5PydXHtq`+~1G)=)jNqYmbr+12@CSmG+NO>fjxWv#-~|Ka4(}2P>6F=meJans0B@kK2ft z#b7e@A3&lqXHD+6(+|I-DzJf`chYRa84|5G7+`HoW=?*XM+k?I@+sVoB#$g4 z-RuWJ+9NWeL1kvW!?dmFD+N?1`@>T8`k4w?TQ9`zwPzsA)KO3<{Td=|wX;73!r#LZ z)2cCJOo9*P;Mx{oL~$BuKwjkx4=+|xbQHy*PyidV9Cab}=Zezx3(BpeFj#Ardxwmw z@>5(ZV1l~!Wzd*~ztj!j!-??b@xT#+KmdVk2U`4-e_*!gTK4I1czHNFde}Dg9@tT7 zrLfJ?%z0ZZ^hx&GnI^5{oit~0SX6hcD<>)nykd&ux`7h8zuh^}r1ku#^8+t3Bry-~ zsE#(Q0cU^;lFL^NVwMpu0KWSw95-_~%G&3h@{(?^bC_L^SkYw@!KB)&r*MsnUwtwv znv`AUq#Xk`7>A4hkC&k_MpWiQ>;uVy3cji(O4FUNVxU8d9t!_ni`Do&MRIF%qd^>K z8&(Fqw6jNG4?vtnUu`XafPc7uT)erZfKw>FjlN<-d$$p^LM6O&$pYmgyHRHCBiu|d zgrPh~C8UqF&%_gj-Y$jtQ3m*Ktwwk;O8l*hXxX?Yl!vcL58Wis1=6m@L4iJ^F0G z-?YmsIcFSD>bOi2y2BddNNsPsYDGl4NrHc(6xC#7jhAb~fm0n~u{C0;5uIiuVQjG{ zYm^om^%@(<>MclZL_wKwQsOYS>RP$=c+~9&?x-`Y$esj%FvahDp0;FneZTm;n!+mv zLhJhCPS#WRF7_%V;~vpdK81jrrIw<4Py()-h_z-^Q+@@5xu+^?5JJd2<{pUG{Tn|z zI%ee$uKV@4+F_{}tS;n!*b0h)K!fjc*W$D8bL@Dhl$E#j#rm?sig0CL?3A#`2{c)w zVpLkrzLcG>$_#jgKI8pPzine#AX_Ef;}|kd_nokDwo}AyRa}f~7E}aRH221rf|%ZD zFQR(C5VSNr{_gLdi;tC5q=5&gqi<54q7ERfB(h;S|6S~iV6A$m=0TU9dw2Qmp|_|q z3*C;&xa5W8i1n~QoVEmpM|}+b^bRzRVxiC?af^qW`*&}n>QW`&cV)-5M4aI{!O$L! z*b^C6i@_Ex);Y)h%hU(MGuvc8r!K(03aAPO@CV)IS>z~E9 z##}J39`jgWlx&bDtQvQB>jN)XR74!!Cy{Z%7b`ps<@xrTT3JnO>@svqZJ>sr8lXUE zeOeNi0{UC^`?Uf;IT+;6q~beJj2El8Xzd<6WC87Pnh&RRt+PL#;XU{Qf1fSe_|;Rm z+JcB&WS1q8UtG4N4eO%hBj4LYxee+7*Xy+FL1@%bD~M_AZVKIFq2I?FLWl{fylr+| z9P@fYY{jtDyHJE}K5s%@xtZDiey`Byjm^}%V$>x|g{`6*!KWJg70T$ls7qZ|HX3}P z%-5yH)g$~ezC{%&vhnglfGTL~{S!lJl7S8s&7jck6i9BF@~Cn68J|6T!iZUX-dAi) zydL7*WMoKoQBS-LS(X`7t;lFLnL2NH+6)L3~QS7 zAwYf*{vhuL>seOG3{DtOTraO7px_Y zDS6t>1HL2`w6kE-EGxq$*-egS%s zT@}MhM;0&n?exA(?0_>M28ydKks)&yC8ROlf0^Bk)bVHWws4@<`F5T2cVBWF{VrP#@2L@q*Vf z3t*Df0E_X4e4Xow?!(*{f$4FsHUJs*#gi4u{t+pX75T*3KzhOL4BONMQt?HDnf`sf zFnp9tBNN{ge%@uoECP$NMHzO5De==I>(9B%%!g3znn(yU#=}m^E9b+5Bk{xh_9;I~ z%nMs7*D9>bI*4+5Mrur9@l+bA7O#~5Qr@LvF4qHJqp5aU zI3<=3Zv#}2K#kv~A_E_cb!BDY=VozYCBsRyofP`hLq@B0qv3Jr7pN$JyPD zGaPPZZZXSM&Pc;BP{(W|rjX2(Au?4XZ^9&xW;3MTp;!I{C7hx8im}^b=li>%n$1N7 zor`);A~g)L%iIx|_-*QBGp6r0_B7)Sbhr2vgLuR{%g2uIYa2I+?3@Hrrb3u>J8xY8 z*&FIq^r#aylsoEsC(SX6Lf#%-zcx16F@4X-uYz{%J!p}=n>eXs7uA~`x0MPRnlv>m zVS3uFGP>NI!8z*mzX&xnzepqMRo#b1iFV##ab$l6Uvh;WanD2)BwRgC^%*mf>4?^} zJNZQK6NYcbL>#CJ!nRV`(_uC)rNd=zi{cN#Yy}d#6 ziSqJ?5qtA;)iE^QsFQiJpoj8eKEw!n;six zq2*|&TI3&5i<}s@TyU+|im&M;a0K1KKfnuV*}JOUf35gTkas0JC%3AF9TK~XoR|$@ zOBAF#m!+3Dho-1^4w4|Uu2#iSxt|ofZ)2@T*db`iJ-|Afs{roQQv>=j3uB`C9rZ(4&{sjLq7ULlcH~n|{G@u-@5P5YF*b>(dG)Mt2y3|L_mo0@ z2RmF^6E$!rPb|20L+En*-M^J4vgK9E{pt4kdodI%Sjmw2LgRv1a!7mDvW@*wa?3Zs zcE!+KVp#LA;TA1&?N8Rxo?D&4W!JUoXY{AFG-zE?3uLJvvl}E+H9^|QciAMzqZXG= z0w4M{b)!~aYnJQX-2){M)bw= z#JR-8ijqh(R3c%;;xQU$U`Qpz-=rZdToBTnORN)S_H~t(5_s@+arZvRd&Hgeq}BPv zyT$qENS&+vXPP`)(fMAK7dPG6eA^st(F?cX(MU!XZ^zw9$}Qc2<7jl2g8QJ1sTIeb zT~ehsv9?PV=gxSf_M1z_@3NK)Enm?WC-c;b)8x(fm0O{KvB+7A|76DR%R$GdN63fdmAr@ck)sNptE0@i-3(s3xFQ@gZYKi&ramie1#Ij;y%xO@JT-yu{&D{EI{OcJW;l3lw4s`+Z}89gY%*$xZxj`ZZ??;f&AfvHGA79-e^x z{Rjz$4ogi{XGzQTdiGU{J?fmrVRqP5^b*_M2~ebvkVl+{9;v}@F?8IS7dewgm*%jt zITozdc^5WIZ4%ML7&my{QTvt9q}Aeh-d~eeb*sgCSh}KmLBM`+YPb|oxgx*S=I!wj z_DZq@-{~^h&_;fr{5PfAt#=TrVktqF{iSuNikoGIpOMYJ?_r}V>-R_L8NzpxG7Ya^ z7;nsPL3wdQGCCMKECqM*riJg>(h6*%qr{*jcf><^nuffFH_ONid4=-@H##?i&ppB- z1}eMa4r)wkT5<1^ca}ko(rY}<%kw8nPb>fyVeH1D_7aH__Y!S$-B$9A>Cb_S7{Vm?YoB;>;!2uj)Tcq)FxJM6VEBUCN}NP{S}rrylj@| z<$-lBn{2O*WK9^s+`RF~rst{Qj$Qz?hgjrwyN`ZAc;hmE6_CAA&(^b3a z&3V9Cy82ynJ}^UXv&LZFcM1ogW8q!mZ1{e_NPo2nXfdBC{HTKUCVLniRHfF@Zgk(W zyHmD&-7XMP*&87(^$_6 z1iRz$@g+X`C@Pu16r*eiJNt%J9gE&h*R69`rBYj;;7Lmqfz_-n6u_j|(x zs<>V6&xu*1KG=_Qxw@~{NgC~VQ}tg?vmdRNJ~Ma@#5ykVF4Ib2Jh*-tT?IxsKgnfX ztm7rg#u@_WbyH7P@k^5G2OIA4GiT|R9+4lDEsvzevd0^|6fxA!R>2famv>i16m^%+ zRtshcTkY_E*8!qPwBA@tkSSUp(MN(Ewcead5HUC&`2*+Ck|g`cv_~arV~NZag(PQ3 zsq>LyiCHD7)RSTpVhrYWh+YaL-?lKW0PDg!08}fNg5_vd$`K<4#i?(0am_NRL!xJKKmW?cP z;}dF2ndfg@mKK|mRm43h5=G{`iY{HPqvvvd$G1s>DrVymz_El$QcqjsMk~7-^p_Qw z@1sO&B*)B$@?X8uf9+g6j)+JAN#5nR<#Wz%%zB>aAa-}5t--u(`-A)pApRMI{4)@K zR?A~*9n^RliL1wa8cR0VfdjO)J7pTJRnV0K=6ow1@<<4Q1Hq&BWg3RgcXJxzwYMsp zKnwC+)ha&ABqoe%4@WchU>~bI!cy;#W_a@62L>n`-x0(h%4~rjxrm@>yMKL2%^1+I3Bk;V zePyd^%u!J~<0ZR+P-un)NmvA#>${zrk!<|Z^ugc3ZT@WaN;jjK^jI_C*aUNL%O-=m z_GmTZ9QN=s5L^a=U305Jb_I)EL#V+%^&mGBB=&+{6TTzi`vvP`y+bATkyL|x!cy-j zsDVZI>|OsT52DbAdk0(WRjP*ngqG{u+Qxe3=7E{&xw{4_55~|3ZU2F@W4!$1%U5+< zc^S5<2i*;?u@|QrZZqKG8vWe2NuQz}v~6444dD~2ZO3aFl%QMZ8S$}4?3&RN0^)3@)M%o9wv59t{^s<-JH&lBN0+r|#&JLJ#~#WU9DuPbE%;XnA} zzvvJ15MZhi!>ci+s!_T1uw43O-LPE-=W1}L{(9(P@SwCAu%Abn?yR`Mt8BL{gHH8j zy74{s!c?LD7#>a#BD(ZcuZ?h&>_LhKE2{0QDOlg zMlSD@vL}t|opHm`iBjFhY)2m2Rpx-N8oY6XTik2l0Iuo_b>o%o#j#@wvWKR^jB(LJ zH7qv3MM)NhD>48rWQfF?XAGa47C@mL*C%1qXKvhfYDco|O|u981h?(k+LdlcGu^S~ zNV{z3zLrh*ciquy$2r>J;w{?y6&dnD-wR86jQaOZS584@k zb7Q<7@YSt)t-KylwS(@7*R+e%47b&P@r-`i-DFSE>ECv(?TPRe+IHi$?oY6-^N#qm zBlgVb?e})0>juO>;Qx$;-#b-<*45qjOy(V^yNC1+9=+T2jOQKAzuk3%`57{FL-CIF zMe>sc5>?1eIP*Hpa|Z=1R~|LgK!I3N1VVwFD@=BmWkx-nZgc=EH=IMs32j5z)jp9! zGo6I0za=-ABf9e`o!%o9M%Z>n>>jNP`J+EDw+oYyN+jVr+!qpBJwUjj7^%S^`?&#= zln&W{V89>*lPV~5#~`3tcs^8WK%7xB0zD~oYyiz5qFFHlO*Pbh*Md<;i{x~m!N9Ls zRvL9FTw)iTQ9WP)H76t_BrI88M2l2d(afOK43RPh9V;iiJeeF;A6jZZKk%g`LPedk zKGxC4*jQ8N;Lw{Lq1kH| zZJ}WcxGOsI;3_xvbg4X|$r;+yQIax>j}JKwD!r`?6tBKJhdDI+U??s7|Yd_b_bw4Cq~j%Rv4 zS{@O-r5V;3j`D12j@z!sVD2Meyi8qEG8|pqq7F^ARD;+YZPg_Xy)HIzK5;le$zq+# zWxP1G29P&QiMig*uXFa)ohHQAt#gRfhwu z$#m0p^ox#+(U5_meoY+?Is2c5UtC&){U&YtTO_NTr@}ZfXLdX}DYXjyhz?y_l8$Af zk6PFeVTsO3Tzlc!(K9JkcmQyK+Gz%48}GJ)GUo-AnvCb$Bs4RKp@IEyD(?-6HD^Za zn@&4-M&&H*fX*^JsWhTG?SE|rbs-HFtd-% zDD6Lqz$}%sCdxs=0kaZTYAr#JQ)SX1*LR&F@i77D0whXOk`3J8$WZ3yUKDsU$fG*U z$zl{Ldf9vqYAN1_&q!J{WlAj)rWfnf@tGtc8aZUC0C1+Y#7*5&$J=!63am7dCg;bA zajiKr6faaIAc~$Gsr!QE&+D`nqd69h1YG zT0w^5ND>k7aNHc^uyd#*n0U~Npq%u3p~WQth4>9@iXjaP{a7=n1?#l(M$ffT;|y#U zaWS!&ow%@bC&@@&fncRlhZQA39@qgp-dv9~SgyMf9w|l~X?hXBsB@aY0C> z(oyynIVf|?V>!t^KSpaDM*%GikvO$3WR%8TWMuVqrWRkx900SzzXJ)?@CUUBC!b=x zKweIvpP?RnL2}kN)JQODH&(E(v_42&a)RW>LIL`&#q1aGjQCm3o~B1{?S@X`^uv#f zLt)sT7OF8~xTUm#`;H5>uBVRDT=`M@1O`L(ULr?9LT-ci$*qEldHtLejUvHC7bbP| z32YVaW*b~kvDg@?hgqLVxA*grIO6?&G zBgDIT%>q0W^NMQ&JB>Ky%amM_6Gvq%=}~A%i;}10oVpJwoD&9vo-|aMGdKm|lFBDR zGn7KwvdLkp zg9}lNycqhF#>;z+pRy(P_pXv?Cs*-IS7q0voyB<5OF=(*R#^E9Q{kMf-IOE~nKgf^ z*lR>zcb?Cwou95PYJOjc+qC@RF6?8zV2jI{;PARTew1rKZO!q;Ra)fxv8rFJjk)iT zvzmUObX+ab6Y788nEniY@Syx+g{?de!$M@lYL|7|B>ejZR>f01jiG8a=-%uo`_ z5OP;XS9Citha0Kj>tKshcQG@25|7O;&``Atw9shZjtR9HniId$Sezes!B8ARakfrMq`)nPMO~KT$KR4lsNbB8qlb8FbrI^+K9MSM zI#v&g(x+ZDZ^}Y)QEQ48=8!+2cdGP!6U{c18%nih6Cg8nNgJW!5wq%7KI-Ndpi&5%&T6SQnu*pa;&0PbyB_erXP@ zQJI%D8rlshNxE1;Lx2d%?(d?v$~YpqlGyajNwZ+EH1YDv-s_tl4vEv;7Z?7OrSE9m z7O|zFqJSm4h@4An>_L=_5E4^%RyG%|Bj$AJkOCFyjaS$=a#0SBmqp2FFOXbKa9nw; zC@-sZF+K`mpJ7(DWx6{_#%@I)%kz)1EHt)2>eL($N~F=Y@R(#MItXF(fd30{vQ6)G zkbJP~#b_=t4ooq$_?6@N>5#`-N*pVtXZTAeu2jV7b@y-1SIMu2uKCU1&DM8X7(5&5 zifb8Z4wtw#&W1gJi;QudW3UxaLBm$Cw zxI4tRtsUvom!x!k{jz7;m-_&6W#X63q(6jv1mP6+zPdk;<+P2S*>s>zFUlBC&3NA^ zY%CTjv$)CMal#ZqCVJNX5JVE82uMcaeY%E88$T8|QbE5djF&O2~@R8`@ga>)RMP*qR&B8#tR=8PS_M=o?uX)9dRy z&{`Wi=^N=g>C@Rc*xDI8IGGzeN=ef=jM0zE&_I1B5||vHs$-pJ-j73l0{uL4?AV{A2{c+~Iq5L!IKPdkX z*|#S6?=zIqw=p*{c66e1v$pzI1OB6gh;I2nKw&jNKrsJ_{+9WFuD`jVmA<2+u_K*@ zzQex){~7zA&O-e2@^6F)bRig100i_8%*m1de*+=>CkE&rQ1gF-%nfb7{dNBzU;<~( z@*+`Spl2!&AiDno|KsY>{{;WX&!znjW3(o=HctAk#*Vhu#&k|jCjaW#ziyQOG@t)x d^&I&Bf7{4Qfr0;H3gY|O1qK2Ny7*>5{|C9)D0lz> literal 0 HcmV?d00001 diff --git a/medtronic/build.gradle b/medtronic/build.gradle index de6506e40d..1f2fc0dcaf 100644 --- a/medtronic/build.gradle +++ b/medtronic/build.gradle @@ -13,9 +13,10 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':pump-common') implementation project(':rileylink') implementation project(':shared') - implementation project(':iconify') } diff --git a/omnipod-common/build.gradle b/omnipod-common/build.gradle index e1fccf18b1..84bd275697 100644 --- a/omnipod-common/build.gradle +++ b/omnipod-common/build.gradle @@ -14,7 +14,8 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':shared') - implementation project(':iconify') } \ No newline at end of file diff --git a/omnipod-dash/build.gradle b/omnipod-dash/build.gradle index 307befd0aa..d255a3b8e5 100644 --- a/omnipod-dash/build.gradle +++ b/omnipod-dash/build.gradle @@ -30,12 +30,13 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':pump-common') implementation project(':omnipod-common') implementation project(':database') implementation project(':shared') - implementation project(':iconify') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/omnipod-eros/build.gradle b/omnipod-eros/build.gradle index 595ed441d0..a4975db071 100644 --- a/omnipod-eros/build.gradle +++ b/omnipod-eros/build.gradle @@ -23,13 +23,14 @@ android { } dependencies { + implementation(files("${rootProject.rootDir}/libs/iconify.aar")) + implementation project(':core') implementation project(':pump-common') implementation project(':omnipod-common') implementation project(':rileylink') implementation project(':database') implementation project(':shared') - implementation project(':iconify') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/settings.gradle b/settings.gradle index d34737dfb6..8411805772 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,7 +15,5 @@ include ':omnipod-common' include ':omnipod-eros' include ':omnipod-dash' include ':diaconn' - include ':openhumans' -include ':shared' -include ':iconify' \ No newline at end of file +include ':shared' \ No newline at end of file From 719ab099404928b403616e86ad011e60a4355331 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 27 Oct 2022 16:42:09 +0200 Subject: [PATCH 45/77] move aar to :libraries module --- app/build.gradle | 4 +-- automation/build.gradle | 3 +-- combo/build.gradle | 3 +-- core/build.gradle | 3 +-- dana/build.gradle | 3 +-- diaconn/build.gradle | 3 +-- libraries/.gitignore | 1 + libraries/build.gradle | 6 +++++ libraries/consumer-rules.pro | 0 {libs => libraries/libs}/graphview.aar | Bin {libs => libraries/libs}/iconify.aar | Bin libraries/libs/libs/graphview.aar | Bin 0 -> 62697 bytes libraries/libs/libs/iconify.aar | Bin 0 -> 126846 bytes .../libs/libs}/ustwo-clockwise-debug.aar | Bin .../libs}/wearpreferenceactivity-0.5.0.aar | Bin libraries/libs/ustwo-clockwise-debug.aar | Bin 0 -> 90266 bytes .../libs/wearpreferenceactivity-0.5.0.aar | Bin 0 -> 30815 bytes libraries/proguard-rules.pro | 21 +++++++++++++++ .../libraries/ExampleInstrumentedTest.kt | 25 ++++++++++++++++++ libraries/src/main/AndroidManifest.xml | 4 +++ .../nightscout/libraries/ExampleUnitTest.kt | 18 +++++++++++++ medtronic/build.gradle | 3 +-- omnipod-common/build.gradle | 3 +-- omnipod-dash/build.gradle | 3 +-- omnipod-eros/build.gradle | 3 +-- settings.gradle | 3 ++- wear/build.gradle | 4 +-- 27 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 libraries/.gitignore create mode 100644 libraries/build.gradle create mode 100644 libraries/consumer-rules.pro rename {libs => libraries/libs}/graphview.aar (100%) rename {libs => libraries/libs}/iconify.aar (100%) create mode 100644 libraries/libs/libs/graphview.aar create mode 100644 libraries/libs/libs/iconify.aar rename {libs => libraries/libs/libs}/ustwo-clockwise-debug.aar (100%) rename {libs => libraries/libs/libs}/wearpreferenceactivity-0.5.0.aar (100%) create mode 100644 libraries/libs/ustwo-clockwise-debug.aar create mode 100644 libraries/libs/wearpreferenceactivity-0.5.0.aar create mode 100644 libraries/proguard-rules.pro create mode 100644 libraries/src/androidTest/java/info/nightscout/libraries/ExampleInstrumentedTest.kt create mode 100644 libraries/src/main/AndroidManifest.xml create mode 100644 libraries/src/test/java/info/nightscout/libraries/ExampleUnitTest.kt diff --git a/app/build.gradle b/app/build.gradle index 7b3fe324dc..41f1c21a8a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -171,10 +171,8 @@ dependencies { // in order to use internet's versions you'd need to enable Jetifier again // https://github.com/nightscout/graphview.git - implementation(files("${rootProject.rootDir}/libs/graphview.aar")) // https://github.com/nightscout/iconify.git - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':shared') implementation project(':core') implementation project(':automation') diff --git a/automation/build.gradle b/automation/build.gradle index 9d2099d443..552bc37408 100644 --- a/automation/build.gradle +++ b/automation/build.gradle @@ -13,8 +13,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/graphview.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':database') implementation project(':shared') diff --git a/combo/build.gradle b/combo/build.gradle index b76bc9ab23..4d81e1672a 100644 --- a/combo/build.gradle +++ b/combo/build.gradle @@ -13,8 +13,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':shared') } \ No newline at end of file diff --git a/core/build.gradle b/core/build.gradle index 784e264e5d..dc9f6108da 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -12,8 +12,7 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" dependencies { - implementation(files("${rootProject.rootDir}/libs/graphview.aar")) - + implementation project(':libraries') implementation project(':shared') implementation project(':database') } diff --git a/dana/build.gradle b/dana/build.gradle index 35f9454dab..4ca6452d9f 100644 --- a/dana/build.gradle +++ b/dana/build.gradle @@ -23,8 +23,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':shared') diff --git a/diaconn/build.gradle b/diaconn/build.gradle index 2c512646e3..137f787732 100644 --- a/diaconn/build.gradle +++ b/diaconn/build.gradle @@ -23,8 +23,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':shared') diff --git a/libraries/.gitignore b/libraries/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/libraries/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/libraries/build.gradle b/libraries/build.gradle new file mode 100644 index 0000000000..5d7e7997bb --- /dev/null +++ b/libraries/build.gradle @@ -0,0 +1,6 @@ +// in order to use internet's versions you'd need to enable Jetifier again +// https://github.com/nightscout/graphview.git +// https://github.com/nightscout/iconify.git +configurations.create("default") +artifacts.add("default", file('libs/graphview.aar')) +artifacts.add("default", file('libs/iconify.aar')) \ No newline at end of file diff --git a/libraries/consumer-rules.pro b/libraries/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/graphview.aar b/libraries/libs/graphview.aar similarity index 100% rename from libs/graphview.aar rename to libraries/libs/graphview.aar diff --git a/libs/iconify.aar b/libraries/libs/iconify.aar similarity index 100% rename from libs/iconify.aar rename to libraries/libs/iconify.aar diff --git a/libraries/libs/libs/graphview.aar b/libraries/libs/libs/graphview.aar new file mode 100644 index 0000000000000000000000000000000000000000..f3d0206ceebf549858dade47e8069709509a96d5 GIT binary patch literal 62697 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 literal 0 HcmV?d00001 diff --git a/libraries/libs/libs/iconify.aar b/libraries/libs/libs/iconify.aar new file mode 100644 index 0000000000000000000000000000000000000000..1247bf7f92650c7b349b347fa5280b195deb840c GIT binary patch literal 126846 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

    SFlevHLABJ}SVe&e& zV1nvCy;t2|GSvc-R#6OPQXx^J1Ia___4kbLUZp81(X8qof6w~iyOe@o#iiK;#6F6d zi_6ic&Dek~%*W8WAN@<%v<9^3{zCq-Y-ej^J6cmat_KSM01Gp-!2(&7A7Ue5j_i={ z2MfVp<%eXEZj;}T{|q|hkJih-Cp_xG^}V1Jvz*BvF~61nEWZf^`5*G%<)4Exdbj*@ z`5#~`62SFnZ26k_iRe*#DdoYq%>fJg3no||Q;Fg~8t_`|y~b)!+%>@7F)%d8N1J?^ zMV;`S&dh(Wfos;h2R=y2fy|?{w-*d%QZQ9>`#rZo*FpKnb@0g@nUg!{9hp77@S@{) z9zIMJ+FNWYejJ5H3+%v(>9x@q6Hw=VDkmN0Lp2ruzeKUbH0LsF>ixYh%AZ)T3b>fs zk_!2wCsKQ!cw$cq9IGsQsH~FwJhXN8i378@Zk^4XH+$>3@bZqX-S6xKrgT?F=6qKm z03Q41;fKF@7+!x*>6kI4_n?bD&u8CS@J*NqE=IAhNi-KJnvL!t)Idrv1-I;cWarLD z;3H&{<^555@6dhtnEJ2q+k0$JZ}$s5&J_Vi{og-PU>u|N8!RaE+>vYhzR~x&}V@@5eZ3K6)ci4 zvC}bnPX(#@yO!2JoJa>0Zm6ITq2- zVp+Gjru2e|OHvxm&G15ZK&z>%=XHKpX+X=Dm1;DBA8 zOW2@8gt|ALAmQI6v|YmOgC$oixFcy+YK(`%XfQGX!uf|AHjeoRSdLfP+C!t`43_i7 z5kghZoQi5t9iBH;vuIyG4HLDKu6feh8LqkY{+dvy%^2}}UV6({(a@x4O?S$DcNtih zsqXe~AM<-mmuW548-FYRec!TBb(GQAD>$IxMC01W0R4osyqp;eDu-FZZmEvgt!qU` zyluj{hNYeLi>&2yK(o!ou~sX`mslkykA!lTFUin+xPW149>61yAL3PI{H}=t&!|-dfQNBxO6m;_KMvd00;_IOWk6BLXbRcDxB!=kw zPh|ZuD41c>_@1iIM-FB5*4i10D3W3x>@!so=$^ zDee$7g;hWel=EfZgxWJiq6F2Y5EgU;ej3J9NfpbxWVNJlYJw~msX`3ru-e&8;dvLO z>X$4S-!^-8^yV9{-?Z_;DQo-uwJX+4-oC7{aaLgb0r|r+Pe(i+?4+kneFV^G79PKA z*9%^+&yRN4e|&WCT93!?A77E|j4s=>^CjlOwrSHk;-a3ras9e6w3%iMIbV2!-L1^Z z6tDy>g#Ad}!XIZA;6E-kv<l{p8-GTVo~*adH-&mH<0-i}?O6`WRf zH}O*}MN-@hw0@wdhB%p@7b2Xwj-eA(tt|^$TbWtO+G(u|S`V~VSG9tvktBR*U214$ zYW-y1VC1JPe|z~9-e};#A$-2Is=AdabKv_Z|K4b=lIK*nwpN3Os#>MYnn?1`c<;~3 zZ!!XJ0XHUI+_vq-#KlIQGwiFX+GpT+W9G)}Rn;vmXdcD#&bNf4!bJIzWMc&tpdL&H zUlRP00H#1{aBv|WRSJagxWjXJ{BEaPK?n)I?R2OSD;_`?s~FHpEJKo+E)-W)5qOYC zqkaM{t=m_90~R$Q!I_gei}~+K;Z;IvqVUl5zzFB z11|)u?ZBce5=_aEXvbObdoTe`kzUEg9%zfB2?mW<=wcH0j&DY6pK-!8-;QK;TppX< z(ZF+P*@$bzC^J>K5l#6V3DUB5fJVIB3kYbbfgWkcH)x0h55$E51jvLYP(Nsp3@Z(R z?~j{+2-PuCKy)_`&09H#;yj5pRz!~#!Y7Fa3)MQI%#Kk4{lcqx?f4-yxh;vzG)*b$SuW6qXXZd7TKfV@hb?FLjqeptbNij?wcL0IW`n z6#%!CX>h3Hg0)yAeW;)AL5UbXMGM ztFqI;Q)Uz$vosKJ8k?7a9K$jd5w?=C-lsLws%p3_2FN7H&5{19p_9IItHNDEb>R{yxpKnpyC0;6eSjkHOtWoZa> zkYO}}2ABnyu-YN-bOc=?O=x+kWlczQ==`3V1=4hD&E$$`Y1!RLDOpkNWOaT3(D1Dj z7Faw^Tg)5vYmFi_unh3iwBLGBz`1I?qq>?Ft-1@wcGc<`H1LTYUK6y3tmg^_1~&GD z$H)3B#!Y0AjIc7X*n~t4z0U29`$e~?6`(yNnyr$q>5R&jw(i(iec0>s(E<=mF0-3i z4J5#!ssIzMH*)eEps}#5MhAgeM{DrwhVm_<(^TR%m+Aa`H9PiPtF_~jF98Ua0_L^APAlJ!*Dw6tcoNlP>QxCsD^D>v1YLt3u|Ws=62kh4gd^h$)shpkYyQ;=7G@aGU(gO zwKQMSF}ACWyKkJhM&q=Vca)Y&fE~Zu;AI?_X-$zz+SF1Xadv6U8pvw-Mzd*3NW(=+ zIvr&|+Um8fUF;HrUOio9aY3kMfyw#{4No()j^hC|Cm0|O>Ma@oH~<(o&3*H*jHdyqIg?jVYV1?Ge z=tRH2+h=8Iqp6B>8ti&gmtfIyB^u5v&|FR9_^{=tjZ^(vr`cYHnXlKxyR6qVZhYyC z9o05a=B_&2wS4=gwJmQhte;#7p+ATkT_YLF*q|^kF=^NM$*iwFP=cyeqSsHIY$%U< z+!#wY+RzPTu-?01gfa&Q^_qEx)@~`AWU{O!Q^#^u@ zf{b|f`8yA!y&yur|JE-Tj@fX-(BIL74re{{&GcCpZ<%=EkJNJzL$4y_h zmVf#2w7<~j0C3&i(vRPEO^mnNWdA3R0z*l1Tz6@#igTduMWdAg3tt`$yHIVvc4`@3 zdqn6ufO&?a4IWzYS;DNn5XX_01H!|O<4x(T{h=KyBvl+?WmS;cutXHc3}ucU4x@xa!7je6Y7GwV^XKbwTUFGwj};@zL4!RSjhg(f_```_c^) zz`73)@9mq>eT{tLxeewXbqBC`2fWuXH(uk^J9*x0c3EaPeST-MHnBKT-m#&(ZAoiT zsIUvx%5c7LQISJ{zI;2ol`szK|9S4a#<2h~L) zm9ln(1i|udAe6qL0_$Kr!RfFo262o9nEWjVHA=@_fc_-NmfA8+j&cqJ93J17b`R|| zGUYb;cUX%H&Jg_{n`X2#9A|eo_~gGEwHkSuz1xtOK8HSkdD4Cd(>{Zl`3r~NZ$0rC zdO)wsRA$=SW<%Fjl?B~jbj!QsUs~+88oO1emE9%0);^uxn^@l8KlG^ui~|=B*Tbnk z4RNeewgL|Ywo04ju*|5Yo~Go4r4z^> zN^k6esh*AUASn%;`>nTQwLq2u z4kD4t?x-kK?yz8)*-}QTms8nm`}n>~s8Q8(6&5^^&%AT+dtAR1P1d{{V0Vv||oP8$qi*GDX4CW6Gb zmQ4_1c7k`q5(id?olP&f^_@@Oxpj%M0UH>z{Jzm7$nQU{^XeX#-xo|q`F%6PY9D`G z%Q9wAflh*o$F+X#*%c6_{}#4b=~(V9k!_U-{>SuY=OtegGV=?&9E>G37Jg*mA@1gHf?u zs8n#kxU^~uu2wz&h@#Us!vB3lOh~c-bpoy_{DRS$t)l_1nfmc5iSJYVYiZQfW}4iS@8M~j zz=s3yx!#a#u=7nx664}atTj1d#n@DIb$5$kddgbrlqA~n>t+QOByi0!wFiBXxivAKkx3FQKpk0p zOw_Ew2&h17Is7pu;uS%(?nNUbj!PBME?y9Nu)`NNXroV;EH0r3r~sRBw7ygpl|gch z917#bt+GUiKg4F!nKrxFHG8W@YZS_Oi%0N0QTwM2>t@&09qZq)9IX-uHpSWjMjaaaa5%QdTp&utjpO7<}ZwfwGDBXrnI8H{lSH$V-4k{JN_}`pJWnTKL13o`&OfyW%b5# zfz>Zt(_7(xX8D;*-DOX-_TDf_aD0AH*<9Uq&BcA~o!g&UzXdR<`!AiEyiPEnZU9@_ zI<^=EJ?c@-YvJ-`JDSkbQ5iaVjp*slF|2V`Z)S_zB{sO{Jl-`iCUWIXb)0Kjp?tBK z(oz!US0{Y1XswM|@2!x>B*qoM%%j25VrN9=oCjWf;ei9s`vcF*w`N{_;$Bd}#GZIH z^BAbO*S~Dp!f&p<_8YcMb`QyCt$Y_ap9K?tlc|zFd3Pl^JOuvY`HlRnqU%HQ!-Ysz zTZeToG!|DmiYEveXgn4mHXi`=dBt&>#c8%2#A6W_t^64QEpyNig>@qW{**bKWH0nC zTGqF6*{oKxWs`jPP08hwj)3Yl6;qZiTCrfRZ}ZESZSE+Exp@2JuH|zUBx|`zdsZxH zi~8&=W6-!KH#G{OX!kj-6)a~JH9T4)33c&B%P;DJ;kKFc=S^?1SR4(Ub6U^#tyhDe z^lWYO(t@W%r~63$7Pvws;GLs_s4><|-95L?8kjk~=HdZBL)uc-G{+%h_9)-<+t*{%x5}&z!vl zxF^itF8>o4x6hvdCY_{Cf+^_d%FfPt+qW0Unk7hDs#jxcMy36!2vJPi2EhH}$Pgz#X@retVr!K|Jp99}n*g>_3paV0B zDh#Ib$?q)f2pL|{ndXaGEW?kmHc%m#)uM!KS*$qz^gDvP(%3J_poUx-LPIZok60=m zef#D47WWtdewK~?5mOK!26wW`>KEVnMf|TQE?naNklR%ktG~>cBP_NFm;g8 zh*m(i5`>HsTN)&v&4(kUB>Lo#-kOE<6bMXLi4{4Z538Qbu#7>Uh*@TH_@$w&2sen9g*g9L`!HI`MGNx{{rnA@C+4xxE_ld_q2)MzXVHPwM3jvi8uYs+QQI=vk=bR1@D@$za7Ub%O|$7R=jt?nc0L~Vg%NoVlUZz+;l)iYqqH&I!a}7gHg^Z z_B~^%WrYP&9v}f@lnxR+t#;n1U4-(t!_I06(JVC0!?lX93|`f|7d#;_^7J%Z~UHf@0~ln-RU*cCq0?T%%o>h2oTZ;J+#oP z5PA_|XeuhGC`AQ{ir70A6x~?YwV?iR3%(ZI)!o(AwHF|Bc+a_a5(2V6-Ou~~2j<>W zZ#nmr=Q+>wd>;wt#RMu)gIqvIBeahvkhZ|ZL|IP|E?jhL3J+E0ouJ*ABZMS~FwRj4XNzO!TqIv$jsD?Iieg1C0tLVle^rv7>k;OtZD#6>} zBzT)>S28M()!3fQj1Pjt(IM#elEF&2L{W-_8Ow9QeuoA%fIb%tWmG^hmw7Ij0foa2 z!6)J%K(p*u)uSfgU&@WHC~VOr&}#|l=*q%oP2wh}v1()@Z{NIqHdAFsB5!|8%!q?{ zTsnpnj@@oFRgS65+duE1rLPaf=b_i&&m*g*c`EKQ+A7Az^Y5I0&|)TmJ7Ti-DqJ@P z%HqRit;v!GrKp)WADES0UK$Rx zS+kbfATQHlj)Rrs6AvFWw^9AFL_u$##l3kbHIkY}EuknLuV6taph?n#@F%Dd_caLj z#1ABSgT6R%YHt?JBQdql@+Pye2I6lEIX)gMp|TjfR6_z#6U56+oXYaYaXd(TX5hGK zLp@mh(!W_LtC8B7X7qVM4zK3Lj#A*}nR2^v_HhmnEMEM!j+aP|TAjnixhY z(c|7+gCt)9X8p$QdGw`I-+t&{6@9mZg`oNC9Xq~8htZAbFbRP%pc7PmdgYa$q8HI2 z^dbqt)E&F~_^Dtykn*8QN2ls6MVHeo^f-YW$beGMtAP|fg`{+{KegwX`CTIuN(*n- zxRic&!SVDO37eP2bUgUtJLte{c<7!5Ik4os8#fCNbLz<}KLu46JVXE5BecJs=xG5R z8}ySg;!hYQjM2cDb$|~ff}t2=W~$NGpP+00^an8c#0m5nh<#2!5J-P_!>ZeW@eShA zGi5lK-g(VW2W|HUPhPwC?=H3-)u6RYM>RU{_pIyJ&ldbNDXAb;M6C9WzDyVP#ehc_ z)eZWc!(C(hgHgJd?oDMoPRkwHDS+3cRR8}9NA@Y4Q6a&BpK(A!p_GW8ah6Ks8=w1$ zP@cpCT&mxp4Hbm zOG8!;!T&+!;~WRI1yY20!(-lCX8DH?38FT&0{^MOBf%lVgKu3rS6UziT>zjS{Qj4m zO|dtKIxT=FLJB@eK_b(@Y?j_!O(#gOn1I326IIo@*-2Fxoqc$6c_g=?X8ZFwf$KY0 z7sg|y<&LDURlXC}r>hhS_~H=oG6-L-(JcNFKUvjhH@rDctq#p7zg+io#)l01v9N|x zz(YovxaWmOmOq+h=I~PpL>{KI=!A!+;2)JwpoiYuk3KoJX3a6+*bnml{LZCMZu~!~ z)c@HyZs(Lnj|4Ttf7e%?K=<{M0-zi?j;;B_A69Mp2>txgrlMh!Is&3znK(}nn^7;- zDo7+uMCmdpD4>%)wunCia7?_sJ1Xx~v1z0$jAI!eUcmzwdn(AteRw5}bmb{BEhWk=yfLybrqqx!E zDFOEUKuN4A7Aas%mo+3q4P1MG=lddGM@_VDA2VWFlQzFU9 zk?eLC6bLml=b<^3?pEfzP*xtkdTtJ@N8d|YvMO_25tY@v_JIf1S}m$#@X5vb5*MC* z2zqfM1Kc&BmLj~MsB+>2Y%HUwQU$n>k#wN*)Fh{OF7H|H2-^27>lnGrZs6@;+ir5| ztXzKkGBEN&{^f|hx~+S08~W5>w;NWk?O3{`9pJ^(!N)&ZyWU`T@R!;gm$olm3LdzS zt08mL9bAf?EIhY>DI`9$Xr4ac>|J(dpcZid?wxzHh(3|H|^)(2tLvIrT75R+Xb~ zb1Euw2JY;QV=vL(Fzixr z)0=O;*#V8|e}Q4>DUxtAG~k?}=m;2kDf9QfY3J~8qOM%>gK%e6alV(5oV0Iq-d zG6Qc;j9Yg+T6fu9k6hMN|Mc-h)n&B#JSED8RHp_Qbzo#_A~~mvf$}-JwS1~1y(Rk? z59i^izwap=1V5kOzH%!2tc-gT&!?NHqtt8EG3tHlZ`41i&!{gcqPY}z(U^5Gt07mw z`iLf}i*o}Ljs`{Ji;_e&#M1*|Q3c%_MkKb$l8EPhfulC}Q`k_FLAW5ok`S3d1p6{` zLQR_!1ze~A<`7pUm@IX{8elYI;!av4>MRk3Rm`Q);SmaLEm z(y$_dN1}gEm33CPLt;cOx7MOlgTG4^M&8acW{Jke-67Lib($vtxYJa4U16e7-jK_7 zROcmf3`V&{8KJ}ZK2XK#IJHF1$rw&!(-*4OPt=ARYMeu*%B(Dt()80hM_#totM(~! zr5wy|>pQG2&C}7jKZTCOWp=083fEj(l|-kCE*TDPqkU!3Qie0O)jH6SE{Qx}$sc#i zv*|Sel7Ca_!p2q8hLz4wRJjs0+Q7aCj_#TU8CJ#yIH%HO4VXN(n(SuWC*)dplSx%p zWrViajI5#zcp;wkLav{a)H&(dzlU;kGO-tycNn zNryEYh6>G}Sff-U!2~>{8IbGp*b3~UWU_n*z$?(ysYZXuoUbe6n>Di7*gIdzrDbv% zALkT(qiwnFctI(fub}M2H%cif20*y7$m8nq82dM6 z#x&Vvg8k11GrJ)~f0k_I3zmw4TC+IH1eH1tcM?IjJPt|-@(WSFBN7>+|0Pf)qVBVx z^JU1a^|2D%?}RR!$nZzZwJh&i+O#prN);LoNWBZDN3zG|a>_j3V2%}9oW(Y^OlPJw z617aL<`s6ILMmtFX3!}&=es916q@q$9iv8raCvzcfLmsDml$-lElB{XhF1gH zTadl_*g^D<-z{ABd*JAqaM!veBa%+JG++o@91}*~5_GoORhA*cR<6JAJUa>(UL`xJ z)p$P8Ks5;U+rlP-n5#B(5(6eDYG~Sw2?ejj;HJ4kSO5|QA_fm0|0dA@Geox26J|ny z719Yek*K%;ZIEy#!RnT1i)!dl4Xh?gHMk;E(6h%?`@k4&_wX^RCk!za)GGHV0)fEX zfNRff&nfpR19O`K&b>W*ZrkH($g?+gt{&68OgZ{Kdd})GO-t2dpJ`C+5z4ss_TYcc zWTCNn7M$H|E2vlEjHbCl#%+6@^-qmeENdOJ8obrB*Oe?VHg>KVGpt)X_Q6`^UPWMT zFhB}IJ-K7kJaR|;&sBe9oCZJGn(0l3!ZW+ZteG;@k=Gy;nVY$xEBU|}#WKd+vRpCd z$@)>-WSD*PAK9O!>PRxFM=3i##A4dhS3Z1?+9^SOG+%vlEn;NNH$~ZjC@CSxYy>5)g z9gu@veW%sw0#3yeg=o$ETvz}xqg%lkz-u%ol^L9D49;nts(}n-##^4SySB-I7b>Jg z_fF1o9HW!ypoG?HebC3yasZS@7%5{TBOQ_w2#Uc;jmoT1(q@ef4?{++gggJ1lfLPn zjP$c~+zqdHr~m0*R7+Pp1=gL`se0;0S(U8?oD5GLdKf5n`Z*nDq*G`9@T25A6@W}! z1|(!bO}(;cfe}p+Y<2r_3y3}3P--0R39G0ps6EtO)RR>2z)sJAGgbC{xNkx~5MM~f z3vHQnzY_odyF4#~a(Q$hi|l8n$bmgs-ne^yUr*hX(lG1^cRBVt!s#plB@68QDz@)rRMQ#ncAD67HEJQ6oQ(I?D!2h6%^ZD_g}{8 z|MGkOmi}=e2+sfO_5QznK2}gzIU{PS^qzz4|KAU(-&*k80aAnf`26Ntfco$6B%y+~ zQ^G!%1Rv2LxYlofE%@j_@Z#`67Z08h@J56K{4c8Y{TF4=gD}FpX7a3->1DeF?vIjP zsAvZU>kIk&_3I9z_cPjc=zT|NyWryBssMeJNKhAf2 z@(C{esi;}kzn3E7>^cRB(MTfu5_ultMV>5}qK_4jSw7haqbJrBc;@qYaRza=5*SpP z*rEm^8Ix4O6FsdAj<0H7SBZ};msX;CN4GR@ZWIpSs+Bwr@B&-jY7vzH;%truJ2f_ZPm1K3i5$E~sp}Wf?vW-?wb;s`jRRi&wTc?O#l6ug+4C_{}zoScSYPV6qR3?jA#bef`UUzSjj!uvp;b>r>zD-~Zh?ERKGgBR6hLpkqV% zKt(>Fh(Mab*bp{QF~yRCsdOp{pH4TX8`;x-cRJ~)bEK1Qe?buTn(|DrH&`$kOor<| zTY?aRY06irLn*Bmq;!=&nhMvc0VS25rPOtzxi-GPRP_IG&Jr1Cu>s*ZSdck~`s3ue zShCxT=~Xe1dBA{hz)vYGy!ZeG=Q~MoBU*?SvhNOxp zKA4G){3#9CV^_U73#Jz>I}-=tH-C@*2UuGtK8O0yzhK9>D_7LqzjS%=sHLgK^nT`n zb?ATQb-tK>GMPYc0_mUM2K<#DZqvCIuZi4s__^UN*ZtX1zkcH59a)FgjJR}kxh?Yz z`}Zli`iN$3+@z^<390KV>N6bDv^l+mL zmVzBe+rj!3J=ZP>HH~h0_>NW6jy$^#${U7(TfnZ3se`v({$}-6is8je6o_e@4{Ff! z=S#rQ^?hG1TXJhoNq1RWjt;%>ROb}*$cZI$vzmv<4Oz;)ORSpIr`y>pM4+wKeAs$zP>I?yZr6dK{zIN@kucf!| zoNKqwZK-v;_cj|l3|T9O&ZXaeZ2gAE9^0_~vEAs0qiBTkg)M8Iw*DP#ZJVMp5xaiH zGe?1fag+Mjo_X%=ost~)p5~UMTk4Tk4yQj_{}`_S=%X8+ML(kFH$J*|`6Teb{vrtW zJOiZY2kJb&QHtNEo@&YXi6C32l*kDRrps~s(D8GdU{(E0M<9~GR&`&#F-M)S1tnGAm&yuBW?Mu+BhnAHW84UOum8&ft7G5HL%$tTxT7Au&zT>-g zAAjdY^c)DR0`KB<)H8GY_E&doCn()#$4b6p&r&MfFY_^vJVHPlqPc(|c*V?<$&R^Y zS_5dJ-5O7X0I@a#m^-6+(gHw22SPm2NMwn`iBq#&5T_*QK!PZ(v2je%o9G4&M3eB? zS8y7c7q;ddzM*DXk(*|o(?L$^Yr960I;t$@^+Ruz{{1+2?_bN(p~Cmji~Pri_OPYc zS7a%Id*0P6OscTI%G0Ru{sWY)+wne{yvN%yq*A8?yWDZ5A_Nwr>r76%EMPBf@=xNF zupDijH0=6$qm4!|%T}q=*IYI>{W-eH>7yBrJqQ+q`44DKCi>ADbj>qLFw^Z|puv=9 zjiZ;*u0X5L;5C`#dU_aG_~MtN(A9>q6KW_;o98(uZwBj0p()@bm?h?3@5TEwHJg|sQ?8$hNGV}d5v*6sjXHvMV$(t|w=qV9R zE=6A8)M@c?XAXLA#v`P`)aJ?LC6eUvlj8B*OPnMm)=BazC`)K2ut{uyzGs9erU$Yx ze{xcIKgv%As;eI(k8A)Dw_^$NW&=mj_byQ&6p!r5pbbTU+;2s_R=*seh%Ly2ou3NF zm&q|j;M7xm(DpLeiI1Oxot-5?-S(i>=d%X4>w-AE^ytHH^qAe*ZiRE}g9kwV93$_{ee*)t_QouJ znOBx;a7yiS6!tH|#_c((sMRO+tW)`buFyPuL?IV&xpSm}hAL(D#0vyLK=k{HzX?w$ zVdBq>qdCl9hj1vtCp-*=-mw5PV)J&m&~Z>`L7#y$I1KWcchXP0(KHwO$^{DHP!~Ah z0y-BSdpi8PMn*BqDK%bUiTC$PY8W+|noiB2mSAplJLX6CQ}WSMS7{1*o=}H z8%J?7lD6e&gSj7cKSp*2y@kZGH(@49II&Qo1kd)gnKSr=^e86S&tAkWbKB zOhKyTGPPO_R5BCDQ7BbXtyBf%3W-dukjc(`VK6{7)ajslyv+usGP7AG1-7GBt3nQq zMkrTIF`J=MWi+akT{y0m$P5OVL=85gkBmk+r-hhR(sJ@CJg<=A5ROX~({Y-C#}SoO zrUctw(P%W7BT%a~2F(n$T5Hk*r4ndOnm?-bHa(C?lu#~HNI5lRW*=J7_ivTnF{bN9 z;L^p)RvbF`4OGb0YI*vHZ{(_yJcT6Y5p;X0zOjPW74&_0tUEKBx-Q3MTY};*baLfqkovp<7WGy7ky9u2)exjbc~eAE;?c2-a+>PkE({c^9)%;`MD^{}95O~kiAkd%=PTnT3s_scmb z_`4(4?10#Y7|H%Cu{WrI5yAK#zcxN#%0dl*#Ed7ogrN5qj0HmmjwWS8Gh_P9kg2)rCD8Ip_RYM@DExNqsgZplppix->D`#X= z#;9emB+=lvs8kBK5tx;F8L@>|CXl^kOmsNds8QkP5#TA5VBHnFpowjc+DlzWaO_{CvI1G>_w1ZB$8dWIqvZKo+X(&pldO_;j^AQ<*oD$r?82^hI8JSShK zfpARsmFqihiG(%ALJ6c<*QG-aBD>}C@OXM{PA3BM({c0=EYdm-$ z#nF(V0ZXS29Bf4IcFw@uA&yJnbxW^idIyU>z}sm9zLOGmz!z11lU!pOWdW^?%(!;cWKP2j*+YF{DSl! zfdwe_o{kA_&Bfj+hl>2h8As=dCCq>kRiq5R`U*^{kLo3x9_>Bdm=^sF&kcG}Z!f8m z>LyhP(q#X$_V34#=S@&e0xEgTXJlhOXXb4D^>^?QFm4?XEQ1Bj=QtmW5~qSNLq5Y4 zQ4AzMy7GU0yHpBMaQg!3^&eg@HO@%2nY>2@-)Kx~&>#41|zGRIa9|P_0QT3(GDA$S zyGWmo{?>7N;hqrN-)aJSWHj>YE1=-D7YRptA!!!14E+RTvfs3P(W(Br03RWK|6cO` zK;8-DvWtBG1T}(SCjF*2t0oqsfM~oEyHdeq#be@V!OssM>g~j25tFx=K;Xr)Bs28u zAHPd#Q$!WC^ob{=G!EFLe^uj`RjdDcVLDo=(!i^rNmY|M|E3nfR|w)OefJ%{LJ(gG z$6S;ibEH;+3BUtgfK7yCAke?jjCnR48^Dx_&X94!MR*aB zb^Z&Sh#p0cKmR-(#i8%eqb)#-7q73c2CeBknKz$Dj{{ZuPCDxCd()U_?0eJerK322 z6To7$2+aA&zj0&V`(Wqck1l`Wi6Vc=&OwY`VWJh=%(EChuP-zhbk5HnzNxd z+YG&!g#XYyfNv_L*wwgSc8Yyc*sb$ta@%U_hIcHkS$i++EBO7|gP#HUKki)g zbUc*1?Dq1TkKTs9xI-k<3?zajiI7A~W#OYY#Obr*f=^b~j3;8wWPq>zQtco1 zqAmBm&~b0a3unH0!QptJ6V`!sV!~?~7pwHl7dks%a7d_&XbG!3NhMsBRJadqNk1nf zfZ)esW$6p|iI)@hYqBIK**_B$2yjlhNlz5{DS}UsRZX`1LopMhmz>=857di#Q13ss zy#U&eeSkj5_=BB|KKS4mXnz5w9wwRF{sEE?{}C+v+WkpB>iPR7(f#YDzk{y)PuyRl z?L;4($Mf31aU0ISJwC2aM2hifWCTSL!F(MMBX_c?nINVcaX}M^5RN2M2&e^{c+u3o zfWcf()Ku(}n)MmIa$fqEmsubUCrdr-@L`d;E!A3W$f2>T)bi~79JOk0sMWxOkkN2k zk0(SkrZ$ITPF@GkyS;`&&xDafO~%UM7A7mFI9sh!bMkP0TX92fk%I^HhiK8+Bk1tI zw!+;fz*;;~q|w={_U<|~G!oLfb=v6Wr88YlYq7^Bku1|S+U!M(v)oTUUa-XL2@KWg zmZ^t1ou#)NN#?r^9-TI}Zq>T(Iisp{Iu-5o)OY~0sJ2`bsRnhwF$F?BP!R#f{}~G6QOv*9H%*A#3dnW zJ7(Mk6TuMC*e2bQaC3e+G&7)CUVIZp+i zp8qzwb$+=sulC0Gb+zfgjxyQHrcW<(@f|)^T0S4$`gUop?)@8U^VWW*R{zsof26Fl zsAN(}QD@nadiOuo>d!oNM=Hh_&lggQrM ziRUo5`LL(7)G@RB67)~+{clO?fO2f!-DMFtu{~#OPWz;m+w1k;$mQSY>u+zFBqU94 zzP&;JwOszSzTx&}7_5Veu{rmY=9GHwe=B_-ntj+)Qt6m;N%u@gX{jgZ!5R1Dj8#B< zYrKY%C%a@7#;i%DvE7OATNEF1xFLWIW8z(QA zKHJ~a(&7&uYAuUYj$K)i7tCG~ZfMRu+0|+K5PAw$#b39z}qY%W5pBeFHdj*sDr4ui#AxPk`oL?B)fw7~cLiFm*t zi;ubh-&I02;Cbk%fIF=f_AnPxtB5xYpO^S0pvlTa0%T+e9>@h`7S^cscm=iO7-1q} z89BZ=0(?ZHJ`^Qt_5q`SY8BH(V_pI2p1|7UoT!nw*wPs?THoS22uIy{>-~EwDl68l zTLo19TZrIGImya7)UNN5fg+FH*@X>hkpnX6W{e`VZHjsDkw-|D6Sq->Z@XzNdq#M9@ zxGUsM0;PyYN9n81_t{!@mSTR7zmZeG3KGG=I7lR5WZNq!;x-a<6k;7NV8aNQlSFe@ z1QsHj%mVN+QLMnk2;H=_tuk62`zasTjVvA}YGbgmAzU?7yQByFdmsAl)?~fW%(8xC zv~1d=spjU?qc7l7iCh)TmM16g`^(B(fr>HoEb-O1q3y_G@<6*`{dd26d{brT2wzV7 zk^(%izu%{31NhF2DpMVwrY)Uo2piP=r8`#rW#6QIcpcPd)6;2~7Y(NGqPLrVZKkj10sJ z0N+n{RbzVd1py=6gK6dA0)Ff{;(f5F8(usa;2=Z#gD^NlT*6NfMF_GS(Oxl&pmSP* zVl}~rNOo>rU2ZmQjfU;{`Sx)1i()Ya-d_?TDWMYdqdRmD`s5C?&tog9ws*+V!_bE> zf|i#b24%H?mBZEtq9Q2D@keaitvLae427*_|KRj&&`wW9-g9^VGdf}v?*7vA>g zg#N%^PULB$ri|LYpv{lJs)_5Li3F%%;p4LBJAxHW_a)TYW9XB8_oLS?;ed3TT%+ZN zzq@MgvsaBAdDXLXryp+IM%*}~q%9Z@xi&2T{0;kn<5>E1zvA9WK>>|+pjQbt*Y#WE zR_RqTD4#kPSAQE{WoX@1u27ih5fYEq8)q$Edu%Tn(B$jt*IhfOzhWnRg&JxFI$T=- z&a))jg!)9vS|Gt^-v_S0Kyb)XICF3z^yDvOgVp$6FW`G^#q?xG`%IW6@eD%5bOIQm zkv5oJbcVYdTq1Du5R+AzW9oGw+f7yod8F zHg8_J)&qblke(b=0T9q8BVnth@JK=Ky*Xy9J3FrN5F9I3s+MUg3;Y&K!I6TTdvdH+ zZ*Hl^hb!9PGge&Drym)$TJa@w@6WYbefi}$)2pp4^jlIKmu+>s7`fcI3S427GmPAb zw(l^>CBW&n<#Ak&#pPnB(KH+ zb1;+X0Ib}6Ro}=}MmYzaE?b^}FJw8JVi0cQybN}PV0v;+Iomf7B8vB-jc`1hU|pbq zCBoPwwBNeW>c7@!TWIs$FnxVpa{Tx;i$Mf@Wc9Q4!<|VWu_|I`QdYm;%DixH@`K8W^kJv9_lJ4R0|@Cz+rPmDMEV&qI;n0Mix87@cM zJAy9M0|mEK8CSU*ni%GDXEL zWxUjI{cb}Nf-&qb%=lR9vhky4&&d8N2`9zsa zZj*P)-&a@^opQO%E}JOJ(yIl~lP>jxdWRnW-!qXEmE&SIxs1L!Vvy$@T4*hjv*FPj zy$bL^!FLV#g2~&SxVHZuz(sIhCnR~k0pw*W;w#&~5{@z<QU+_nH~B)K4)B@Ul0esk{{?-YV!SB$zRX+#7bC30ClKl@CxW+bQcuS4LIBcqIX5n z#p1ajOkOlO{emM1VbBiG{x`KiDvi)4v?+~r(e~|+0TrkQ%EQ~+qq=itf_9X$2Tu;@ zzYp@tiI!e0b!X7Naicw${x7P4t5ov25X_RRbS2FrTFL`~@|F?JC1~8a5~J}Y@r4KE ze;G^!gP^@rmcalUn3s5hW<&&j{Rx6dAz}stux{)?2=)eTK^wvo@+r;&|4HC&#VDT1 z@3wG#CkV_D$Rc3B{UN3|jq}sOQUNJ?o;jU_y?rT^SrqUhL771!<0hOOMLJh_W(V;_ zV&I6j5EBA;fePwtfEf^hBuCDYCz=9i@$Q~GP{k3n`*ARTUEv))yTNtA`8d7%b8vl- z>1vuEMBTVZ;X0wj5%4l8a($p_0j~NvxGsR-!FpCH`G?@^&PbID-iQXHA6&#gq>IIr zO{4J*pyi;?RlF363$a!7gEJK5j8vV{QlzjSjDBdS%U-(F^KU%xxXZ0I7!q z%(%9>D{AMBI> z_UvKlCXKy>%!D)XTDUJGt0g!RxK|18yL5bl*xnlxKnFY=5yA3w>U!wD{`&Npv7qq; zCYW2%(XH`(A!Nq76u*y*UtWU)NmZ{tWDm2Abi+wj;yc&I}^YKbns?YJMo^8w@ZMM>7 z+&$5NO?_{nn$`J=z{=NKrH*tbTTxz$E|=P~K}&g9MhD?7v{Qp#skZ=gf!gH)O_xPv zjzH0F$%zfg=2ej+|}KjfZ1>_T0%Dxlf;d{?(8{-mH;AOpFwU!L0l0B)rc2L78CJ zFUoRK=h;2jDIca;iLV;`^#lq}C%`+#&ifJiRoEc(=nUL>P!66LLm?u~PYYHWEQK(^ zbnb@}X1;M-9m2g#oxSIJw( zk8hEy^t*vpI&Vf^b#>luy;8nq=guv1B~H}H_8&N~Uq%W({l*(llY&G8POzB~_Am!a zq-v-U)F^5OwSc-556%mG!BPL^nP5VSXm)}hyn(dA75d zdc@$^MHA@}&2yXaf7D;U-wcn%Mou$~XBm_@yh_D9&Jw5`DM_>a411Pd7SpfvU zH^Kx$6fHzoP6l5HGk~B;VoN(0awnm2V%V~vCcbj4!}Hh$I-h5&R)(?7~RCiZvEppDNyNapZWcn;q#@C*f1 zrC^`nf)Y+(^2wfRz{T{V#0w5^py)0Ke`E<43=w1n!FwFd?0T2tu_3;9_za;GB zE%IQlang(#B~RJ{t1XM_uJfh2EEAX1w{efxO}|^y5{R-P%(-a_{UmKk#l@ z7xIpJ-kNh@$B7p{?i%I}UsXQl{l}hY($s8q>muny&z{Z89(?A}gPm&vxsSo;b+z|C zjlRSG9>29Hp>6%=#CMYgQzX@*-+17Q6Uk-5%+h#V za7;jOM#M(}9p!zjV4*?)C5)nKGG~gKh?==5JczqN0JDyCG!ZqKqZf`K?#ZjvB{ZX? zm8UnAE0XAY2ogYZyUw<9*cA@}HgIU}A-H!)`=$E;*jW^;42^9xnVS}G+7GWO&MPix zjB7w|s@C-5gT8lJ&CRLilAndHEX7CY4eXG~v*d}@AQV@%O+rl*8do_Hgd5ZA;U=wp z<&@dO%zmRQ%cHo?3s%pZ-(d9`O&(yC-V#qA?lLveFPsrB#tP#?JJ2>9rKfC^pDL!> zsD;!fY8Q0}b%gpO^$GPIa024{K$NV+1JPK#fbn_R{&$!c8W+P2&VXjWDB!yrB}pehYecL^fuQay}vhz|5}DbIJZn)NJ5<1Ykx; z5@|V1uLa3Ha4v^GBR8;XoZ!yg_QJ=A4|<4m^$p|#|F#%QzC9Y_S+rc19sbK~PTY{-k`EnSKa z8*X^~#xvIoX{+-i1@q?@MDkaYG_d8ojyf^R(2bzDA&k7cIYg_nbMq?_R!0L>^wW_@=9-PQB`;#fx?_>cK-s z^t&#M89APH$vww2W@NmipC$UG z!2O;Q9(nB+%EPDsU9fvJ1cd% zDu-Y4b&@yKoEkN=ZR*sf{7P4CEl6f3oJPCRY4K*4#Dl+Hf4UHy&DUe-U zQ&W%|42PTM%x=nIeyTlyUPAXE140syE!g+K{N3~C?*{O?p`8F@$#j>gQ<1SZWB5wcg}g7N-DozEB||B2sqBUz(_ z7&pL&3K{t4G2+inew<(+5lqfJ)}Fk@-fHzsc?#=OH{{<7!B8_}0_@Tb}9*L%Ii z5pPL&(<;BOxY+lVC3)Fp9%~>sV2y=0uJo6;-8gCO7Te|45gWJGa5);cQYW$dos*_r zGGi${c47MRwzlF#ymiruO3#q6vkH9ctPCzJMBluN|0*ki2Au`qsi)HK8e9ey2f@V7 zPN11Ep|2EZ%5c5(JD(=n+7j?kRaHSjVc`s*9&1)A0j#PjF9&P$@Sh3)O`DdN_ZYZ> zluUP;GJoae=<M6PE&zgXw1nV+5PdU2ipBDAA$gE>H9q4Klu%p)1PAqk@ZKzDB*1UJl0mG&$4Z3q zoI!MOkLhXg0ZqT45k89soW4lF5ukOLq0~Wz-ej|YsZqbvPf}0c-BR7d!&)GfG#j8E zDD_$sJ$5>XWs?*&ZEqMhYe>1HQqQP{@Zbe0+oIs+=drpGtTdDlI#f7HodxS#st*{1 zi*zWNUtYvEgj@u#2jn6jsG1Z)(K;TU8qVh6nFK2Mu%BCc-m<TwsBM zG2Y{k2=N^iF&@p8$oWN5ISr@%6|fSyC%kZYMWe-_lxcxcE|c%ut(CEG=@zD2s*;25 z(o7ZA@?TZ~T1*t(57Y|O1z8ync%KR1&I~>}Zz(4GAOmZ$hKf+b@Jc)p)33{^tEpSW zbr>(GF`^jmiwmo;ukRVhEMSp>pDXB8@9<$!*C<9L{l0>4XzNl;PX9dga^z|Jr z1x2;>A$O6p!>u3IHL@s*nUb!J`T|{bUT}C;VU{unY}2T+3gz<6yKSY~!ri;!qWtjC zWK6ncw?AuCv7P~9 zT2&^s&C{I~3^kV5TGVE(+p1rZ9mod0#a9@YO6UBa(SDa=B^P_} zJ<^*=1Cc%35F05G#xhxDfQi6}5Tvv?@gG&q5El>q8$@{VG82_}iK*(#<`R_L{q8OR zD6O_)Ox7GGDh2YNAC}vtqjBJAKGHG1D)jkt($e-)>AL4);C7q????MyEoq*=d)NGj zvc^4;Xcb2ISpQ5nd%PSk>dw@Y|}bV5(G{D1Yu81Yqxr+=a^$$5P1W)ls07jM zA-)BLDO4vSG5uN`c<|8hNI16N@1Hn8eEt3z65?Kqn|NV?)Wso`28YupL2nT!M=#1b zda+*JB|29S1cD&esA&y@WVlt+2x4k|4-`Z#X`ui~K(@c?e+bk6ULk`}whM>*nn$f! zF^YalxXoRGl9Iq(`aw9ud4eV)(G?(&K$Hl%LOTiNvf=&*|Ue`U!v7E z<`zG>bI;2~IgOl5M(6&TmdRi_xtjP<72bic?!Wp4AITkTs&GOtT5E zn4~Q3)LP2p72cK1kp%8Sz&acRB~HIU`f-Z*Nl+x+|)t`TXJB^ zZI5jE>(+5s2B8AT*p;l5g{xU>mZN-pT@gBn-tX5`|Kt&cO`0tQP(J(2R>9An;6D$H z2Y16$3)faHJT$F)?bhGx7T-TT3PH>hsT=>h2loT{Ekl!hsYIz@73rHTmXHm|LRBkU zG4(&GzlpAsK}E4rsgjNAB$ouGz;SFX8b6>{CCIpZ6p_uEw8VDDpaDeQPP}!nA)a`x z%m~$qFA5n50i&eh=#-D=%H{tfx5?+F?+nCVKT9Q30XT7$B4_$0W#qVMU@6{7%ye)#jH&n+wG8cM4**=lQT)9kqtYI0-E z`1IA6PCT+9H5%5(&-~cD&@}Xq==;gHzp;{yguH>e$rXOhdGg9!yb`aYuA%mc=+O}Y z-;!*e!l)32Q6VCxi(wwK3Lz2Hl@su_E*>Fl3{eB~4Ez(>8Bx`ViJcSr{W8K)r>Ok) zpu?5hn4RVHw-@BM`&~wJ$l}X&IfCt-LYB`fMDl$?k^F*oztdz2lOn&YA>`sJ-R()@ ztw8*jZ0|lp4J(a};2mBEAMAwxF_I!87l++qH<|2Ko5N|f@>;bC#~qnO90JK+A=63zIl_I>k_ZDTw=Ax_7`|Nw2W}Y4Hk3VX|NF#Dr(FDDNS@Iq-L9^fU#% z^UWttqwO)LOlc>e06H4_L63c}2 z86QX-#f+o62n9*7gc(tnR}vy#j|ad+MB5F#W z$tvY?SBXCWh8*8jF|V~bQsydFWL1n`-O=^n>_6^*WMrv*w8jZGqq8^saOJq`e?M>B zb#um*SLBr2y0(p67Od$QH@>M$oXRY>Ilp3F zqgJ=*AVZsT6!v^}MzIkX>&{yP#tHItq7xV@>EE{UnJ@_*5^+Kd0vat|@JxcBfhBEZ zHi~n8VgOE97~ov=BG~bJKlk~=G6oj=<2qpACx_&oA<_1AP&;j=GaRvlQ5Dk~&1In> zZK+YSo|sQFlOMd~>B$B~WzNzG%l00e+r7L%>N92g6Q#{L3--=E&$qxQ57fz30S8nm zpubR~@ehs5orY!YoVIJcQ>t-f+t~8P>k4B~=;S)<1*)5l}4|{OMyt@~y zGEOa@Sk@4-UkyJ!-w=V$$X`WVPa=D;b6j?n)wTScJs9uXFFJge8#l6IXnN=p0 z(JvKGw4kku)~~wy>Q!LV+-I+PhpcI7s(*E(NeEibRp>u;qVLfg==;u*SAn}OpbG}s z`%wadJ!Jvn-C^cw05hO&k6GS<`^+A=H}mLucLXSN>3-Vb`tu$}nD>eL1wIk$NDHQl zh%^d+=Nh8KEzy#(5sG5+9(XvDnGt~UiA{juqm9rDS$GP`B7VaXA+mgueuGm8uO_&S zjpETC%7h3IS~LPrqgTQ{%hB3lTaF&xvh3kIp4OLvB_IoB&6sCo*`r%3s~*(IO&X(5 z|KQ}KKng0+DYOHfYHO@T2lSqo&3$(tL8kzBWa+GJg32REfyc&tC@L&^3_vk)))A0u z%sS&fihe$N{a0gZZUm_m;_W=i% z0xt1nuq2owVsi)T&Kqp^%n3awm*Ct{7sz_~evl|yBFJgsdH#KU7vfIoN{CdFm~ol; ze%UP}%2l1iSf9CXzS+kPV}mXx=nDSBVMwP84u=7z4B&oJI8EV0$~s5(2(W{(!2XDA zo*5_x$!4Jvq|8pI8KqnW1#nT=;Rrj@6VrF5Vk1VxQsNO#>|P9BXvd_lTCH9uq?p!2w|iMCC@@2SVcfQ2_)( z(@!vc@La+^8S$s<{E>(sKIaEgb6*Y#)7Okg?>+DcI{uKE{u4>)TRt9y9@z5jgLA>M zh<~$g^ZV$nyM9CqW;{!Bx8OJ^zWWETYsOK31pcit8f}b@9XmSW^GB||`yur1BmLny z4}Al+_#$J*+=bryU^9@Pi1>vVDE?qG`td}B*gGiBQp^vTZ)?Z>e}#baO`G*Z<|NoM z7vNVT7)NFTeJ7y>r_sb>kE|;aqO~nJk=B(ED-plALE&N&5dqgogbByv#E6rFA&D>J z4h<7`rp&@4Y*U;wUl`MF+gf93Oh~fZnaC zTr;AGH?+;!;#HfoRKc=3ry+W)wc^zNzumGIf2UIPhh+h!GPhye_ztI*vuHJpqoFD* zIUztZ+hkG?92xJp$5SG0DOEZja^}XDj+x?ETjk8YqoZ~63lbZzP}LSx zPr0{m@8a%V?=hF7r;Omm`qIAcc4>|kavZ&NI+`G7!PNJCeLwgQU1L*QTC>`xC*x>; zcFpw%@4W}W+@fZEaZJIwyd@5vVIa@@9X6At;L0KHWiF)>%8x-#9UH!Hq}P*F&ebWs zA5KWjT4!r=Rj<{6WAoZ)rJvDBv>O&(KWo_Z|I6H$2S!ok`*&4$PtScH$t0P~WHK{3 zC&y%F5+KPWgd-$C2&bIkz9HO)2*Zs6id+gPW;oy+V9o3FT7eVRjYZ2y^2$-W&K`Z-)JXfD>kn1O}Jdrn7$$>VidI8ouFlr z_H?QRSPf!>eN5Y8AojqvQGJgs&FFh-!3*^Z+dtn5!dpMzjta>$b_Cky7HVPlAT15^ zeRE4knAmu{9N+pmsO{W?-_omDaq-TyG_%d3YzCJgn^8fzYna|#tGtLGEyO^iv0KdR zT2C&2oQa0|MKREO&1lk7l3q_rO~tnqWUlgWtw~L-+2pS>1@Y8#$UaDM^ndzrX4$)xWc9#@QI})7IH)F{;HCaDu27#{3UVwGH$Ls z?60cwqgf`?V>wmu&hEE&B|<;jyP+18aO!Hdw-c^jVnGoTN=x7+Z$$DCvyWFBRnWnN&;GA}XbMGRt=N@}vv(@%$lTq0d#sUR#Xq7xWOh?5~o z+Z+LMiLej`if@bWIAczLeE@YOdJcj*k3;|tiwj3f5IO~CkOdYHG&n$j_u)m3#mqW_ zKm&Y!!K^cq_bj@g&H@U6pbL5=E+=m>$)L-l;{_kE7z!Y6IIPJ){xxk0b9|@ThK``N1xL<0l*88m%!(qRcYY~wC)9%gTB({!G{4C(%Hw z0lv%`4P4)CVS!ot9xp|8Akf)*4F7TEg`2Ye0NDpN4&~uSQ#yz4kjaeLcvvd6Way1X zqa#VG1jD&>qf7>7@aaYz28;t7$kc%Oa%qyog#R2#5+yne9A=doJ;$YYz6GYCqgpnV zlgW8>J7mGDV8V-12wKmb({_xK@HNBd0y%msg!ZI@0J@*k;P9s=()^UWtxba}{YP}%lbE_xZA1wPGg^!dkmU`GeUMPb4v237+O6``lW z&!3_%J8wi^fRw-dWgwU<=WtzTMeb;1#r+bB%}+4t7}^cuodQ>Q0<+wco8gzB>B-HV zKW=`KyYNWJi&DLzs(g0b<}+Ycd-awVUf7cP7`UHcj3cABzesmB<9>GoBd1!o$$kvS zuw(**=Px{-{^AF`*aUjUB|h+k%Ot=AC4!l~7yTY(tTMg@nl3bg8IuN~>mx5Oo>b8c z1L)W?r~}ip)aWA=S~Z*f!`X+nA6W>7ylHBv;^(bFY3S^AV=sWIZ{1Wieo5pkx_LdtOeqWrmpq8mgFJoJPl7Z?I~ zx*hP@$<7TMb7#qd7f)zJ#c=}F+++z@gqcS+uRnM8&-?fP`RuvyI{ru-fL|Xz{562+ zzc-%0bKL_kw;ep#_VNSk=B{~U{OhMq{Sf@){@Xu!q-E*4w^zJ<{M75*>JDkyg#G&` zlyR3g%$wJ7Z&?)^8Mb@(uue8N&$(bh2D_8H?MQX!NMG@+`MfxvK90xe32}LdiU0F` z=&PQ)0Z=vMy9JmBFeUiI@C;5i<*P#QOjqF7(Y|SlrvS#0Hzkx=Mk7fU&l;h zrs7rod}cATj9G;#^#*1ub0f2xxs^G9sr7N@67CUX3&=(9eus%jmsxsWL5q-h5p_X{ z7a;guzj6_OpDFkYz81pIViK-#xneUd3Q}W(0W&$m^Ed@6L+;1ZXNgQd%J%>Y*{>FS7gV=r=Hrl>B%S2`<{L^{XET6t!#S#DQUq{XRu*-FgweX zQLDkT@=TdcZ8a;?f_{gDY2Sk$0*zJd(ave;13v4u*U-DmmhDgY-I7t@P-l2E$fa_4 zGcvr6g2~$c*z0Fb3A=1Y{V?NQ7hHKRlg5zJzqaEASDGd|rzN_<3BP|XGnSTm zuBb0E4Nz9GzJP*&5Uh|G);t$A4O9aH#r?;X5F>RJAjrn{R%{$uj&nqLF4?`H`gN%# z@}{7A92X=1GIR6Cgkn2UqpKg~1G zxJwNC@Mrho$)*7?1iG4u?E8;%ZP*K3!~=b}*MMX0Vhkj{jQ@GwMLiedJf3LER8m}8O#4v)bhgASL2r4xIXcw|mBZx9>-NAX3t7+nNkgGrHrH@=D5Q5zemZSPGI{yj}Q40vqLX5sZ z*U1=-9HT4HLx#v%;!FzP;<2cfxs7ST12oy57d#Xy`qytkQF!$iZ?42ZI+h%p>wH87 zsEI&z5*-Sxt~>N^eG-^lyq^p+f&o`@c>Ktb`hb4qNNoSb8wvDl{v+G-6GDaF(HU*0 z!{T93__WQad&iI%)31IGga8r4LAbq$5gLB!`W4?b#J920U}y{h7wBUxm-hj=M0gur z>LV|=qF2y|dhFTwtC4V45gIer|M-}$mHy01hH)5hNg6Z&L=`khJueM1%SL}oD&2RX8Q;H|HL!Oeq2$Q;$;xuzO z-)6C;&RuH2pS8MARi;?qk96F+INhF(S9D|p{<+@U?os_ie3);;bKK!%ByE$yki-rfBN*ooAP@a-x(Q=A(r_E@zWu_}Rb&@4Tj$^{{DV>4g>~KVseTBty33B=C z>c9z6YZZ*^lu4o7Qw{>LCt^){9Ju~dfT(N5U@-$c<`Do{iJ-tE0y$N1M6n#9rGh0J z=?p01;$K7J@T>62>EQ(2p=+9 zQ%tDv$gLk;&aDk)W`=5WFOxYO>|(eu--+ilKC&ys2s&S^RmV5%;<&gvFMw1tET_*T zXGZwq!sz|?+qywrMC-wSZd59Eezx@_$a$!f5nCKN17cf0Mo;6mln_*8C*rgZ0sWC} zU+&cy_M*S(#Zw*fR^oXmk=N^~uaRmhh8bQ+4}vWq3RL40)5d7|R;!zS0Bu@7;mD=G zT{%n>&O?$XIFL7QJj?m_E zQNB%Y!bNEMl_K=J8Om{nDGp)Tu@S04DTyG7C7P|c^)xP25mAADRNie zrf5%he3XzS+8*dwQ_Tz^XU|cF_gFRvxZ7{!k2H}0Lx_Nj^zT@vIEKiy$7*B!weol1 zpPQ6gV1HxfN8^~TZEAgFdqUmd#)4~yHkoZ*M_;>k25}?O9eESvTGZ78kzU==lvrCZ zF8?{7pnLo$c_Vcf^ayciU{jA>_t;<%j3WvM>^%#C|LsD+mAt-WrpziYlmpq^#ncBA zAv^KhI&VzWV|>|Bu=nVHSW2WBymr*TSPrCl(iHi!=54gi$I>-_a@1pb>H76ol_J^u zfrQ_Qk1(Z71yjc~(i0jplw6B+IDUbMkQRbRO*4ZBNsmO!7Sjodn-07{NA~1&pcvbU zBp8{NNRV>lKMy8Q48-&zH#*>X>-+-`oPP^=I``qJOY5@PhY!zQMn_h7<;GR3ZiJzy zNiLqI9_&Akpzj{i_8>)96QuJX-(Xs{%w#}+jJ&=XEZDpm?MFYC9shINePv>i;|V#Z z89rQtIzf~+l-<|%=i_B$-UhlP0%>mpnFeMuv*2274o{yYj3CMMc-f#hbh_evm^~Y( zCEB4t37x1|DuByqw%}4@g5=Z-(?y0z^3g_Y1Ckyst-jKnj(&LZ9dxY!iVOQ1q_Ug- zynW?|*U|Qq7_M)|6MLy6Vz|3Mz`xG$C&yW!e#8Iqc3hBbD=t9nfPTOZTvK9OoAO=w z3Djv#`{0aZ_OVY^ZU5T=jo1f6iJ^u}kuAe+sKw|`ZoiM-PIOw*Z0~?d*Xq6KN~eHl zL81#fi(POTN}}f*LvR^RWaj)z8R9ncZxJS{4n!+he0b)Hr`a;G@zKYg{S=qo zW2iGFW8E;#)ty!MG|0I7S)fVFST~jS#=l0JAy`bBU)g=2^}e#sc+*3n`^tLo5cQ=9 z?}=lk5NDPYdXApKZjQ-c97iwhlF7W72<;lyb37e(N_0PU>DR~AcX!FHIG}9z@SfxA zuv4P@sY|~w&cZH^jqXA1H_I|nT2+%*I6|3#| zMDd;142IXlh$bGV9v$JH;}Bla31M!1EH4zTTugNWxs))3pHG}^nJqql>@d_31B;5) zjj+&QKp)6bWchOW)98aJjsJx-0{7E$c|H!@5$etoT!=G_J`g>g7O5Z}haLhs@$wNJ zpBBH;`R!HXDyVw_e?jkQZM>kC= z@VIz->t*YDK zkDNn4CZ{Fa%uwSSo@-_wSa9a%IVD?BOVd*)Hx3PzdiLc`&uy$N=H+*$Py7Omw^hv< zxpzcGb$dnS$l@_`R?IDU@GOeFn%7vED@z^EY8vM+jO|OW#bvh*uO})9st6;Zhr|#L z@akC97iOkhiGXH^VgX?XHW7zb2%7aVm@tAzXP`_-?3>p6d8pGaDk$4JZBPARzz#}E zl_UuUjZ|7ZfX}EYouZU$nm2rXV#bUUUn6X+9{$5oOxA(r_0_9iM_(WM{Yf-s$AZLIDkrMuLqEZyf)6=p23)i3FWT zU%$S3@-}eb(LWx-F;o33QG75F)5k#fh&{Lz@QNkq@H=$)ii;{G*!6KN5UMwZUWC<` zA(zBn+E7~B(4Lg=ApUN@!Vq?9a)l{y%u3>mSL4MWIu-{a?w6nh|-NX{^J zx0c}kf#?)Aftw^Y4me_5BvkphDYlu!`(i5?!kJ1m*G)k$en!yqVF)y-36u!SIn5wKTB7R|8!0DB{AM;;a@a=K4wfp{zyyI01;I}#Om{xRMIX+&`{}~ z4!M)|$`cl_bdZ=)vz=y>PQJSH`S=x?Y==yxmR-3bQ>(C*SbDicOpm)Le*%N5GZ9A1k6tFn~^#L{|N16~>yL zBhFC+7zrNVyO?%N$mu2!3?009@Zd#$%x8B+Limv&m4yHy^Aw8=nThYg&|RNld$=3x zme4UX<#u6xCWqiKIb@`*dmMfrOIcqGcvNd`Mc)NMEt-jr;QyJRHi*7!Z3PVI57vVI zh*|KSgh8R!aBF8POAOE&!P&yYRgAuf-yvg-lh9|5&}TfSp;c8Ws=dzi>0_EdalSb+ z@9%i*l2&W(XftcImmcfD^Rn-$vLzfdruENm?F?^viho^`m8E%|e`*sO-ui5NE7h$8 zE)WQ&I38TWw{ykah--fzCVZdy&9wYk)F~Q@w6RE3IT|8TDA!DusEQT5NRkyve2AUZ z+=S`SN~$L%mB`1??Y6kOZL&#Xw#XpS@9uGtv04U1M>sk;NvA~xrZl5LZ3A6w2$~~* zy!7y%}O1z;6;6r2U`fv-RWDslA@JRUa%*D>>Cx0`56_P8ZMYNsG5 z5-|*6KnR$DFGGle(0HQ9nI&$#)DkM74FEHqJDbHAITuwTO|aF;;v#x45!bgCe{|R* zXQ6l+M~1ozK(>E8B|&fWJ-q5O+E@z#L2?Te2g%EMG6@t?&{x4$Qa~ZPr3wTS;YP(N zCV_kvz(##2N~zN*1jKKe2(lhdpd|o|K{RaLL)-CuYX3^cvoB+-e z$PD5>;WyFGQcypSTI!T|)U1#p$-oxTjjZ?0Y=D6Oxz)fT)(+*{CGX)mf|(*hIdPIK z9MvE%q3<|N#V(R7A>bDg?TCg(92FlBp<9h&D#0gGw?5eqL1PNeQ;FaMpznPN7V zsm5mH57}OrRnWdvHAb|0;cFnUCQDcR*rx_NDTs*5DpZM zGe<^5Ub2iW8uKiGyg@2SR;LIuMQWN&Wl42f^+tu@AE%JXG{azqJC#>?)hv`}%QYHH z4X9X>YBx!>Lo9t*7IFfgQdC%+wYH#q)~z=hb4nZ)N;neur}Z1133!2n5U_nLwR${m zq%Q6^C`qkTaEUHi`rpLQOKpKDhv8a)@b8WQjPXu z&SX`8n~G;keVQRQb&kSh*4nPTU~7~)45=wuX*H^3r%U4ta_Xg(81%fPzQ2K@KG{K`GTr4cxpkPHEGoLdb#tN`ircJf&18>yrjXu(}#g z_L_0Lb5p=KMrGlC|MIlsQzaIdE>q^o4FIx+(a;EIqKE1mq|&O;g$n?1EnJe?09cJC zM=eW-TIHMn^$Kj_$F0tB574plF}}d2om!V5OE#FRdCq4_u#ZcrlBt{y??Rp*osnSY zsx{L56lZa+#V};<-2HPuSeW0xU#%o-Vf#mlbc?QZ$v_ATa*~s?3n6=Cq*fC3nwgFB>D zRm4jrJkdW1WJaAq!9t)btCUH-Dpgu0E|bU>wRX@-h0;Gi;BSDi-$#|DOUg@jOyy({ zQ+9(zp;Cxj9JDQqy zM8=oR-+tro-vS;`_TJ7v-ZnL#%^9>{-O#6JrcIgDG|;Uaei)rTfj;`^`Ay4eY8(Z* zC|(-1so$78&YqYFhLzLh{2Z=jvi$K;(2CXwGx z1fa$<{@9b-F6oU`$YrC4(3_ub+43nU0ga%9*dhzBMqys6)!MaMaQ(bGXBu7Jr#VN6 zQq3_j>368}=4Uoj^E~?KJlo{9c7|hM=X~pyPtlvbzV^~JFqOhGPo+KcuLPRkje-prlMC8adH^gTIcVT zgh*4*Gy?noMS57gto{EfJrK`E|Ig9`8JRIvZn_sKpI&s{I#J_D-9 z!w^$vNwtl*qiWeL+(N3FW7BJLW76s5Ld6+$&R|t4v$B-R6g~LX=E*{t*trgSgO{)$ zugl@va&){w#Fl2sJ|EE^U^fx8DxJ}R?{<&G;q?3LejUE+N~qluz&>mUwT8nW6bhm5 zo14-1p%4g#!>ART+U91U4e{YN)D(`iwT1WY4Yxsi7_?BUSe!B0hL|RXT#9(nm+qPp zOc=_9q$52Qn|=pxqKcCJI=|E8!U>_=tT>fa=WSG8otRX7-6X|57KJ+)L=@15c?J+H zU9z1b!B>Z9BJA3UL$P6^z%+tea2F0w^!18waSVv*ux%$B{@6j($3ScmhPI$EB&~?N zz=*gxIAb_Z>GAy`UsS)u*q*uSnKzv?mP3%3OQ*@_a&%{vX!v#D3%4`BBN`Q6iThMi|_nDSoQB5!g|a z=vtc9*;G2X5j$#_M0pzt)qTtm1#Oie;EL^h5ZXG+{r3{rDN{r_5ByD@$bma0fXV|(`PPNyLQ3M>4kGrQ#U+0EiZ4{lN)BT zwPUKwLXFj|o=0Wi??a~ageNK~aq(~$@$|J;oJ_y~Ic;fFxZLm+?SPfsld;}UZTJn-@C=l}LR{$)poWP`WSi|7X&!~3i5 z0_r>OMD;s=y0__W^zJhcpbt;Zy#E_k(h~!V?J-xwb4$J#ZNCcN+2rgNVlz|BzHVHq zutC+)N_IB6kjfCAT-`xQJ%@(_+;?JrEiEy}CK4>_%nj`hJQ-B9w8VVEQMafrRw<#~ zgpbwFlry85g=8Ow?9dUMcU^q%H@@SG*WU353Lg>+!o~Kp#M2haR2V3>*f_qogQOMH zPUZ@spbU6iU6}>xEUcZ5Zm=n1pB*b+PY~b@OOH2SXo_AP+h?7nRN5ME&Fbs zG;ryRIh?*;&&`>!bYKT_Emtl?G$TYpY#2w`{!=$J5wE}>rM9v`gUYByTR@`koLalQ z+To~PUaQ#k_7l$t4u|l}6L0TQT+=mie>0yMid(G~3TAzb-Jx4OmR28hLtVlFKJ^9_ ztlxqAw8ciG?$oTwft$9+i-YjtOD!#z#4@2tZi+wiqD zF80KSQ3qN)Zys8VIuekXcyKH35w`+90img1+J;Ae*s|q^M>nJijx2}J^D%K>HJ^@0 z|FazC0*BG!AmY=|rVMJ)|%0$sG;P#yxiQp>q;7m`eayHuJc;1)4JaZ>D6Ik;#(*4dp?&I3rLb+%n^5Um2=TDrjh4F$!eW z&T5;!8%)_`8qj^t(}e4|h#_EHq*$Dy97r;V0WbnuGPqd$Q3(-ef*CK109hgltT-j} zfT+ZuctjCkk4~(%S5K@y><;iKHX-Tv5)W$6aX^xboBlh&(m7!hgc zw=ffheFx_aE8acbVo2x1)!s-m)DqFq$oE~$TfRDfZU$m}c^Tk5go%kSzn3U zEJ26JE*?jj=A*1i0xx07{8NN5B8M@w$p}2f=Os=RfOW+nsd-ZrcO*!TCRyq$%J~aX z-4f-%N5vw^Mi0*wojz7+si@^q$Gn3F=Pk(_GU4DnZ$4a(JMh5;W6*;WZ#icmibj=Ws=!nm+yk=2wjmv%h%q;3mR*|$lL&4g1)&U zlazZ|$pEh#y&m3OPR1}=F(41#;jdfoC_?Xf zD+YQmTo{-q9pTRztlJ%LdvraRNwM*8O9F8Pd*#3tpRABd@Q8MxE5S{RPPquaECDt& zIiko(J_qHfh^`7qwTJb!>EL`Ao{&|_hvdcSXh8L3+?R{ADo~!3Mi|Pi zZV6Lb)cMc5&Y?SrMwZjJG&k5+-5=gQefVs9L-UnZF#XOAtg6IqwL87Wbhq7Y%~R*~ zDb3PoTGL#UtL;{|a8%_@d6{ltiFkNqZdb)Dr!)&^&){TZ7*S>`&XB8D->d+ne~Q2* ztTVxiUjq&*#3VASa~9SuYRe^LECoaX_O{tS-Gbm#Ib`z=&g+0 zlDbmRk&y$RaFj@ANI79STV3F;kWII4VMB%Pa@nmL?va(lDUl(gYY<;tc5rTTQAVLT zD8F7tl`5og=%$V5BRgYu%-TNZFwsAM5*>x`&?)abgI<_)rIcJz3`;F@JiSR*14N2=I&Q0Y}#A_ zGR~w)H_68?n>_-J0ux8fUNBm|W0EZeInDW)0xqtb5=-LEvOoQwsb@xkGB{wCNbI6Qo0{zq_tX{@k)^83pdqCKGzA}O4En-ecxk_a-Imd&o#P@i<{kWp?%=$J&8a#} ztWrz^Ry^Yfs)q~;7B^t}RQ<5oWwJ_DTjbSV?A#&?byP_&&&sWQ1yiQF&^dK=mcNcm z%^RQ?ZP=|FoZ}xM%^P^(f_Gqr7rj^HSYPL7*H|i#ot``qJve5;K|EiA%k#bS4o(=7 zw}cR5)WO#VGi}F?R2G3oqt#ozU8~L2r=m}YJ<|r7^v2>!Fx#9ISvg>__iJb&v^Nrl zYFB<;``-h(U}SCM1oXPwJD{YDjC`3p(3}3cI3A4f7{@TlbPj2{Hs?;UnKzgP>grJt ze6I{_P~|%wx8EQFhZ^Xiv_Zs%xz3`p%2=MR3ZX)S!#;Fo^4F8I!~G5#iWB@2ba7hl}Qb^8>KHE(W^y1Xm_|`^t92nl6-U# zegE=`6)yuV$OBqx``{WU5p2~shaUZP$opugPOa5}h3IY)4}rr;O21>)#C@4^Hn8Gl z^nI`RP+hNxuq`p)`Iy#FZB(E*7$_h@et3}L<1k0*L|sxPo*@!-Fr>RU{=HyV6-}=* zBsl5N9JL}}qSq=oPGd~5xeWEwnufRrXtfHBR_a%2SZ$uaF@OI{FS1G;RGu%@{YKDz zFTd!yx-cX6Tz!B93g+nbjVcbRSWc!+ux)d~QW!;A(_o1SbuyJzni5=zbf zRw%CM8pRGw*Qi6%k3wB-LMv~lJSB{bvj`p;2+CMb&>{l@{)cUZ&_$YH%ZaAJ$PU`h zqEBH9Y>71CXV8Z1XMv*$g<%`n=p-IA7;#P~fuh04Yo9fNFwv643=xbof8oL4YVe`N%s1N#YV8O1yg1*ig%hq2blTQ#~ zlyPTp5b|Oezfuie!LR-|j_wSO4!<}KT)9T0B>UAL$rwHpr_;csMzvrLU`FB=8t$nT zAa=6KN7>5)RLL*Zl|n-is-GFP`9wB*HK0IjfIxH=+n}kW0>(Ib4GuMBPbWKqgrx&7 z&nbK{^i#GO2USiEcLv>_V9?_Za+`v~g27>(o+T|y@Q>TLq+$5dB`uu;jxAe$?4B== zahr}UUv>;XbbgBd`^*g&*R8vF!x{Dggx*1C(TaoSwl{pe^$5Crc#*6k4=g+Y?)Y;XxCy3+pASOv^}uBE%_U0!O+zdF z@G*d|FOQ)tupVgEU24Cyj#DgNG~w{Y70cefeR4z~&bS)zXF1Nd!FSs;cc9CMnx~gu zZ(ie?zT^;)-to+B*nP&5X540GburvwN*4`;Uzmb6;+x6X&71>lfM^UCEK%lnyaJ6f zmj?;gk(U+ukZc^LrG&A_2H1XR2l^Sv!D=8!2cO!!`KiqyPsORS@;%GW)dGdhrc57` z-v1o>DSZsKrUS*`HX)6dU63yy4_ zG;#ChiIXDtrQ~O3JCbWngJ~=(o2}*?`q73hV@Q0a+GIy|W`2s%rq)|IwbN?$B_~_; zYFh%1n7{;>3d*e-JGu7)iJ*oV?gDBfoJSVIC1k{O509w$5#IwP1(3{Lq1J7eXwCMk zwvg|dv}MwyEx;$w?3*rkuiLaTB_+LYrrey>f8;H`n~Th5nYrA2X6aCTmzm9HN_LOx zpEc+O^y3RJ03}?T2zkmP64Ru}&&DJ^S(=oUsn;j-NyhxXd46@t&4tkjmeq?VYW;Hi_Af!`5h#QvcD&~x zK#N5K9O!ira11E&WuSGAD3AK>mgA_>1w10Xqq-S#KeF@ccZfCPv`jMeir0pQ?br5gi|6ny@?%z(Jl7C0Z-E zAwT^Cv*Fz|_b~|i^*1>d*cVkM)l31QOZyBJOC6U~UkKo7^`O31@FoB|D&45)@NQ`_Ozq?B+qq{(IXIHz0iXK^z+zAUz21TUsCoB5um}p75&()| zMKK!ah#(z%#a*NZn5yJ)yE{U433%FaCW%>!XSI71C>~jTsyP8va4w@j;IVP}<6P2J zK{`EhC4e{-H5=2bAgL-1ndb)yHX(i}pc?SVOt*lp3#ckL!iz|iV^rdfDROxvj@Ug$ z1NL!8velhYjH8__Td{5D6c!y5R&Uug8QwI9O-<%heTRI!S&JtG5}+MC)6Ovl zGgJeP-HyIM0~Ykr54?T0La|hp^X>A$W+A!GH(IJuB=eT>rJ9|3ldmD$H@VhTUM9oK zCv-~BfXIo)z#eoC&ifBx7RDVkev1em07aP-~pp|86bkbikI7zGA^+)3!KYF0O5 zDa`*vKPjI00e*y2uoTLl@1HxgG)0j4Jdo>?2?f1M%1#-fD9=r=o#mhK#zSuR$U!H; z_{BrfeDv~$F6N_C(_{NNQ5^puE&<$gILhKm*gx_36r_S5ZbI+~{A^!bZ@>sCltMu7 zFM%GaEl|&2I{xAj^v$fg>p1SZx>>+@pa|S^c*mTT zH?BPV>MMs=ZC^Ei`)z#cqP-g?weQZ^-9Bl<-bD*m1L^+nK+WkVNJ|2%Ixn}P2i8}P zDh1O%{|lH_HnQplbSk<&(c*ghp2=nWOeHgr>br4>t5!U1A*sfRB>WaZy-ULC8N50n zKxPC6$IMcaP3jHMeLuqC3LJD%i-}^##t-*Tf3O(bSNa7yf8yEuKfm|eeBH!Xf$^z- zR)VKNvQ5KuJsO%by0C8Mz|OK50N<5YrjA*5+uA3+)4*l;9{=7gd;SE+mKN@P zdD5u6e%v~8IS`h$^t&I-`FS|{77sX6zzS<{TJ`diPk={8P8(Qo|KjZ(>&8qPIrx)p zZ^0oqzwknAuPrQydPWE?z%@@cO;?>6`V$YQ8H4HyJ++jGCz=sEpobBi^e_T6MeO9z zQWC134D2io*h$Vb*|$1H9+=pfLpaL!BBslX$Hl+lbXmyhvB5{q(?lj{{2%>#c3j*s z!19Ez&qI&fMD^6TSGn9by*#iq)2n8a^ac+4Y-Ll>_k}ez+*hCk8-^$O}yv z$O#j7R4j@voqcm~XU)@Zu(54xW82x-_{O&FY_zenv2EM7ZQHh!o9AWK@2&gZs@tcg zyU(2YboI=czh6grMbTqUp8cvjvb4n#`rGTqE z?!;Ky-}>6%B3rNtsVNiNUV&X+*FWCq+B=%$2$k~&%6O9;CNq2d561~mHR=maW~>|9 zTsu5$lK7z{58&%4H}VZJR;@CU1QxljdK)Y^tubS+WRfURRT89=*_qpY&IVC=$-PQt zp0*s{BB4iSZ{>??TimbC8A}w+sq}^r)YvUGvg=twl*VhoF|6__6O&Z$G>R2qZc8n! zQ!}e7XIB)1%C%Trh5PzL;UXQ+XHhfQoIT($peA1vTR==m@Zr<3bP`W-*_1Y)eZ#XSwz05n&fOZTf@E3K zKt+7hd{guu3*w-lR%qqx?u#=K!dRoZ!@{8nSJhA$6!ilHIOXe*BL~YBl&yH~Pezru zcwIb2gW}_cl|9cus?l)0f!8aiv6wx%I>rIndou8rnM4@k^NLvX`szTWcVQi8(}}1_ znia27iwypPIWASJHKupzVYBw^<(sS>%khjV2B)gCa?yOlI9;FjijC4Fd%#V($1#lRS7t{Tk>e_3a4*5*ei4BIIqC0$ z#kBE|l6F2G&h}A4Gl$p~EL7uOLnac?Vw+6*^OX_}DP zaY3fSQBjn`%oK8C^c^_ZFog`EZ(Xv|5Ku{r?>|zeF>P|6b z3_Y8b6uH3+^W5YX7YcmXr5D{|Ez8oOhC($d*Xti_=*PCGKk2C95um@zi2R_)L8*cs zk#%xiToL{N>{upZy8zSHFuV?PP zj?wFGzRGb2kty$vGEt1jvwU>oxuSXbpVG_cKC{p!te2wbJ|k8?T@Q@=&x&aZPY8e+>G5Q~)N8uELt;jJwP_G>aU$7fkNAJWB4*tc zikv`Z|8g7`U(NukP+^yzRX1>LdVoGiNMf+DJW{#NUbPms|{)ijP6CmkR&m<~-aL%nh%~amUA3X6Fu2 z$A>H{8Mcn!qFu>$d`;3HZ3mxjcqQ(a6Gd)zv`TFKE+;DXd)W-56*F-6D9b%?rYBBJ zfIvBzdtcXqzl>}D%8|cGtT}7z>MzA5+?ieJd(Dj~5ORzzV$qO2T+*^W$B7E*%3lR6 zr(rtr8sOC*mu2|Tcog}_!^dz`B|r3k`B9u*5apq=!r=UwfvHk1>O4urmxY3qO{8 zT>7RJCvN)#*wGZ=4MCU2SC-7+TkkG3*&<~mZa2NXY*u`4*?aDrw!lfmgCG_={8qzD z-DHr5ZUx{I>u6@@;l3026d^ZS7=ituMb1{@pEvBB8=)CY#OJ0{UP#JNnhk zkdN@BD#e(wQ=bkl2UFlJRpM&5=q%u1H`i2TGRgBmTOo!ubp6#!E8jbeg_bkR^$t4X zn<^ZEvEw67zrIrmnmKHKkKab+fNf+i7K#Tic7>waYP-C=K;`}yL4k`DID*;Vx$du- zZAFM=$LYX>41+J;L%aHIHg1RS=UI4K(Lp2*k4BfB*(}r*US1JR(|(G-a_0(jL1}|= z&Vrs1#M&oZYM3Zc4j2Gb;)7+*TAf|O7{@htYEbKC<4W|Z-VXz+TkhrloeM%|Sj0cZsJboQ`DEno zh@xnTvgrB3+i5xz7T-Yyfo`?6pk(u>>Vn@QC^9~X-Qb66XuNV^cLMOA;A71(@o+`n zzoeO#&JkLvS}KX{PWgEyC&?Y%sO63&NgE6tG$Lv9l7taBdEmZ#`#j6IDz$Kwl;&ZR zThTpdgesJOW>ZXhLTpsVvaMhzo?sE5 ztTRbo(u4f5y&h)2w-_lBJqhei@QB6h;QqE@xD<(_s=yaDp!B;%CT3%HHnyUA1TAcR zjXXNdGtGTt+5P}+Z#&Pcko0$W^!MQfJn%`3pWl9o7q%*3lP;JkArWt9bf_kx0@JV7 zs41aJz^8x!D>xOEEl?{nE+K&=X>1OyWq?Wj#`w0T=FIFj{xlfb)UE?1DK`Qd4W}Qm z7CbyoI8ME6ZvPw~h&U<$vlFm(?F$;6HgnGY$2jlJ5PydXHtq`+~1G)=)jNqYmbr+12@CSmG+NO>fjxWv#-~|Ka4(}2P>6F=meJans0B@kK2ft z#b7e@A3&lqXHD+6(+|I-DzJf`chYRa84|5G7+`HoW=?*XM+k?I@+sVoB#$g4 z-RuWJ+9NWeL1kvW!?dmFD+N?1`@>T8`k4w?TQ9`zwPzsA)KO3<{Td=|wX;73!r#LZ z)2cCJOo9*P;Mx{oL~$BuKwjkx4=+|xbQHy*PyidV9Cab}=Zezx3(BpeFj#Ardxwmw z@>5(ZV1l~!Wzd*~ztj!j!-??b@xT#+KmdVk2U`4-e_*!gTK4I1czHNFde}Dg9@tT7 zrLfJ?%z0ZZ^hx&GnI^5{oit~0SX6hcD<>)nykd&ux`7h8zuh^}r1ku#^8+t3Bry-~ zsE#(Q0cU^;lFL^NVwMpu0KWSw95-_~%G&3h@{(?^bC_L^SkYw@!KB)&r*MsnUwtwv znv`AUq#Xk`7>A4hkC&k_MpWiQ>;uVy3cji(O4FUNVxU8d9t!_ni`Do&MRIF%qd^>K z8&(Fqw6jNG4?vtnUu`XafPc7uT)erZfKw>FjlN<-d$$p^LM6O&$pYmgyHRHCBiu|d zgrPh~C8UqF&%_gj-Y$jtQ3m*Ktwwk;O8l*hXxX?Yl!vcL58Wis1=6m@L4iJ^F0G z-?YmsIcFSD>bOi2y2BddNNsPsYDGl4NrHc(6xC#7jhAb~fm0n~u{C0;5uIiuVQjG{ zYm^om^%@(<>MclZL_wKwQsOYS>RP$=c+~9&?x-`Y$esj%FvahDp0;FneZTm;n!+mv zLhJhCPS#WRF7_%V;~vpdK81jrrIw<4Py()-h_z-^Q+@@5xu+^?5JJd2<{pUG{Tn|z zI%ee$uKV@4+F_{}tS;n!*b0h)K!fjc*W$D8bL@Dhl$E#j#rm?sig0CL?3A#`2{c)w zVpLkrzLcG>$_#jgKI8pPzine#AX_Ef;}|kd_nokDwo}AyRa}f~7E}aRH221rf|%ZD zFQR(C5VSNr{_gLdi;tC5q=5&gqi<54q7ERfB(h;S|6S~iV6A$m=0TU9dw2Qmp|_|q z3*C;&xa5W8i1n~QoVEmpM|}+b^bRzRVxiC?af^qW`*&}n>QW`&cV)-5M4aI{!O$L! z*b^C6i@_Ex);Y)h%hU(MGuvc8r!K(03aAPO@CV)IS>z~E9 z##}J39`jgWlx&bDtQvQB>jN)XR74!!Cy{Z%7b`ps<@xrTT3JnO>@svqZJ>sr8lXUE zeOeNi0{UC^`?Uf;IT+;6q~beJj2El8Xzd<6WC87Pnh&RRt+PL#;XU{Qf1fSe_|;Rm z+JcB&WS1q8UtG4N4eO%hBj4LYxee+7*Xy+FL1@%bD~M_AZVKIFq2I?FLWl{fylr+| z9P@fYY{jtDyHJE}K5s%@xtZDiey`Byjm^}%V$>x|g{`6*!KWJg70T$ls7qZ|HX3}P z%-5yH)g$~ezC{%&vhnglfGTL~{S!lJl7S8s&7jck6i9BF@~Cn68J|6T!iZUX-dAi) zydL7*WMoKoQBS-LS(X`7t;lFLnL2NH+6)L3~QS7 zAwYf*{vhuL>seOG3{DtOTraO7px_Y zDS6t>1HL2`w6kE-EGxq$*-egS%s zT@}MhM;0&n?exA(?0_>M28ydKks)&yC8ROlf0^Bk)bVHWws4@<`F5T2cVBWF{VrP#@2L@q*Vf z3t*Df0E_X4e4Xow?!(*{f$4FsHUJs*#gi4u{t+pX75T*3KzhOL4BONMQt?HDnf`sf zFnp9tBNN{ge%@uoECP$NMHzO5De==I>(9B%%!g3znn(yU#=}m^E9b+5Bk{xh_9;I~ z%nMs7*D9>bI*4+5Mrur9@l+bA7O#~5Qr@LvF4qHJqp5aU zI3<=3Zv#}2K#kv~A_E_cb!BDY=VozYCBsRyofP`hLq@B0qv3Jr7pN$JyPD zGaPPZZZXSM&Pc;BP{(W|rjX2(Au?4XZ^9&xW;3MTp;!I{C7hx8im}^b=li>%n$1N7 zor`);A~g)L%iIx|_-*QBGp6r0_B7)Sbhr2vgLuR{%g2uIYa2I+?3@Hrrb3u>J8xY8 z*&FIq^r#aylsoEsC(SX6Lf#%-zcx16F@4X-uYz{%J!p}=n>eXs7uA~`x0MPRnlv>m zVS3uFGP>NI!8z*mzX&xnzepqMRo#b1iFV##ab$l6Uvh;WanD2)BwRgC^%*mf>4?^} zJNZQK6NYcbL>#CJ!nRV`(_uC)rNd=zi{cN#Yy}d#6 ziSqJ?5qtA;)iE^QsFQiJpoj8eKEw!n;six zq2*|&TI3&5i<}s@TyU+|im&M;a0K1KKfnuV*}JOUf35gTkas0JC%3AF9TK~XoR|$@ zOBAF#m!+3Dho-1^4w4|Uu2#iSxt|ofZ)2@T*db`iJ-|Afs{roQQv>=j3uB`C9rZ(4&{sjLq7ULlcH~n|{G@u-@5P5YF*b>(dG)Mt2y3|L_mo0@ z2RmF^6E$!rPb|20L+En*-M^J4vgK9E{pt4kdodI%Sjmw2LgRv1a!7mDvW@*wa?3Zs zcE!+KVp#LA;TA1&?N8Rxo?D&4W!JUoXY{AFG-zE?3uLJvvl}E+H9^|QciAMzqZXG= z0w4M{b)!~aYnJQX-2){M)bw= z#JR-8ijqh(R3c%;;xQU$U`Qpz-=rZdToBTnORN)S_H~t(5_s@+arZvRd&Hgeq}BPv zyT$qENS&+vXPP`)(fMAK7dPG6eA^st(F?cX(MU!XZ^zw9$}Qc2<7jl2g8QJ1sTIeb zT~ehsv9?PV=gxSf_M1z_@3NK)Enm?WC-c;b)8x(fm0O{KvB+7A|76DR%R$GdN63fdmAr@ck)sNptE0@i-3(s3xFQ@gZYKi&ramie1#Ij;y%xO@JT-yu{&D{EI{OcJW;l3lw4s`+Z}89gY%*$xZxj`ZZ??;f&AfvHGA79-e^x z{Rjz$4ogi{XGzQTdiGU{J?fmrVRqP5^b*_M2~ebvkVl+{9;v}@F?8IS7dewgm*%jt zITozdc^5WIZ4%ML7&my{QTvt9q}Aeh-d~eeb*sgCSh}KmLBM`+YPb|oxgx*S=I!wj z_DZq@-{~^h&_;fr{5PfAt#=TrVktqF{iSuNikoGIpOMYJ?_r}V>-R_L8NzpxG7Ya^ z7;nsPL3wdQGCCMKECqM*riJg>(h6*%qr{*jcf><^nuffFH_ONid4=-@H##?i&ppB- z1}eMa4r)wkT5<1^ca}ko(rY}<%kw8nPb>fyVeH1D_7aH__Y!S$-B$9A>Cb_S7{Vm?YoB;>;!2uj)Tcq)FxJM6VEBUCN}NP{S}rrylj@| z<$-lBn{2O*WK9^s+`RF~rst{Qj$Qz?hgjrwyN`ZAc;hmE6_CAA&(^b3a z&3V9Cy82ynJ}^UXv&LZFcM1ogW8q!mZ1{e_NPo2nXfdBC{HTKUCVLniRHfF@Zgk(W zyHmD&-7XMP*&87(^$_6 z1iRz$@g+X`C@Pu16r*eiJNt%J9gE&h*R69`rBYj;;7Lmqfz_-n6u_j|(x zs<>V6&xu*1KG=_Qxw@~{NgC~VQ}tg?vmdRNJ~Ma@#5ykVF4Ib2Jh*-tT?IxsKgnfX ztm7rg#u@_WbyH7P@k^5G2OIA4GiT|R9+4lDEsvzevd0^|6fxA!R>2famv>i16m^%+ zRtshcTkY_E*8!qPwBA@tkSSUp(MN(Ewcead5HUC&`2*+Ck|g`cv_~arV~NZag(PQ3 zsq>LyiCHD7)RSTpVhrYWh+YaL-?lKW0PDg!08}fNg5_vd$`K<4#i?(0am_NRL!xJKKmW?cP z;}dF2ndfg@mKK|mRm43h5=G{`iY{HPqvvvd$G1s>DrVymz_El$QcqjsMk~7-^p_Qw z@1sO&B*)B$@?X8uf9+g6j)+JAN#5nR<#Wz%%zB>aAa-}5t--u(`-A)pApRMI{4)@K zR?A~*9n^RliL1wa8cR0VfdjO)J7pTJRnV0K=6ow1@<<4Q1Hq&BWg3RgcXJxzwYMsp zKnwC+)ha&ABqoe%4@WchU>~bI!cy;#W_a@62L>n`-x0(h%4~rjxrm@>yMKL2%^1+I3Bk;V zePyd^%u!J~<0ZR+P-un)NmvA#>${zrk!<|Z^ugc3ZT@WaN;jjK^jI_C*aUNL%O-=m z_GmTZ9QN=s5L^a=U305Jb_I)EL#V+%^&mGBB=&+{6TTzi`vvP`y+bATkyL|x!cy-j zsDVZI>|OsT52DbAdk0(WRjP*ngqG{u+Qxe3=7E{&xw{4_55~|3ZU2F@W4!$1%U5+< zc^S5<2i*;?u@|QrZZqKG8vWe2NuQz}v~6444dD~2ZO3aFl%QMZ8S$}4?3&RN0^)3@)M%o9wv59t{^s<-JH&lBN0+r|#&JLJ#~#WU9DuPbE%;XnA} zzvvJ15MZhi!>ci+s!_T1uw43O-LPE-=W1}L{(9(P@SwCAu%Abn?yR`Mt8BL{gHH8j zy74{s!c?LD7#>a#BD(ZcuZ?h&>_LhKE2{0QDOlg zMlSD@vL}t|opHm`iBjFhY)2m2Rpx-N8oY6XTik2l0Iuo_b>o%o#j#@wvWKR^jB(LJ zH7qv3MM)NhD>48rWQfF?XAGa47C@mL*C%1qXKvhfYDco|O|u981h?(k+LdlcGu^S~ zNV{z3zLrh*ciquy$2r>J;w{?y6&dnD-wR86jQaOZS584@k zb7Q<7@YSt)t-KylwS(@7*R+e%47b&P@r-`i-DFSE>ECv(?TPRe+IHi$?oY6-^N#qm zBlgVb?e})0>juO>;Qx$;-#b-<*45qjOy(V^yNC1+9=+T2jOQKAzuk3%`57{FL-CIF zMe>sc5>?1eIP*Hpa|Z=1R~|LgK!I3N1VVwFD@=BmWkx-nZgc=EH=IMs32j5z)jp9! zGo6I0za=-ABf9e`o!%o9M%Z>n>>jNP`J+EDw+oYyN+jVr+!qpBJwUjj7^%S^`?&#= zln&W{V89>*lPV~5#~`3tcs^8WK%7xB0zD~oYyiz5qFFHlO*Pbh*Md<;i{x~m!N9Ls zRvL9FTw)iTQ9WP)H76t_BrI88M2l2d(afOK43RPh9V;iiJeeF;A6jZZKk%g`LPedk zKGxC4*jQ8N;Lw{Lq1kH| zZJ}WcxGOsI;3_xvbg4X|$r;+yQIax>j}JKwD!r`?6tBKJhdDI+U??s7|Yd_b_bw4Cq~j%Rv4 zS{@O-r5V;3j`D12j@z!sVD2Meyi8qEG8|pqq7F^ARD;+YZPg_Xy)HIzK5;le$zq+# zWxP1G29P&QiMig*uXFa)ohHQAt#gRfhwu z$#m0p^ox#+(U5_meoY+?Is2c5UtC&){U&YtTO_NTr@}ZfXLdX}DYXjyhz?y_l8$Af zk6PFeVTsO3Tzlc!(K9JkcmQyK+Gz%48}GJ)GUo-AnvCb$Bs4RKp@IEyD(?-6HD^Za zn@&4-M&&H*fX*^JsWhTG?SE|rbs-HFtd-% zDD6Lqz$}%sCdxs=0kaZTYAr#JQ)SX1*LR&F@i77D0whXOk`3J8$WZ3yUKDsU$fG*U z$zl{Ldf9vqYAN1_&q!J{WlAj)rWfnf@tGtc8aZUC0C1+Y#7*5&$J=!63am7dCg;bA zajiKr6faaIAc~$Gsr!QE&+D`nqd69h1YG zT0w^5ND>k7aNHc^uyd#*n0U~Npq%u3p~WQth4>9@iXjaP{a7=n1?#l(M$ffT;|y#U zaWS!&ow%@bC&@@&fncRlhZQA39@qgp-dv9~SgyMf9w|l~X?hXBsB@aY0C> z(oyynIVf|?V>!t^KSpaDM*%GikvO$3WR%8TWMuVqrWRkx900SzzXJ)?@CUUBC!b=x zKweIvpP?RnL2}kN)JQODH&(E(v_42&a)RW>LIL`&#q1aGjQCm3o~B1{?S@X`^uv#f zLt)sT7OF8~xTUm#`;H5>uBVRDT=`M@1O`L(ULr?9LT-ci$*qEldHtLejUvHC7bbP| z32YVaW*b~kvDg@?hgqLVxA*grIO6?&G zBgDIT%>q0W^NMQ&JB>Ky%amM_6Gvq%=}~A%i;}10oVpJwoD&9vo-|aMGdKm|lFBDR zGn7KwvdLkp zg9}lNycqhF#>;z+pRy(P_pXv?Cs*-IS7q0voyB<5OF=(*R#^E9Q{kMf-IOE~nKgf^ z*lR>zcb?Cwou95PYJOjc+qC@RF6?8zV2jI{;PARTew1rKZO!q;Ra)fxv8rFJjk)iT zvzmUObX+ab6Y788nEniY@Syx+g{?de!$M@lYL|7|B>ejZR>f01jiG8a=-%uo`_ z5OP;XS9Citha0Kj>tKshcQG@25|7O;&``Atw9shZjtR9HniId$Sezes!B8ARakfrMq`)nPMO~KT$KR4lsNbB8qlb8FbrI^+K9MSM zI#v&g(x+ZDZ^}Y)QEQ48=8!+2cdGP!6U{c18%nih6Cg8nNgJW!5wq%7KI-Ndpi&5%&T6SQnu*pa;&0PbyB_erXP@ zQJI%D8rlshNxE1;Lx2d%?(d?v$~YpqlGyajNwZ+EH1YDv-s_tl4vEv;7Z?7OrSE9m z7O|zFqJSm4h@4An>_L=_5E4^%RyG%|Bj$AJkOCFyjaS$=a#0SBmqp2FFOXbKa9nw; zC@-sZF+K`mpJ7(DWx6{_#%@I)%kz)1EHt)2>eL($N~F=Y@R(#MItXF(fd30{vQ6)G zkbJP~#b_=t4ooq$_?6@N>5#`-N*pVtXZTAeu2jV7b@y-1SIMu2uKCU1&DM8X7(5&5 zifb8Z4wtw#&W1gJi;QudW3UxaLBm$Cw zxI4tRtsUvom!x!k{jz7;m-_&6W#X63q(6jv1mP6+zPdk;<+P2S*>s>zFUlBC&3NA^ zY%CTjv$)CMal#ZqCVJNX5JVE82uMcaeY%E88$T8|QbE5djF&O2~@R8`@ga>)RMP*qR&B8#tR=8PS_M=o?uX)9dRy z&{`Wi=^N=g>C@Rc*xDI8IGGzeN=ef=jM0zE&_I1B5||vHs$-pJ-j73l0{uL4?AV{A2{c+~Iq5L!IKPdkX z*|#S6?=zIqw=p*{c66e1v$pzI1OB6gh;I2nKw&jNKrsJ_{+9WFuD`jVmA<2+u_K*@ zzQex){~7zA&O-e2@^6F)bRig100i_8%*m1de*+=>CkE&rQ1gF-%nfb7{dNBzU;<~( z@*+`Spl2!&AiDno|KsY>{{;WX&!znjW3(o=HctAk#*Vhu#&k|jCjaW#ziyQOG@t)x d^&I&Bf7{4Qfr0;H3gY|O1qK2Ny7*>5{|C9)D0lz> literal 0 HcmV?d00001 diff --git a/libs/ustwo-clockwise-debug.aar b/libraries/libs/libs/ustwo-clockwise-debug.aar similarity index 100% rename from libs/ustwo-clockwise-debug.aar rename to libraries/libs/libs/ustwo-clockwise-debug.aar diff --git a/libs/wearpreferenceactivity-0.5.0.aar b/libraries/libs/libs/wearpreferenceactivity-0.5.0.aar similarity index 100% rename from libs/wearpreferenceactivity-0.5.0.aar rename to libraries/libs/libs/wearpreferenceactivity-0.5.0.aar diff --git a/libraries/libs/ustwo-clockwise-debug.aar b/libraries/libs/ustwo-clockwise-debug.aar new file mode 100644 index 0000000000000000000000000000000000000000..8257a991be6e1ff5490cafa8f66372d72b49e003 GIT binary patch literal 90266 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 z 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 U0-rk*OpE&|;B3@zHvoYD10>zvIRF3v literal 0 HcmV?d00001 diff --git a/libraries/libs/wearpreferenceactivity-0.5.0.aar b/libraries/libs/wearpreferenceactivity-0.5.0.aar new file mode 100644 index 0000000000000000000000000000000000000000..66b3cad816ca298c74a9f5c4d8c11fb1bfde068b GIT binary patch literal 30815 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 + + + \ No newline at end of file diff --git a/libraries/src/test/java/info/nightscout/libraries/ExampleUnitTest.kt b/libraries/src/test/java/info/nightscout/libraries/ExampleUnitTest.kt new file mode 100644 index 0000000000..1f93248f94 --- /dev/null +++ b/libraries/src/test/java/info/nightscout/libraries/ExampleUnitTest.kt @@ -0,0 +1,18 @@ +package info.nightscout.libraries + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/medtronic/build.gradle b/medtronic/build.gradle index 1f2fc0dcaf..525dd93b52 100644 --- a/medtronic/build.gradle +++ b/medtronic/build.gradle @@ -13,8 +13,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':pump-common') implementation project(':rileylink') diff --git a/omnipod-common/build.gradle b/omnipod-common/build.gradle index 84bd275697..83adbcfabc 100644 --- a/omnipod-common/build.gradle +++ b/omnipod-common/build.gradle @@ -14,8 +14,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':shared') } \ No newline at end of file diff --git a/omnipod-dash/build.gradle b/omnipod-dash/build.gradle index d255a3b8e5..04d92e3880 100644 --- a/omnipod-dash/build.gradle +++ b/omnipod-dash/build.gradle @@ -30,8 +30,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':pump-common') implementation project(':omnipod-common') diff --git a/omnipod-eros/build.gradle b/omnipod-eros/build.gradle index a4975db071..5e5fa44f0f 100644 --- a/omnipod-eros/build.gradle +++ b/omnipod-eros/build.gradle @@ -23,8 +23,7 @@ android { } dependencies { - implementation(files("${rootProject.rootDir}/libs/iconify.aar")) - + implementation project(':libraries') implementation project(':core') implementation project(':pump-common') implementation project(':omnipod-common') diff --git a/settings.gradle b/settings.gradle index 8411805772..4c3046732a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,4 +16,5 @@ include ':omnipod-eros' include ':omnipod-dash' include ':diaconn' include ':openhumans' -include ':shared' \ No newline at end of file +include ':shared' +include ':libraries' diff --git a/wear/build.gradle b/wear/build.gradle index e02bd28f66..60f43a20c3 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -107,8 +107,8 @@ dependencies { compileOnly "com.google.android.wearable:wearable:$wearable_version" implementation "com.google.android.support:wearable:$wearable_version" implementation "com.google.android.gms:play-services-wearable:$play_services_wearable_version" - implementation(files("${rootProject.rootDir}/libs/ustwo-clockwise-debug.aar")) - implementation(files("${rootProject.rootDir}/libs/wearpreferenceactivity-0.5.0.aar")) + implementation(files("${rootProject.rootDir}/libraries/libs/ustwo-clockwise-debug.aar")) + implementation(files("${rootProject.rootDir}/libraries/libs/wearpreferenceactivity-0.5.0.aar")) implementation('com.github.lecho:hellocharts-library:1.5.8@aar') implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" From e216a9330d7e301900bc376fc7e6bbdffc2e8f0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 08:09:18 +0000 Subject: [PATCH 46/77] chore(deps): bump android.joda from 2.12.0 to 2.12.1 Bumps [android.joda](https://github.com/dlew/joda-time-android) from 2.12.0 to 2.12.1. - [Release notes](https://github.com/dlew/joda-time-android/releases) - [Changelog](https://github.com/dlew/joda-time-android/blob/main/CHANGELOG.md) - [Commits](https://github.com/dlew/joda-time-android/compare/v2.12.0...v2.12.1) --- updated-dependencies: - dependency-name: net.danlew:android.joda dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 063e8f8e0c..10f3341d0f 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ buildscript { work_version = '2.7.1' tink_version = '1.5.0' json_version = '20220320' - joda_version = '2.12.0' + joda_version = '2.12.1' junit_version = '4.13.2' mockito_version = '4.4.0' From d6ec3d8be0020a416683293893842ba96d64a602 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 31 Oct 2022 10:13:31 +0100 Subject: [PATCH 47/77] New Crowdin updates (#2136) * New translations exam.xml (Russian) * New translations exam.xml (Russian) * New translations strings.xml (Russian) * New translations exam.xml (Russian) * New translations objectives.xml (Russian) * New translations strings.xml (Russian) * New translations strings.xml (Russian) * New translations strings.xml (Russian) * New translations exam.xml (Russian) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Slovak) * New translations strings.xml (Czech) * New translations strings.xml (Spanish) * New translations strings.xml (Italian) * New translations exam.xml (Italian) * New translations objectives.xml (Italian) * New translations strings.xml (Italian) * New translations strings.xml (Italian) * New translations strings.xml (Italian) * New translations exam.xml (Italian) --- app/src/main/res/values-es-rES/strings.xml | 2 +- app/src/main/res/values-it-rIT/exam.xml | 33 ++++++++++++++ app/src/main/res/values-it-rIT/objectives.xml | 2 + app/src/main/res/values-it-rIT/strings.xml | 22 ++++++++- app/src/main/res/values-ru-rRU/exam.xml | 45 ++++++++++++++++--- app/src/main/res/values-ru-rRU/objectives.xml | 16 ++++--- app/src/main/res/values-ru-rRU/strings.xml | 18 ++++++++ app/src/main/res/values-sk-rSK/strings.xml | 3 ++ core/src/main/res/values-cs-rCZ/strings.xml | 1 + core/src/main/res/values-it-rIT/strings.xml | 6 +++ core/src/main/res/values-ru-rRU/strings.xml | 12 +++-- core/src/main/res/values-sk-rSK/strings.xml | 1 + .../src/main/res/values-it-rIT/strings.xml | 1 + .../src/main/res/values-ru-rRU/strings.xml | 1 + 14 files changed, 144 insertions(+), 19 deletions(-) diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index c1fba36884..97ab4a810d 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1049,6 +1049,6 @@ Error al solicitar permisos Ajustar sensibilidad y glucosa Limpiar base de dados - ¿Desea limpiar la base de datos?\nSe eliminarán los cambios registrados y los datos históricos más de 3 meses de antiguedad. + ¿Desea limpiar la base de datos?\nSe eliminarán los cambios registrados y los datos históricos con más de 3 meses de antiguedad. Entradas eliminadas diff --git a/app/src/main/res/values-it-rIT/exam.xml b/app/src/main/res/values-it-rIT/exam.xml index 20674d5f76..049aef6e52 100644 --- a/app/src/main/res/values-it-rIT/exam.xml +++ b/app/src/main/res/values-it-rIT/exam.xml @@ -5,10 +5,12 @@ Dovresti impostare il valore DIA nel tuo profilo. Il valore minimo consentito è 5 ore. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html?#insulin + Se sei soddisfatto del valore DIA che hai usato nel tuo micro prima di AAPS, non c\'è bisogno di cambiarlo quando inizi l\'attività di loop. Dovresti determinare da te il valore appropriato per DIA. Temp-Target Ipoglicemia Qual è la ragione principale per impostare un target temporaneo \"ipoglicemia\"? Per correggere ipoglicemie causate da impostazioni non corrette della velocità basale. + Per evitare che AAPS corregga eccessivamente un aumento della glicemia causato dai carboidrati a veloce assorbimento usati per trattare una ipoglicemia. Per correggere una ipoglicemia indotta da esercizio fisico. Per evitare che la glicemia si abbassi se è già in esecuzione una velocità basale temporanea dello 0%. https://androidaps.readthedocs.io/en/latest/EN/Usage/temptarget.html @@ -16,10 +18,15 @@ Argomento: profilo offline Il profilo NS può essere usato, ma non configurato. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#profile + Motivi per azionare la funzione \"Disconnetti micro\" in AAPS Cosa dovrebbe essere fatto quando si disconnette il micro? Questo non è necessario poiché l\'insulina non verrà erogata se il micro è fisicamente disconnesso. + Evita che AAPS tenga conto di insulina che non è stata erogata mentre il micro è fisicamente disconnesso. Non interromperà l\'erogazione di insulina se il micro rimane connesso. + Manderà AAPS in modalità loop aperto. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#other-settings + Impostazioni AAPS + Impostazioni AAPS Quali sono le migliori pratiche per il backup delle tue impostazioni? Non hai bisogno di esportare le tue impostazioni a condizione di prenderne nota. Esportare le tue impostazioni dopo aver completato un obiettivo. @@ -33,6 +40,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#what-emergency-equipment-is-recommended-to-take-with-me Letture CGM \"rumorose\" (noisy) Cosa dovrebbe essere fatto se i dati CGM sono \"rumorosi\"? + Nulla - AAPS se ne occuperà. Disabilitare il loop chiuso per evitare un possibile sovra-dosaggio o sotto-dosaggio. Sostituire i sensori costantemente \"rumorosi\" o inaccurati. Verificare che la tua app CGM faccia lo smoothing dei dati della glicemia. @@ -63,6 +71,7 @@ Una volta impostati e validati, questi valori non dovrebbero cambiare nel tempo. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#androidaps-settings Prerequisiti + Cosa è essenziale per configurare e usare AAPS? Informazioni profilo validate (basale, IC, ISF, DIA). Un computer con Android Studio installato e configurato. Un telefono supportato. @@ -77,17 +86,25 @@ Uno smartwatch. Un CGM Supportato. Prerequisiti + Cosa è essenziale per configurare e usare AAPS? Informazioni validate per configurare un profilo (ISF, rapporto I:C, velocità basali, DIA, ecc). Un dispositivo Android compatibile (smartphone, smartwatch con versione integrale di Android o tablet). + AAPS richiede una connessione internet per poter funzionare in loop chiuso. Un CGM supportato e un\'app appropriata per ricevere valori della glicemia sul telefono/dispositivo. https://androidaps.readthedocs.io/en/latest/EN/Module/module.html + Aggiornamento AAPS Seleziona tutte le risposte corrette. Devi avere Git installato e configurato sul tuo computer. + Quando vengono rilasciate versioni aggiornate di AAPS, le precedenti potrebbero essere limitate da remoto dopo un determinato periodo di tempo. Dovresti salvare e annotare la posizione del tuo archivio chiavi e usare per gli aggiornamenti la stessa chiave di firma della tua installazione precedente. Non aggiornare mai se il sistema funziona bene. Se hai difficoltà a costruire l\'apk, puoi installare un apk che è stato costruito da un amico. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch Risoluzione problemi + Dove puoi cercare aiuto con AAPS? + Puoi chiedere consiglio nel gruppo Facebook degli utenti AAPS. + Dovresti leggere (e rileggere) la documentazione di AAPS. + Puoi chiedere consigli e segnalare problemi tecnici nel Discord di AAPS. Dovresti chiedere al tuo endocrinologo/centro diabetologico. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting https://www.facebook.com/groups/aapsitalia/ @@ -101,6 +118,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#insulin Plugin sensibilità Seleziona tutte le risposte corrette. + I plugin di sensibilità consentono ad AAPS di adattarsi a cambiamenti temporanei o di breve durata nella sensibilità all\'insulina (ad esempio cambiamenti ormonali o problemi di assorbimento legati al sito di infusione). I plugin di sensibilità forniscono all\'utente suggerimenti su cambi a velocità basali, rapporti I:C e ISF che possono essere utilizzati per modificare il profilo. La registrazione di un cambio cannula ripristinerà il rapporto Autosens al 100%. Alcune opzioni del plugin hanno intervalli di tempo configurabili che possono essere impostati dall\'utente. @@ -110,11 +128,14 @@ Cosa dovresti fare se hai fatto un inserimento non corretto di carboidrati? Eliminare nei Trattamenti l\'inserimento non corretto e immettere il nuovo valore CHO. Erogare un bolo di insulina usando il menu caricamento set di infusione. + Non fare nulla - AAPS effettuerà gli opportuni aggiustamenti. Erogare un bolo di insulina usando il tasto Insulina nella sezione Panoramica. Errori erogazione/inserimento insulina Cosa dovresti fare se hai ricevuto meno insulina di quanto lo storico del micro suggerisce? Ad esempio a causa di un\'occlusione, una cannula difettosa o l\'aver dimenticato di riattaccare il micro dopo una doccia?  Eliminare dal portale Nightscout i dati relativi all\'insulina per rimuoverli dallo storico del micro. + Compara i valori in AAPS con lo storico micro (se supportato). Erogare un bolo con parte della tua insulina calcolata \"mancante\" usando una siringa/penna o la funzione caricamento. + Non fare nulla e permettere ad AAPS di correggere eventuali glicemie alte. CHO attivi (COB) In che modo la modifica del valore ISF influisce sul calcolo dei COB? L\'aumento di ISF richiederà un tempo maggiore per l\'assorbimento dei CHO @@ -136,20 +157,28 @@ Inserimento CHO e boli Solo i grammi dovrebbero essere utilizzati per stimare e registrare i carboidrati consumati. I carboidrati consumati possono essere registrati utilizzando un sistema di scambio appropriato (ad esempio: gli scambi CHO \"DAFNE\" o le unità di pane europee \"Bread Units\"). + AAPS usa un modello dinamico per stimare il \"decadimento\" dei carboidrati e calcolare COB. Se la glicemia è di fuori dei valori accettabili (troppo bassa o troppo alta) il calcolatore di boli può essere utilizzato per fornire suggerimenti per le correzioni con carboidrati o insulina. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-to-carb-ratio-ic-g-u e-carbs Per cosa potresti usare gli e-carbs (carboidrati estesi)? Per indicare i carboidrati nel futuro e/o distribuiti su un intervallo di tempo (similmente a un bolo esteso che distribuisce insulina sullo stesso intervallo). + Per la registrazione di \"carboidrati da esercizio\" che vuoi nascondere da AAPS. + Gli e-carbs (distribuiti nel futuro) possono aiutare AAPS a gestire pasti ricchi di grassi/proteine. Per registrare i carboidrati che usi per trattare la glicemia bassa. https://androidaps.readthedocs.io/en/latest/EN/Usage/Extended-Carbs.html Monitoraggio remoto + Come puoi monitorare AAPS (ad esempio per il tuo bambino) da remoto? + L\'app AAPSClient, l\'app Nightscout e la versione web di Nightscout ti consentono di seguire AAPS da remoto. Altre app (ad esempio: Dexcom follow o xDrip in modalità follower) consentono di seguire da remoto alcuni parametri come i valori di glicemia/sensore, ma usano algoritmi diversi e potrebbero mostrare valori inaccurati di IOB o COB. + Per seguire AAPS da remoto, entrambi i dispositivi devono avere accesso a internet (ad esempio via Wi-Fi o dati da rete mobile/cellulare). + AAPSClient utilizzato come follower remoto monitorerà AAPS e ne fornirà il pieno controllo. https://androidaps.readthedocs.io/en/latest/EN/Children/Children.html Fattore di sensibilità insulinica (ISF) Aumentare i valori di ISF porterà a una maggiore erogazione di insulina per coprire una specifica quantità di carboidrati. Ridurre i valori ISF porta a una maggiore erogazione di insulina per correggere una glicemia al di sopra del target. Aumentare o ridurre ISF non ha alcun effetto sull\'erogazione di insulina quando le glicemie sono al di sotto del target. + ISF dovrebbe essere inserito nelle tue preferenze di AAPS. Cambiare il valore ISF nel tuo profilo è sufficiente per applicare la modifica. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html @@ -176,6 +205,7 @@ La glicemia target rimarrà invariata. ISF sarà il 20% più alto. Cambio profilo + Se ti svegli 2 ore prima del solito, come dovresti informare AAPS del cambiamento nei tuoi programmi? Avviare un cambio profilo con un timeshift di 2 Avviare un cambio profilo con un timeshift di -2 Impostare un target temporaneo \"pasto a breve\". @@ -183,6 +213,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html?highlight=profile%20switch#timeshift Modifiche ai profili Velocità basali, ISF, rapporti I:C, ecc., dovrebbero essere impostati nei profili. + L\'attivazione delle modifiche al tuo profilo Nightscout richiede che il tuo telefono con AAPS abbia una connessione internet. Modificare i profili per cambiare i valori è sufficiente per attivare ogni cambiamento fatto. Più profili possono essere impostati e selezionati per adattarsi a diverse circostanze (ad esempio: cambiamenti ormonali, turni di lavoro, stile di vita nei giorni lavorativi/weekend). https://androidaps.readthedocs.io/en/latest/EN/Module/module.html#good-individual-dosage-algorithm-for-your-diabetes-therapy @@ -192,4 +223,6 @@ Google Facebook Altri Farmaci. Leggere la seguente dichiarazione e, per proseguire, accettarla selezionando la casella. + AAPS riduce la velocità basale o sospende l\'erogazione di insulina per aumentare la glicemia. Farmaci appartenenti al gruppo degli inibitori SGLT2 (gliflozine) possono ostacolare l\'aumento previsto della glicemia e, quindi, provocare una pericolosa carenza di insulina (DKA). +\nI marchi più comuni sono: Invokana®, Forxiga®, Jardiance®, Steglatro®, Suglat®, Apleway®, Deberza®, Synjardy®, Vokanamet®, Xigduo®.\n\nCon ciò prometto che non prenderò tali farmaci durante l\'uso di AAPS o disattiverò il loop prima di usare questi farmaci. diff --git a/app/src/main/res/values-it-rIT/objectives.xml b/app/src/main/res/values-it-rIT/objectives.xml index 50d88778fe..895140e5fe 100644 --- a/app/src/main/res/values-it-rIT/objectives.xml +++ b/app/src/main/res/values-it-rIT/objectives.xml @@ -26,6 +26,8 @@ Stato micro disponibile in NS Attivazioni manuali Completato: %1$s + Impara a controllare AAPS + Esegui varie azioni in AAPS Imposta il profilo \"90%\" per 10 min (premi a lungo sul nome profilo nella sezione Panoramica) Simula la doccia. Disconnetti il micro per 1h (premi a lungo su Loop aperto) ... e riconnetti allo stesso modo diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 96c3b36c66..1a53c311af 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -40,7 +40,9 @@ Scarica dati glicemia da Nightscout Ricevi valori glicemia da xDrip+. Salva tutti i trattamenti che sono stati fatti + Monitora e controlla AAPS usando il tuo smartwatch WearOS. Mostra le informazioni del loop sulla watchface di xDrip+. + Controlla AAPS in remoto usando i comandi SMS. Insulina: CHO: IOB: @@ -77,7 +79,9 @@ Trattamenti Micro virtuale Micro + Quale micro vorresti usare con AAPS? Profilo + Quale profilo AAPS dovrebbe usare? APS Quale algoritmo APS dovrebbe apportare aggiustamenti terapeutici? Generale @@ -85,6 +89,7 @@ Quali vincoli sono applicati? Vincoli Loop + Usalo per attivare l\'integrazione del loop di AAPS. APS Dopo elaborazione vincoli Basale temporanea impostata dal micro @@ -101,6 +106,7 @@ Basale: Cambia il tuo input! Origine BG + Da dove AAPS dovrebbe ottenere i suoi dati? xDrip+ Modalità APS Loop chiuso @@ -325,6 +331,7 @@ Fornisci il nome del paziente o il nickname per distinguere questa configurazione tra altre Utente Glimp + %1$s necessita della whitelist per l\'ottimizzazione della batteria per avere prestazioni adeguate Loop sospeso Sospeso (%1$d m) Sospendi loop per 1h @@ -422,6 +429,7 @@ Sensibilità WeightedAverage Non tutti i profili caricati! Valori non memorizzati! + Abilita trasmissioni ad altre app (come xDrip+). Non abilitare se hai installato più di un\'istanza di AAPS o AAPSClient! Abilita trasmissioni locali OpenAPS SMB ISF Dinamico @@ -623,6 +631,7 @@ Benvenuto nella configurazione guidata. Ti seguirò durante tutto il processo.\n Lettura stato Salta configurazione guidata + Premi il tasto in basso per permettere ad AAPS di proporre/fare modifiche alla basale Il plugin di sensibilità è usato per il rilevamento della sensibilità all\'insulina e il calcolo di COB. Per ulteriori informazioni visita: https://androidaps.readthedocs.io/en/latest/Configuration/Sensitivity-detection-and-COB.html NSClient gestisce la connessione a Nightscout. Puoi saltare questa parte ora, ma non sarai in grado di superare gli obiettivi fino a quando non ne porterai a termine la configurazione. @@ -664,6 +673,7 @@ Rimuovi elementi Ordina elementi Trovate impostazioni memorizzate + Attenzione: se attivi e connetti un micro, AAPS copierà le impostazioni della basale dal profilo al micro, sovrascrivendo la velocità basale esistente memorizzata sul micro. Assicurati di avere la giusta impostazione della basale in AAPS. Se non sei sicuro o non vuoi sovrascrivere le impostazioni della basale sul micro, premi annulla e ripeti il processo in un altro momento. Dati trattamento incompleti Impostazioni manutenzione Destinatario email @@ -691,6 +701,7 @@ Il loop aperto mostrerà una nuova richiesta di modifica solo se la modifica è maggiore di questo valore in %. Il valore predefinito è 20% == ∑ %1$s U Registra cambio sensore in NS + Crea evento \"Cambio Sensore\" in NS all\'avvio del sensore Tomato (MiaoMiao) Tomato Il tuo nome utente per l\'accesso a Tidepool, generalmente il tuo indirizzo email @@ -708,8 +719,8 @@ Carica basali temporanee Carica cambi profilo, target temporanei Carica test BG - Cambio all\'ora legale in 24h o meno - Cambio all\'ora legale avvenuto meno di 3 ore fa - Loop chiuso disabilitato + Cambio all\'ora legale/solare in 24h o meno + Cambio all\'ora legale/solare avvenuto meno di 3 ore fa - Loop chiuso disabilitato vincolo di archiviazione interna Libera almeno %1$d MB dalla memoria interna! Loop disabilitato! Formato errato @@ -763,6 +774,7 @@ ID: Invia Profilo più comune: + Nota: solo i dati visibili su questa schermata verranno caricati (in modo anonimo). Un ID è assegnato a questa installazione di AAPS. Puoi inviare nuovamente i dati se il tuo profilo principale viene modificato, ma lascialo in esecuzione almeno per una settimana per rendere il risultato visibile nel time in range (TIR). Il tuo aiuto è apprezzato. Inserimento età non valido Inserimento peso non valido Inserimento % non valido @@ -807,9 +819,11 @@ Sei sicuro di voler copiare l\'OTP secret negli appunti?\n\nPotresti averne bisogno solo se la tua app autenticatore ha problemi con la scansione del QRCode, vuoi inserirlo manualmente o vuoi configurare un token OTP hardware usando un\'app dedicata. OTP secret (in formato Base32) esportato e copiato negli appunti. Incollalo nell\'autenticatore o nel configuratore hardware di OTP! 1. Installa l\'autenticatore + 2. Scansione il codice per configurare i codici OTP di AAPS 3. Testa OTP Resetta autenticatori Su ogni telefono follower installa una app autenticatore che supporta i token RFC 6238 TOTP. App gratuite popolari sono:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Resettando l\'autenticatore rendi non validi tutti gli autenticatori già forniti. Dovrai configurarli di nuovo! Predizioni Trattamenti Pendenza deviazione @@ -1006,6 +1020,7 @@ Sopra Mostra record di loop Nascondi record di loop + AAPS widget Configura opacità Stato loop Scala del grafico @@ -1033,4 +1048,7 @@ (Nessuno smartwatch connesso) Errore nel richiedere le autorizzazioni Regola sensibilità e BG + Pulizia database + Vuoi pulire il database?\nIl processo rimuoverà i cambiamenti tracciati e i dati dello storico più vecchi di 3 mesi. + Elementi cancellati diff --git a/app/src/main/res/values-ru-rRU/exam.xml b/app/src/main/res/values-ru-rRU/exam.xml index 13be44dc90..b0398c1cc4 100644 --- a/app/src/main/res/values-ru-rRU/exam.xml +++ b/app/src/main/res/values-ru-rRU/exam.xml @@ -5,10 +5,12 @@ Следует задать значение DIA в вашем профиле. Минимально допустимое значение-5 часов. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html?#insulin + Если вы удовлетворены значением длительности действия инсулина DIA, заданным в помпе до AAPS, то при запуске цикла изменять это значение не требуется. Следует самостоятельно определить DIA подходящее для вас. Временная цель Гипо Какова основная причина для установки временной цели гипо? Для коррекции гипо, вызванных неверными настройками базальной скорости. + Чтобы не допустить чрезмерной коррекции подъема ГК, вызванного быстрыми углеводами, принятыми для устранения гипо. Чтобы исправить гипо вызванное нагрузкой. Чтобы предотвратить снижение уровня глюкозы в крови, если временная базальная скорость уже 0%. https://androidaps.readthedocs.io/en/latest/EN/Usage/temptarget.html @@ -16,10 +18,15 @@ Тема: Автономный профиль Профилем NS можно пользоваться, но не настраивать. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#profile + Причины применения опции «Отсоединить помпу» в AAPS Что следует делать при отсоединении помпы? This is unnecessary as insulin will not be delivered if the pump is physically disconnected. + Это позволяет AAPS не учитывать инсулин, который не был подан во время физического отключения помпы Это не прекратит подачу инсулина если помпа остается подключенной. + Это переведет AAPS в режим открытого цикла. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#other-settings + Настройки AAPS + Настройки AAPS Как эффективнее сохранять свои настройки? Экспорт настроек не нужен, если они у вас где-то записаны. Экспортируйте настройки после прохождения цели. @@ -33,6 +40,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#what-emergency-equipment-is-recommended-to-take-with-me Зашумленные данные мониторинга Что следует делать, если данные мониторинга зашумлены? + Ничего не делать - алгоритм AAPS сам справится с этим. Отключить замкнутый цикл, чтобы избежать возможной передозировки или уменьшения дозы. Заменить постоянно шумящий или неточный сенсор. Убедитесь, что приложение мониторинга сглаживает данные ГК. @@ -63,7 +71,8 @@ После установки и проверки, эти значения не должны меняться со временем. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#androidaps-settings Предварительные требования - Проверенные данные профиля (базал, инс-углеводы IC, фактор чувствительности к инсулину ISF, длительность действия инсулина DIA). + Что необходимо для настройки и использования AAPS? + Проверенные данные профиля (базал, углеводный коэффициент IC, фактор чувствительности к инсулину ISF, длительность действия инсулина DIA). Компьютер с установленной и настроенной Android Studio. Поддерживаемый телефон. Совместимая инсулиновая помпа, если вы планируете использовать замкнутый цикл. @@ -77,17 +86,25 @@ Смарт часы. Поддерживаемый мониторинг. Предварительные требования + Что необходимо для настройки и использования AAPS? Проверенные настройки профиля (чувствительность ISF, I:C, скорость базала, продолжительность действия инсулина и т.д.). Совместимое устройство на Android (мобильный телефон, планшет или часы на полноценном Android). + AAPS требует подключения к интернет чтоб работать в режиме замкнутого цикла. Поддерживаемая система мониторинга и подходящее приложение для получения данных ГК на устройстве. https://androidaps.readthedocs.io/en/latest/EN/Module/module.html + Обновление AAPS Отметьте все правильные ответы. На компьютере должен быть установлен и настроен Git. + При выходе новой версии AAPS, функционал старых версий может быть удаленно ограничен после указанного периода времени. Необходимо сохранить и запомнить расположение хранилища ключей и использовать тот же ключ подписи для обновлений, что и для предыдущей установки. Никогда не обновлять, если система работает хорошо. Если у вас возникли трудности с построением приложения, вы можете установить апк, который был построен другом. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch Устранение неполадок + Где искать помощь по AAPS? + Можно попросить совета в группе AAPS Users на Facebook. + Следует прочитать (и перечитать) документацию AAPS. + Можно консультироваться, a также пересылать логи технических проблем и неполадок в чате Discord по AAPS. Вы должны спросить в диабетической клинике / у вашего врача-эндокринолога. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting https://www.facebook.com/groups/AndroidAPSUsers/ @@ -101,6 +118,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#insulin Модули чувствительности Отметьте все правильные ответы. + Модули чувствительности позволяют AAPS подстраиваться под временные или кратковременные изменения в чувствительности к инсулину (например, гормональные изменения или проблемы с поглощением в месте установки катетера). Модули чувствительности предлагают пользователю изменения скорости базала, коэффициентов I:C и ISF, которые можно внести в профиль. Внесение записи о замене катетера вернет коэффициент Autosens к 100%. У некоторых опций модуля есть настраиваемые диапазоны времени, которые может задать пользователь. @@ -110,11 +128,14 @@ Что нужно делать, если сделан неправильный ввод углеводов? Удалить неверную запись в Журнале терапии и заново ввести правильное значение углеводов. Ввести инсулин через меню для заполнения канюли. + Ничего не делать – AAPS сам внесет необходимые изменения. Ввести инсулин через кнопку Инсулин (болюс) на вкладке Начало. Ошибки подачи/поступления инсулина Что делать, если вы получили меньше инсулина, чем указано в истории помпы, например, из-за окклюзии, проблем с канюлей или из-за того, что вы забыли подключить помпу обратно после душа? Удалить данные об инсулине в Портале терапии Nightscout, чтобы удалить их из истории помпы. + Сравнить значения в истории AAPS и помпы (если помпа это поддерживает). Рассчитать и ввести «пропущенный» вами инсулин шприцем/ручкой или через кнопку заполнения канюли. + Ничего не делать и позволить AAPS исправить возможный высокий уровень ГК. Активные углеводы COB - углеводы в процессе компенсации Как изменение значения ISF влияет на расчет COB? Увеличение фактора чувствительности ISF потребует больше времени на усвоение углеводов @@ -136,31 +157,39 @@ Запись углеводов и болюсов Для оценки и записи потребляемых углеводов следует использовать только граммы. Употребленные углеводы можно записывать с помощью соответствующей системы обмена (например, DAFNE «CHO» или европейские «хлебные единицы»). - Если уровень глюкозы в крови находится вне допустимых значений (слишком низкое или слишком высокое), то калькулятор болюса может быть использован для внесения предложений по коррекции соотношения инсулин/углеводы. + AAPS использует динамическую модель для оценки \"распада\" и расчета COB. + Если уровень глюкозы в крови находится вне допустимых значений (слишком низкое или слишком высокое), то калькулятор болюса может быть использован для внесения предложений по коррекции углеводного коэффициента IC. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-to-carb-ratio-ic-g-u Растянутые углеводы Для чего можно использовать e-carbs (растянутые углеводы)? Запланировать углеводы в будущем, возможно, распределить в течение определенного времени (по аналогии с растянутым болюсом на определенный интервал времени). + Для внесения «свободных» углеводов при физнагрузке, чтобы скрыть их от AAPS. + Растянутые углеводы e-carbs (распределяемые в будущем) могут помочь AAPS в работе с пищей с высоким содержанием жиров/белков. Для указания «лечебных» углеводов, при поднятии низкого уровня ГК. https://androidaps.readthedocs.io/en/latest/EN/Usage/Extended-Carbs.html Удаленный мониторинг + Как можно удаленно следить за работой AAPS (например, вашего ребенка)? + Приложение AAPSClient, приложение Nightscout и сайт Nightscout позволяют удаленно отслеживать AAPS. Прочие приложения (например, Dexcom follow, xDrip в режиме фолловера) позволяют удаленно отслеживать некоторые параметры (например, уровень ГК/значения сенсоров), но используют другие алгоритмы, поэтому могут отображать неточные значения IOB или COB. + Для удаленного отслеживания AAPS оба устройства должны иметь доступ в Интернет (напр.,Wi-Fi или мобильной/сотовой сети). + AAPSClient в режиме удаленного мониторинга предоставляет как отслеживание, так и полное управление AAPS. https://androidaps.readthedocs.io/en/latest/EN/Children/Children.html Фактор Чувствительности к Инсулину (ISF) Увеличения фактора чувствительности к инсулину ISF приведет к увеличению дозы инсулина на покрытие определенного числа углеводов. Уменьшение фактора чувствительности к инсулину ISF приведет к увеличению дозы инсулина для корректировки ГК выше целевого уровня. Увеличение или уменьшение фактора чувствительности к инсулину ISF не влияет на дозировку инсулина когда уровень ГК ниже целевого. + Фактор чувствительности к инсулину ISF задается в параметрах AAPS. Изменение значения ISF в профиле достаточно для применения изменений. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html Вы можете использовать больше одного значения для коэффициента I:C в своем профиле. Если вы изменяете ISF в своем профиле, вам всегда следует изменять соотношение I:C. - Углеводный коэффициент (соотношение I:C) + Углеводный коэффициент IC (ГУ/ед.инс) Более высокий I:C приводит к уменьшению количества инсулина, вводимого на данное число углеводов. Более низкий I:C приводит к уменьшению количества инсулина, вводимого на данное число углеводов. - Если у вас 0 активных углеводов COB, изменение соотношения инсулин-углеводы IC приведет к иному количеству инсулина на коррекцию данной ГК. - Соотношение инсулин-углеводы IC изменится если принимать ХЕ за 10 или 12г. - Смысл соотношения инсулин-углеводы IC таков: сколько хлебных единиц покрываются одной ед. инсулина. + Если у вас 0 активных углеводов COB, изменение углеводного коэффициента IC приведет к иному количеству инсулина на коррекцию данной ГК. + Углеводный коэффициент IC изменится если принимать ХЕ за 10 или 12г. + Смысл углеводного коэффициента IC таков: сколько ГУ (хлебных единиц) покрываются одной ед. инсулина. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#carbohydrate-to-insulin-ratio-cr-g-u Cмена профиля При установке 90% при переключении профиля, какие утверждения верны? @@ -176,6 +205,7 @@ Целевой уровень ГК не изменится. ISF будет на 20% выше. Переключение профиля + Если вы проснулись на 2 часа раньше обычного, как следует уведомить AAPS об изменении режима? Выполнить переключение профиля со сдвигом времени 2 Выполнить переключение профиля со сдвигом времени -2 Установить временную цель \"Eating Soon\" (Ожидаемый прием пищи). @@ -183,6 +213,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html?highlight=profile%20switch#timeshift Изменения в профилях Базальные скорости, ISF, соотношение I:C и т.д. должны быть установлены в профилях. + Для активации изменений в профиле Nightscout требуется, чтобы телефон с AAPS был подключен к Интернету. Сохранения новых значений в профиле достаточно, чтобы все сделанные изменения вступили в силу. Можно настроить несколько профилей и выбирать их в связи с меняющимися обстоятельствами (например, гормональные изменения, посменная работа, образ жизни в будние/выходные дни). https://androidaps.readthedocs.io/en/latest/EN/Module/module.html#good-individual-dosage-algorithm-for-your-diabetes-therapy @@ -192,4 +223,6 @@ Google Facebook Прочие препараты. Прочтите высказывание ниже, а затем отметьте галочку, чтобы принять условия. + AAPS понижает базальную скорость или приостанавливает ввод инсулина для повышения уровня ГК. Препараты из класса ингибиторов SGLT2 (глифлозины) могут предотвращать повышение уровня ГК и, следовательно, вызывать опасную нехватку инсулина, приводящую к диабетическому кетоацидозу DKA. +\nОбщими торговыми наименованиями являются: Invokana®, Forxiga®, Jardiance®, Steglatro®, Suglat®, Apleway®, Deberza®, Synjardy®, Vokanamet®, Xigduo®.\n\nЯ подтверждаю, что не буду принимать такие препараты, при использовании AAPS или отключу цикл перед их применением. diff --git a/app/src/main/res/values-ru-rRU/objectives.xml b/app/src/main/res/values-ru-rRU/objectives.xml index a5c15e0988..223c176927 100644 --- a/app/src/main/res/values-ru-rRU/objectives.xml +++ b/app/src/main/res/values-ru-rRU/objectives.xml @@ -1,17 +1,17 @@ - Старт - Подтвердить - %1$d. Цель + Начать + Проверить + Цель %1$d Цель %1$d не начата Цель %1$d не завершена Настройка визуализации и мониторинга, анализ базала и коэффициентов - Убедитесь, что значения ГК и данные по инсулину помпы передаются в Nightscout + Убедитесь, что величина ГК и данные по инсулину помпы передаются в Nightscout Старт незамкнутого цикла Начинайте работу в режиме незамкнутого цикла и ручной подстройки величины временного базала. Установите и применяйте временные цели и временные цели по умолчанию (напр. углеводы при нагрузке или купировании гипо) - Глубже понимаем незакольцованную систему Open Loop, включая ее рекомендации по временным базалам - На основе полученного опыта определияем макс величину базала и вводим ее в помпу и настройки - Начинаем замыкать цикл с Low Glucose Suspend (прекращением подачи инсулина на низких сахарах) + Глубже понимаем работу системы в режиме незамкнутого цикла, включая ее рекомендации по временным базалам + На основе накопленного опыта, определяем максимальную величину базала и задаем ее в помпе и в настройки AndroidAPS + Начинаем замыкать цикл с прекращением подачи инсулина при низком значении Ск (режим Low Glucose Suspend) Работа в замкнутом цикле с макс активным инсулином IOB = 0 на протяжении нескольких дней избегая событий типа приостановка на низких ГК Low Suspend Настройка замкнутого цикла с поднятием макс величины IOB выше 0 и постепенным понижением целевой ГК Работа несколько дней и по кр мере одну ночь без срабатывания оповещений о низкой ГК @@ -25,6 +25,8 @@ Статус помпы доступен в NS Ввод вручную Выполнено: %1$s + Научитесь контролировать AAPS + Выполняйте различные действия в AAPS Установите профиль 90% на 10 мин (Долгое нажатие на имя профиля на главном экране) Имитация душа. Отключите помпу на 1ч (Долгое нажатие на Открытый цикл Open Loop) ... и обратное подключение таким же способом diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 3d4c783324..18d7673a1b 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -40,7 +40,9 @@ Получать данные гликемии с сайта Nightscout Получать данные гликемии от xDrip+. Сохраняет все выполненные назначения + Мониторить и контролировать AAPS при помощи часов WearOS. Показать информацию о работе алгоритма ИПЖ на экране смарт-часов xDrip+. + Дистанционное управление AAPS при помощи команд SMS. инсулин: углеводы: IOB: активн инс @@ -77,7 +79,9 @@ Терапия Виртуальная помпа помпа + Какой помпой вы хотели бы пользоваться с AAPS? профиль + Какой профиль следует использовать в AAPS? система ИПЖ Какой алгоритм ИПЖ должен выполнять подстройку терапии? Общее @@ -85,6 +89,7 @@ Какие ограничения применяются? ограничения замкнутый цикл + Используйте, чтобы активировать интеграцию AAPS в цикл ИПЖ. Система ИПЖ после наложенных ограничений Временный базал определяется помпой @@ -101,6 +106,7 @@ базал: измените введенные данные источник СК + Откуда должен получать данные AAPS? xDrip + режим APS Замкнутый цикл @@ -325,6 +331,7 @@ Укажите имя или псевдоним пациента, чтобы распознавать разные настройки Пользователь Glimp + %1$s необходимо включить в белый список оптимизации батареи для корректной работы ЗЦ остановлен Остановлен на(%1$d m) приостановить цикл на 1 час @@ -422,6 +429,7 @@ Средневзвешенная чувствительность не все профили загружены! Данные не сохранены! + Включить трансляцию для других приложений (например, xDrip). Не включайте, если установлено несколько экземпляров приложений AAPS или AAPSClient! Активировать локальную передачу Супер микро болюс OpenAPS Динамический ISF @@ -623,6 +631,7 @@ Добро пожаловать в мастер установки Статус \'чтение\' Пропустить Мастер установки + Нажмите на кнопку ниже, чтобы AAPS мог предложить/внести изменения в базал Плагин чувствительности Sensitivity применяется для определения чувствительности к инсулину и вычисления активных углеводов COB. Дополнительная информация: https://androidaps.readthedocs.io/en/latest/Configuration/Sensitivity-detection-and-COB.html NSClient обрабатывает подключения к Nightscout. Вы можете пропустить этот этап сейчас, но не преодолеете все Цели пока не настроите его. @@ -664,6 +673,7 @@ Удалить элементы Сортировать элементы Найдены сохраненные параметры + Внимание: Если вы активируете подключение к невиртуальной помпе, AAPS скопирует настройки базала в профиль помпы, перезаписывая существующие настройки, хранящиеся в ней. Убедитесь, что настройки базала в AAPS корректны. Если вы не уверены или не хотите перезаписать настройки базала на помпу, нажмите отменить и повторите подключение в другое время. Данные терапии неполные Параметры обслуживания Адрес электронной почты @@ -691,6 +701,7 @@ Алгоритм ИПЖ выдаст всплывающее окно с запросом на новые изменения, только если изменение больше, чем это значение в %. Значение по умолчанию — 20% == ∑ %1$s ед Внести замену сенсора в лог NS + Автоматически создать событие \"Замена сенсора\" в NS при запуске сенсора Томато (MiaoMiao) Томато Имя пользователя Tidepool, обычно ваш адрес электронной почты @@ -763,6 +774,7 @@ Идентификатор: Отправить Наиболее часто применяемый профиль: + Примечание: Данные, видимые на этом экране, будут загружены анонимно. Для этой установки AAPS назначен идентификатор. Вы можете снова передать данные, если ваш основной профиль будет изменен, но пусть он работает по крайней мере в течение недели, чтобы результат был виден в динамике. Ваша помощь ценна. Некорректное значение возраст Некорректное значение вес Некорректный ввод % @@ -807,9 +819,11 @@ Вы действительно хотите скопировать пароль OTP в буфер обмена?\n\nЭто может потребоваться только в том случае, если у вашего приложения идентификации проблемы при сканировании QR кода, вы хотите ввести его вручную или настроить аппаратный маркер OTP с помощью специального приложения. Секретный одноразовый код OTP (в формате Base32) экспортирован и скопирован в буфер обмена. Вставьте его в систему идентификации или аппаратный маркер OTP! 1. Установить Аутентификатор + 2. Сканируйте код для настройки OTP кодов AAPS 3. Одноразовый Пароль Сбросить аутентификаторы В каждом отслеживающем телефоне установите приложение Authenticator, поддерживающее маркеры TOTP RFC 6238. Популярные бесплатные приложения: \n Authy\n Google Authenticator\n LastPass Authenticator\n FreeOTP Authenticator + После сброса аутентификатора вы делаете все созданные идентификаторы недействительными. Вам нужно будет снова создать их! Прогнозирование Терапия Линия отклонения @@ -1005,6 +1019,7 @@ Выше целевых Показать записи цикла Скрыть записи цикла + Виджет AAPS Настроить прозрачность Статус цикла Масштаб графика @@ -1032,4 +1047,7 @@ (Часы не подключены) Ошибка при запросе разрешения Настроить чувствительность относительно ГК + Очистка базы данных + Вы хотите очистить базу данных?\nЭто удалит отслеживаемые изменения и данные старше 3 месяцев. + Удалённые записи diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 124171c210..ceead9bb42 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -1048,4 +1048,7 @@ (Žiadne hodinky nie sú pripojené) Chyba pri žiadosti o oprávnenie Upraviť citlivosť a glykémiu + Vyčistenie databázy + Chcete vyčistiť databázu?\nOdstráni sledované zmeny a historické dáta staršie ako 3 mesiace. + Vymazané záznamy diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml index a3ecf8abe8..35a3b91303 100644 --- a/core/src/main/res/values-cs-rCZ/strings.xml +++ b/core/src/main/res/values-cs-rCZ/strings.xml @@ -361,6 +361,7 @@ EXPORTOVAT NASTAVENÍ IMPORTOVAT NASTAVENÍ RESETOVAT DATABÁZE + VYČISTIT DATABÁZE EXPORTOVAT DATABÁZE IMPORTOVAT DATABÁZE EXPORT OTP diff --git a/core/src/main/res/values-it-rIT/strings.xml b/core/src/main/res/values-it-rIT/strings.xml index 2bbaf18cac..78e496de8f 100644 --- a/core/src/main/res/values-it-rIT/strings.xml +++ b/core/src/main/res/values-it-rIT/strings.xml @@ -20,6 +20,7 @@ Disconnesso Disconnessione In attesa della disconnessione + AAPS avviato %1$.1f U %1$.2f U %1$+.2f U @@ -279,6 +280,7 @@ Versione %1$s disponibile Versione: %1$s | Scadenza: %2$s + Riavvia il tuo telefono oppure fai ripartire AndroidAPS dalle impostazioni di sistema \naltrimenti Android APS non farà il log (è importante monitorare e verificare che gli algoritmi stiano funzionando correttamente)! L M @@ -359,6 +361,7 @@ ESPORTA IMPOSTAZIONI IMPORTA IMPOSTAZIONI RESETTA DATABASE + PULIZIA DATABASE ESPORTA DATABASE IMPORTA DATABASE ESPORTAZIONE OTP @@ -395,6 +398,7 @@ »%1$s« è fuori dai limiti consentiti »%1$s« %2$.2f è fuori dai limiti consentiti Valore basale + La versione di AAPSClient non corrisponde alla versione di AAPS. Aggiorna. BOLO %1$.2f U CHO %1$d g @@ -482,6 +486,8 @@ Aggiornare il profilo %1$s con il profilo Autotune? Ripristinare il profilo %1$s con il profilo di input? Profilo non valido + Autotune eseguito senza cambio profilo + Autotune eseguito e profilo cambiato automaticamente Errore durante l\'ultima esecuzione di Autotune È stata rilevata un\'altra esecuzione di Autotune, esecuzione annullata L\'applicazione richiede l\'autorizzazione bluetooth diff --git a/core/src/main/res/values-ru-rRU/strings.xml b/core/src/main/res/values-ru-rRU/strings.xml index 0e82a51a15..12a6ec6359 100644 --- a/core/src/main/res/values-ru-rRU/strings.xml +++ b/core/src/main/res/values-ru-rRU/strings.xml @@ -20,6 +20,7 @@ Разъединено разъединение Ожидание разъединения + AAPS запущен %1$.1f ед %1$.2f ед %1$+.2f ед @@ -45,12 +46,12 @@ дата единицы DIA (время действия инсулина) - IC (инсулин/углеводы): + Углеводный коэффициент IC (ГУ/ед. инс) ISF (чувствительность к инсулину) базал Целевое значение СК: Продолжительность действия инсулина - Соотношение инсулин/углеводы I: C + Углеводный коэффициент IC (ГУ/ед. инс.) Фактор Чувствительности к Инсулину (ISF) Базальная скорость Целевая ГК @@ -279,6 +280,7 @@ Доступна версия %1$s Версия: %1$s истекает %2$s + Перезагрузите телефон или перезапустите AAPS из системных настроек \n иначе AAPS не будет вести лог (важно для отслеживания и проверки алгоритмов)! Пн Вт @@ -359,6 +361,7 @@ ЭКСПОРТИРОВАТЬ НАСТРОЙКИ ИМПОРТИРОВАТЬ НАСТРОЙКИ СБРОСИТЬ БАЗЫ ДАННЫХ + ОЧИСТКА ДАННЫХ ЭКСПОРТИРОВАТЬ БАЗЫ ДАННЫХ ИМПОРТИРОВАТЬ БАЗЫ ДАННЫХ ЭКСПОРТИРОВАТЬ OTP @@ -390,11 +393,12 @@ Значение чувствительности в профиле Максимальное значение базала в профиле Текущее значение базала - Коэффициент углеводов в профиле + Значение Углеводного коэффициента IC в профиле %1$.2f ограничено до %2$.2f »%1$s« за пределами жестких ограничений »%1$s« %2$.2f за пределами жестких ограничений Величина базала + Версия AAPSClient не совпадает с версией AAPS. Обновите версию. БОЛЮС %1$.2f ЕД УГЛ %1$d г @@ -482,6 +486,8 @@ Обновить профиль %1$s профилем Autotune? Восстановить профиль %1$s с помощью входного профиля? Неверный профиль + Autotune выполнен без переключения профиля + Autotune выполнен и профиль переключён автоматически Ошибка во время последнего выполнения Autotune Обнаружен другой запуск Autotune, выполнение отменено Приложению требуется разрешение Bluetooth diff --git a/core/src/main/res/values-sk-rSK/strings.xml b/core/src/main/res/values-sk-rSK/strings.xml index 5c8271302e..93d2595c0d 100644 --- a/core/src/main/res/values-sk-rSK/strings.xml +++ b/core/src/main/res/values-sk-rSK/strings.xml @@ -361,6 +361,7 @@ EXPORTOVAŤ NASTAVENIA IMPORTOVAŤ NASTAVENIA RESETOVAŤ DATABÁZY + VYČISTIŤ DATABÁZU EXPORTOVAŤ DATABÁZY IMPORTOVAŤ DATABÁZY EXPORT OTP diff --git a/openhumans/src/main/res/values-it-rIT/strings.xml b/openhumans/src/main/res/values-it-rIT/strings.xml index 19181113ab..3be8ca8245 100644 --- a/openhumans/src/main/res/values-it-rIT/strings.xml +++ b/openhumans/src/main/res/values-it-rIT/strings.xml @@ -12,6 +12,7 @@ Upload solo se in carica Caricamento su Open Humans… Notifiche Open Humans + AAPS sta caricando i dati su Open Humans. Potrebbe volerci un po\' di tempo. Sei stato disconnesso da Open Humans Fare click qui per accedere di nuovo. Carica adesso diff --git a/openhumans/src/main/res/values-ru-rRU/strings.xml b/openhumans/src/main/res/values-ru-rRU/strings.xml index 35960caefc..8c51e1acf3 100644 --- a/openhumans/src/main/res/values-ru-rRU/strings.xml +++ b/openhumans/src/main/res/values-ru-rRU/strings.xml @@ -12,6 +12,7 @@ Загружать только при зарядке Идет передача данных в Open Humans… Уведомления Open Humans + AAPS передает данные в Open Humans. Это может занять некоторое время. Вы вышли из Open Humans Нажмите здесь, чтобы снова войти в систему, если выход произошел случайно. Начать передачу данных From ef4a15a4c56cb8c80bac90d8751ec55feab62250 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 31 Oct 2022 16:16:39 +0100 Subject: [PATCH 48/77] revert extracting graphview to aar --- app/build.gradle | 1 + automation/build.gradle | 2 +- core/build.gradle | 2 +- graphview/.gitignore | 1 + graphview/build.gradle | 14 + graphview/consumer-rules.pro | 0 graphview/proguard-rules.pro | 21 + graphview/src/main/AndroidManifest.xml | 4 + .../graphview/DefaultLabelFormatter.java | 105 ++ .../java/com/jjoe64/graphview/GraphView.java | 548 ++++++ .../jjoe64/graphview/GridLabelRenderer.java | 1468 +++++++++++++++++ .../com/jjoe64/graphview/LabelFormatter.java | 54 + .../com/jjoe64/graphview/LegendRenderer.java | 394 +++++ .../com/jjoe64/graphview/SecondScale.java | 165 ++ .../jjoe64/graphview/ValueDependentColor.java | 41 + .../java/com/jjoe64/graphview/Viewport.java | 1005 +++++++++++ .../graphview/compat/OverScrollerCompat.java | 46 + .../helper/DateAsXAxisLabelFormatter.java | 94 ++ .../jjoe64/graphview/helper/GraphViewXML.java | 137 ++ .../helper/StaticLabelsFormatter.java | 209 +++ .../graphview/series/BarGraphSeries.java | 380 +++++ .../jjoe64/graphview/series/BaseSeries.java | 448 +++++ .../jjoe64/graphview/series/DataPoint.java | 63 + .../graphview/series/DataPointInterface.java | 41 + .../graphview/series/LineGraphSeries.java | 409 +++++ .../series/OnDataPointTapListener.java | 38 + .../graphview/series/PointsGraphSeries.java | 312 ++++ .../com/jjoe64/graphview/series/Series.java | 125 ++ graphview/src/main/res/values/attr.xml | 10 + libraries/build.gradle | 2 - libraries/libs/graphview.aar | Bin 62697 -> 0 bytes libraries/libs/libs/graphview.aar | Bin 62697 -> 0 bytes libraries/libs/libs/iconify.aar | Bin 126846 -> 0 bytes libraries/libs/libs/ustwo-clockwise-debug.aar | Bin 90266 -> 0 bytes .../libs/wearpreferenceactivity-0.5.0.aar | Bin 30815 -> 0 bytes .../libraries/ExampleInstrumentedTest.kt | 25 - .../nightscout/libraries/ExampleUnitTest.kt | 18 - settings.gradle | 3 +- 38 files changed, 6137 insertions(+), 48 deletions(-) create mode 100644 graphview/.gitignore create mode 100644 graphview/build.gradle create mode 100644 graphview/consumer-rules.pro create mode 100644 graphview/proguard-rules.pro create mode 100644 graphview/src/main/AndroidManifest.xml create mode 100644 graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/GraphView.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/SecondScale.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/Viewport.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java create mode 100644 graphview/src/main/java/com/jjoe64/graphview/series/Series.java create mode 100644 graphview/src/main/res/values/attr.xml delete mode 100644 libraries/libs/graphview.aar delete mode 100644 libraries/libs/libs/graphview.aar delete mode 100644 libraries/libs/libs/iconify.aar delete mode 100644 libraries/libs/libs/ustwo-clockwise-debug.aar delete mode 100644 libraries/libs/libs/wearpreferenceactivity-0.5.0.aar delete mode 100644 libraries/src/androidTest/java/info/nightscout/libraries/ExampleInstrumentedTest.kt delete mode 100644 libraries/src/test/java/info/nightscout/libraries/ExampleUnitTest.kt diff --git a/app/build.gradle b/app/build.gradle index 41f1c21a8a..196a0503e6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -172,6 +172,7 @@ dependencies { // in order to use internet's versions you'd need to enable Jetifier again // https://github.com/nightscout/graphview.git // https://github.com/nightscout/iconify.git + implementation project(':graphview') implementation project(':libraries') implementation project(':shared') implementation project(':core') diff --git a/automation/build.gradle b/automation/build.gradle index 552bc37408..6c80e0f396 100644 --- a/automation/build.gradle +++ b/automation/build.gradle @@ -13,7 +13,7 @@ android { } dependencies { - implementation project(':libraries') + implementation project(':graphview') implementation project(':core') implementation project(':database') implementation project(':shared') diff --git a/core/build.gradle b/core/build.gradle index dc9f6108da..9993b6655e 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -12,7 +12,7 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" dependencies { - implementation project(':libraries') + implementation project(':graphview') implementation project(':shared') implementation project(':database') } diff --git a/graphview/.gitignore b/graphview/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/graphview/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/graphview/build.gradle b/graphview/build.gradle new file mode 100644 index 0000000000..d4855aaefe --- /dev/null +++ b/graphview/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' + +apply from: "${project.rootDir}/core/android_dependencies.gradle" + +android { + + namespace 'com.jjoe64.graphview' +} + +dependencies { + api "androidx.core:core-ktx:$core_version" +} \ No newline at end of file diff --git a/graphview/consumer-rules.pro b/graphview/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graphview/proguard-rules.pro b/graphview/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/graphview/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/graphview/src/main/AndroidManifest.xml b/graphview/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a5918e68ab --- /dev/null +++ b/graphview/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java new file mode 100644 index 0000000000..0a761e2d73 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/DefaultLabelFormatter.java @@ -0,0 +1,105 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import java.text.NumberFormat; + +/** + * The label formatter that will be used + * by default. + * It will use the NumberFormat from Android + * and sets the maximal fraction digits + * depending on the range between min and max + * value of the current viewport. + * + * It is recommended to use this label formatter + * as base class to implement a custom formatter. + * + * @author jjoe64 + */ +public class DefaultLabelFormatter implements LabelFormatter { + /** + * number formatter for x and y values + */ + protected NumberFormat[] mNumberFormatter = new NumberFormat[2]; + + /** + * reference to the viewport of the + * graph. + * Will be used to calculate the current + * range of values. + */ + protected Viewport mViewport; + + /** + * uses the default number format for the labels + */ + public DefaultLabelFormatter() { + } + + /** + * use custom number format + * + * @param xFormat the number format for the x labels + * @param yFormat the number format for the y labels + */ + public DefaultLabelFormatter(NumberFormat xFormat, NumberFormat yFormat) { + mNumberFormatter[0] = yFormat; + mNumberFormatter[1] = xFormat; + } + + /** + * @param viewport the viewport of the graph + */ + @Override + public void setViewport(Viewport viewport) { + mViewport = viewport; + } + + /** + * Formats the raw value to a nice + * looking label, depending on the + * current range of the viewport. + * + * @param value raw value + * @param isValueX true if it's a x value, otherwise false + * @return the formatted value as string + */ + public String formatLabel(double value, boolean isValueX) { + int i = isValueX ? 1 : 0; + if (mNumberFormatter[i] == null) { + mNumberFormatter[i] = NumberFormat.getNumberInstance(); + double highestvalue = isValueX ? mViewport.getMaxX(false) : mViewport.getMaxY(false); + double lowestvalue = isValueX ? mViewport.getMinX(false) : mViewport.getMinY(false); + if (highestvalue - lowestvalue < 0.1) { + mNumberFormatter[i].setMaximumFractionDigits(6); + } else if (highestvalue - lowestvalue < 1) { + mNumberFormatter[i].setMaximumFractionDigits(4); + } else if (highestvalue - lowestvalue < 20) { + mNumberFormatter[i].setMaximumFractionDigits(3); + } else if (highestvalue - lowestvalue < 100) { + mNumberFormatter[i].setMaximumFractionDigits(1); + } else { + mNumberFormatter[i].setMaximumFractionDigits(0); + } + } + return mNumberFormatter[i].format(value); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/GraphView.java b/graphview/src/main/java/com/jjoe64/graphview/GraphView.java new file mode 100644 index 0000000000..51debe1eef --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/GraphView.java @@ -0,0 +1,548 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.PointF; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +import com.jjoe64.graphview.series.Series; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author jjoe64 + * @version 4.0.0 + */ +public class GraphView extends View { + /** + * Class to wrap style options that are general + * to graphs. + * + * @author jjoe64 + */ + private static final class Styles { + /** + * The font size of the title that can be displayed + * above the graph. + * + * @see GraphView#setTitle(String) + */ + float titleTextSize; + + /** + * The font color of the title that can be displayed + * above the graph. + * + * @see GraphView#setTitle(String) + */ + int titleColor; + } + + /** + * Helper class to detect tap events on the + * graph. + * + * @author jjoe64 + */ + private class TapDetector { + /** + * save the time of the last down event + */ + private long lastDown; + + /** + * point of the tap down event + */ + private PointF lastPoint; + + /** + * to be called to process the events + * + * @param event + * @return true if there was a tap event. otherwise returns false. + */ + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + lastDown = System.currentTimeMillis(); + lastPoint = new PointF(event.getX(), event.getY()); + } else if (lastDown > 0 && event.getAction() == MotionEvent.ACTION_MOVE) { + if (Math.abs(event.getX() - lastPoint.x) > 60 + || Math.abs(event.getY() - lastPoint.y) > 60) { + lastDown = 0; + } + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - lastDown < 400) { + return true; + } + } + return false; + } + } + + /** + * our series (this does not contain the series + * that can be displayed on the right side. The + * right side series is a special feature of + * the {@link SecondScale} feature. + */ + private List mSeries; + + /** + * the renderer for the grid and labels + */ + private GridLabelRenderer mGridLabelRenderer; + + /** + * viewport that holds the current bounds of + * view. + */ + private Viewport mViewport; + + /** + * title of the graph that will be shown above + */ + private String mTitle; + + /** + * wraps the general styles + */ + private Styles mStyles; + + /** + * feature to have a second scale e.g. on the + * right side + */ + protected SecondScale mSecondScale; + + /** + * tap detector + */ + private TapDetector mTapDetector; + + /** + * renderer for the legend + */ + private LegendRenderer mLegendRenderer; + + /** + * paint for the graph title + */ + private Paint mPaintTitle; + + /** + * paint for the preview (in the SDK) + */ + private Paint mPreviewPaint; + + /** + * Initialize the GraphView view + * @param context + */ + public GraphView(Context context) { + super(context); + init(); + } + + /** + * Initialize the GraphView view. + * + * @param context + * @param attrs + */ + public GraphView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * Initialize the GraphView view + * + * @param context + * @param attrs + * @param defStyle + */ + public GraphView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + /** + * initialize the internal objects. + * This method has to be called directly + * in the constructors. + */ + protected void init() { + mPreviewPaint = new Paint(); + mPreviewPaint.setTextAlign(Paint.Align.CENTER); + mPreviewPaint.setColor(Color.BLACK); + mPreviewPaint.setTextSize(50); + + mStyles = new Styles(); + mViewport = new Viewport(this); + mGridLabelRenderer = new GridLabelRenderer(this); + mLegendRenderer = new LegendRenderer(this); + + mSeries = new ArrayList(); + mPaintTitle = new Paint(); + + mTapDetector = new TapDetector(); + + loadStyles(); + } + + /** + * loads the font + */ + protected void loadStyles() { + mStyles.titleColor = mGridLabelRenderer.getHorizontalLabelsColor(); + mStyles.titleTextSize = mGridLabelRenderer.getTextSize(); + } + + /** + * @return the renderer for the grid and labels + */ + public GridLabelRenderer getGridLabelRenderer() { + return mGridLabelRenderer; + } + + /** + * Add a new series to the graph. This will + * automatically redraw the graph. + * @param s the series to be added + */ + public void addSeries(Series s) { + s.onGraphViewAttached(this); + mSeries.add(s); + onDataChanged(false, false); + } + + /** + * important: do not do modifications on the list + * object that will be returned. + * Use {@link #removeSeries(com.jjoe64.graphview.series.Series)} and {@link #addSeries(com.jjoe64.graphview.series.Series)} + * + * @return all series + */ + public List getSeries() { + // TODO immutable array + return mSeries; + } + + /** + * call this to let the graph redraw and + * recalculate the viewport. + * This will be called when a new series + * was added or removed and when data + * was appended via {@link com.jjoe64.graphview.series.BaseSeries#appendData(com.jjoe64.graphview.series.DataPointInterface, boolean, int)} + * or {@link com.jjoe64.graphview.series.BaseSeries#resetData(com.jjoe64.graphview.series.DataPointInterface[])}. + * + * @param keepLabelsSize true if you don't want + * to recalculate the size of + * the labels. It is recommended + * to use "true" because this will + * improve performance and prevent + * a flickering. + * @param keepViewport true if you don't want that + * the viewport will be recalculated. + * It is recommended to use "true" for + * performance. + */ + public void onDataChanged(boolean keepLabelsSize, boolean keepViewport) { + // adjust grid system + mViewport.calcCompleteRange(); + mGridLabelRenderer.invalidate(keepLabelsSize, keepViewport); + invalidate(); + } + + /** + * will be called from Android system. + * + * @param canvas Canvas + */ + @Override + protected void onDraw(Canvas canvas) { + if (isInEditMode()) { + canvas.drawColor(Color.rgb(200, 200, 200)); + canvas.drawText("GraphView: No Preview available", canvas.getWidth()/2, canvas.getHeight()/2, mPreviewPaint); + } else { + drawTitle(canvas); + mViewport.drawFirst(canvas); + mGridLabelRenderer.draw(canvas); + for (Series s : mSeries) { + s.draw(this, canvas, false); + } + if (mSecondScale != null) { + for (Series s : mSecondScale.getSeries()) { + s.draw(this, canvas, true); + } + } + mViewport.draw(canvas); + mLegendRenderer.draw(canvas); + } + } + + /** + * Draws the Graphs title that will be + * shown above the viewport. + * Will be called by GraphView. + * + * @param canvas Canvas + */ + protected void drawTitle(Canvas canvas) { + if (mTitle != null && mTitle.length()>0) { + mPaintTitle.setColor(mStyles.titleColor); + mPaintTitle.setTextSize(mStyles.titleTextSize); + mPaintTitle.setTextAlign(Paint.Align.CENTER); + float x = canvas.getWidth()/2; + float y = mPaintTitle.getTextSize(); + canvas.drawText(mTitle, x, y, mPaintTitle); + } + } + + /** + * Calculates the height of the title. + * + * @return the actual size of the title. + * if there is no title, 0 will be + * returned. + */ + protected int getTitleHeight() { + if (mTitle != null && mTitle.length()>0) { + return (int) mPaintTitle.getTextSize(); + } else { + return 0; + } + } + + /** + * @return the viewport of the Graph. + * @see com.jjoe64.graphview.Viewport + */ + public Viewport getViewport() { + return mViewport; + } + + /** + * Called by Android system if the size + * of the view was changed. Will recalculate + * the viewport and labels. + * + * @param w + * @param h + * @param oldw + * @param oldh + */ + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + onDataChanged(false, false); + } + + /** + * @return the space on the left side of the + * view from the left border to the + * beginning of the graph viewport. + */ + public int getGraphContentLeft() { + int border = getGridLabelRenderer().getStyles().padding; + return border + getGridLabelRenderer().getLabelVerticalWidth() + getGridLabelRenderer().getVerticalAxisTitleWidth(); + } + + /** + * @return the space on the top of the + * view from the top border to the + * beginning of the graph viewport. + */ + public int getGraphContentTop() { + int border = getGridLabelRenderer().getStyles().padding + getTitleHeight(); + return border; + } + + /** + * @return the height of the graph viewport. + */ + public int getGraphContentHeight() { + int border = getGridLabelRenderer().getStyles().padding; + int graphheight = getHeight() - (2 * border) - getGridLabelRenderer().getLabelHorizontalHeight() - getTitleHeight(); + graphheight -= getGridLabelRenderer().getHorizontalAxisTitleHeight(); + return graphheight; + } + + /** + * @return the width of the graph viewport. + */ + public int getGraphContentWidth() { + int border = getGridLabelRenderer().getStyles().padding; + int graphwidth = getWidth() - (2 * border) - getGridLabelRenderer().getLabelVerticalWidth(); + if (mSecondScale != null) { + graphwidth -= getGridLabelRenderer().getLabelVerticalSecondScaleWidth(); + } + return graphwidth; + } + + /** + * will be called from Android system. + * + * @param event + * @return + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean b = mViewport.onTouchEvent(event); + boolean a = super.onTouchEvent(event); + + // is it a click? + if (mTapDetector.onTouchEvent(event)) { + for (Series s : mSeries) { + s.onTap(event.getX(), event.getY()); + } + if (mSecondScale != null) { + for (Series s : mSecondScale.getSeries()) { + s.onTap(event.getX(), event.getY()); + } + } + } + + return b || a; + } + + /** + * + */ + @Override + public void computeScroll() { + super.computeScroll(); + mViewport.computeScroll(); + } + + /** + * @return the legend renderer. + * @see com.jjoe64.graphview.LegendRenderer + */ + public LegendRenderer getLegendRenderer() { + return mLegendRenderer; + } + + /** + * use a specific legend renderer + * + * @param mLegendRenderer the new legend renderer + */ + public void setLegendRenderer(LegendRenderer mLegendRenderer) { + this.mLegendRenderer = mLegendRenderer; + } + + /** + * @return the title that will be shown + * above the graph. + */ + public String getTitle() { + return mTitle; + } + + /** + * Set the title of the graph that will + * be shown above the graph's viewport. + * + * @param mTitle the title + * @see #setTitleColor(int) to set the font color + * @see #setTitleTextSize(float) to set the font size + */ + public void setTitle(String mTitle) { + this.mTitle = mTitle; + } + + /** + * @return the title font size + */ + public float getTitleTextSize() { + return mStyles.titleTextSize; + } + + /** + * Set the title's font size + * + * @param titleTextSize font size + * @see #setTitle(String) + */ + public void setTitleTextSize(float titleTextSize) { + mStyles.titleTextSize = titleTextSize; + } + + /** + * @return font color of the title + */ + public int getTitleColor() { + return mStyles.titleColor; + } + + /** + * Set the title's font color + * + * @param titleColor font color of the title + * @see #setTitle(String) + */ + public void setTitleColor(int titleColor) { + mStyles.titleColor = titleColor; + } + + /** + * + * @return + */ + public SecondScale getSecondScale() { + if (mSecondScale == null) { + mSecondScale = new SecondScale(mViewport); + } + return mSecondScale; + } + + /** + * Removes all series of the graph. + */ + public void removeAllSeries() { + mSeries.clear(); + onDataChanged(false, false); + } + + /** + * Remove a specific series of the graph. + * This will also re-render the graph, but + * without recalculating the viewport and + * label sizes. + * If you want this, you have to call {@link #onDataChanged(boolean, boolean)} + * manually. + * + * @param series + */ + public void removeSeries(Series series) { + mSeries.remove(series); + onDataChanged(false, false); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java b/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java new file mode 100644 index 0000000000..b6a8ff7d9b --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java @@ -0,0 +1,1468 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.TypedValue; + +import androidx.core.view.ViewCompat; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * The default renderer for the grid + * and the labels. + * + * @author jjoe64 + */ +public class GridLabelRenderer { + /** + * wrapper for the styles regarding + * to the grid and the labels + */ + public final class Styles { + /** + * the general text size of the axis titles. + * can be overwritten with #verticalAxisTitleTextSize + * and #horizontalAxisTitleTextSize + */ + public float textSize; + + /** + * the alignment of the vertical labels + */ + public Paint.Align verticalLabelsAlign; + + /** + * the alignment of the labels on the right side + */ + public Paint.Align verticalLabelsSecondScaleAlign; + + /** + * the color of the vertical labels + */ + public int verticalLabelsColor; + + /** + * the color of the labels on the right side + */ + public int verticalLabelsSecondScaleColor; + + /** + * the color of the horizontal labels + */ + public int horizontalLabelsColor; + + /** + * the color of the grid lines + */ + public int gridColor; + + /** + * flag whether the zero-lines (vertical+ + * horizontal) shall be highlighted + */ + public boolean highlightZeroLines; + + /** + * the padding around the graph and labels + */ + public int padding; + + /** + * font size of the vertical axis title + */ + public float verticalAxisTitleTextSize; + + /** + * font color of the vertical axis title + */ + public int verticalAxisTitleColor; + + /** + * font size of the horizontal axis title + */ + public float horizontalAxisTitleTextSize; + + /** + * font color of the horizontal axis title + */ + public int horizontalAxisTitleColor; + + /** + * flag whether the horizontal labels are + * visible + */ + boolean horizontalLabelsVisible; + + /** + * flag whether the vertical labels are + * visible + */ + boolean verticalLabelsVisible; + + /** + * defines which lines will be drawn in the background + */ + GridStyle gridStyle; + + /** + * the space between the labels text and the graph content + */ + int labelsSpace; + } + + /** + * Definition which lines will be drawn in the background + */ + public enum GridStyle { + BOTH, VERTICAL, HORIZONTAL, NONE; + + public boolean drawVertical() { return this == BOTH || this == VERTICAL && this != NONE; } + public boolean drawHorizontal() { return this == BOTH || this == HORIZONTAL && this != NONE; } + } + + /** + * wraps the styles regarding the + * grid and labels + */ + protected Styles mStyles; + + /** + * reference to graphview + */ + private final GraphView mGraphView; + + /** + * cache of the vertical steps + * (horizontal lines and vertical labels) + * Key = Pixel (y) + * Value = y-value + */ + private Map mStepsVertical; + + /** + * cache of the vertical steps for the + * second scale, which is on the right side + * (horizontal lines and vertical labels) + * Key = Pixel (y) + * Value = y-value + */ + private Map mStepsVerticalSecondScale; + + /** + * cache of the horizontal steps + * (vertical lines and horizontal labels) + * Key = Pixel (x) + * Value = x-value + */ + private Map mStepsHorizontal; + + /** + * the paint to draw the grid lines + */ + private Paint mPaintLine; + + /** + * the paint to draw the labels + */ + private Paint mPaintLabel; + + /** + * the paint to draw axis titles + */ + private Paint mPaintAxisTitle; + + /** + * flag whether is bounds are automatically + * adjusted for nice human-readable numbers + */ + private boolean mIsAdjusted; + + /** + * the width of the vertical labels + */ + private Integer mLabelVerticalWidth; + + /** + * indicates if the width was set manually + */ + private boolean mLabelVerticalWidthFixed; + + /** + * the height of the vertical labels + */ + private Integer mLabelVerticalHeight; + + /** + * indicates if the height was set manually + */ + private boolean mLabelHorizontalHeightFixed; + + /** + * the width of the vertical labels + * of the second scale + */ + private Integer mLabelVerticalSecondScaleWidth; + + /** + * the height of the vertical labels + * of the second scale + */ + private Integer mLabelVerticalSecondScaleHeight; + + /** + * the width of the horizontal labels + */ + private Integer mLabelHorizontalWidth; + + /** + * the height of the horizontal labels + */ + private Integer mLabelHorizontalHeight; + + /** + * the label formatter, that converts + * the raw numbers to strings + */ + private LabelFormatter mLabelFormatter; + + /** + * the title of the horizontal axis + */ + private String mHorizontalAxisTitle; + + /** + * the title of the vertical axis + */ + private String mVerticalAxisTitle; + + /** + * count of the vertical labels, that + * will be shown at one time. + */ + private int mNumVerticalLabels; + + /** + * count of the horizontal labels, that + * will be shown at one time. + */ + private int mNumHorizontalLabels; + + /** + * create the default grid label renderer. + * + * @param graphView the corresponding graphview object + */ + public GridLabelRenderer(GraphView graphView) { + mGraphView = graphView; + setLabelFormatter(new DefaultLabelFormatter()); + mStyles = new Styles(); + resetStyles(); + mNumVerticalLabels = 5; + mNumHorizontalLabels = 5; + } + + /** + * resets the styles. This loads the style + * from reading the values of the current + * theme. + */ + @SuppressWarnings({"deprecation"}) + public void resetStyles() { + // get matching styles from theme + TypedValue typedValue = new TypedValue(); + mGraphView.getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceSmall, typedValue, true); + + int color1; + int color2; + int size; + int size2; + + TypedArray array = null; + try { + array = mGraphView.getContext().obtainStyledAttributes(typedValue.data, new int[]{ + android.R.attr.textColorPrimary + , android.R.attr.textColorSecondary + , android.R.attr.textSize + , android.R.attr.horizontalGap}); + color1 = array.getColor(0, Color.BLACK); + color2 = array.getColor(1, Color.GRAY); + size = array.getDimensionPixelSize(2, 20); + size2 = array.getDimensionPixelSize(3, 20); + array.recycle(); + } catch (Exception e) { + color1 = Color.BLACK; + color2 = Color.GRAY; + size = 20; + size2 = 20; + } + + mStyles.verticalLabelsColor = color1; + mStyles.verticalLabelsSecondScaleColor = color1; + mStyles.horizontalLabelsColor = color1; + mStyles.gridColor = color2; + mStyles.textSize = size; + mStyles.padding = size2; + mStyles.labelsSpace = (int) mStyles.textSize/5; + + mStyles.verticalLabelsAlign = Paint.Align.RIGHT; + mStyles.verticalLabelsSecondScaleAlign = Paint.Align.LEFT; + mStyles.highlightZeroLines = true; + + mStyles.verticalAxisTitleColor = mStyles.verticalLabelsColor; + mStyles.horizontalAxisTitleColor = mStyles.horizontalLabelsColor; + mStyles.verticalAxisTitleTextSize = mStyles.textSize; + mStyles.horizontalAxisTitleTextSize = mStyles.textSize; + + mStyles.horizontalLabelsVisible = true; + mStyles.verticalLabelsVisible = true; + + mStyles.gridStyle = GridStyle.BOTH; + + reloadStyles(); + } + + /** + * will load the styles to the internal + * paint objects (color, text size, text align) + */ + public void reloadStyles() { + mPaintLine = new Paint(); + mPaintLine.setColor(mStyles.gridColor); + mPaintLine.setStrokeWidth(0); + + mPaintLabel = new Paint(); + mPaintLabel.setTextSize(getTextSize()); + + mPaintAxisTitle = new Paint(); + mPaintAxisTitle.setTextSize(getTextSize()); + mPaintAxisTitle.setTextAlign(Paint.Align.CENTER); + } + + /** + * @return the general text size for the axis titles + */ + public float getTextSize() { + return mStyles.textSize; + } + + /** + * @return the font color of the vertical labels + */ + public int getVerticalLabelsColor() { + return mStyles.verticalLabelsColor; + } + + /** + * @return the alignment of the text of the + * vertical labels + */ + public Paint.Align getVerticalLabelsAlign() { + return mStyles.verticalLabelsAlign; + } + + /** + * @return the font color of the horizontal labels + */ + public int getHorizontalLabelsColor() { + return mStyles.horizontalLabelsColor; + } + + /** + * clears the internal cache and forces + * to redraw the grid and labels. + * Normally you should always call {@link GraphView#onDataChanged(boolean, boolean)} + * which will call this method. + * + * @param keepLabelsSize true if you don't want + * to recalculate the size of + * the labels. It is recommended + * to use "true" because this will + * improve performance and prevent + * a flickering. + * @param keepViewport true if you don't want that + * the viewport will be recalculated. + * It is recommended to use "true" for + * performance. + */ + public void invalidate(boolean keepLabelsSize, boolean keepViewport) { + if (!keepViewport) { + mIsAdjusted = false; + } + if (!keepLabelsSize) { + if (!mLabelVerticalWidthFixed) { + mLabelVerticalWidth = null; + } + mLabelVerticalHeight = null; + mLabelVerticalSecondScaleWidth = null; + mLabelVerticalSecondScaleHeight = null; + } + //reloadStyles(); + } + + /** + * calculates the vertical steps of + * the second scale. + * This will not do any automatically update + * of the bounds. + * Use always manual bounds for the second scale. + * + * @return true if it is ready + */ + protected boolean adjustVerticalSecondScale() { + if (mLabelHorizontalHeight == null) { + return false; + } + if (mGraphView.mSecondScale == null) { + return true; + } + + double minY = mGraphView.mSecondScale.getMinY(); + double maxY = mGraphView.mSecondScale.getMaxY(); + + // TODO find the number of labels + int numVerticalLabels = mNumVerticalLabels; + + double newMinY; + double exactSteps; + + if (mGraphView.mSecondScale.isYAxisBoundsManual()) { + newMinY = minY; + double rangeY = maxY - newMinY; + exactSteps = rangeY / (numVerticalLabels - 1); + } else { + // TODO auto adjusting + throw new IllegalStateException("Not yet implemented"); + } + + double newMaxY = newMinY + (numVerticalLabels - 1) * exactSteps; + + // TODO auto adjusting + //mGraphView.getViewport().setMinY(newMinY); + //mGraphView.getViewport().setMaxY(newMaxY); + + //if (!mGraphView.getViewport().isYAxisBoundsManual()) { + // mGraphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); + //} + + if (mStepsVerticalSecondScale != null) { + mStepsVerticalSecondScale.clear(); + } else { + mStepsVerticalSecondScale = new LinkedHashMap(numVerticalLabels); + } + int height = mGraphView.getGraphContentHeight(); + double v = newMaxY; + int p = mGraphView.getGraphContentTop(); // start + int pixelStep = height / (numVerticalLabels - 1); + for (int i = 0; i < numVerticalLabels; i++) { + mStepsVerticalSecondScale.put(p, v); + p += pixelStep; + v -= exactSteps; + } + + return true; + } + + /** + * calculates the vertical steps. This will + * automatically change the bounds to nice + * human-readable min/max. + * + * @return true if it is ready + */ + protected boolean adjustVertical() { + if (mLabelHorizontalHeight == null) { + return false; + } + + double minY = mGraphView.getViewport().getMinY(false); + double maxY = mGraphView.getViewport().getMaxY(false); + + if (minY == maxY) { + return false; + } + + // TODO find the number of labels + int numVerticalLabels = mNumVerticalLabels; + + double newMinY; + double exactSteps; + + if (mGraphView.getViewport().isYAxisBoundsManual()) { + newMinY = minY; + double rangeY = maxY - newMinY; + exactSteps = rangeY / (numVerticalLabels - 1); + } else { + // find good steps + boolean adjusting = true; + newMinY = minY; + exactSteps = 0d; + while (adjusting) { + double rangeY = maxY - newMinY; + exactSteps = rangeY / (numVerticalLabels - 1); + exactSteps = humanRound(exactSteps, true); + + // adjust viewport + // wie oft passt STEP in minY rein? + int count = 0; + if (newMinY >= 0d) { + // positive number + while (newMinY - exactSteps >= 0) { + newMinY -= exactSteps; + count++; + } + newMinY = exactSteps * count; + } else { + // negative number + count++; + while (newMinY + exactSteps < 0) { + newMinY += exactSteps; + count++; + } + newMinY = exactSteps * count * -1; + } + + // wenn minY sich geändert hat, steps nochmal berechnen + // wenn nicht, fertig + if (newMinY == minY) { + adjusting = false; + } else { + minY = newMinY; + } + } + } + + double newMaxY = newMinY + (numVerticalLabels - 1) * exactSteps; + mGraphView.getViewport().setMinY(newMinY); + mGraphView.getViewport().setMaxY(newMaxY); + + if (!mGraphView.getViewport().isYAxisBoundsManual()) { + mGraphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); + } + + if (mStepsVertical != null) { + mStepsVertical.clear(); + } else { + mStepsVertical = new LinkedHashMap(numVerticalLabels); + } + int height = mGraphView.getGraphContentHeight(); + double v = newMaxY; + int p = mGraphView.getGraphContentTop(); // start + int pixelStep = height / (numVerticalLabels - 1); + for (int i = 0; i < numVerticalLabels; i++) { + mStepsVertical.put(p, v); + p += pixelStep; + v -= exactSteps; + } + + return true; + } + + /** + * calculates the horizontal steps. This will + * automatically change the bounds to nice + * human-readable min/max. + * + * @return true if it is ready + */ + protected boolean adjustHorizontal() { + if (mLabelVerticalWidth == null) { + return false; + } + + double minX = mGraphView.getViewport().getMinX(false); + double maxX = mGraphView.getViewport().getMaxX(false); + if (minX == maxX) return false; + + // TODO find the number of labels + int numHorizontalLabels = mNumHorizontalLabels; + + double newMinX; + double exactSteps; + + float scalingOffset = 0f; + if (mGraphView.getViewport().isXAxisBoundsManual() && mGraphView.getViewport().getXAxisBoundsStatus() != Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { + // scaling + if (mGraphView.getViewport().mScalingActive) { + minX = mGraphView.getViewport().mScalingBeginLeft; + maxX = minX + mGraphView.getViewport().mScalingBeginWidth; + + //numHorizontalLabels *= (mGraphView.getViewport().mCurrentViewport.width()+oldStep)/(mGraphView.getViewport().mScalingBeginWidth+oldStep); + //numHorizontalLabels = (float) Math.ceil(numHorizontalLabels); + } + + newMinX = minX; + double rangeX = maxX - newMinX; + exactSteps = rangeX / (numHorizontalLabels - 1); + } else { + // find good steps + boolean adjusting = true; + newMinX = minX; + exactSteps = 0d; + while (adjusting) { + double rangeX = maxX - newMinX; + exactSteps = rangeX / (numHorizontalLabels - 1); + + boolean roundAlwaysUp = true; + if (mGraphView.getViewport().getXAxisBoundsStatus() == Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { + // if viewports gets smaller, round down + if (mGraphView.getViewport().mCurrentViewport.width() < mGraphView.getViewport().mScalingBeginWidth) { + roundAlwaysUp = false; + } + } + exactSteps = humanRound(exactSteps, roundAlwaysUp); + + // adjust viewport + // wie oft passt STEP in minX rein? + int count = 0; + if (newMinX >= 0d) { + // positive number + while (newMinX - exactSteps >= 0) { + newMinX -= exactSteps; + count++; + } + newMinX = exactSteps * count; + } else { + // negative number + count++; + while (newMinX + exactSteps < 0) { + newMinX += exactSteps; + count++; + } + newMinX = exactSteps * count * -1; + } + + // wenn minX sich geändert hat, steps nochmal berechnen + // wenn nicht, fertig + if (newMinX == minX) { + adjusting = false; + } else { + minX = newMinX; + } + } + + double newMaxX = newMinX + (numHorizontalLabels - 1) * exactSteps; + mGraphView.getViewport().setMinX(newMinX); + mGraphView.getViewport().setMaxX(newMaxX); + if (mGraphView.getViewport().getXAxisBoundsStatus() == Viewport.AxisBoundsStatus.READJUST_AFTER_SCALE) { + mGraphView.getViewport().setXAxisBoundsStatus(Viewport.AxisBoundsStatus.FIX); + } else { + mGraphView.getViewport().setXAxisBoundsStatus(Viewport.AxisBoundsStatus.AUTO_ADJUSTED); + } + } + + if (mStepsHorizontal != null) { + mStepsHorizontal.clear(); + } else { + mStepsHorizontal = new LinkedHashMap((int) numHorizontalLabels); + } + int width = mGraphView.getGraphContentWidth(); + + float scrolled = 0; + float scrolledPixels = 0; + + double v = newMinX; + int p = mGraphView.getGraphContentLeft(); // start + float pixelStep = width / (numHorizontalLabels - 1); + + if (mGraphView.getViewport().mScalingActive) { + float oldStep = mGraphView.getViewport().mScalingBeginWidth / (numHorizontalLabels - 1); + float factor = (mGraphView.getViewport().mCurrentViewport.width() + oldStep) / (mGraphView.getViewport().mScalingBeginWidth + oldStep); + pixelStep *= 1f / factor; + + //numHorizontalLabels *= (mGraphView.getViewport().mCurrentViewport.width()+oldStep)/(mGraphView.getViewport().mScalingBeginWidth+oldStep); + //numHorizontalLabels = (float) Math.ceil(numHorizontalLabels); + + //scrolled = ((float) mGraphView.getViewport().getMinX(false) - mGraphView.getViewport().mScalingBeginLeft)*2; + float newWidth = width * 1f / factor; + scrolledPixels = (newWidth - width) * -0.5f; + + } + + // scrolling + if (!Float.isNaN(mGraphView.getViewport().mScrollingReferenceX)) { + scrolled = mGraphView.getViewport().mScrollingReferenceX - (float) newMinX; + scrolledPixels += scrolled * (pixelStep / (float) exactSteps); + + if (scrolled < 0 - exactSteps) { + mGraphView.getViewport().mScrollingReferenceX += exactSteps; + } else if (scrolled > exactSteps) { + mGraphView.getViewport().mScrollingReferenceX -= exactSteps; + } + } + p += scrolledPixels; + v += scrolled; + + for (int i = 0; i < numHorizontalLabels; i++) { + // don't draw steps before 0 (scrolling) + if (p >= mGraphView.getGraphContentLeft()) { + mStepsHorizontal.put(p, v); + } + p += pixelStep; + v += exactSteps; + } + + return true; + } + + /** + * adjusts the grid and labels to match to the data + * this will automatically change the bounds to + * nice human-readable values, except the bounds + * are manual. + */ + protected void adjust() { + mIsAdjusted = adjustVertical(); + mIsAdjusted &= adjustVerticalSecondScale(); + mIsAdjusted &= adjustHorizontal(); + } + + /** + * calculates the vertical label size + * @param canvas canvas + */ + protected void calcLabelVerticalSize(Canvas canvas) { + // test label with first and last label + String testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMaxY(false), false); + if (testLabel == null) testLabel = ""; + + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelVerticalWidth = textBounds.width(); + mLabelVerticalHeight = textBounds.height(); + + testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMinY(false), false); + if (testLabel == null) testLabel = ""; + + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelVerticalWidth = Math.max(mLabelVerticalWidth, textBounds.width()); + + // add some pixel to get a margin + mLabelVerticalWidth += 6; + + // space between text and graph content + mLabelVerticalWidth += mStyles.labelsSpace; + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelVerticalHeight *= lines; + } + + /** + * calculates the vertical second scale + * label size + * @param canvas canvas + */ + protected void calcLabelVerticalSecondScaleSize(Canvas canvas) { + if (mGraphView.mSecondScale == null) { + mLabelVerticalSecondScaleWidth = 0; + mLabelVerticalSecondScaleHeight = 0; + return; + } + + // test label + double testY = ((mGraphView.mSecondScale.getMaxY() - mGraphView.mSecondScale.getMinY()) * 0.783) + mGraphView.mSecondScale.getMinY(); + String testLabel = mGraphView.mSecondScale.getLabelFormatter().formatLabel(testY, false); + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelVerticalSecondScaleWidth = textBounds.width(); + mLabelVerticalSecondScaleHeight = textBounds.height(); + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelVerticalSecondScaleHeight *= lines; + } + + /** + * calculates the horizontal label size + * @param canvas canvas + */ + protected void calcLabelHorizontalSize(Canvas canvas) { + // test label + double testX = ((mGraphView.getViewport().getMaxX(false) - mGraphView.getViewport().getMinX(false)) * 0.783) + mGraphView.getViewport().getMinX(false); + String testLabel = mLabelFormatter.formatLabel(testX, true); + if (testLabel == null) { + testLabel = ""; + } + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel, 0, testLabel.length(), textBounds); + mLabelHorizontalWidth = textBounds.width(); + + if (!mLabelHorizontalHeightFixed) { + mLabelHorizontalHeight = textBounds.height(); + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelHorizontalHeight *= lines; + + mLabelHorizontalHeight = (int) Math.max(mLabelHorizontalHeight, mStyles.textSize); + } + + // space between text and graph content + mLabelHorizontalHeight += mStyles.labelsSpace; + } + + /** + * do the drawing of the grid + * and labels + * @param canvas canvas + */ + public void draw(Canvas canvas) { + boolean labelSizeChanged = false; + if (mLabelHorizontalWidth == null) { + calcLabelHorizontalSize(canvas); + labelSizeChanged = true; + } + if (mLabelVerticalWidth == null) { + calcLabelVerticalSize(canvas); + labelSizeChanged = true; + } + if (mLabelVerticalSecondScaleWidth == null) { + calcLabelVerticalSecondScaleSize(canvas); + labelSizeChanged = true; + } + if (labelSizeChanged) { + // redraw + ViewCompat.postInvalidateOnAnimation(mGraphView); + return; + } + + if (!mIsAdjusted) { + adjust(); + } + + if (mIsAdjusted) { + drawVerticalSteps(canvas); + drawVerticalStepsSecondScale(canvas); + drawHorizontalSteps(canvas); + } else { + // we can not draw anything + return; + } + + drawHorizontalAxisTitle(canvas); + drawVerticalAxisTitle(canvas); + } + + /** + * draws the horizontal axis title if + * it is set + * @param canvas canvas + */ + protected void drawHorizontalAxisTitle(Canvas canvas) { + if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { + mPaintAxisTitle.setColor(getHorizontalAxisTitleColor()); + mPaintAxisTitle.setTextSize(getHorizontalAxisTitleTextSize()); + float x = canvas.getWidth() / 2; + float y = canvas.getHeight() - mStyles.padding; + canvas.drawText(mHorizontalAxisTitle, x, y, mPaintAxisTitle); + } + } + + /** + * draws the vertical axis title if + * it is set + * @param canvas canvas + */ + protected void drawVerticalAxisTitle(Canvas canvas) { + if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { + mPaintAxisTitle.setColor(getVerticalAxisTitleColor()); + mPaintAxisTitle.setTextSize(getVerticalAxisTitleTextSize()); + float x = getVerticalAxisTitleWidth(); + float y = canvas.getHeight() / 2; + canvas.save(); + canvas.rotate(-90, x, y); + canvas.drawText(mVerticalAxisTitle, x, y, mPaintAxisTitle); + canvas.restore(); + } + } + + /** + * @return the horizontal axis title height + * or 0 if there is no title + */ + public int getHorizontalAxisTitleHeight() { + if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { + return (int) getHorizontalAxisTitleTextSize(); + } else { + return 0; + } + } + + /** + * @return the vertical axis title width + * or 0 if there is no title + */ + public int getVerticalAxisTitleWidth() { + if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { + return (int) getVerticalAxisTitleTextSize(); + } else { + return 0; + } + } + + /** + * draws the horizontal steps + * vertical lines and horizontal labels + * + * @param canvas canvas + */ + protected void drawHorizontalSteps(Canvas canvas) { + // draw horizontal steps (vertical lines and horizontal labels) + mPaintLabel.setColor(getHorizontalLabelsColor()); + int i = 0; + for (Map.Entry e : mStepsHorizontal.entrySet()) { + // draw line + if (mStyles.highlightZeroLines) { + if (e.getValue() == 0d) { + mPaintLine.setStrokeWidth(5); + } else { + mPaintLine.setStrokeWidth(0); + } + } + if (mStyles.gridStyle.drawVertical()) { + canvas.drawLine(e.getKey(), mGraphView.getGraphContentTop(), e.getKey(), mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight(), mPaintLine); + } + + // draw label + if (isHorizontalLabelsVisible()) { + mPaintLabel.setTextAlign(Paint.Align.CENTER); + if (i == mStepsHorizontal.size() - 1) + mPaintLabel.setTextAlign(Paint.Align.RIGHT); + if (i == 0) + mPaintLabel.setTextAlign(Paint.Align.LEFT); + + // multiline labels + String label = mLabelFormatter.formatLabel(e.getValue(), true); + if (label == null) { + label = ""; + } + String[] lines = label.split("\n"); + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y = (canvas.getHeight() - mStyles.padding - getHorizontalAxisTitleHeight()) - (lines.length - li - 1) * getTextSize() * 1.1f + mStyles.labelsSpace; + canvas.drawText(lines[li], e.getKey(), y, mPaintLabel); + } + } + i++; + } + } + + /** + * draws the vertical steps for the + * second scale on the right side + * + * @param canvas canvas + */ + protected void drawVerticalStepsSecondScale(Canvas canvas) { + if (mGraphView.mSecondScale == null) { + return; + } + + // draw only the vertical labels on the right + float startLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth(); + mPaintLabel.setColor(getVerticalLabelsSecondScaleColor()); + mPaintLabel.setTextAlign(getVerticalLabelsSecondScaleAlign()); + for (Map.Entry e : mStepsVerticalSecondScale.entrySet()) { + // draw label + int labelsWidth = mLabelVerticalSecondScaleWidth; + int labelsOffset = (int) startLeft; + if (getVerticalLabelsSecondScaleAlign() == Paint.Align.RIGHT) { + labelsOffset += labelsWidth; + } else if (getVerticalLabelsSecondScaleAlign() == Paint.Align.CENTER) { + labelsOffset += labelsWidth / 2; + } + + float y = e.getKey(); + + String[] lines = mGraphView.mSecondScale.mLabelFormatter.formatLabel(e.getValue(), false).split("\n"); + y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; + canvas.drawText(lines[li], labelsOffset, y2, mPaintLabel); + } + } + } + + /** + * draws the vertical steps + * horizontal lines and vertical labels + * + * @param canvas canvas + */ + protected void drawVerticalSteps(Canvas canvas) { + // draw vertical steps (horizontal lines and vertical labels) + float startLeft = mGraphView.getGraphContentLeft(); + mPaintLabel.setColor(getVerticalLabelsColor()); + mPaintLabel.setTextAlign(getVerticalLabelsAlign()); + for (Map.Entry e : mStepsVertical.entrySet()) { + // draw line + if (mStyles.highlightZeroLines) { + if (e.getValue() == 0d) { + mPaintLine.setStrokeWidth(5); + } else { + mPaintLine.setStrokeWidth(0); + } + } + if (mStyles.gridStyle.drawHorizontal()) { + canvas.drawLine(startLeft, e.getKey(), startLeft + mGraphView.getGraphContentWidth(), e.getKey(), mPaintLine); + } + + // draw label + if (isVerticalLabelsVisible()) { + int labelsWidth = mLabelVerticalWidth; + int labelsOffset = 0; + if (getVerticalLabelsAlign() == Paint.Align.RIGHT) { + labelsOffset = labelsWidth; + labelsOffset -= mStyles.labelsSpace; + } else if (getVerticalLabelsAlign() == Paint.Align.CENTER) { + labelsOffset = labelsWidth / 2; + } + labelsOffset += mStyles.padding + getVerticalAxisTitleWidth(); + + float y = e.getKey(); + + String label = mLabelFormatter.formatLabel(e.getValue(), false); + if (label == null) { + label = ""; + } + String[] lines = label.split("\n"); + y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; + canvas.drawText(lines[li], labelsOffset, y2, mPaintLabel); + } + } + } + } + + /** + * this will do rounding to generate + * nice human-readable bounds. + * + * @param in the raw value that is to be rounded + * @param roundAlwaysUp true if it shall always round up (ceil) + * @return the rounded number + */ + protected double humanRound(double in, boolean roundAlwaysUp) { + // round-up to 1-steps, 2-steps or 5-steps + int ten = 0; + while (in >= 10d) { + in /= 10d; + ten++; + } + while (in < 1d) { + in *= 10d; + ten--; + } + if (roundAlwaysUp) { + if (in == 1d) { + } else if (in <= 2d) { + in = 2d; + } else if (in <= 5d) { + in = 5d; + } else if (in < 10d) { + in = 10d; + } + } else { // always round down + if (in == 1d) { + } else if (in <= 4.9d) { + in = 2d; + } else if (in <= 9.9d) { + in = 5d; + } else if (in < 15d) { + in = 10d; + } + } + return in * Math.pow(10d, ten); + } + + /** + * @return the wrapped styles + */ + public Styles getStyles() { + return mStyles; + } + + /** + * @return the vertical label width + * 0 if there are no vertical labels + */ + public int getLabelVerticalWidth() { + return mLabelVerticalWidth == null || !isVerticalLabelsVisible() ? 0 : mLabelVerticalWidth; + } + + /** + * sets a manual and fixed with of the space for + * the vertical labels. This will prevent GraphView to + * calculate the width automatically. + * + * @param width the width of the space for the vertical labels. + * Use null to let GraphView automatically calculate the width. + */ + public void setLabelVerticalWidth(Integer width) { + mLabelVerticalWidth = width; + mLabelVerticalWidthFixed = mLabelVerticalWidth != null; + } + + /** + * @return the horizontal label height + * 0 if there are no horizontal labels + */ + public int getLabelHorizontalHeight() { + return mLabelHorizontalHeight == null || !isHorizontalLabelsVisible() ? 0 : mLabelHorizontalHeight; + } + + /** + * sets a manual and fixed height of the space for + * the horizontal labels. This will prevent GraphView to + * calculate the height automatically. + * + * @param height the height of the space for the horizontal labels. + * Use null to let GraphView automatically calculate the height. + */ + public void setLabelHorizontalHeight(Integer height) { + mLabelHorizontalHeight = height; + mLabelHorizontalHeightFixed = mLabelHorizontalHeight != null; + } + + /** + * @return the grid line color + */ + public int getGridColor() { + return mStyles.gridColor; + } + + /** + * @return whether the line at 0 are highlighted + */ + public boolean isHighlightZeroLines() { + return mStyles.highlightZeroLines; + } + + /** + * @return the padding around the grid and labels + */ + public int getPadding() { + return mStyles.padding; + } + + /** + * @param textSize the general text size of the axis titles. + * can be overwritten with {@link #setVerticalAxisTitleTextSize(float)} + * and {@link #setHorizontalAxisTitleTextSize(float)} + */ + public void setTextSize(float textSize) { + mStyles.textSize = textSize; + } + + /** + * @param verticalLabelsAlign the alignment of the vertical labels + */ + public void setVerticalLabelsAlign(Paint.Align verticalLabelsAlign) { + mStyles.verticalLabelsAlign = verticalLabelsAlign; + } + + /** + * @param verticalLabelsColor the color of the vertical labels + */ + public void setVerticalLabelsColor(int verticalLabelsColor) { + mStyles.verticalLabelsColor = verticalLabelsColor; + } + + /** + * @param horizontalLabelsColor the color of the horizontal labels + */ + public void setHorizontalLabelsColor(int horizontalLabelsColor) { + mStyles.horizontalLabelsColor = horizontalLabelsColor; + } + + /** + * @param gridColor the color of the grid lines + */ + public void setGridColor(int gridColor) { + mStyles.gridColor = gridColor; + } + + /** + * @param highlightZeroLines flag whether the zero-lines (vertical+ + * horizontal) shall be highlighted + */ + public void setHighlightZeroLines(boolean highlightZeroLines) { + mStyles.highlightZeroLines = highlightZeroLines; + } + + /** + * @param padding the padding around the graph and labels + */ + public void setPadding(int padding) { + mStyles.padding = padding; + } + + /** + * @return the label formatter, that converts + * the raw numbers to strings + */ + public LabelFormatter getLabelFormatter() { + return mLabelFormatter; + } + + /** + * @param mLabelFormatter the label formatter, that converts + * the raw numbers to strings + */ + public void setLabelFormatter(LabelFormatter mLabelFormatter) { + this.mLabelFormatter = mLabelFormatter; + mLabelFormatter.setViewport(mGraphView.getViewport()); + } + + /** + * @return the title of the horizontal axis + */ + public String getHorizontalAxisTitle() { + return mHorizontalAxisTitle; + } + + /** + * @param mHorizontalAxisTitle the title of the horizontal axis + */ + public void setHorizontalAxisTitle(String mHorizontalAxisTitle) { + this.mHorizontalAxisTitle = mHorizontalAxisTitle; + } + + /** + * @return the title of the vertical axis + */ + public String getVerticalAxisTitle() { + return mVerticalAxisTitle; + } + + /** + * @param mVerticalAxisTitle the title of the vertical axis + */ + public void setVerticalAxisTitle(String mVerticalAxisTitle) { + this.mVerticalAxisTitle = mVerticalAxisTitle; + } + + /** + * @return font size of the vertical axis title + */ + public float getVerticalAxisTitleTextSize() { + return mStyles.verticalAxisTitleTextSize; + } + + /** + * @param verticalAxisTitleTextSize font size of the vertical axis title + */ + public void setVerticalAxisTitleTextSize(float verticalAxisTitleTextSize) { + mStyles.verticalAxisTitleTextSize = verticalAxisTitleTextSize; + } + + /** + * @return font color of the vertical axis title + */ + public int getVerticalAxisTitleColor() { + return mStyles.verticalAxisTitleColor; + } + + /** + * @param verticalAxisTitleColor font color of the vertical axis title + */ + public void setVerticalAxisTitleColor(int verticalAxisTitleColor) { + mStyles.verticalAxisTitleColor = verticalAxisTitleColor; + } + + /** + * @return font size of the horizontal axis title + */ + public float getHorizontalAxisTitleTextSize() { + return mStyles.horizontalAxisTitleTextSize; + } + + /** + * @param horizontalAxisTitleTextSize font size of the horizontal axis title + */ + public void setHorizontalAxisTitleTextSize(float horizontalAxisTitleTextSize) { + mStyles.horizontalAxisTitleTextSize = horizontalAxisTitleTextSize; + } + + /** + * @return font color of the horizontal axis title + */ + public int getHorizontalAxisTitleColor() { + return mStyles.horizontalAxisTitleColor; + } + + /** + * @param horizontalAxisTitleColor font color of the horizontal axis title + */ + public void setHorizontalAxisTitleColor(int horizontalAxisTitleColor) { + mStyles.horizontalAxisTitleColor = horizontalAxisTitleColor; + } + + /** + * @return the alignment of the labels on the right side + */ + public Paint.Align getVerticalLabelsSecondScaleAlign() { + return mStyles.verticalLabelsSecondScaleAlign; + } + + /** + * @param verticalLabelsSecondScaleAlign the alignment of the labels on the right side + */ + public void setVerticalLabelsSecondScaleAlign(Paint.Align verticalLabelsSecondScaleAlign) { + mStyles.verticalLabelsSecondScaleAlign = verticalLabelsSecondScaleAlign; + } + + /** + * @return the color of the labels on the right side + */ + public int getVerticalLabelsSecondScaleColor() { + return mStyles.verticalLabelsSecondScaleColor; + } + + /** + * @param verticalLabelsSecondScaleColor the color of the labels on the right side + */ + public void setVerticalLabelsSecondScaleColor(int verticalLabelsSecondScaleColor) { + mStyles.verticalLabelsSecondScaleColor = verticalLabelsSecondScaleColor; + } + + /** + * @return the width of the vertical labels + * of the second scale + */ + public int getLabelVerticalSecondScaleWidth() { + return mLabelVerticalSecondScaleWidth==null?0:mLabelVerticalSecondScaleWidth; + } + + /** + * @return flag whether the horizontal labels are + * visible + */ + public boolean isHorizontalLabelsVisible() { + return mStyles.horizontalLabelsVisible; + } + + /** + * @param horizontalTitleVisible flag whether the horizontal labels are + * visible + */ + public void setHorizontalLabelsVisible(boolean horizontalTitleVisible) { + mStyles.horizontalLabelsVisible = horizontalTitleVisible; + } + + /** + * @return flag whether the vertical labels are + * visible + */ + public boolean isVerticalLabelsVisible() { + return mStyles.verticalLabelsVisible; + } + + /** + * @param verticalTitleVisible flag whether the vertical labels are + * visible + */ + public void setVerticalLabelsVisible(boolean verticalTitleVisible) { + mStyles.verticalLabelsVisible = verticalTitleVisible; + } + + /** + * @return count of the vertical labels, that + * will be shown at one time. + */ + public int getNumVerticalLabels() { + return mNumVerticalLabels; + } + + /** + * @param mNumVerticalLabels count of the vertical labels, that + * will be shown at one time. + */ + public void setNumVerticalLabels(int mNumVerticalLabels) { + this.mNumVerticalLabels = mNumVerticalLabels; + } + + /** + * @return count of the horizontal labels, that + * will be shown at one time. + */ + public int getNumHorizontalLabels() { + return mNumHorizontalLabels; + } + + /** + * @param mNumHorizontalLabels count of the horizontal labels, that + * will be shown at one time. + */ + public void setNumHorizontalLabels(int mNumHorizontalLabels) { + this.mNumHorizontalLabels = mNumHorizontalLabels; + } + + /** + * @return the grid style + */ + public GridStyle getGridStyle() { + return mStyles.gridStyle; + } + + /** + * Define which grid lines shall be drawn + * + * @param gridStyle the grid style + */ + public void setGridStyle(GridStyle gridStyle) { + mStyles.gridStyle = gridStyle; + } + + /** + * @return the space between the labels text and the graph content + */ + public int getLabelsSpace() { + return mStyles.labelsSpace; + } + + /** + * the space between the labels text and the graph content + * + * @param labelsSpace the space between the labels text and the graph content + */ + public void setLabelsSpace(int labelsSpace) { + mStyles.labelsSpace = labelsSpace; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java new file mode 100644 index 0000000000..80aad2990a --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/LabelFormatter.java @@ -0,0 +1,54 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +/** + * Interface to use as label formatter. + * Implement this in order to generate + * your own labels format. + * It is recommended to override {@link com.jjoe64.graphview.DefaultLabelFormatter}. + * + * @author jjoe64 + */ +public interface LabelFormatter { + /** + * converts a raw number as input to + * a formatted string for the label. + * + * @param value raw input number + * @param isValueX true if it is a value for the x axis + * false if it is a value for the y axis + * @return the formatted number as string + */ + public String formatLabel(double value, boolean isValueX); + + /** + * will be called in order to have a + * reference to the current viewport. + * This is useful if you need the bounds + * to generate your labels. + * You store this viewport in as member variable + * and access it e.g. in the {@link #formatLabel(double, boolean)} + * method. + * + * @param viewport the used viewport + */ + public void setViewport(Viewport viewport); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java b/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java new file mode 100644 index 0000000000..db901577f7 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/LegendRenderer.java @@ -0,0 +1,394 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.RectF; +import android.util.TypedValue; + +import com.jjoe64.graphview.series.Series; + +import java.util.ArrayList; +import java.util.List; + +/** + * The default renderer for the legend box + * + * @author jjoe64 + */ +public class LegendRenderer { + /** + * wrapped styles regarding to the + * legend + */ + private final class Styles { + float textSize; + int spacing; + int padding; + int width; + int backgroundColor; + int textColor; + int margin; + LegendAlign align; + Point fixedPosition; + } + + /** + * alignment of the legend + */ + public enum LegendAlign { + /** + * top right corner + */ + TOP, + + /** + * middle right + */ + MIDDLE, + + /** + * bottom right corner + */ + BOTTOM + } + + /** + * wrapped styles + */ + private Styles mStyles; + + /** + * reference to the graphview + */ + private final GraphView mGraphView; + + /** + * flag whether legend will be + * drawn + */ + private boolean mIsVisible; + + /** + * paint for the drawing + */ + private Paint mPaint; + + /** + * cached legend width + * this will be filled in the drawing. + * Can be cleared via {@link #resetStyles()} + */ + private int cachedLegendWidth; + + /** + * creates legend renderer + * + * @param graphView regarding graphview + */ + public LegendRenderer(GraphView graphView) { + mGraphView = graphView; + mIsVisible = false; + mPaint = new Paint(); + mPaint.setTextAlign(Paint.Align.LEFT); + mStyles = new Styles(); + cachedLegendWidth = 0; + resetStyles(); + } + + /** + * resets the styles to the defaults + * and clears the legend width cache + */ + public void resetStyles() { + mStyles.align = LegendAlign.MIDDLE; + mStyles.textSize = mGraphView.getGridLabelRenderer().getTextSize(); + mStyles.spacing = (int) (mStyles.textSize / 5); + mStyles.padding = (int) (mStyles.textSize / 2); + mStyles.width = 0; + mStyles.backgroundColor = Color.argb(180, 100, 100, 100); + mStyles.margin = (int) (mStyles.textSize / 5); + + // get matching styles from theme + TypedValue typedValue = new TypedValue(); + mGraphView.getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceSmall, typedValue, true); + + int color1; + + try { + TypedArray array = mGraphView.getContext().obtainStyledAttributes(typedValue.data, new int[]{ + android.R.attr.textColorPrimary}); + color1 = array.getColor(0, Color.BLACK); + array.recycle(); + } catch (Exception e) { + color1 = Color.BLACK; + } + + mStyles.textColor = color1; + + cachedLegendWidth = 0; + } + + /** + * draws the legend if it is visible + * + * @param canvas canvas + * @see #setVisible(boolean) + */ + public void draw(Canvas canvas) { + if (!mIsVisible) return; + + mPaint.setTextSize(mStyles.textSize); + + int shapeSize = (int) (mStyles.textSize*0.8d); + + List allSeries = new ArrayList(); + allSeries.addAll(mGraphView.getSeries()); + if (mGraphView.mSecondScale != null) { + allSeries.addAll(mGraphView.getSecondScale().getSeries()); + } + + // width + int legendWidth = mStyles.width; + if (legendWidth == 0) { + // auto + legendWidth = cachedLegendWidth; + + if (legendWidth == 0) { + Rect textBounds = new Rect(); + for (Series s : allSeries) { + if (s.getTitle() != null) { + mPaint.getTextBounds(s.getTitle(), 0, s.getTitle().length(), textBounds); + legendWidth = Math.max(legendWidth, textBounds.width()); + } + } + if (legendWidth == 0) legendWidth = 1; + + // add shape size + legendWidth += shapeSize+mStyles.padding*2 + mStyles.spacing; + cachedLegendWidth = legendWidth; + } + } + + // rect + float legendHeight = (mStyles.textSize+mStyles.spacing)*allSeries.size() -mStyles.spacing; + float lLeft; + float lTop; + if (mStyles.fixedPosition != null) { + // use fied position + lLeft = mGraphView.getGraphContentLeft() + mStyles.margin + mStyles.fixedPosition.x; + lTop = mGraphView.getGraphContentTop() + mStyles.margin + mStyles.fixedPosition.y; + } else { + lLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth() - legendWidth - mStyles.margin; + switch (mStyles.align) { + case TOP: + lTop = mGraphView.getGraphContentTop() + mStyles.margin; + break; + case MIDDLE: + lTop = mGraphView.getHeight() / 2 - legendHeight / 2; + break; + default: + lTop = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - mStyles.margin - legendHeight - 2*mStyles.padding; + } + } + float lRight = lLeft+legendWidth; + float lBottom = lTop+legendHeight+2*mStyles.padding; + mPaint.setColor(mStyles.backgroundColor); + canvas.drawRoundRect(new RectF(lLeft, lTop, lRight, lBottom), 8, 8, mPaint); + + int i=0; + for (Series series : allSeries) { + mPaint.setColor(series.getColor()); + canvas.drawRect(new RectF(lLeft+mStyles.padding, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing)), lLeft+mStyles.padding+shapeSize, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing))+shapeSize), mPaint); + if (series.getTitle() != null) { + mPaint.setColor(mStyles.textColor); + canvas.drawText(series.getTitle(), lLeft+mStyles.padding+shapeSize+mStyles.spacing, lTop+mStyles.padding+mStyles.textSize+(i*(mStyles.textSize+mStyles.spacing)), mPaint); + } + i++; + } + } + + /** + * @return the flag whether the legend will be drawn + */ + public boolean isVisible() { + return mIsVisible; + } + + /** + * set the flag whether the legend will be drawn + * + * @param mIsVisible visible flag + */ + public void setVisible(boolean mIsVisible) { + this.mIsVisible = mIsVisible; + } + + /** + * @return font size + */ + public float getTextSize() { + return mStyles.textSize; + } + + /** + * sets the font size. this will clear + * the internal legend width cache + * + * @param textSize font size + */ + public void setTextSize(float textSize) { + mStyles.textSize = textSize; + cachedLegendWidth = 0; + } + + /** + * @return the spacing between the text lines + */ + public int getSpacing() { + return mStyles.spacing; + } + + /** + * set the spacing between the text lines + * + * @param spacing the spacing between the text lines + */ + public void setSpacing(int spacing) { + mStyles.spacing = spacing; + } + + /** + * padding is the space between the edge of the box + * and the beginning of the text + * + * @return padding from edge to text + */ + public int getPadding() { + return mStyles.padding; + } + + /** + * padding is the space between the edge of the box + * and the beginning of the text + * + * @param padding padding from edge to text + */ + public void setPadding(int padding) { + mStyles.padding = padding; + } + + /** + * the width of the box exclusive padding + * + * @return the width of the box + * 0 => auto + */ + public int getWidth() { + return mStyles.width; + } + + /** + * the width of the box exclusive padding + * @param width the width of the box exclusive padding + * 0 => auto + */ + public void setWidth(int width) { + mStyles.width = width; + } + + /** + * @return background color of the box + * it is recommended to use semi-transparent + * color. + */ + public int getBackgroundColor() { + return mStyles.backgroundColor; + } + + /** + * @param backgroundColor background color of the box + * it is recommended to use semi-transparent + * color. + */ + public void setBackgroundColor(int backgroundColor) { + mStyles.backgroundColor = backgroundColor; + } + + /** + * @return margin from the edge of the box + * to the corner of the graphview + */ + public int getMargin() { + return mStyles.margin; + } + + /** + * @param margin margin from the edge of the box + * to the corner of the graphview + */ + public void setMargin(int margin) { + mStyles.margin = margin; + } + + /** + * @return the vertical alignment of the box + */ + public LegendAlign getAlign() { + return mStyles.align; + } + + /** + * @param align the vertical alignment of the box + */ + public void setAlign(LegendAlign align) { + mStyles.align = align; + } + + /** + * @return font color + */ + public int getTextColor() { + return mStyles.textColor; + } + + /** + * @param textColor font color + */ + public void setTextColor(int textColor) { + mStyles.textColor = textColor; + } + + /** + * Use fixed coordinates to position the legend. + * This will override the align setting. + * + * @param x x coordinates in pixel + * @param y y coordinates in pixel + */ + public void setFixedPosition(int x, int y) { + mStyles.fixedPosition = new Point(x, y); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java b/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java new file mode 100644 index 0000000000..1fff8ee8a9 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/SecondScale.java @@ -0,0 +1,165 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import com.jjoe64.graphview.series.Series; + +import java.util.ArrayList; +import java.util.List; + +/** + * To be used to plot a second scale + * on the graph. + * The second scale has always to have + * manual bounds. + * Use {@link #setMinY(double)} and {@link #setMaxY(double)} + * to set them. + * The second scale has it's own array of series. + * + * @author jjoe64 + */ +public class SecondScale { + /** + * reference to the viewport of the graph + */ + protected final Viewport mViewport; + + /** + * array of series for the second + * scale + */ + protected List mSeries; + + /** + * flag whether the y axis bounds + * are manual. + * For the current version this is always + * true. + */ + private boolean mYAxisBoundsManual = true; + + /** + * min y value for the y axis bounds + */ + private double mMinY; + + /** + * max y value for the y axis bounds + */ + private double mMaxY; + + /** + * label formatter for the y labels + * on the right side + */ + protected LabelFormatter mLabelFormatter; + + /** + * creates the second scale. + * normally you do not call this contructor. + * Use {@link com.jjoe64.graphview.GraphView#getSecondScale()} + * in order to get the instance. + */ + SecondScale(Viewport viewport) { + mViewport = viewport; + mSeries = new ArrayList(); + mLabelFormatter = new DefaultLabelFormatter(); + mLabelFormatter.setViewport(mViewport); + } + + /** + * add a series to the second scale. + * Don't add this series also to the GraphView + * object. + * + * @param s the series + */ + public void addSeries(Series s) { + mSeries.add(s); + } + + //public void setYAxisBoundsManual(boolean mYAxisBoundsManual) { + // this.mYAxisBoundsManual = mYAxisBoundsManual; + //} + + /** + * set the min y bounds + * + * @param d min y value + */ + public void setMinY(double d) { + mMinY = d; + } + + /** + * set the max y bounds + * + * @param d max y value + */ + public void setMaxY(double d) { + mMaxY = d; + } + + /** + * @return the series of the second scale + */ + public List getSeries() { + return mSeries; + } + + /** + * @return min y bound + */ + public double getMinY() { + return mMinY; + } + + /** + * @return max y bound + */ + public double getMaxY() { + return mMaxY; + } + + /** + * @return always true for the current implementation + */ + public boolean isYAxisBoundsManual() { + return mYAxisBoundsManual; + } + + /** + * @return label formatter for the y labels on the right side + */ + public LabelFormatter getLabelFormatter() { + return mLabelFormatter; + } + + /** + * Set a custom label formatter that is used + * for the y labels on the right side. + * + * @param formatter label formatter for the y labels + */ + public void setLabelFormatter(LabelFormatter formatter) { + mLabelFormatter = formatter; + mLabelFormatter.setViewport(mViewport); + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java b/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java new file mode 100644 index 0000000000..a02f22a21e --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/ValueDependentColor.java @@ -0,0 +1,41 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ + +package com.jjoe64.graphview; + +import com.jjoe64.graphview.series.DataPointInterface; + +/** + * you can change the color depending on the value. + * takes only effect for BarGraphSeries. + * + * @see com.jjoe64.graphview.series.BarGraphSeries#setValueDependentColor(ValueDependentColor) + */ +public interface ValueDependentColor { + /** + * this is called when a bar is about to draw + * and the color is be loaded. + * + * @param data the current input value + * @return the color that the bar should be drawn with + * Generate the int via the android.graphics.Color class. + */ + public int get(T data); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/Viewport.java b/graphview/src/main/java/com/jjoe64/graphview/Viewport.java new file mode 100644 index 0000000000..6a92f30430 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/Viewport.java @@ -0,0 +1,1005 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.widget.OverScroller; + +import androidx.core.view.ViewCompat; +import androidx.core.widget.EdgeEffectCompat; + +import com.jjoe64.graphview.compat.OverScrollerCompat; +import com.jjoe64.graphview.series.DataPointInterface; +import com.jjoe64.graphview.series.Series; + +import java.util.Iterator; +import java.util.List; + +/** + * This is the default implementation for the viewport. + * This implementation so for a normal viewport + * where there is a horizontal x-axis and a + * vertical y-axis. + * This viewport is compatible with + * - {@link com.jjoe64.graphview.series.BarGraphSeries} + * - {@link com.jjoe64.graphview.series.LineGraphSeries} + * - {@link com.jjoe64.graphview.series.PointsGraphSeries} + * + * @author jjoe64 + */ +@SuppressWarnings("ALL") +public class Viewport { + /** + * listener for the scale gesture + */ + private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener + = new ScaleGestureDetector.OnScaleGestureListener() { + /** + * called by android + * @param detector detector + * @return always true + */ + @Override + public boolean onScale(ScaleGestureDetector detector) { + float viewportWidth = mCurrentViewport.width(); + float center = mCurrentViewport.left + viewportWidth / 2; + viewportWidth /= detector.getScaleFactor(); + mCurrentViewport.left = center - viewportWidth / 2; + mCurrentViewport.right = mCurrentViewport.left+viewportWidth; + + // viewportStart must not be < minX + float minX = (float) getMinX(true); + if (mCurrentViewport.left < minX) { + mCurrentViewport.left = minX; + mCurrentViewport.right = mCurrentViewport.left+viewportWidth; + } + + // viewportStart + viewportSize must not be > maxX + float maxX = (float) getMaxX(true); + if (viewportWidth == 0) { + mCurrentViewport.right = maxX; + } + double overlap = mCurrentViewport.left + viewportWidth - maxX; + if (overlap > 0) { + // scroll left + if (mCurrentViewport.left-overlap > minX) { + mCurrentViewport.left -= overlap; + mCurrentViewport.right = mCurrentViewport.left+viewportWidth; + } else { + // maximal scale + mCurrentViewport.left = minX; + mCurrentViewport.right = maxX; + } + } + + // adjust viewport, labels, etc. + mGraphView.onDataChanged(true, false); + + ViewCompat.postInvalidateOnAnimation(mGraphView); + + return true; + } + + /** + * called when scaling begins + * + * @param detector detector + * @return true if it is scalable + */ + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + if (mIsScalable) { + mScalingBeginWidth = mCurrentViewport.width(); + mScalingBeginLeft = mCurrentViewport.left; + mScalingActive = true; + return true; + } else { + return false; + } + } + + /** + * called when sacling ends + * This will re-adjust the viewport. + * + * @param detector detector + */ + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + mScalingActive = false; + + // re-adjust + mXAxisBoundsStatus = AxisBoundsStatus.READJUST_AFTER_SCALE; + + mScrollingReferenceX = Float.NaN; + + // adjust viewport, labels, etc. + mGraphView.onDataChanged(true, false); + + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + }; + + /** + * simple gesture listener to track scroll events + */ + private final GestureDetector.SimpleOnGestureListener mGestureListener + = new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDown(MotionEvent e) { + if (!mIsScrollable || mScalingActive) return false; + + // Initiates the decay phase of any active edge effects. + releaseEdgeEffects(); + mScrollerStartViewport.set(mCurrentViewport); + // Aborts any active scroll animations and invalidates. + mScroller.forceFinished(true); + ViewCompat.postInvalidateOnAnimation(mGraphView); + return true; + } + + @Override + @SuppressWarnings({"deprecation"}) + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if (!mIsScrollable || mScalingActive) return false; + + if (Float.isNaN(mScrollingReferenceX)) { + mScrollingReferenceX = mCurrentViewport.left; + } + + // Scrolling uses math based on the viewport (as opposed to math using pixels). + /** + * Pixel offset is the offset in screen pixels, while viewport offset is the + * offset within the current viewport. For additional information on surface sizes + * and pixel offsets, see the docs for {@link computeScrollSurfaceSize()}. For + * additional information about the viewport, see the comments for + * {@link mCurrentViewport}. + */ + float viewportOffsetX = distanceX * mCurrentViewport.width() / mGraphView.getGraphContentWidth(); + float viewportOffsetY = -distanceY * mCurrentViewport.height() / mGraphView.getGraphContentHeight(); + + int completeWidth = (int)((mCompleteRange.width()/mCurrentViewport.width()) * (float) mGraphView.getGraphContentWidth()); + int completeHeight = (int)((mCompleteRange.height()/mCurrentViewport.height()) * (float) mGraphView.getGraphContentHeight()); + + int scrolledX = (int) (completeWidth + * (mCurrentViewport.left + viewportOffsetX - mCompleteRange.left) + / mCompleteRange.width()); + int scrolledY = (int) (completeHeight + * (mCompleteRange.bottom - mCurrentViewport.bottom - viewportOffsetY) + / mCompleteRange.height()); + boolean canScrollX = mCurrentViewport.left > mCompleteRange.left + || mCurrentViewport.right < mCompleteRange.right; + boolean canScrollY = mCurrentViewport.bottom > mCompleteRange.bottom + || mCurrentViewport.top < mCompleteRange.top; + + if (canScrollX) { + if (viewportOffsetX < 0) { + float tooMuch = mCurrentViewport.left+viewportOffsetX - mCompleteRange.left; + if (tooMuch < 0) { + viewportOffsetX -= tooMuch; + } + } else { + float tooMuch = mCurrentViewport.right+viewportOffsetX - mCompleteRange.right; + if (tooMuch > 0) { + viewportOffsetX -= tooMuch; + } + } + mCurrentViewport.left += viewportOffsetX; + mCurrentViewport.right += viewportOffsetX; + } + if (canScrollY) { + //mCurrentViewport.top += viewportOffsetX; + //mCurrentViewport.bottom -= viewportOffsetX; + } + + if (canScrollX && scrolledX < 0) { + mEdgeEffectLeft.onPull(scrolledX / (float) mGraphView.getGraphContentWidth()); + mEdgeEffectLeftActive = true; + } + if (canScrollY && scrolledY < 0) { + mEdgeEffectBottom.onPull(scrolledY / (float) mGraphView.getGraphContentHeight()); + mEdgeEffectBottomActive = true; + } + if (canScrollX && scrolledX > completeWidth - mGraphView.getGraphContentWidth()) { + mEdgeEffectRight.onPull((scrolledX - completeWidth + mGraphView.getGraphContentWidth()) + / (float) mGraphView.getGraphContentWidth()); + mEdgeEffectRightActive = true; + } + //if (canScrollY && scrolledY > mSurfaceSizeBuffer.y - mContentRect.height()) { + // mEdgeEffectTop.onPull((scrolledY - mSurfaceSizeBuffer.y + mContentRect.height()) + // / (float) mContentRect.height()); + // mEdgeEffectTopActive = true; + //} + + // adjust viewport, labels, etc. + mGraphView.onDataChanged(true, false); + + ViewCompat.postInvalidateOnAnimation(mGraphView); + return true; + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, + float velocityX, float velocityY) { + //fling((int) -velocityX, (int) -velocityY); + return true; + } + }; + + /** + * the state of the axis bounds + */ + public enum AxisBoundsStatus { + /** + * initial means that the bounds gets + * auto adjusted if they are not manual. + * After adjusting the status comes to + * #AUTO_ADJUSTED. + */ + INITIAL, + + /** + * after the bounds got auto-adjusted, + * this status will set. + */ + AUTO_ADJUSTED, + + /** + * this flags the status that a scale was + * done and the bounds has to be auto-adjusted + * afterwards. + */ + READJUST_AFTER_SCALE, + + /** + * means that the bounds are fix (manually) and + * are not to be auto-adjusted. + */ + FIX + } + + /** + * paint to draw background + */ + private Paint mPaint; + + /** + * reference to the graphview + */ + private final GraphView mGraphView; + + /** + * this holds the current visible viewport + * left = minX, right = maxX + * bottom = minY, top = maxY + */ + protected RectF mCurrentViewport = new RectF(); + + /** + * this holds the whole range of the data + * left = minX, right = maxX + * bottom = minY, top = maxY + */ + protected RectF mCompleteRange = new RectF(); + + /** + * flag whether scaling is currently active + */ + protected boolean mScalingActive; + + /** + * stores the width of the viewport at the time + * of beginning of the scaling. + */ + protected float mScalingBeginWidth; + + /** + * stores the viewport left at the time of + * beginning of the scaling. + */ + protected float mScalingBeginLeft; + + /** + * flag whether the viewport is scrollable + */ + private boolean mIsScrollable; + + /** + * flag whether the viewport is scalable + */ + private boolean mIsScalable; + + /** + * gesture detector to detect scrolling + */ + protected GestureDetector mGestureDetector; + + /** + * detect scaling + */ + protected ScaleGestureDetector mScaleGestureDetector; + + /** + * not used - for fling + */ + protected OverScroller mScroller; + + /** + * not used + */ + private EdgeEffectCompat mEdgeEffectTop; + + /** + * not used + */ + private EdgeEffectCompat mEdgeEffectBottom; + + /** + * glow effect when scrolling left + */ + private EdgeEffectCompat mEdgeEffectLeft; + + /** + * glow effect when scrolling right + */ + private EdgeEffectCompat mEdgeEffectRight; + + /** + * not used + */ + private boolean mEdgeEffectTopActive; + + /** + * not used + */ + private boolean mEdgeEffectBottomActive; + + /** + * glow effect when scrolling left + */ + private boolean mEdgeEffectLeftActive; + + /** + * glow effect when scrolling right + */ + private boolean mEdgeEffectRightActive; + + /** + * stores the viewport at the time of + * the beginning of scaling + */ + private RectF mScrollerStartViewport = new RectF(); + + /** + * stores the viewport left value at the + * time of beginning of the scrolling + */ + protected float mScrollingReferenceX = Float.NaN; + + /** + * state of the x axis + */ + private AxisBoundsStatus mXAxisBoundsStatus; + + /** + * state of the y axis + */ + private AxisBoundsStatus mYAxisBoundsStatus; + + /** + * flag whether the x axis bounds are manual + */ + private boolean mXAxisBoundsManual; + + /** + * flag whether the y axis bounds are manual + */ + private boolean mYAxisBoundsManual; + + /** + * background color of the viewport area + * it is recommended to use a semi-transparent color + */ + private int mBackgroundColor; + + /** + * creates the viewport + * + * @param graphView graphview + */ + @SuppressWarnings({"deprecation"}) + Viewport(GraphView graphView) { + mScroller = new OverScroller(graphView.getContext()); + mEdgeEffectTop = new EdgeEffectCompat(graphView.getContext()); + mEdgeEffectBottom = new EdgeEffectCompat(graphView.getContext()); + mEdgeEffectLeft = new EdgeEffectCompat(graphView.getContext()); + mEdgeEffectRight = new EdgeEffectCompat(graphView.getContext()); + mGestureDetector = new GestureDetector(graphView.getContext(), mGestureListener); + mScaleGestureDetector = new ScaleGestureDetector(graphView.getContext(), mScaleGestureListener); + + mGraphView = graphView; + mXAxisBoundsStatus = AxisBoundsStatus.INITIAL; + mYAxisBoundsStatus = AxisBoundsStatus.INITIAL; + mBackgroundColor = Color.TRANSPARENT; + mPaint = new Paint(); + } + + /** + * will be called on a touch event. + * needed to use scaling and scrolling + * + * @param event + * @return true if it was consumed + */ + public boolean onTouchEvent(MotionEvent event) { + boolean b = mScaleGestureDetector.onTouchEvent(event); + b |= mGestureDetector.onTouchEvent(event); + return b; + } + + /** + * change the state of the x axis. + * normally you do not call this method. + * If you want to set manual axis use + * {@link #setXAxisBoundsManual(boolean)} and {@link #setYAxisBoundsManual(boolean)} + * + * @param s state + */ + public void setXAxisBoundsStatus(AxisBoundsStatus s) { + mXAxisBoundsStatus = s; + } + + /** + * change the state of the y axis. + * normally you do not call this method. + * If you want to set manual axis use + * {@link #setXAxisBoundsManual(boolean)} and {@link #setYAxisBoundsManual(boolean)} + * + * @param s state + */ + public void setYAxisBoundsStatus(AxisBoundsStatus s) { + mYAxisBoundsStatus = s; + } + + /** + * @return whether the viewport is scrollable + */ + public boolean isScrollable() { + return mIsScrollable; + } + + /** + * @param mIsScrollable whether is viewport is scrollable + */ + public void setScrollable(boolean mIsScrollable) { + this.mIsScrollable = mIsScrollable; + } + + /** + * @return the x axis state + */ + public AxisBoundsStatus getXAxisBoundsStatus() { + return mXAxisBoundsStatus; + } + + /** + * @return the y axis state + */ + public AxisBoundsStatus getYAxisBoundsStatus() { + return mYAxisBoundsStatus; + } + + /** + * caches the complete range (minX, maxX, minY, maxY) + * by iterating all series and all datapoints and + * stores it into #mCompleteRange + */ + @SuppressWarnings({"deprecation"}) + public void calcCompleteRange() { + List series = mGraphView.getSeries(); + mCompleteRange.set(0, 0, 0, 0); + if (!series.isEmpty() && !series.get(0).isEmpty()) { + double d = series.get(0).getLowestValueX(); + for (Series s : series) { + if (!s.isEmpty() && d > s.getLowestValueX()) { + d = s.getLowestValueX(); + } + } + mCompleteRange.left = (float) d; + + d = series.get(0).getHighestValueX(); + for (Series s : series) { + if (!s.isEmpty() && d < s.getHighestValueX()) { + d = s.getHighestValueX(); + } + } + mCompleteRange.right = (float) d; + + d = series.get(0).getLowestValueY(); + for (Series s : series) { + if (!s.isEmpty() && d > s.getLowestValueY()) { + d = s.getLowestValueY(); + } + } + mCompleteRange.bottom = (float) d; + + d = series.get(0).getHighestValueY(); + for (Series s : series) { + if (!s.isEmpty() && d < s.getHighestValueY()) { + d = s.getHighestValueY(); + } + } + mCompleteRange.top = (float) d; + } + + // calc current viewport bounds + if (mYAxisBoundsStatus == AxisBoundsStatus.AUTO_ADJUSTED) { + mYAxisBoundsStatus = AxisBoundsStatus.INITIAL; + } + if (mYAxisBoundsStatus == AxisBoundsStatus.INITIAL) { + mCurrentViewport.top = mCompleteRange.top; + mCurrentViewport.bottom = mCompleteRange.bottom; + } + + if (mXAxisBoundsStatus == AxisBoundsStatus.AUTO_ADJUSTED) { + mXAxisBoundsStatus = AxisBoundsStatus.INITIAL; + } + if (mXAxisBoundsStatus == AxisBoundsStatus.INITIAL) { + mCurrentViewport.left = mCompleteRange.left; + mCurrentViewport.right = mCompleteRange.right; + } else if (mXAxisBoundsManual && !mYAxisBoundsManual && mCompleteRange.width() != 0) { + // get highest/lowest of current viewport + // lowest + double d = Double.MAX_VALUE; + for (Series s : series) { + @SuppressWarnings({"unchecked"}) + Iterator values = s.getValues(mCurrentViewport.left, mCurrentViewport.right); + while (values.hasNext()) { + double v = values.next().getY(); + if (d > v) { + d = v; + } + } + } + + mCurrentViewport.bottom = (float) d; + + // highest + d = Double.MIN_VALUE; + for (Series s : series) { + @SuppressWarnings({"unchecked"}) + Iterator values = s.getValues(mCurrentViewport.left, mCurrentViewport.right); + while (values.hasNext()) { + double v = values.next().getY(); + if (d < v) { + d = v; + } + } + } + mCurrentViewport.top = (float) d; + } + + // fixes blank screen when range is zero + if (mCurrentViewport.left == mCurrentViewport.right) mCurrentViewport.right++; + if (mCurrentViewport.top == mCurrentViewport.bottom) mCurrentViewport.top++; + } + + /** + * @param completeRange if true => minX of the complete range of all series + * if false => minX of the current visible viewport + * @return the min x value + */ + public double getMinX(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.left; + } else { + return (double) mCurrentViewport.left; + } + } + + /** + * @param completeRange if true => maxX of the complete range of all series + * if false => maxX of the current visible viewport + * @return the max x value + */ + public double getMaxX(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.right; + } else { + return mCurrentViewport.right; + } + } + + /** + * @param completeRange if true => minY of the complete range of all series + * if false => minY of the current visible viewport + * @return the min y value + */ + public double getMinY(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.bottom; + } else { + return mCurrentViewport.bottom; + } + } + + /** + * @param completeRange if true => maxY of the complete range of all series + * if false => maxY of the current visible viewport + * @return the max y value + */ + public double getMaxY(boolean completeRange) { + if (completeRange) { + return (double) mCompleteRange.top; + } else { + return mCurrentViewport.top; + } + } + + /** + * set the maximal y value for the current viewport. + * Make sure to set the y bounds to manual via + * {@link #setYAxisBoundsManual(boolean)} + * @param y max / highest value + */ + public void setMaxY(double y) { + mCurrentViewport.top = (float) y; + } + + /** + * set the minimal y value for the current viewport. + * Make sure to set the y bounds to manual via + * {@link #setYAxisBoundsManual(boolean)} + * @param y min / lowest value + */ + public void setMinY(double y) { + mCurrentViewport.bottom = (float) y; + } + + /** + * set the maximal x value for the current viewport. + * Make sure to set the x bounds to manual via + * {@link #setXAxisBoundsManual(boolean)} + * @param x max / highest value + */ + public void setMaxX(double x) { + mCurrentViewport.right = (float) x; + } + + /** + * set the minimal x value for the current viewport. + * Make sure to set the x bounds to manual via + * {@link #setXAxisBoundsManual(boolean)} + * @param x min / lowest value + */ + public void setMinX(double x) { + mCurrentViewport.left = (float) x; + } + + /** + * release the glowing effects + */ + @SuppressWarnings({"deprecation"}) + private void releaseEdgeEffects() { + mEdgeEffectLeftActive + = mEdgeEffectRightActive + = false; + mEdgeEffectLeft.onRelease(); + mEdgeEffectRight.onRelease(); + } + + /** + * not used currently + * + * @param velocityX + * @param velocityY + */ + private void fling(int velocityX, int velocityY) { + velocityY = 0; + releaseEdgeEffects(); + // Flings use math in pixels (as opposed to math based on the viewport). + mScrollerStartViewport.set(mCurrentViewport); + int maxX = (int)((mCurrentViewport.width()/mCompleteRange.width())*(float)mGraphView.getGraphContentWidth()) - mGraphView.getGraphContentWidth(); + int maxY = (int)((mCurrentViewport.height()/mCompleteRange.height())*(float)mGraphView.getGraphContentHeight()) - mGraphView.getGraphContentHeight(); + int startX = (int)((mCurrentViewport.left - mCompleteRange.left)/mCompleteRange.width())*maxX; + int startY = (int)((mCurrentViewport.top - mCompleteRange.top)/mCompleteRange.height())*maxY; + mScroller.forceFinished(true); + mScroller.fling( + startX, + startY, + velocityX, + velocityY, + 0, maxX, + 0, maxY, + mGraphView.getGraphContentWidth() / 2, + mGraphView.getGraphContentHeight() / 2); + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + + /** + * not used currently + */ + @SuppressWarnings({"deprecation"}) + public void computeScroll() { + if (true) return; + + boolean needsInvalidate = false; + + if (mScroller.computeScrollOffset()) { + // The scroller isn't finished, meaning a fling or programmatic pan operation is + // currently active. + + int completeWidth = (int)((mCompleteRange.width()/mCurrentViewport.width()) * (float) mGraphView.getGraphContentWidth()); + int completeHeight = (int)((mCompleteRange.height()/mCurrentViewport.height()) * (float) mGraphView.getGraphContentHeight()); + + int currX = mScroller.getCurrX(); + int currY = mScroller.getCurrY(); + + boolean canScrollX = mCurrentViewport.left > mCompleteRange.left + || mCurrentViewport.right < mCompleteRange.right; + boolean canScrollY = mCurrentViewport.bottom > mCompleteRange.bottom + || mCurrentViewport.top < mCompleteRange.top; + + if (canScrollX + && currX < 0 + && mEdgeEffectLeft.isFinished() + && !mEdgeEffectLeftActive) { + mEdgeEffectLeft.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectLeftActive = true; + needsInvalidate = true; + } else if (canScrollX + && currX > (completeWidth - mGraphView.getGraphContentWidth()) + && mEdgeEffectRight.isFinished() + && !mEdgeEffectRightActive) { + mEdgeEffectRight.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectRightActive = true; + needsInvalidate = true; + } + + if (canScrollY + && currY < 0 + && mEdgeEffectTop.isFinished() + && !mEdgeEffectTopActive) { + mEdgeEffectTop.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectTopActive = true; + needsInvalidate = true; + } else if (canScrollY + && currY > (completeHeight - mGraphView.getGraphContentHeight()) + && mEdgeEffectBottom.isFinished() + && !mEdgeEffectBottomActive) { + mEdgeEffectBottom.onAbsorb((int) OverScrollerCompat.getCurrVelocity(mScroller)); + mEdgeEffectBottomActive = true; + needsInvalidate = true; + } + + float currXRange = mCompleteRange.left + mCompleteRange.width() + * currX / completeWidth; + float currYRange = mCompleteRange.top - mCompleteRange.height() + * currY / completeHeight; + + float currWidth = mCurrentViewport.width(); + float currHeight = mCurrentViewport.height(); + mCurrentViewport.left = currXRange; + mCurrentViewport.right = currXRange + currWidth; + //mCurrentViewport.bottom = currYRange; + //mCurrentViewport.top = currYRange + currHeight; + } + + if (needsInvalidate) { + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + } + + /** + * Draws the overscroll "glow" at the four edges of the chart region, if necessary. + * + * @see EdgeEffectCompat + */ + @SuppressWarnings({"deprecation"}) + private void drawEdgeEffectsUnclipped(Canvas canvas) { + // The methods below rotate and translate the canvas as needed before drawing the glow, + // since EdgeEffectCompat always draws a top-glow at 0,0. + + boolean needsInvalidate = false; + + if (!mEdgeEffectTop.isFinished()) { + final int restoreCount = canvas.save(); + canvas.translate(mGraphView.getGraphContentLeft(), mGraphView.getGraphContentTop()); + mEdgeEffectTop.setSize(mGraphView.getGraphContentWidth(), mGraphView.getGraphContentHeight()); + if (mEdgeEffectTop.draw(canvas)) { + needsInvalidate = true; + } + canvas.restoreToCount(restoreCount); + } + + //if (!mEdgeEffectBottom.isFinished()) { + // final int restoreCount = canvas.save(); + // canvas.translate(2 * mContentRect.left - mContentRect.right, mContentRect.bottom); + // canvas.rotate(180, mContentRect.width(), 0); + // mEdgeEffectBottom.setSize(mContentRect.width(), mContentRect.height()); + // if (mEdgeEffectBottom.draw(canvas)) { + // needsInvalidate = true; + // } + // canvas.restoreToCount(restoreCount); + //} + + if (!mEdgeEffectLeft.isFinished()) { + final int restoreCount = canvas.save(); + canvas.translate(mGraphView.getGraphContentLeft(), mGraphView.getGraphContentTop()+ mGraphView.getGraphContentHeight()); + canvas.rotate(-90, 0, 0); + mEdgeEffectLeft.setSize(mGraphView.getGraphContentHeight(), mGraphView.getGraphContentWidth()); + if (mEdgeEffectLeft.draw(canvas)) { + needsInvalidate = true; + } + canvas.restoreToCount(restoreCount); + } + + if (!mEdgeEffectRight.isFinished()) { + final int restoreCount = canvas.save(); + canvas.translate(mGraphView.getGraphContentLeft()+ mGraphView.getGraphContentWidth(), mGraphView.getGraphContentTop()); + canvas.rotate(90, 0, 0); + mEdgeEffectRight.setSize(mGraphView.getGraphContentHeight(), mGraphView.getGraphContentWidth()); + if (mEdgeEffectRight.draw(canvas)) { + needsInvalidate = true; + } + canvas.restoreToCount(restoreCount); + } + + if (needsInvalidate) { + ViewCompat.postInvalidateOnAnimation(mGraphView); + } + } + + /** + * will be first called in order to draw + * the canvas + * Used to draw the background + * + * @param c canvas. + */ + public void drawFirst(Canvas c) { + // draw background + if (mBackgroundColor != Color.TRANSPARENT) { + mPaint.setColor(mBackgroundColor); + c.drawRect( + mGraphView.getGraphContentLeft(), + mGraphView.getGraphContentTop(), + mGraphView.getGraphContentLeft()+mGraphView.getGraphContentWidth(), + mGraphView.getGraphContentTop()+mGraphView.getGraphContentHeight(), + mPaint + ); + } + } + + /** + * draws the glowing edge effect + * + * @param c canvas + */ + public void draw(Canvas c) { + drawEdgeEffectsUnclipped(c); + } + + /** + * @return background of the viewport area + */ + public int getBackgroundColor() { + return mBackgroundColor; + } + + /** + * @param mBackgroundColor background of the viewport area + * use transparent to have no background + */ + public void setBackgroundColor(int mBackgroundColor) { + this.mBackgroundColor = mBackgroundColor; + } + + /** + * @return whether the viewport is scalable + */ + public boolean isScalable() { + return mIsScalable; + } + + /** + * active the scaling/zooming feature + * notice: sets the x axis bounds to manual + * + * @param mIsScalable whether the viewport is scalable + */ + public void setScalable(boolean mIsScalable) { + this.mIsScalable = mIsScalable; + if (mIsScalable) { + mIsScrollable = true; + + // set viewport to manual + setXAxisBoundsManual(true); + } + + } + + /** + * @return whether the x axis bounds are manual. + * @see #setMinX(double) + * @see #setMaxX(double) + */ + public boolean isXAxisBoundsManual() { + return mXAxisBoundsManual; + } + + /** + * @param mXAxisBoundsManual whether the x axis bounds are manual. + * @see #setMinX(double) + * @see #setMaxX(double) + */ + public void setXAxisBoundsManual(boolean mXAxisBoundsManual) { + this.mXAxisBoundsManual = mXAxisBoundsManual; + if (mXAxisBoundsManual) { + mXAxisBoundsStatus = AxisBoundsStatus.FIX; + } + } + + /** + * @return whether the y axis bound are manual + */ + public boolean isYAxisBoundsManual() { + return mYAxisBoundsManual; + } + + /** + * @param mYAxisBoundsManual whether the y axis bounds are manual + * @see #setMaxY(double) + * @see #setMinY(double) + */ + public void setYAxisBoundsManual(boolean mYAxisBoundsManual) { + this.mYAxisBoundsManual = mYAxisBoundsManual; + if (mYAxisBoundsManual) { + mYAxisBoundsStatus = AxisBoundsStatus.FIX; + } + } + + /** + * forces the viewport to scroll to the end + * of the range by keeping the current viewport size. + * + * Important: Only takes effect if x axis bounds are manual. + * + * @see #setXAxisBoundsManual(boolean) + */ + public void scrollToEnd() { + if (mXAxisBoundsManual) { + float size = mCurrentViewport.width(); + mCurrentViewport.right = mCompleteRange.right; + mCurrentViewport.left = mCompleteRange.right - size; + mScrollingReferenceX = Float.NaN; + mGraphView.onDataChanged(true, false); + } else { + Log.w("GraphView", "scrollToEnd works only with manual x axis bounds"); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java b/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java new file mode 100644 index 0000000000..20b497c91f --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/compat/OverScrollerCompat.java @@ -0,0 +1,46 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.compat; + +import android.annotation.TargetApi; +import android.os.Build; +import android.widget.OverScroller; + +/** + * A utility class for using {@link android.widget.OverScroller} in a backward-compatible fashion. + */ +public class OverScrollerCompat { + /** + * Disallow instantiation. + */ + private OverScrollerCompat() { + } + /** + * @see android.view.ScaleGestureDetector#getCurrentSpanY() + */ + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) + public static float getCurrVelocity(OverScroller overScroller) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return overScroller.getCurrVelocity(); + } else { + return 0; + } + } +} \ No newline at end of file diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java new file mode 100644 index 0000000000..1e9fa3cff4 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/helper/DateAsXAxisLabelFormatter.java @@ -0,0 +1,94 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.helper; + +import android.content.Context; + +import com.jjoe64.graphview.DefaultLabelFormatter; + +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Helper class to use date objects as x-values. + * This will use your own Date Format or by default + * the Android default date format to convert + * the x-values (that has to be millis from + * 01-01-1970) into a formatted date string. + * + * See the DateAsXAxis example in the GraphView-Demos project + * to see a working example. + * + * @author jjoe64 + */ +public class DateAsXAxisLabelFormatter extends DefaultLabelFormatter { + /** + * the date format that will convert + * the unix timestamp to string + */ + protected final DateFormat mDateFormat; + + /** + * calendar to avoid creating new date objects + */ + protected final Calendar mCalendar; + + /** + * create the formatter with the Android default date format to convert + * the x-values. + * + * @param context the application context + */ + public DateAsXAxisLabelFormatter(Context context) { + mDateFormat = android.text.format.DateFormat.getDateFormat(context); + mCalendar = Calendar.getInstance(); + } + + /** + * create the formatter with your own custom + * date format to convert the x-values. + * + * @param context the application context + * @param dateFormat custom date format + */ + public DateAsXAxisLabelFormatter(Context context, DateFormat dateFormat) { + mDateFormat = dateFormat; + mCalendar = Calendar.getInstance(); + } + + /** + * formats the x-values as date string. + * + * @param value raw value + * @param isValueX true if it's a x value, otherwise false + * @return value converted to string + */ + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX) { + // format as date + mCalendar.setTimeInMillis((long) value); + return mDateFormat.format(mCalendar.getTimeInMillis()); + } else { + return super.formatLabel(value, isValueX); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java b/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java new file mode 100644 index 0000000000..d036805bc8 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/helper/GraphViewXML.java @@ -0,0 +1,137 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.helper; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; +import android.util.Log; + +import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.R; +import com.jjoe64.graphview.series.BarGraphSeries; +import com.jjoe64.graphview.series.BaseSeries; +import com.jjoe64.graphview.series.DataPoint; +import com.jjoe64.graphview.series.DataPointInterface; +import com.jjoe64.graphview.series.LineGraphSeries; +import com.jjoe64.graphview.series.PointsGraphSeries; +import com.jjoe64.graphview.series.Series; + +/** + * helper class to use GraphView directly + * in a XML layout file. + * + * You can set the data via attribute app:seriesData + * in the format: "X=Y;X=Y;..." e.g. "0=5.0;1=5;2=4;3=9" + * + * Other styling options: + *
  • app:seriesType="line|bar|points"
  • + *
  • app:seriesColor="#ff0000"
  • + *
  • app:seriesTitle="foobar" - if this is set, the legend will be drawn
  • + *
  • android:title="foobar"
  • + * + * Example: + *
    + * {@code
    + *  
    + * }
    + * 
    + * + * @author jjoe64 + */ +public class GraphViewXML extends GraphView { + /** + * creates the graphview object with data and + * other options from xml attributes. + * + * @param context + * @param attrs + */ + public GraphViewXML(Context context, AttributeSet attrs) { + super(context, attrs); + + // get attributes + TypedArray a=context.obtainStyledAttributes( + attrs, + R.styleable.GraphViewXML); + + String dataStr = a.getString(R.styleable.GraphViewXML_seriesData); + int color = a.getColor(R.styleable.GraphViewXML_seriesColor, Color.TRANSPARENT); + String type = a.getString(R.styleable.GraphViewXML_seriesType); + String seriesTitle = a.getString(R.styleable.GraphViewXML_seriesTitle); + String title = a.getString(R.styleable.GraphViewXML_android_title); + + a.recycle(); + + // decode data + DataPoint[] data; + if (dataStr == null || dataStr.isEmpty()) { + throw new IllegalArgumentException("Attribute seriesData is required in the format: 0=5.0;1=5;2=4;3=9"); + } else { + String[] d = dataStr.split(";"); + try { + data = new DataPoint[d.length]; + int i = 0; + for (String dd : d) { + String[] xy = dd.split("="); + data[i] = new DataPoint(Double.parseDouble(xy[0]), Double.parseDouble(xy[1])); + i++; + } + } catch (Exception e) { + Log.e("GraphViewXML", e.toString()); + throw new IllegalArgumentException("Attribute seriesData is broken. Use this format: 0=5.0;1=5;2=4;3=9"); + } + } + + // create series + BaseSeries series; + if (type == null || type.isEmpty()) { + type = "line"; + } + if (type.equals("line")) { + series = new LineGraphSeries(data); + } else if (type.equals("bar")) { + series = new BarGraphSeries(data); + } else if (type.equals("points")) { + series = new PointsGraphSeries(data); + } else { + throw new IllegalArgumentException("unknown graph type: "+type+". Possible is line|bar|points"); + } + if (color != Color.TRANSPARENT) { + series.setColor(color); + } + addSeries(series); + + if (seriesTitle != null && !seriesTitle.isEmpty()) { + series.setTitle(seriesTitle); + getLegendRenderer().setVisible(true); + } + + if (title != null && !title.isEmpty()) { + setTitle(title); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java b/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java new file mode 100644 index 0000000000..4b38dbf4c2 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/helper/StaticLabelsFormatter.java @@ -0,0 +1,209 @@ +package com.jjoe64.graphview.helper; + +import com.jjoe64.graphview.DefaultLabelFormatter; +import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.LabelFormatter; +import com.jjoe64.graphview.Viewport; + +/** + * Use this label formatter to show static labels. + * Static labels are not bound to the data. It is typical used + * for show text like "low", "middle", "high". + * + * You can set the static labels for vertical or horizontal + * individually and you can define a label formatter that + * is to be used if you don't define static labels. + * + * For example if you only use static labels for horizontal labels, + * graphview will use the dynamicLabelFormatter for the vertical labels. + */ +public class StaticLabelsFormatter implements LabelFormatter { + /** + * reference to the viewport + */ + protected Viewport mViewport; + + /** + * the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + protected String[] mVerticalLabels; + + /** + * the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + protected String[] mHorizontalLabels; + + /** + * the label formatter that will format the labels + * for that there are no static labels defined. + */ + protected LabelFormatter mDynamicLabelFormatter; + + /** + * reference to the graphview + */ + protected final GraphView mGraphView; + + /** + * creates the formatter without any static labels + * define your static labels via {@link #setHorizontalLabels(String[])} and {@link #setVerticalLabels(String[])} + * + * @param graphView reference to the graphview + */ + public StaticLabelsFormatter(GraphView graphView) { + mGraphView = graphView; + init(null, null, null); + } + + /** + * creates the formatter without any static labels. + * define your static labels via {@link #setHorizontalLabels(String[])} and {@link #setVerticalLabels(String[])} + * + * @param graphView reference to the graphview + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + public StaticLabelsFormatter(GraphView graphView, LabelFormatter dynamicLabelFormatter) { + mGraphView = graphView; + init(null, null, dynamicLabelFormatter); + } + + /** + * creates the formatter with static labels defined. + * + * @param graphView reference to the graphview + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + public StaticLabelsFormatter(GraphView graphView, String[] horizontalLabels, String[] verticalLabels) { + mGraphView = graphView; + init(horizontalLabels, verticalLabels, null); + } + + /** + * creates the formatter with static labels defined. + * + * @param graphView reference to the graphview + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + public StaticLabelsFormatter(GraphView graphView, String[] horizontalLabels, String[] verticalLabels, LabelFormatter dynamicLabelFormatter) { + mGraphView = graphView; + init(horizontalLabels, verticalLabels, dynamicLabelFormatter); + } + + /** + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + protected void init(String[] horizontalLabels, String[] verticalLabels, LabelFormatter dynamicLabelFormatter) { + mDynamicLabelFormatter = dynamicLabelFormatter; + if (mDynamicLabelFormatter == null) { + mDynamicLabelFormatter = new DefaultLabelFormatter(); + } + + mHorizontalLabels = horizontalLabels; + mVerticalLabels = verticalLabels; + } + + /** + * Set a label formatter that will be used for the labels + * that don't have static labels. + * + * For example if you only use static labels for horizontal labels, + * graphview will use the dynamicLabelFormatter for the vertical labels. + * + * @param dynamicLabelFormatter the label formatter that will format the labels + * for that there are no static labels defined. + */ + public void setDynamicLabelFormatter(LabelFormatter dynamicLabelFormatter) { + this.mDynamicLabelFormatter = dynamicLabelFormatter; + adjust(); + } + + /** + * @param horizontalLabels the horizontal labels, ordered form the left to the right + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + public void setHorizontalLabels(String[] horizontalLabels) { + this.mHorizontalLabels = horizontalLabels; + adjust(); + } + + /** + * @param verticalLabels the vertical labels, ordered from bottom to the top + * if it is null, the labels will be generated via the #dynamicLabelFormatter + */ + public void setVerticalLabels(String[] verticalLabels) { + this.mVerticalLabels = verticalLabels; + adjust(); + } + + /** + * + * @param value raw input number + * @param isValueX true if it is a value for the x axis + * false if it is a value for the y axis + * @return + */ + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX && mHorizontalLabels != null) { + double minX = mViewport.getMinX(false); + double maxX = mViewport.getMaxX(false); + double range = maxX - minX; + value = value-minX; + int idx = (int)((value/range) * (mHorizontalLabels.length-1)); + return mHorizontalLabels[idx]; + } else if (!isValueX && mVerticalLabels != null) { + double minY = mViewport.getMinY(false); + double maxY = mViewport.getMaxY(false); + double range = maxY - minY; + value = value-minY; + int idx = (int)((value/range) * (mVerticalLabels.length-1)); + return mVerticalLabels[idx]; + } else { + return mDynamicLabelFormatter.formatLabel(value, isValueX); + } + } + + /** + * @param viewport the used viewport + */ + @Override + public void setViewport(Viewport viewport) { + mViewport = viewport; + adjust(); + } + + /** + * adjusts the number of vertical/horizontal labels + */ + protected void adjust() { + mDynamicLabelFormatter.setViewport(mViewport); + if (mVerticalLabels != null) { + if (mVerticalLabels.length < 2) { + throw new IllegalStateException("You need at least 2 vertical labels if you use static label formatter."); + } + mGraphView.getGridLabelRenderer().setNumVerticalLabels(mVerticalLabels.length); + } + if (mHorizontalLabels != null) { + if (mHorizontalLabels.length < 2) { + throw new IllegalStateException("You need at least 2 horizontal labels if you use static label formatter."); + } + mGraphView.getGridLabelRenderer().setNumHorizontalLabels(mHorizontalLabels.length); + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java new file mode 100644 index 0000000000..ec40a239a4 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java @@ -0,0 +1,380 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.Log; + +import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.ValueDependentColor; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Series with Bars to visualize the data. + * The Bars are always vertical. + * + * @author jjoe64 + */ +@SuppressWarnings("unchecked") +public class BarGraphSeries extends BaseSeries { + /** + * paint to do drawing on canvas + */ + private Paint mPaint; + + /** + * spacing between the bars in percentage. + * 0 => no spacing + * 100 => the space bewetten the bars is as big as the bars itself + */ + private int mSpacing; + + /** + * callback to generate value-dependent colors + * of the bars + */ + private ValueDependentColor mValueDependentColor; + + /** + * flag whether the values should drawn + * above the bars as text + */ + private boolean mDrawValuesOnTop; + + /** + * color of the text above the bars. + * + * @see #mDrawValuesOnTop + */ + private int mValuesOnTopColor; + + /** + * font size of the text above the bars. + * + * @see #mDrawValuesOnTop + */ + private float mValuesOnTopSize; + + /** + * stores the coordinates of the bars to + * trigger tap on series events. + */ + private Map mDataPoints = new HashMap(); + + /** + * creates bar series without any data + */ + public BarGraphSeries() { + mPaint = new Paint(); + } + + /** + * creates bar series with data + * + * @param data values + */ + public BarGraphSeries(E[] data) { + super(data); + mPaint = new Paint(); + } + + /** + * draws the bars on the canvas + * + * @param graphView corresponding graphview + * @param canvas canvas + * @param isSecondScale whether we are plotting the second scale or not + */ + @Override + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { + mPaint.setTextAlign(Paint.Align.CENTER); + if (mValuesOnTopSize == 0) { + mValuesOnTopSize = graphView.getGridLabelRenderer().getTextSize(); + } + mPaint.setTextSize(mValuesOnTopSize); + + // get data + double maxX = graphView.getViewport().getMaxX(false); + double minX = graphView.getViewport().getMinX(false); + + double maxY; + double minY; + if (isSecondScale) { + maxY = graphView.getSecondScale().getMaxY(); + minY = graphView.getSecondScale().getMinY(); + } else { + maxY = graphView.getViewport().getMaxY(false); + minY = graphView.getViewport().getMinY(false); + } + + // Iterate through all bar graph series + // so we know how wide to make our bar, + // and in what position to put it in + int numBarSeries = 0; + int currentSeriesOrder = 0; + int numValues = 0; + boolean isCurrentSeries; + SortedSet xVals = new TreeSet(); + for(Series inspectedSeries: graphView.getSeries()) { + if(inspectedSeries instanceof BarGraphSeries) { + isCurrentSeries = (inspectedSeries == this); + if(isCurrentSeries) { + currentSeriesOrder = numBarSeries; + } + numBarSeries++; + + // calculate the number of slots for bars based on the minimum distance between + // x coordinates in the series. This is divided into the range to find + // the placement and width of bar slots + // (sections of the x axis for each bar or set of bars) + // TODO: Move this somewhere more general and cache it, so we don't recalculate it for each series + Iterator curValues = inspectedSeries.getValues(minX, maxX); + if (curValues.hasNext()) { + xVals.add(curValues.next().getX()); + if(isCurrentSeries) { numValues++; } + while (curValues.hasNext()) { + xVals.add(curValues.next().getX()); + if(isCurrentSeries) { numValues++; } + } + } + } + } + if (numValues == 0) { + return; + } + + Double lastVal = null; + double minGap = 0; + for(Double curVal: xVals) { + if(lastVal != null) { + double curGap = Math.abs(curVal - lastVal); + if (minGap == 0 || (curGap > 0 && curGap < minGap)) { + minGap = curGap; + } + } + lastVal = curVal; + } + + int numBarSlots = (minGap == 0) ? 1 : (int)Math.round((maxX - minX)/minGap) + 1; + + Iterator values = getValues(minX, maxX); + + // Calculate the overall bar slot width - this includes all bars across + // all series, and any spacing between sets of bars + float barSlotWidth = numBarSlots == 1 + ? graphView.getGraphContentWidth() + : graphView.getGraphContentWidth() / (numBarSlots-1); + Log.d("BarGraphSeries", "numBars=" + numBarSlots); + + // Total spacing (both sides) between sets of bars + float spacing = Math.min((float) barSlotWidth*mSpacing/100, barSlotWidth*0.98f); + // Width of an individual bar + float barWidth = (barSlotWidth - spacing) / numBarSeries; + // Offset from the center of a given bar to start drawing + float offset = barSlotWidth/2; + + double diffY = maxY - minY; + double diffX = maxX - minX; + float contentHeight = graphView.getGraphContentHeight(); + float contentWidth = graphView.getGraphContentWidth(); + float contentLeft = graphView.getGraphContentLeft(); + float contentTop = graphView.getGraphContentTop(); + + // draw data + int i=0; + while (values.hasNext()) { + E value = values.next(); + + double valY = value.getY() - minY; + double ratY = valY / diffY; + double y = contentHeight * ratY; + + double valY0 = 0 - minY; + double ratY0 = valY0 / diffY; + double y0 = contentHeight * ratY0; + + double valX = value.getX() - minX; + double ratX = valX / diffX; + double x = contentWidth * ratX; + + // hook for value dependent color + if (getValueDependentColor() != null) { + mPaint.setColor(getValueDependentColor().get(value)); + } else { + mPaint.setColor(getColor()); + } + + float left = (float)x + contentLeft - offset + spacing/2 + currentSeriesOrder*barWidth; + float top = (contentTop - (float)y) + contentHeight; + float right = left + barWidth; + float bottom = (contentTop - (float)y0) + contentHeight - (graphView.getGridLabelRenderer().isHighlightZeroLines()?4:1); + + boolean reverse = top > bottom; + if (reverse) { + float tmp = top; + top = bottom + (graphView.getGridLabelRenderer().isHighlightZeroLines()?4:1); + bottom = tmp; + } + + // overdraw + left = Math.max(left, contentLeft); + right = Math.min(right, contentLeft+contentWidth); + bottom = Math.min(bottom, contentTop+contentHeight); + top = Math.max(top, contentTop); + + mDataPoints.put(new RectF(left, top, right, bottom), value); + + canvas.drawRect(left, top, right, bottom, mPaint); + + // set values on top of graph + if (mDrawValuesOnTop) { + if (reverse) { + top = bottom + mValuesOnTopSize + 4; + if (top > contentTop+contentHeight) top = contentTop + contentHeight; + } else { + top -= 4; + if (top<=contentTop) top+=contentTop+4; + } + + mPaint.setColor(mValuesOnTopColor); + canvas.drawText( + graphView.getGridLabelRenderer().getLabelFormatter().formatLabel(value.getY(), false) + , (left+right)/2, top, mPaint); + } + + i++; + } + } + + /** + * @return the hook to generate value-dependent color. default null + */ + public ValueDependentColor getValueDependentColor() { + return mValueDependentColor; + } + + /** + * set a hook to make the color of the bars depending + * on the actually value/data. + * + * @param mValueDependentColor hook + * null to disable + */ + public void setValueDependentColor(ValueDependentColor mValueDependentColor) { + this.mValueDependentColor = mValueDependentColor; + } + + /** + * @return the spacing between the bars in percentage + */ + public int getSpacing() { + return mSpacing; + } + + /** + * @param mSpacing spacing between the bars in percentage. + * 0 => no spacing + * 100 => the space between the bars is as big as the bars itself + */ + public void setSpacing(int mSpacing) { + this.mSpacing = mSpacing; + } + + /** + * @return whether the values should be drawn above the bars + */ + public boolean isDrawValuesOnTop() { + return mDrawValuesOnTop; + } + + /** + * @param mDrawValuesOnTop flag whether the values should drawn + * above the bars as text + */ + public void setDrawValuesOnTop(boolean mDrawValuesOnTop) { + this.mDrawValuesOnTop = mDrawValuesOnTop; + } + + /** + * @return font color of the values on top of the bars + * @see #setDrawValuesOnTop(boolean) + */ + public int getValuesOnTopColor() { + return mValuesOnTopColor; + } + + /** + * @param mValuesOnTopColor the font color of the values on top of the bars + * @see #setDrawValuesOnTop(boolean) + */ + public void setValuesOnTopColor(int mValuesOnTopColor) { + this.mValuesOnTopColor = mValuesOnTopColor; + } + + /** + * @return font size of the values above the bars + * @see #setDrawValuesOnTop(boolean) + */ + public float getValuesOnTopSize() { + return mValuesOnTopSize; + } + + /** + * @param mValuesOnTopSize font size of the values above the bars + * @see #setDrawValuesOnTop(boolean) + */ + public void setValuesOnTopSize(float mValuesOnTopSize) { + this.mValuesOnTopSize = mValuesOnTopSize; + } + + /** + * resets the cached coordinates of the bars + */ + @Override + protected void resetDataPoints() { + mDataPoints.clear(); + } + + /** + * find the corresponding data point by + * coordinates. + * + * @param x pixels + * @param y pixels + * @return datapoint or null + */ + @Override + protected E findDataPoint(float x, float y) { + for (Map.Entry entry : mDataPoints.entrySet()) { + if (x >= entry.getKey().left && x <= entry.getKey().right + && y >= entry.getKey().top && y <= entry.getKey().bottom) { + return entry.getValue(); + } + } + return null; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java new file mode 100644 index 0000000000..8ecdf23a73 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/BaseSeries.java @@ -0,0 +1,448 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.PointF; +import android.util.Log; + +import com.jjoe64.graphview.GraphView; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * Basis implementation for series. + * Used for series that are plotted on + * a default x/y 2d viewport. + * + * Extend this class to implement your own custom + * graph type. + * + * This implementation uses a internal Array to store + * the data. If you want to implement a custom data provider + * you may want to implement {@link com.jjoe64.graphview.series.Series}. + * + * @author jjoe64 + */ +public abstract class BaseSeries implements Series { + /** + * holds the data + */ + final private List mData = new ArrayList(); + + /** + * stores the used coordinates to find the + * corresponding data point on a tap + * + * Key => x/y pixel + * Value => Plotted Datapoint + * + * will be filled while drawing via {@link #registerDataPoint(float, float, DataPointInterface)} + */ + private Map mDataPoints = new HashMap(); + + /** + * title for this series that can be displayed + * in the legend. + */ + private String mTitle; + + /** + * base color for this series. will be used also in + * the legend + */ + private int mColor = 0xff0077cc; + + /** + * listener to handle tap events on a data point + */ + protected OnDataPointTapListener mOnDataPointTapListener; + + /** + * stores the graphviews where this series is used. + * Can be more than one. + */ + private List mGraphViews; + + /** + * creates series without data + */ + public BaseSeries() { + mGraphViews = new ArrayList(); + } + + /** + * creates series with data + * + * @param data data points + * important: array has to be sorted from lowest x-value to the highest + */ + public BaseSeries(E[] data) { + mGraphViews = new ArrayList(); + for (E d : data) { + mData.add(d); + } + } + + /** + * @return the lowest x value, or 0 if there is no data + */ + public double getLowestValueX() { + if (mData.isEmpty()) return 0d; + return mData.get(0).getX(); + } + + /** + * @return the highest x value, or 0 if there is no data + */ + public double getHighestValueX() { + if (mData.isEmpty()) return 0d; + return mData.get(mData.size()-1).getX(); + } + + /** + * @return the lowest y value, or 0 if there is no data + */ + public double getLowestValueY() { + if (mData.isEmpty()) return 0d; + double l = mData.get(0).getY(); + for (int i = 1; i < mData.size(); i++) { + double c = mData.get(i).getY(); + if (l > c) { + l = c; + } + } + return l; + } + + /** + * @return the highest y value, or 0 if there is no data + */ + public double getHighestValueY() { + if (mData.isEmpty()) return 0d; + double h = mData.get(0).getY(); + for (int i = 1; i < mData.size(); i++) { + double c = mData.get(i).getY(); + if (h < c) { + h = c; + } + } + return h; + } + + /** + * get the values for a given x range. if from and until are bigger or equal than + * all the data, the original data is returned. + * If it is only a part of the data, the range is returned plus one datapoint + * before and after to get a nice scrolling. + * + * @param from minimal x-value + * @param until maximal x-value + * @return data for the range +/- 1 datapoint + */ + @Override + public Iterator getValues(final double from, final double until) { + if (from <= getLowestValueX() && until >= getHighestValueX()) { + return mData.iterator(); + } else { + return new Iterator() { + Iterator org = mData.iterator(); + E nextValue = null; + E nextNextValue = null; + boolean plusOne = true; + + { + // go to first + boolean found = false; + E prevValue = null; + if (org.hasNext()) { + prevValue = org.next(); + } + if (prevValue.getX() >= from) { + nextValue = prevValue; + found = true; + } else { + while (org.hasNext()) { + nextValue = org.next(); + if (nextValue.getX() >= from) { + found = true; + nextNextValue = nextValue; + nextValue = prevValue; + break; + } + prevValue = nextValue; + } + } + if (!found) { + nextValue = null; + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public E next() { + if (hasNext()) { + E r = nextValue; + if (r.getX() > until) { + plusOne = false; + } + if (nextNextValue != null) { + nextValue = nextNextValue; + nextNextValue = null; + } else if (org.hasNext()) nextValue = org.next(); + else nextValue = null; + return r; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public boolean hasNext() { + return nextValue != null && (nextValue.getX() <= until || plusOne); + } + }; + } + } + + /** + * @return the title of the series + */ + public String getTitle() { + return mTitle; + } + + /** + * set the title of the series. This will be used in + * the legend. + * + * @param mTitle title of the series + */ + public void setTitle(String mTitle) { + this.mTitle = mTitle; + } + + /** + * @return color of the series + */ + public int getColor() { + return mColor; + } + + /** + * set the color of the series. This will be used in + * plotting (depends on the series implementation) and + * is used in the legend. + * + * @param mColor + */ + public void setColor(int mColor) { + this.mColor = mColor; + } + + /** + * set a listener for tap on a data point. + * + * @param l listener + */ + public void setOnDataPointTapListener(OnDataPointTapListener l) { + this.mOnDataPointTapListener = l; + } + + /** + * called by the tap detector in order to trigger + * the on tap on datapoint event. + * + * @param x pixel + * @param y pixel + */ + @Override + public void onTap(float x, float y) { + if (mOnDataPointTapListener != null) { + E p = findDataPoint(x, y); + if (p != null) { + mOnDataPointTapListener.onTap(this, p); + } + } + } + + /** + * find the data point which is next to the + * coordinates + * + * @param x pixel + * @param y pixel + * @return the data point or null if nothing was found + */ + protected E findDataPoint(float x, float y) { + float shortestDistance = Float.NaN; + E shortest = null; + for (Map.Entry entry : mDataPoints.entrySet()) { + float x1 = entry.getKey().x; + float y1 = entry.getKey().y; + float x2 = x; + float y2 = y; + + float distance = (float) Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); + if (shortest == null || distance < shortestDistance) { + shortestDistance = distance; + shortest = entry.getValue(); + } + } + if (shortest != null) { + if (shortestDistance < 120) { + return shortest; + } + } + return null; + } + + /** + * register the datapoint to find it at a tap + * + * @param x pixel + * @param y pixel + * @param dp the data point to save + */ + protected void registerDataPoint(float x, float y, E dp) { + mDataPoints.put(new PointF(x, y), dp); + } + + /** + * clears the cached data point coordinates + */ + protected void resetDataPoints() { + mDataPoints.clear(); + } + + /** + * clears the data of this series and sets new. + * will redraw the graph + * + * @param data the values must be in the correct order! + * x-value has to be ASC. First the lowest x value and at least the highest x value. + */ + public void resetData(E[] data) { + mData.clear(); + for (E d : data) { + mData.add(d); + } + checkValueOrder(null); + + // update graphview + for (GraphView gv : mGraphViews) { + gv.onDataChanged(true, false); + } + } + + /** + * called when the series was added to a graph + * + * @param graphView graphview + */ + @Override + public void onGraphViewAttached(GraphView graphView) { + mGraphViews.add(graphView); + } + + /** + * + * @param dataPoint values the values must be in the correct order! + * x-value has to be ASC. First the lowest x value and at least the highest x value. + * @param scrollToEnd true => graphview will scroll to the end (maxX) + * @param maxDataPoints if max data count is reached, the oldest data + * value will be lost to avoid memory leaks + */ + public void appendData(E dataPoint, boolean scrollToEnd, int maxDataPoints) { + checkValueOrder(dataPoint); + + if (!mData.isEmpty() && dataPoint.getX() < mData.get(mData.size()-1).getX()) { + throw new IllegalArgumentException("new x-value must be greater then the last value. x-values has to be ordered in ASC."); + } + synchronized (mData) { + int curDataCount = mData.size(); + if (curDataCount < maxDataPoints) { + // enough space + mData.add(dataPoint); + } else { + // we have to trim one data + mData.remove(0); + mData.add(dataPoint); + } + } + + // recalc the labels when it was the first data + boolean keepLabels = mData.size() != 1; + + // update linked graph views + // update graphview + for (GraphView gv : mGraphViews) { + gv.onDataChanged(keepLabels, scrollToEnd); + if (scrollToEnd) { + gv.getViewport().scrollToEnd(); + } + } + } + + /** + * @return whether there are data points + */ + @Override + public boolean isEmpty() { + return mData.isEmpty(); + } + + /** + * checks that the data is in the correct order + * + * @param onlyLast if not null, it will only check that this + * datapoint is after the last point. + */ + protected void checkValueOrder(DataPointInterface onlyLast) { + if (mData.size()>1) { + if (onlyLast != null) { + // only check last + if (onlyLast.getX() < mData.get(mData.size()-1).getX()) { + throw new IllegalArgumentException("new x-value must be greater then the last value. x-values has to be ordered in ASC."); + } + } else { + double lx = mData.get(0).getX(); + + for (int i = 1; i < mData.size(); i++) { + if (mData.get(i).getX() != Double.NaN) { + if (lx > mData.get(i).getX()) { + throw new IllegalArgumentException("The order of the values is not correct. X-Values have to be ordered ASC. First the lowest x value and at least the highest x value."); + } + lx = mData.get(i).getX(); + } + } + } + } + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java b/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java new file mode 100644 index 0000000000..b5f5eb3ef3 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/DataPoint.java @@ -0,0 +1,63 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.provider.ContactsContract; + +import java.io.Serializable; +import java.util.Date; + +/** + * default data point implementation. + * This stores the x and y values. + * + * @author jjoe64 + */ +public class DataPoint implements DataPointInterface, Serializable { + private static final long serialVersionUID=1428263322645L; + + private double x; + private double y; + + public DataPoint(double x, double y) { + this.x=x; + this.y=y; + } + + public DataPoint(Date x, double y) { + this.x = x.getTime(); + this.y = y; + } + + @Override + public double getX() { + return x; + } + + @Override + public double getY() { + return y; + } + + @Override + public String toString() { + return "["+x+"/"+y+"]"; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java b/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java new file mode 100644 index 0000000000..9be683bef8 --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/DataPointInterface.java @@ -0,0 +1,41 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +/** + * interface of data points. Implement this in order + * to use your class in {@link com.jjoe64.graphview.series.Series}. + * + * You can also use the default implementation {@link com.jjoe64.graphview.series.DataPoint} so + * you do not have to implement it for yourself. + * + * @author jjoe64 + */ +public interface DataPointInterface { + /** + * @return the x value + */ + public double getX(); + + /** + * @return the y value + */ + public double getY(); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java new file mode 100644 index 0000000000..4d721c2e6c --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/LineGraphSeries.java @@ -0,0 +1,409 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; + +import com.jjoe64.graphview.GraphView; + +import java.util.Iterator; + +/** + * Series to plot the data as line. + * The line can be styled with many options. + * + * @author jjoe64 + */ +public class LineGraphSeries extends BaseSeries { + /** + * wrapped styles regarding the line + */ + private final class Styles { + /** + * the thickness of the line. + * This option will be ignored if you are + * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} + */ + private int thickness = 5; + + /** + * flag whether the area under the line to the bottom + * of the viewport will be filled with a + * specific background color. + * + * @see #backgroundColor + */ + private boolean drawBackground = false; + + /** + * flag whether the data points are highlighted as + * a visible point. + * + * @see #dataPointsRadius + */ + private boolean drawDataPoints = false; + + /** + * the radius for the data points. + * + * @see #drawDataPoints + */ + private float dataPointsRadius = 10f; + + /** + * the background color for the filling under + * the line. + * + * @see #drawBackground + */ + private int backgroundColor = Color.argb(100, 172, 218, 255); + } + + /** + * wrapped styles + */ + private Styles mStyles; + + /** + * internal paint object + */ + private Paint mPaint; + + /** + * paint for the background + */ + private Paint mPaintBackground; + + /** + * path for the background filling + */ + private Path mPathBackground; + + /** + * path to the line + */ + private Path mPath; + + /** + * custom paint that can be used. + * this will ignore the thickness and color styles. + */ + private Paint mCustomPaint; + + /** + * creates a series without data + */ + public LineGraphSeries() { + init(); + } + + /** + * creates a series with data + * + * @param data data points + */ + public LineGraphSeries(E[] data) { + super(data); + init(); + } + + /** + * do the initialization + * creates internal objects + */ + protected void init() { + mStyles = new Styles(); + mPaint = new Paint(); + mPaint.setStrokeCap(Paint.Cap.ROUND); + mPaint.setStyle(Paint.Style.STROKE); + mPaintBackground = new Paint(); + + mPathBackground = new Path(); + mPath = new Path(); + } + + /** + * plots the series + * draws the line and the background + * + * @param graphView graphview + * @param canvas canvas + * @param isSecondScale flag if it is the second scale + */ + @Override + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { + resetDataPoints(); + + // get data + double maxX = graphView.getViewport().getMaxX(false); + double minX = graphView.getViewport().getMinX(false); + + double maxY; + double minY; + if (isSecondScale) { + maxY = graphView.getSecondScale().getMaxY(); + minY = graphView.getSecondScale().getMinY(); + } else { + maxY = graphView.getViewport().getMaxY(false); + minY = graphView.getViewport().getMinY(false); + } + + Iterator values = getValues(minX, maxX); + + // draw background + double lastEndY = 0; + double lastEndX = 0; + + // draw data + mPaint.setStrokeWidth(mStyles.thickness); + mPaint.setColor(getColor()); + mPaintBackground.setColor(mStyles.backgroundColor); + + Paint paint; + if (mCustomPaint != null) { + paint = mCustomPaint; + } else { + paint = mPaint; + } + + if (mStyles.drawBackground) { + mPathBackground.reset(); + } + + double diffY = maxY - minY; + double diffX = maxX - minX; + + float graphHeight = graphView.getGraphContentHeight(); + float graphWidth = graphView.getGraphContentWidth(); + float graphLeft = graphView.getGraphContentLeft(); + float graphTop = graphView.getGraphContentTop(); + + lastEndY = 0; + lastEndX = 0; + double lastUsedEndX = 0; + float firstX = 0; + int i=0; + while (values.hasNext()) { + E value = values.next(); + + double valY = value.getY() - minY; + double ratY = valY / diffY; + double y = graphHeight * ratY; + + double valX = value.getX() - minX; + double ratX = valX / diffX; + double x = graphWidth * ratX; + + double orgX = x; + double orgY = y; + + if (i > 0) { + // overdraw + if (x > graphWidth) { // end right + double b = ((graphWidth - lastEndX) * (y - lastEndY)/(x - lastEndX)); + y = lastEndY+b; + x = graphWidth; + } + if (y < 0) { // end bottom + double b = ((0 - lastEndY) * (x - lastEndX)/(y - lastEndY)); + x = lastEndX+b; + y = 0; + } + if (y > graphHeight) { // end top + double b = ((graphHeight - lastEndY) * (x - lastEndX)/(y - lastEndY)); + x = lastEndX+b; + y = graphHeight; + } + if (lastEndY < 0) { // start bottom + double b = ((0 - y) * (x - lastEndX)/(lastEndY - y)); + lastEndX = x-b; + lastEndY = 0; + } + if (lastEndX < 0) { // start left + double b = ((0 - x) * (y - lastEndY)/(lastEndX - x)); + lastEndY = y-b; + lastEndX = 0; + } + if (lastEndY > graphHeight) { // start top + double b = ((graphHeight - y) * (x - lastEndX)/(lastEndY - y)); + lastEndX = x-b; + lastEndY = graphHeight; + } + + float startX = (float) lastEndX + (graphLeft + 1); + float startY = (float) (graphTop - lastEndY) + graphHeight; + float endX = (float) x + (graphLeft + 1); + float endY = (float) (graphTop - y) + graphHeight; + + // draw data point + if (mStyles.drawDataPoints) { + //fix: last value was not drawn. Draw here now the end values + canvas.drawCircle(endX, endY, mStyles.dataPointsRadius, mPaint); + } + registerDataPoint(endX, endY, value); + + mPath.reset(); + mPath.moveTo(startX, startY); + mPath.lineTo(endX, endY); + canvas.drawPath(mPath, paint); + if (mStyles.drawBackground) { + if (i==1) { + firstX = startX; + mPathBackground.moveTo(startX, startY); + } + mPathBackground.lineTo(endX, endY); + } + lastUsedEndX = endX; + } else if (mStyles.drawDataPoints) { + //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above) + float first_X = (float) x + (graphLeft + 1); + float first_Y = (float) (graphTop - y) + graphHeight; + //TODO canvas.drawCircle(first_X, first_Y, dataPointsRadius, mPaint); + } + lastEndY = orgY; + lastEndX = orgX; + i++; + } + + if (mStyles.drawBackground) { + // end / close path + mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop); + mPathBackground.lineTo(firstX, graphHeight + graphTop); + mPathBackground.close(); + canvas.drawPath(mPathBackground, mPaintBackground); + } + + } + + /** + * the thickness of the line. + * This option will be ignored if you are + * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} + * + * @return the thickness of the line + */ + public int getThickness() { + return mStyles.thickness; + } + + /** + * the thickness of the line. + * This option will be ignored if you are + * using a custom paint via {@link #setCustomPaint(android.graphics.Paint)} + * + * @param thickness thickness of the line + */ + public void setThickness(int thickness) { + mStyles.thickness = thickness; + } + + /** + * flag whether the area under the line to the bottom + * of the viewport will be filled with a + * specific background color. + * + * @return whether the background will be drawn + * @see #getBackgroundColor() + */ + public boolean isDrawBackground() { + return mStyles.drawBackground; + } + + /** + * flag whether the area under the line to the bottom + * of the viewport will be filled with a + * specific background color. + * + * @param drawBackground whether the background will be drawn + * @see #setBackgroundColor(int) + */ + public void setDrawBackground(boolean drawBackground) { + mStyles.drawBackground = drawBackground; + } + + /** + * flag whether the data points are highlighted as + * a visible point. + * + * @return flag whether the data points are highlighted + * @see #setDataPointsRadius(float) + */ + public boolean isDrawDataPoints() { + return mStyles.drawDataPoints; + } + + /** + * flag whether the data points are highlighted as + * a visible point. + * + * @param drawDataPoints flag whether the data points are highlighted + * @see #setDataPointsRadius(float) + */ + public void setDrawDataPoints(boolean drawDataPoints) { + mStyles.drawDataPoints = drawDataPoints; + } + + /** + * @return the radius for the data points. + * @see #setDrawDataPoints(boolean) + */ + public float getDataPointsRadius() { + return mStyles.dataPointsRadius; + } + + /** + * @param dataPointsRadius the radius for the data points. + * @see #setDrawDataPoints(boolean) + */ + public void setDataPointsRadius(float dataPointsRadius) { + mStyles.dataPointsRadius = dataPointsRadius; + } + + /** + * @return the background color for the filling under + * the line. + * @see #setDrawBackground(boolean) + */ + public int getBackgroundColor() { + return mStyles.backgroundColor; + } + + /** + * @param backgroundColor the background color for the filling under + * the line. + * @see #setDrawBackground(boolean) + */ + public void setBackgroundColor(int backgroundColor) { + mStyles.backgroundColor = backgroundColor; + } + + /** + * custom paint that can be used. + * this will ignore the thickness and color styles. + * + * @param customPaint the custom paint to be used for rendering the line + */ + public void setCustomPaint(Paint customPaint) { + this.mCustomPaint = customPaint; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java b/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java new file mode 100644 index 0000000000..748a1122ee --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/OnDataPointTapListener.java @@ -0,0 +1,38 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +/** + * Listener for the tap event which will be + * triggered when the user touches on a datapoint. + * + * Use this in {@link com.jjoe64.graphview.series.BaseSeries#setOnDataPointTapListener(OnDataPointTapListener)} + * + * @author jjoe64 + */ +public interface OnDataPointTapListener { + /** + * gets called when the user touches on a datapoint. + * + * @param series the corresponding series + * @param dataPoint the data point that was tapped on + */ + void onTap(Series series, DataPointInterface dataPoint); +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java b/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java new file mode 100644 index 0000000000..c57d476d7b --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/PointsGraphSeries.java @@ -0,0 +1,312 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Point; + +import com.jjoe64.graphview.GraphView; + +import java.util.Iterator; + +/** + * Series that plots the data as points. + * The points can be different shapes or a + * complete custom drawing. + * + * @author jjoe64 + */ +public class PointsGraphSeries extends BaseSeries { + /** + * interface to implement a custom + * drawing for the data points. + */ + public static interface CustomShape { + /** + * called when drawing a single data point. + * use the x and y coordinates to render your + * drawing at this point. + * + * @param canvas canvas to draw on + * @param paint internal paint object. this has the correct color. + * But you can use your own paint. + * @param x x-coordinate the point has to be drawn to + * @param y y-coordinate the point has to be drawn to + * @param dataPoint the related data point + */ + void draw(Canvas canvas, Paint paint, float x, float y, DataPointInterface dataPoint); + } + + /** + * choose a predefined shape to render for + * each data point. + * You can also render a custom drawing via {@link com.jjoe64.graphview.series.PointsGraphSeries.CustomShape} + */ + public enum Shape { + /** + * draws a point / circle + */ + POINT, + + /** + * draws a triangle + */ + TRIANGLE, + + /** + * draws a rectangle + */ + RECTANGLE + } + + /** + * wrapped styles for this series + */ + private final class Styles { + /** + * this is used for the size of the shape that + * will be drawn. + * This is useless if you are using a custom shape. + */ + float size; + + /** + * the shape that will be drawn for each point. + */ + Shape shape; + } + + /** + * wrapped styles + */ + private Styles mStyles; + + /** + * internal paint object + */ + private Paint mPaint; + + /** + * handler to use a custom drawing + */ + private CustomShape mCustomShape; + + /** + * creates the series without data + */ + public PointsGraphSeries() { + init(); + } + + /** + * creates the series with data + * + * @param data datapoints + */ + public PointsGraphSeries(E[] data) { + super(data); + init(); + } + + /** + * inits the internal objects + * set the defaults + */ + protected void init() { + mStyles = new Styles(); + mStyles.size = 20f; + mPaint = new Paint(); + mPaint.setStrokeCap(Paint.Cap.ROUND); + setShape(Shape.POINT); + } + + /** + * plot the data to the viewport + * + * @param graphView graphview + * @param canvas canvas to draw on + * @param isSecondScale whether it is the second scale + */ + @Override + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { + resetDataPoints(); + + // get data + double maxX = graphView.getViewport().getMaxX(false); + double minX = graphView.getViewport().getMinX(false); + + double maxY; + double minY; + if (isSecondScale) { + maxY = graphView.getSecondScale().getMaxY(); + minY = graphView.getSecondScale().getMinY(); + } else { + maxY = graphView.getViewport().getMaxY(false); + minY = graphView.getViewport().getMinY(false); + } + + Iterator values = getValues(minX, maxX); + + // draw background + double lastEndY = 0; + double lastEndX = 0; + + // draw data + mPaint.setColor(getColor()); + + double diffY = maxY - minY; + double diffX = maxX - minX; + + float graphHeight = graphView.getGraphContentHeight(); + float graphWidth = graphView.getGraphContentWidth(); + float graphLeft = graphView.getGraphContentLeft(); + float graphTop = graphView.getGraphContentTop(); + + lastEndY = 0; + lastEndX = 0; + float firstX = 0; + int i=0; + while (values.hasNext()) { + E value = values.next(); + + double valY = value.getY() - minY; + double ratY = valY / diffY; + double y = graphHeight * ratY; + + double valX = value.getX() - minX; + double ratX = valX / diffX; + double x = graphWidth * ratX; + + double orgX = x; + double orgY = y; + + // overdraw + boolean overdraw = false; + if (x > graphWidth) { // end right + overdraw = true; + } + if (y < 0) { // end bottom + overdraw = true; + } + if (y > graphHeight) { // end top + overdraw = true; + } + + float endX = (float) x + (graphLeft + 1); + float endY = (float) (graphTop - y) + graphHeight; + registerDataPoint(endX, endY, value); + + // draw data point + if (!overdraw) { + if (mCustomShape != null) { + mCustomShape.draw(canvas, mPaint, endX, endY, value); + } else if (mStyles.shape == Shape.POINT) { + canvas.drawCircle(endX, endY, mStyles.size, mPaint); + } else if (mStyles.shape == Shape.RECTANGLE) { + canvas.drawRect(endX-mStyles.size, endY-mStyles.size, endX+mStyles.size, endY+mStyles.size, mPaint); + } else if (mStyles.shape == Shape.TRIANGLE) { + Point[] points = new Point[3]; + points[0] = new Point((int)endX, (int)(endY-getSize())); + points[1] = new Point((int)(endX+getSize()), (int)(endY+getSize()*0.67)); + points[2] = new Point((int)(endX-getSize()), (int)(endY+getSize()*0.67)); + drawArrows(points, canvas, mPaint); + } + } + + i++; + } + + } + + /** + * helper to render triangle + * + * @param point array with 3 coordinates + * @param canvas canvas to draw on + * @param paint paint object + */ + private void drawArrows(Point[] point, Canvas canvas, Paint paint) { + float [] points = new float[8]; + points[0] = point[0].x; + points[1] = point[0].y; + points[2] = point[1].x; + points[3] = point[1].y; + points[4] = point[2].x; + points[5] = point[2].y; + points[6] = point[0].x; + points[7] = point[0].y; + + canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint); + Path path = new Path(); + path.moveTo(point[0].x , point[0].y); + path.lineTo(point[1].x,point[1].y); + path.lineTo(point[2].x,point[2].y); + canvas.drawPath(path,paint); + } + + /** + * This is used for the size of the shape that + * will be drawn. + * This is useless if you are using a custom shape. + * + * @return the size of the shape + */ + public float getSize() { + return mStyles.size; + } + + /** + * This is used for the size of the shape that + * will be drawn. + * This is useless if you are using a custom shape. + * + * @param radius the size of the shape + */ + public void setSize(float radius) { + mStyles.size = radius; + } + + /** + * @return the shape that will be drawn for each point + */ + public Shape getShape() { + return mStyles.shape; + } + + /** + * @param s the shape that will be drawn for each point + */ + public void setShape(Shape s) { + mStyles.shape = s; + } + + /** + * Use a custom handler to render your own + * drawing for each data point. + * + * @param shape handler to use a custom drawing + */ + public void setCustomShape(CustomShape shape) { + mCustomShape = shape; + } +} diff --git a/graphview/src/main/java/com/jjoe64/graphview/series/Series.java b/graphview/src/main/java/com/jjoe64/graphview/series/Series.java new file mode 100644 index 0000000000..dce32eb78e --- /dev/null +++ b/graphview/src/main/java/com/jjoe64/graphview/series/Series.java @@ -0,0 +1,125 @@ +/** + * GraphView + * Copyright (C) 2014 Jonas Gehring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * with the "Linking Exception", which can be found at the license.txt + * file in this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with the "Linking Exception" along with this program; if not, + * write to the author Jonas Gehring . + */ +package com.jjoe64.graphview.series; + +import android.graphics.Canvas; + +import com.jjoe64.graphview.GraphView; + +import java.util.Iterator; + +/** + * Basis interface for series that can be plotted + * on the graph. + * You can implement this in order to create a completely + * custom series type. + * But it is recommended to extend {@link com.jjoe64.graphview.series.BaseSeries} or another + * implemented Series class to save time. + * Anyway this interface can make sense if you want to implement + * a custom data provider, because BaseSeries uses a internal Array to store + * the data. + * + * @author jjoe64 + */ +public interface Series { + /** + * @return the lowest x-value of the data + */ + public double getLowestValueX(); + + /** + * @return the highest x-value of the data + */ + public double getHighestValueX(); + + /** + * @return the lowest y-value of the data + */ + public double getLowestValueY(); + + /** + * @return the highest y-value of the data + */ + public double getHighestValueY(); + + /** + * get the values for a specific range. It is + * important that the data comes in the sorted order + * (from lowest to highest x-value). + * + * @param from the minimal x-value + * @param until the maximal x-value + * @return all datapoints between the from and until x-value + * including the from and until data points. + */ + public Iterator getValues(double from, double until); + + /** + * Plots the series to the viewport. + * You have to care about overdrawing. + * This method may be called 2 times: one for + * the default scale and one time for the + * second scale. + * + * @param graphView corresponding graphview + * @param canvas canvas to draw on + * @param isSecondScale true if the drawing is for the second scale + */ + public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale); + + /** + * @return the title of the series. Used in the legend + */ + public String getTitle(); + + /** + * @return the color of the series. Used in the legend and should + * be used for the plotted points or lines. + */ + public int getColor(); + + /** + * set a listener for tap on a data point. + * + * @param l listener + */ + public void setOnDataPointTapListener(OnDataPointTapListener l); + + /** + * called by the tap detector in order to trigger + * the on tap on datapoint event. + * + * @param x pixel + * @param y pixel + */ + void onTap(float x, float y); + + /** + * called when the series was added to a graph + * + * @param graphView graphview + */ + void onGraphViewAttached(GraphView graphView); + + /** + * @return whether there are data points + */ + boolean isEmpty(); +} diff --git a/graphview/src/main/res/values/attr.xml b/graphview/src/main/res/values/attr.xml new file mode 100644 index 0000000000..8b73838605 --- /dev/null +++ b/graphview/src/main/res/values/attr.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/libraries/build.gradle b/libraries/build.gradle index 5d7e7997bb..14c29c3764 100644 --- a/libraries/build.gradle +++ b/libraries/build.gradle @@ -1,6 +1,4 @@ // in order to use internet's versions you'd need to enable Jetifier again -// https://github.com/nightscout/graphview.git // https://github.com/nightscout/iconify.git configurations.create("default") -artifacts.add("default", file('libs/graphview.aar')) artifacts.add("default", file('libs/iconify.aar')) \ No newline at end of file diff --git a/libraries/libs/graphview.aar b/libraries/libs/graphview.aar deleted file mode 100644 index f3d0206ceebf549858dade47e8069709509a96d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62697 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 diff --git a/libraries/libs/libs/graphview.aar b/libraries/libs/libs/graphview.aar deleted file mode 100644 index f3d0206ceebf549858dade47e8069709509a96d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62697 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 diff --git a/libraries/libs/libs/iconify.aar b/libraries/libs/libs/iconify.aar deleted file mode 100644 index 1247bf7f92650c7b349b347fa5280b195deb840c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126846 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

    SFlevHLABJ}SVe&e& zV1nvCy;t2|GSvc-R#6OPQXx^J1Ia___4kbLUZp81(X8qof6w~iyOe@o#iiK;#6F6d zi_6ic&Dek~%*W8WAN@<%v<9^3{zCq-Y-ej^J6cmat_KSM01Gp-!2(&7A7Ue5j_i={ z2MfVp<%eXEZj;}T{|q|hkJih-Cp_xG^}V1Jvz*BvF~61nEWZf^`5*G%<)4Exdbj*@ z`5#~`62SFnZ26k_iRe*#DdoYq%>fJg3no||Q;Fg~8t_`|y~b)!+%>@7F)%d8N1J?^ zMV;`S&dh(Wfos;h2R=y2fy|?{w-*d%QZQ9>`#rZo*FpKnb@0g@nUg!{9hp77@S@{) z9zIMJ+FNWYejJ5H3+%v(>9x@q6Hw=VDkmN0Lp2ruzeKUbH0LsF>ixYh%AZ)T3b>fs zk_!2wCsKQ!cw$cq9IGsQsH~FwJhXN8i378@Zk^4XH+$>3@bZqX-S6xKrgT?F=6qKm z03Q41;fKF@7+!x*>6kI4_n?bD&u8CS@J*NqE=IAhNi-KJnvL!t)Idrv1-I;cWarLD z;3H&{<^555@6dhtnEJ2q+k0$JZ}$s5&J_Vi{og-PU>u|N8!RaE+>vYhzR~x&}V@@5eZ3K6)ci4 zvC}bnPX(#@yO!2JoJa>0Zm6ITq2- zVp+Gjru2e|OHvxm&G15ZK&z>%=XHKpX+X=Dm1;DBA8 zOW2@8gt|ALAmQI6v|YmOgC$oixFcy+YK(`%XfQGX!uf|AHjeoRSdLfP+C!t`43_i7 z5kghZoQi5t9iBH;vuIyG4HLDKu6feh8LqkY{+dvy%^2}}UV6({(a@x4O?S$DcNtih zsqXe~AM<-mmuW548-FYRec!TBb(GQAD>$IxMC01W0R4osyqp;eDu-FZZmEvgt!qU` zyluj{hNYeLi>&2yK(o!ou~sX`mslkykA!lTFUin+xPW149>61yAL3PI{H}=t&!|-dfQNBxO6m;_KMvd00;_IOWk6BLXbRcDxB!=kw zPh|ZuD41c>_@1iIM-FB5*4i10D3W3x>@!so=$^ zDee$7g;hWel=EfZgxWJiq6F2Y5EgU;ej3J9NfpbxWVNJlYJw~msX`3ru-e&8;dvLO z>X$4S-!^-8^yV9{-?Z_;DQo-uwJX+4-oC7{aaLgb0r|r+Pe(i+?4+kneFV^G79PKA z*9%^+&yRN4e|&WCT93!?A77E|j4s=>^CjlOwrSHk;-a3ras9e6w3%iMIbV2!-L1^Z z6tDy>g#Ad}!XIZA;6E-kv<l{p8-GTVo~*adH-&mH<0-i}?O6`WRf zH}O*}MN-@hw0@wdhB%p@7b2Xwj-eA(tt|^$TbWtO+G(u|S`V~VSG9tvktBR*U214$ zYW-y1VC1JPe|z~9-e};#A$-2Is=AdabKv_Z|K4b=lIK*nwpN3Os#>MYnn?1`c<;~3 zZ!!XJ0XHUI+_vq-#KlIQGwiFX+GpT+W9G)}Rn;vmXdcD#&bNf4!bJIzWMc&tpdL&H zUlRP00H#1{aBv|WRSJagxWjXJ{BEaPK?n)I?R2OSD;_`?s~FHpEJKo+E)-W)5qOYC zqkaM{t=m_90~R$Q!I_gei}~+K;Z;IvqVUl5zzFB z11|)u?ZBce5=_aEXvbObdoTe`kzUEg9%zfB2?mW<=wcH0j&DY6pK-!8-;QK;TppX< z(ZF+P*@$bzC^J>K5l#6V3DUB5fJVIB3kYbbfgWkcH)x0h55$E51jvLYP(Nsp3@Z(R z?~j{+2-PuCKy)_`&09H#;yj5pRz!~#!Y7Fa3)MQI%#Kk4{lcqx?f4-yxh;vzG)*b$SuW6qXXZd7TKfV@hb?FLjqeptbNij?wcL0IW`n z6#%!CX>h3Hg0)yAeW;)AL5UbXMGM ztFqI;Q)Uz$vosKJ8k?7a9K$jd5w?=C-lsLws%p3_2FN7H&5{19p_9IItHNDEb>R{yxpKnpyC0;6eSjkHOtWoZa> zkYO}}2ABnyu-YN-bOc=?O=x+kWlczQ==`3V1=4hD&E$$`Y1!RLDOpkNWOaT3(D1Dj z7Faw^Tg)5vYmFi_unh3iwBLGBz`1I?qq>?Ft-1@wcGc<`H1LTYUK6y3tmg^_1~&GD z$H)3B#!Y0AjIc7X*n~t4z0U29`$e~?6`(yNnyr$q>5R&jw(i(iec0>s(E<=mF0-3i z4J5#!ssIzMH*)eEps}#5MhAgeM{DrwhVm_<(^TR%m+Aa`H9PiPtF_~jF98Ua0_L^APAlJ!*Dw6tcoNlP>QxCsD^D>v1YLt3u|Ws=62kh4gd^h$)shpkYyQ;=7G@aGU(gO zwKQMSF}ACWyKkJhM&q=Vca)Y&fE~Zu;AI?_X-$zz+SF1Xadv6U8pvw-Mzd*3NW(=+ zIvr&|+Um8fUF;HrUOio9aY3kMfyw#{4No()j^hC|Cm0|O>Ma@oH~<(o&3*H*jHdyqIg?jVYV1?Ge z=tRH2+h=8Iqp6B>8ti&gmtfIyB^u5v&|FR9_^{=tjZ^(vr`cYHnXlKxyR6qVZhYyC z9o05a=B_&2wS4=gwJmQhte;#7p+ATkT_YLF*q|^kF=^NM$*iwFP=cyeqSsHIY$%U< z+!#wY+RzPTu-?01gfa&Q^_qEx)@~`AWU{O!Q^#^u@ zf{b|f`8yA!y&yur|JE-Tj@fX-(BIL74re{{&GcCpZ<%=EkJNJzL$4y_h zmVf#2w7<~j0C3&i(vRPEO^mnNWdA3R0z*l1Tz6@#igTduMWdAg3tt`$yHIVvc4`@3 zdqn6ufO&?a4IWzYS;DNn5XX_01H!|O<4x(T{h=KyBvl+?WmS;cutXHc3}ucU4x@xa!7je6Y7GwV^XKbwTUFGwj};@zL4!RSjhg(f_```_c^) zz`73)@9mq>eT{tLxeewXbqBC`2fWuXH(uk^J9*x0c3EaPeST-MHnBKT-m#&(ZAoiT zsIUvx%5c7LQISJ{zI;2ol`szK|9S4a#<2h~L) zm9ln(1i|udAe6qL0_$Kr!RfFo262o9nEWjVHA=@_fc_-NmfA8+j&cqJ93J17b`R|| zGUYb;cUX%H&Jg_{n`X2#9A|eo_~gGEwHkSuz1xtOK8HSkdD4Cd(>{Zl`3r~NZ$0rC zdO)wsRA$=SW<%Fjl?B~jbj!QsUs~+88oO1emE9%0);^uxn^@l8KlG^ui~|=B*Tbnk z4RNeewgL|Ywo04ju*|5Yo~Go4r4z^> zN^k6esh*AUASn%;`>nTQwLq2u z4kD4t?x-kK?yz8)*-}QTms8nm`}n>~s8Q8(6&5^^&%AT+dtAR1P1d{{V0Vv||oP8$qi*GDX4CW6Gb zmQ4_1c7k`q5(id?olP&f^_@@Oxpj%M0UH>z{Jzm7$nQU{^XeX#-xo|q`F%6PY9D`G z%Q9wAflh*o$F+X#*%c6_{}#4b=~(V9k!_U-{>SuY=OtegGV=?&9E>G37Jg*mA@1gHf?u zs8n#kxU^~uu2wz&h@#Us!vB3lOh~c-bpoy_{DRS$t)l_1nfmc5iSJYVYiZQfW}4iS@8M~j zz=s3yx!#a#u=7nx664}atTj1d#n@DIb$5$kddgbrlqA~n>t+QOByi0!wFiBXxivAKkx3FQKpk0p zOw_Ew2&h17Is7pu;uS%(?nNUbj!PBME?y9Nu)`NNXroV;EH0r3r~sRBw7ygpl|gch z917#bt+GUiKg4F!nKrxFHG8W@YZS_Oi%0N0QTwM2>t@&09qZq)9IX-uHpSWjMjaaaa5%QdTp&utjpO7<}ZwfwGDBXrnI8H{lSH$V-4k{JN_}`pJWnTKL13o`&OfyW%b5# zfz>Zt(_7(xX8D;*-DOX-_TDf_aD0AH*<9Uq&BcA~o!g&UzXdR<`!AiEyiPEnZU9@_ zI<^=EJ?c@-YvJ-`JDSkbQ5iaVjp*slF|2V`Z)S_zB{sO{Jl-`iCUWIXb)0Kjp?tBK z(oz!US0{Y1XswM|@2!x>B*qoM%%j25VrN9=oCjWf;ei9s`vcF*w`N{_;$Bd}#GZIH z^BAbO*S~Dp!f&p<_8YcMb`QyCt$Y_ap9K?tlc|zFd3Pl^JOuvY`HlRnqU%HQ!-Ysz zTZeToG!|DmiYEveXgn4mHXi`=dBt&>#c8%2#A6W_t^64QEpyNig>@qW{**bKWH0nC zTGqF6*{oKxWs`jPP08hwj)3Yl6;qZiTCrfRZ}ZESZSE+Exp@2JuH|zUBx|`zdsZxH zi~8&=W6-!KH#G{OX!kj-6)a~JH9T4)33c&B%P;DJ;kKFc=S^?1SR4(Ub6U^#tyhDe z^lWYO(t@W%r~63$7Pvws;GLs_s4><|-95L?8kjk~=HdZBL)uc-G{+%h_9)-<+t*{%x5}&z!vl zxF^itF8>o4x6hvdCY_{Cf+^_d%FfPt+qW0Unk7hDs#jxcMy36!2vJPi2EhH}$Pgz#X@retVr!K|Jp99}n*g>_3paV0B zDh#Ib$?q)f2pL|{ndXaGEW?kmHc%m#)uM!KS*$qz^gDvP(%3J_poUx-LPIZok60=m zef#D47WWtdewK~?5mOK!26wW`>KEVnMf|TQE?naNklR%ktG~>cBP_NFm;g8 zh*m(i5`>HsTN)&v&4(kUB>Lo#-kOE<6bMXLi4{4Z538Qbu#7>Uh*@TH_@$w&2sen9g*g9L`!HI`MGNx{{rnA@C+4xxE_ld_q2)MzXVHPwM3jvi8uYs+QQI=vk=bR1@D@$za7Ub%O|$7R=jt?nc0L~Vg%NoVlUZz+;l)iYqqH&I!a}7gHg^Z z_B~^%WrYP&9v}f@lnxR+t#;n1U4-(t!_I06(JVC0!?lX93|`f|7d#;_^7J%Z~UHf@0~ln-RU*cCq0?T%%o>h2oTZ;J+#oP z5PA_|XeuhGC`AQ{ir70A6x~?YwV?iR3%(ZI)!o(AwHF|Bc+a_a5(2V6-Ou~~2j<>W zZ#nmr=Q+>wd>;wt#RMu)gIqvIBeahvkhZ|ZL|IP|E?jhL3J+E0ouJ*ABZMS~FwRj4XNzO!TqIv$jsD?Iieg1C0tLVle^rv7>k;OtZD#6>} zBzT)>S28M()!3fQj1Pjt(IM#elEF&2L{W-_8Ow9QeuoA%fIb%tWmG^hmw7Ij0foa2 z!6)J%K(p*u)uSfgU&@WHC~VOr&}#|l=*q%oP2wh}v1()@Z{NIqHdAFsB5!|8%!q?{ zTsnpnj@@oFRgS65+duE1rLPaf=b_i&&m*g*c`EKQ+A7Az^Y5I0&|)TmJ7Ti-DqJ@P z%HqRit;v!GrKp)WADES0UK$Rx zS+kbfATQHlj)Rrs6AvFWw^9AFL_u$##l3kbHIkY}EuknLuV6taph?n#@F%Dd_caLj z#1ABSgT6R%YHt?JBQdql@+Pye2I6lEIX)gMp|TjfR6_z#6U56+oXYaYaXd(TX5hGK zLp@mh(!W_LtC8B7X7qVM4zK3Lj#A*}nR2^v_HhmnEMEM!j+aP|TAjnixhY z(c|7+gCt)9X8p$QdGw`I-+t&{6@9mZg`oNC9Xq~8htZAbFbRP%pc7PmdgYa$q8HI2 z^dbqt)E&F~_^Dtykn*8QN2ls6MVHeo^f-YW$beGMtAP|fg`{+{KegwX`CTIuN(*n- zxRic&!SVDO37eP2bUgUtJLte{c<7!5Ik4os8#fCNbLz<}KLu46JVXE5BecJs=xG5R z8}ySg;!hYQjM2cDb$|~ff}t2=W~$NGpP+00^an8c#0m5nh<#2!5J-P_!>ZeW@eShA zGi5lK-g(VW2W|HUPhPwC?=H3-)u6RYM>RU{_pIyJ&ldbNDXAb;M6C9WzDyVP#ehc_ z)eZWc!(C(hgHgJd?oDMoPRkwHDS+3cRR8}9NA@Y4Q6a&BpK(A!p_GW8ah6Ks8=w1$ zP@cpCT&mxp4Hbm zOG8!;!T&+!;~WRI1yY20!(-lCX8DH?38FT&0{^MOBf%lVgKu3rS6UziT>zjS{Qj4m zO|dtKIxT=FLJB@eK_b(@Y?j_!O(#gOn1I326IIo@*-2Fxoqc$6c_g=?X8ZFwf$KY0 z7sg|y<&LDURlXC}r>hhS_~H=oG6-L-(JcNFKUvjhH@rDctq#p7zg+io#)l01v9N|x zz(YovxaWmOmOq+h=I~PpL>{KI=!A!+;2)JwpoiYuk3KoJX3a6+*bnml{LZCMZu~!~ z)c@HyZs(Lnj|4Ttf7e%?K=<{M0-zi?j;;B_A69Mp2>txgrlMh!Is&3znK(}nn^7;- zDo7+uMCmdpD4>%)wunCia7?_sJ1Xx~v1z0$jAI!eUcmzwdn(AteRw5}bmb{BEhWk=yfLybrqqx!E zDFOEUKuN4A7Aas%mo+3q4P1MG=lddGM@_VDA2VWFlQzFU9 zk?eLC6bLml=b<^3?pEfzP*xtkdTtJ@N8d|YvMO_25tY@v_JIf1S}m$#@X5vb5*MC* z2zqfM1Kc&BmLj~MsB+>2Y%HUwQU$n>k#wN*)Fh{OF7H|H2-^27>lnGrZs6@;+ir5| ztXzKkGBEN&{^f|hx~+S08~W5>w;NWk?O3{`9pJ^(!N)&ZyWU`T@R!;gm$olm3LdzS zt08mL9bAf?EIhY>DI`9$Xr4ac>|J(dpcZid?wxzHh(3|H|^)(2tLvIrT75R+Xb~ zb1Euw2JY;QV=vL(Fzixr z)0=O;*#V8|e}Q4>DUxtAG~k?}=m;2kDf9QfY3J~8qOM%>gK%e6alV(5oV0Iq-d zG6Qc;j9Yg+T6fu9k6hMN|Mc-h)n&B#JSED8RHp_Qbzo#_A~~mvf$}-JwS1~1y(Rk? z59i^izwap=1V5kOzH%!2tc-gT&!?NHqtt8EG3tHlZ`41i&!{gcqPY}z(U^5Gt07mw z`iLf}i*o}Ljs`{Ji;_e&#M1*|Q3c%_MkKb$l8EPhfulC}Q`k_FLAW5ok`S3d1p6{` zLQR_!1ze~A<`7pUm@IX{8elYI;!av4>MRk3Rm`Q);SmaLEm z(y$_dN1}gEm33CPLt;cOx7MOlgTG4^M&8acW{Jke-67Lib($vtxYJa4U16e7-jK_7 zROcmf3`V&{8KJ}ZK2XK#IJHF1$rw&!(-*4OPt=ARYMeu*%B(Dt()80hM_#totM(~! zr5wy|>pQG2&C}7jKZTCOWp=083fEj(l|-kCE*TDPqkU!3Qie0O)jH6SE{Qx}$sc#i zv*|Sel7Ca_!p2q8hLz4wRJjs0+Q7aCj_#TU8CJ#yIH%HO4VXN(n(SuWC*)dplSx%p zWrViajI5#zcp;wkLav{a)H&(dzlU;kGO-tycNn zNryEYh6>G}Sff-U!2~>{8IbGp*b3~UWU_n*z$?(ysYZXuoUbe6n>Di7*gIdzrDbv% zALkT(qiwnFctI(fub}M2H%cif20*y7$m8nq82dM6 z#x&Vvg8k11GrJ)~f0k_I3zmw4TC+IH1eH1tcM?IjJPt|-@(WSFBN7>+|0Pf)qVBVx z^JU1a^|2D%?}RR!$nZzZwJh&i+O#prN);LoNWBZDN3zG|a>_j3V2%}9oW(Y^OlPJw z617aL<`s6ILMmtFX3!}&=es916q@q$9iv8raCvzcfLmsDml$-lElB{XhF1gH zTadl_*g^D<-z{ABd*JAqaM!veBa%+JG++o@91}*~5_GoORhA*cR<6JAJUa>(UL`xJ z)p$P8Ks5;U+rlP-n5#B(5(6eDYG~Sw2?ejj;HJ4kSO5|QA_fm0|0dA@Geox26J|ny z719Yek*K%;ZIEy#!RnT1i)!dl4Xh?gHMk;E(6h%?`@k4&_wX^RCk!za)GGHV0)fEX zfNRff&nfpR19O`K&b>W*ZrkH($g?+gt{&68OgZ{Kdd})GO-t2dpJ`C+5z4ss_TYcc zWTCNn7M$H|E2vlEjHbCl#%+6@^-qmeENdOJ8obrB*Oe?VHg>KVGpt)X_Q6`^UPWMT zFhB}IJ-K7kJaR|;&sBe9oCZJGn(0l3!ZW+ZteG;@k=Gy;nVY$xEBU|}#WKd+vRpCd z$@)>-WSD*PAK9O!>PRxFM=3i##A4dhS3Z1?+9^SOG+%vlEn;NNH$~ZjC@CSxYy>5)g z9gu@veW%sw0#3yeg=o$ETvz}xqg%lkz-u%ol^L9D49;nts(}n-##^4SySB-I7b>Jg z_fF1o9HW!ypoG?HebC3yasZS@7%5{TBOQ_w2#Uc;jmoT1(q@ef4?{++gggJ1lfLPn zjP$c~+zqdHr~m0*R7+Pp1=gL`se0;0S(U8?oD5GLdKf5n`Z*nDq*G`9@T25A6@W}! z1|(!bO}(;cfe}p+Y<2r_3y3}3P--0R39G0ps6EtO)RR>2z)sJAGgbC{xNkx~5MM~f z3vHQnzY_odyF4#~a(Q$hi|l8n$bmgs-ne^yUr*hX(lG1^cRBVt!s#plB@68QDz@)rRMQ#ncAD67HEJQ6oQ(I?D!2h6%^ZD_g}{8 z|MGkOmi}=e2+sfO_5QznK2}gzIU{PS^qzz4|KAU(-&*k80aAnf`26Ntfco$6B%y+~ zQ^G!%1Rv2LxYlofE%@j_@Z#`67Z08h@J56K{4c8Y{TF4=gD}FpX7a3->1DeF?vIjP zsAvZU>kIk&_3I9z_cPjc=zT|NyWryBssMeJNKhAf2 z@(C{esi;}kzn3E7>^cRB(MTfu5_ultMV>5}qK_4jSw7haqbJrBc;@qYaRza=5*SpP z*rEm^8Ix4O6FsdAj<0H7SBZ};msX;CN4GR@ZWIpSs+Bwr@B&-jY7vzH;%truJ2f_ZPm1K3i5$E~sp}Wf?vW-?wb;s`jRRi&wTc?O#l6ug+4C_{}zoScSYPV6qR3?jA#bef`UUzSjj!uvp;b>r>zD-~Zh?ERKGgBR6hLpkqV% zKt(>Fh(Mab*bp{QF~yRCsdOp{pH4TX8`;x-cRJ~)bEK1Qe?buTn(|DrH&`$kOor<| zTY?aRY06irLn*Bmq;!=&nhMvc0VS25rPOtzxi-GPRP_IG&Jr1Cu>s*ZSdck~`s3ue zShCxT=~Xe1dBA{hz)vYGy!ZeG=Q~MoBU*?SvhNOxp zKA4G){3#9CV^_U73#Jz>I}-=tH-C@*2UuGtK8O0yzhK9>D_7LqzjS%=sHLgK^nT`n zb?ATQb-tK>GMPYc0_mUM2K<#DZqvCIuZi4s__^UN*ZtX1zkcH59a)FgjJR}kxh?Yz z`}Zli`iN$3+@z^<390KV>N6bDv^l+mL zmVzBe+rj!3J=ZP>HH~h0_>NW6jy$^#${U7(TfnZ3se`v({$}-6is8je6o_e@4{Ff! z=S#rQ^?hG1TXJhoNq1RWjt;%>ROb}*$cZI$vzmv<4Oz;)ORSpIr`y>pM4+wKeAs$zP>I?yZr6dK{zIN@kucf!| zoNKqwZK-v;_cj|l3|T9O&ZXaeZ2gAE9^0_~vEAs0qiBTkg)M8Iw*DP#ZJVMp5xaiH zGe?1fag+Mjo_X%=ost~)p5~UMTk4Tk4yQj_{}`_S=%X8+ML(kFH$J*|`6Teb{vrtW zJOiZY2kJb&QHtNEo@&YXi6C32l*kDRrps~s(D8GdU{(E0M<9~GR&`&#F-M)S1tnGAm&yuBW?Mu+BhnAHW84UOum8&ft7G5HL%$tTxT7Au&zT>-g zAAjdY^c)DR0`KB<)H8GY_E&doCn()#$4b6p&r&MfFY_^vJVHPlqPc(|c*V?<$&R^Y zS_5dJ-5O7X0I@a#m^-6+(gHw22SPm2NMwn`iBq#&5T_*QK!PZ(v2je%o9G4&M3eB? zS8y7c7q;ddzM*DXk(*|o(?L$^Yr960I;t$@^+Ruz{{1+2?_bN(p~Cmji~Pri_OPYc zS7a%Id*0P6OscTI%G0Ru{sWY)+wne{yvN%yq*A8?yWDZ5A_Nwr>r76%EMPBf@=xNF zupDijH0=6$qm4!|%T}q=*IYI>{W-eH>7yBrJqQ+q`44DKCi>ADbj>qLFw^Z|puv=9 zjiZ;*u0X5L;5C`#dU_aG_~MtN(A9>q6KW_;o98(uZwBj0p()@bm?h?3@5TEwHJg|sQ?8$hNGV}d5v*6sjXHvMV$(t|w=qV9R zE=6A8)M@c?XAXLA#v`P`)aJ?LC6eUvlj8B*OPnMm)=BazC`)K2ut{uyzGs9erU$Yx ze{xcIKgv%As;eI(k8A)Dw_^$NW&=mj_byQ&6p!r5pbbTU+;2s_R=*seh%Ly2ou3NF zm&q|j;M7xm(DpLeiI1Oxot-5?-S(i>=d%X4>w-AE^ytHH^qAe*ZiRE}g9kwV93$_{ee*)t_QouJ znOBx;a7yiS6!tH|#_c((sMRO+tW)`buFyPuL?IV&xpSm}hAL(D#0vyLK=k{HzX?w$ zVdBq>qdCl9hj1vtCp-*=-mw5PV)J&m&~Z>`L7#y$I1KWcchXP0(KHwO$^{DHP!~Ah z0y-BSdpi8PMn*BqDK%bUiTC$PY8W+|noiB2mSAplJLX6CQ}WSMS7{1*o=}H z8%J?7lD6e&gSj7cKSp*2y@kZGH(@49II&Qo1kd)gnKSr=^e86S&tAkWbKB zOhKyTGPPO_R5BCDQ7BbXtyBf%3W-dukjc(`VK6{7)ajslyv+usGP7AG1-7GBt3nQq zMkrTIF`J=MWi+akT{y0m$P5OVL=85gkBmk+r-hhR(sJ@CJg<=A5ROX~({Y-C#}SoO zrUctw(P%W7BT%a~2F(n$T5Hk*r4ndOnm?-bHa(C?lu#~HNI5lRW*=J7_ivTnF{bN9 z;L^p)RvbF`4OGb0YI*vHZ{(_yJcT6Y5p;X0zOjPW74&_0tUEKBx-Q3MTY};*baLfqkovp<7WGy7ky9u2)exjbc~eAE;?c2-a+>PkE({c^9)%;`MD^{}95O~kiAkd%=PTnT3s_scmb z_`4(4?10#Y7|H%Cu{WrI5yAK#zcxN#%0dl*#Ed7ogrN5qj0HmmjwWS8Gh_P9kg2)rCD8Ip_RYM@DExNqsgZplppix->D`#X= z#;9emB+=lvs8kBK5tx;F8L@>|CXl^kOmsNds8QkP5#TA5VBHnFpowjc+DlzWaO_{CvI1G>_w1ZB$8dWIqvZKo+X(&pldO_;j^AQ<*oD$r?82^hI8JSShK zfpARsmFqihiG(%ALJ6c<*QG-aBD>}C@OXM{PA3BM({c0=EYdm-$ z#nF(V0ZXS29Bf4IcFw@uA&yJnbxW^idIyU>z}sm9zLOGmz!z11lU!pOWdW^?%(!;cWKP2j*+YF{DSl! zfdwe_o{kA_&Bfj+hl>2h8As=dCCq>kRiq5R`U*^{kLo3x9_>Bdm=^sF&kcG}Z!f8m z>LyhP(q#X$_V34#=S@&e0xEgTXJlhOXXb4D^>^?QFm4?XEQ1Bj=QtmW5~qSNLq5Y4 zQ4AzMy7GU0yHpBMaQg!3^&eg@HO@%2nY>2@-)Kx~&>#41|zGRIa9|P_0QT3(GDA$S zyGWmo{?>7N;hqrN-)aJSWHj>YE1=-D7YRptA!!!14E+RTvfs3P(W(Br03RWK|6cO` zK;8-DvWtBG1T}(SCjF*2t0oqsfM~oEyHdeq#be@V!OssM>g~j25tFx=K;Xr)Bs28u zAHPd#Q$!WC^ob{=G!EFLe^uj`RjdDcVLDo=(!i^rNmY|M|E3nfR|w)OefJ%{LJ(gG z$6S;ibEH;+3BUtgfK7yCAke?jjCnR48^Dx_&X94!MR*aB zb^Z&Sh#p0cKmR-(#i8%eqb)#-7q73c2CeBknKz$Dj{{ZuPCDxCd()U_?0eJerK322 z6To7$2+aA&zj0&V`(Wqck1l`Wi6Vc=&OwY`VWJh=%(EChuP-zhbk5HnzNxd z+YG&!g#XYyfNv_L*wwgSc8Yyc*sb$ta@%U_hIcHkS$i++EBO7|gP#HUKki)g zbUc*1?Dq1TkKTs9xI-k<3?zajiI7A~W#OYY#Obr*f=^b~j3;8wWPq>zQtco1 zqAmBm&~b0a3unH0!QptJ6V`!sV!~?~7pwHl7dks%a7d_&XbG!3NhMsBRJadqNk1nf zfZ)esW$6p|iI)@hYqBIK**_B$2yjlhNlz5{DS}UsRZX`1LopMhmz>=857di#Q13ss zy#U&eeSkj5_=BB|KKS4mXnz5w9wwRF{sEE?{}C+v+WkpB>iPR7(f#YDzk{y)PuyRl z?L;4($Mf31aU0ISJwC2aM2hifWCTSL!F(MMBX_c?nINVcaX}M^5RN2M2&e^{c+u3o zfWcf()Ku(}n)MmIa$fqEmsubUCrdr-@L`d;E!A3W$f2>T)bi~79JOk0sMWxOkkN2k zk0(SkrZ$ITPF@GkyS;`&&xDafO~%UM7A7mFI9sh!bMkP0TX92fk%I^HhiK8+Bk1tI zw!+;fz*;;~q|w={_U<|~G!oLfb=v6Wr88YlYq7^Bku1|S+U!M(v)oTUUa-XL2@KWg zmZ^t1ou#)NN#?r^9-TI}Zq>T(Iisp{Iu-5o)OY~0sJ2`bsRnhwF$F?BP!R#f{}~G6QOv*9H%*A#3dnW zJ7(Mk6TuMC*e2bQaC3e+G&7)CUVIZp+i zp8qzwb$+=sulC0Gb+zfgjxyQHrcW<(@f|)^T0S4$`gUop?)@8U^VWW*R{zsof26Fl zsAN(}QD@nadiOuo>d!oNM=Hh_&lggQrM ziRUo5`LL(7)G@RB67)~+{clO?fO2f!-DMFtu{~#OPWz;m+w1k;$mQSY>u+zFBqU94 zzP&;JwOszSzTx&}7_5Veu{rmY=9GHwe=B_-ntj+)Qt6m;N%u@gX{jgZ!5R1Dj8#B< zYrKY%C%a@7#;i%DvE7OATNEF1xFLWIW8z(QA zKHJ~a(&7&uYAuUYj$K)i7tCG~ZfMRu+0|+K5PAw$#b39z}qY%W5pBeFHdj*sDr4ui#AxPk`oL?B)fw7~cLiFm*t zi;ubh-&I02;Cbk%fIF=f_AnPxtB5xYpO^S0pvlTa0%T+e9>@h`7S^cscm=iO7-1q} z89BZ=0(?ZHJ`^Qt_5q`SY8BH(V_pI2p1|7UoT!nw*wPs?THoS22uIy{>-~EwDl68l zTLo19TZrIGImya7)UNN5fg+FH*@X>hkpnX6W{e`VZHjsDkw-|D6Sq->Z@XzNdq#M9@ zxGUsM0;PyYN9n81_t{!@mSTR7zmZeG3KGG=I7lR5WZNq!;x-a<6k;7NV8aNQlSFe@ z1QsHj%mVN+QLMnk2;H=_tuk62`zasTjVvA}YGbgmAzU?7yQByFdmsAl)?~fW%(8xC zv~1d=spjU?qc7l7iCh)TmM16g`^(B(fr>HoEb-O1q3y_G@<6*`{dd26d{brT2wzV7 zk^(%izu%{31NhF2DpMVwrY)Uo2piP=r8`#rW#6QIcpcPd)6;2~7Y(NGqPLrVZKkj10sJ z0N+n{RbzVd1py=6gK6dA0)Ff{;(f5F8(usa;2=Z#gD^NlT*6NfMF_GS(Oxl&pmSP* zVl}~rNOo>rU2ZmQjfU;{`Sx)1i()Ya-d_?TDWMYdqdRmD`s5C?&tog9ws*+V!_bE> zf|i#b24%H?mBZEtq9Q2D@keaitvLae427*_|KRj&&`wW9-g9^VGdf}v?*7vA>g zg#N%^PULB$ri|LYpv{lJs)_5Li3F%%;p4LBJAxHW_a)TYW9XB8_oLS?;ed3TT%+ZN zzq@MgvsaBAdDXLXryp+IM%*}~q%9Z@xi&2T{0;kn<5>E1zvA9WK>>|+pjQbt*Y#WE zR_RqTD4#kPSAQE{WoX@1u27ih5fYEq8)q$Edu%Tn(B$jt*IhfOzhWnRg&JxFI$T=- z&a))jg!)9vS|Gt^-v_S0Kyb)XICF3z^yDvOgVp$6FW`G^#q?xG`%IW6@eD%5bOIQm zkv5oJbcVYdTq1Du5R+AzW9oGw+f7yod8F zHg8_J)&qblke(b=0T9q8BVnth@JK=Ky*Xy9J3FrN5F9I3s+MUg3;Y&K!I6TTdvdH+ zZ*Hl^hb!9PGge&Drym)$TJa@w@6WYbefi}$)2pp4^jlIKmu+>s7`fcI3S427GmPAb zw(l^>CBW&n<#Ak&#pPnB(KH+ zb1;+X0Ib}6Ro}=}MmYzaE?b^}FJw8JVi0cQybN}PV0v;+Iomf7B8vB-jc`1hU|pbq zCBoPwwBNeW>c7@!TWIs$FnxVpa{Tx;i$Mf@Wc9Q4!<|VWu_|I`QdYm;%DixH@`K8W^kJv9_lJ4R0|@Cz+rPmDMEV&qI;n0Mix87@cM zJAy9M0|mEK8CSU*ni%GDXEL zWxUjI{cb}Nf-&qb%=lR9vhky4&&d8N2`9zsa zZj*P)-&a@^opQO%E}JOJ(yIl~lP>jxdWRnW-!qXEmE&SIxs1L!Vvy$@T4*hjv*FPj zy$bL^!FLV#g2~&SxVHZuz(sIhCnR~k0pw*W;w#&~5{@z<QU+_nH~B)K4)B@Ul0esk{{?-YV!SB$zRX+#7bC30ClKl@CxW+bQcuS4LIBcqIX5n z#p1ajOkOlO{emM1VbBiG{x`KiDvi)4v?+~r(e~|+0TrkQ%EQ~+qq=itf_9X$2Tu;@ zzYp@tiI!e0b!X7Naicw${x7P4t5ov25X_RRbS2FrTFL`~@|F?JC1~8a5~J}Y@r4KE ze;G^!gP^@rmcalUn3s5hW<&&j{Rx6dAz}stux{)?2=)eTK^wvo@+r;&|4HC&#VDT1 z@3wG#CkV_D$Rc3B{UN3|jq}sOQUNJ?o;jU_y?rT^SrqUhL771!<0hOOMLJh_W(V;_ zV&I6j5EBA;fePwtfEf^hBuCDYCz=9i@$Q~GP{k3n`*ARTUEv))yTNtA`8d7%b8vl- z>1vuEMBTVZ;X0wj5%4l8a($p_0j~NvxGsR-!FpCH`G?@^&PbID-iQXHA6&#gq>IIr zO{4J*pyi;?RlF363$a!7gEJK5j8vV{QlzjSjDBdS%U-(F^KU%xxXZ0I7!q z%(%9>D{AMBI> z_UvKlCXKy>%!D)XTDUJGt0g!RxK|18yL5bl*xnlxKnFY=5yA3w>U!wD{`&Npv7qq; zCYW2%(XH`(A!Nq76u*y*UtWU)NmZ{tWDm2Abi+wj;yc&I}^YKbns?YJMo^8w@ZMM>7 z+&$5NO?_{nn$`J=z{=NKrH*tbTTxz$E|=P~K}&g9MhD?7v{Qp#skZ=gf!gH)O_xPv zjzH0F$%zfg=2ej+|}KjfZ1>_T0%Dxlf;d{?(8{-mH;AOpFwU!L0l0B)rc2L78CJ zFUoRK=h;2jDIca;iLV;`^#lq}C%`+#&ifJiRoEc(=nUL>P!66LLm?u~PYYHWEQK(^ zbnb@}X1;M-9m2g#oxSIJw( zk8hEy^t*vpI&Vf^b#>luy;8nq=guv1B~H}H_8&N~Uq%W({l*(llY&G8POzB~_Am!a zq-v-U)F^5OwSc-556%mG!BPL^nP5VSXm)}hyn(dA75d zdc@$^MHA@}&2yXaf7D;U-wcn%Mou$~XBm_@yh_D9&Jw5`DM_>a411Pd7SpfvU zH^Kx$6fHzoP6l5HGk~B;VoN(0awnm2V%V~vCcbj4!}Hh$I-h5&R)(?7~RCiZvEppDNyNapZWcn;q#@C*f1 zrC^`nf)Y+(^2wfRz{T{V#0w5^py)0Ke`E<43=w1n!FwFd?0T2tu_3;9_za;GB zE%IQlang(#B~RJ{t1XM_uJfh2EEAX1w{efxO}|^y5{R-P%(-a_{UmKk#l@ z7xIpJ-kNh@$B7p{?i%I}UsXQl{l}hY($s8q>muny&z{Z89(?A}gPm&vxsSo;b+z|C zjlRSG9>29Hp>6%=#CMYgQzX@*-+17Q6Uk-5%+h#V za7;jOM#M(}9p!zjV4*?)C5)nKGG~gKh?==5JczqN0JDyCG!ZqKqZf`K?#ZjvB{ZX? zm8UnAE0XAY2ogYZyUw<9*cA@}HgIU}A-H!)`=$E;*jW^;42^9xnVS}G+7GWO&MPix zjB7w|s@C-5gT8lJ&CRLilAndHEX7CY4eXG~v*d}@AQV@%O+rl*8do_Hgd5ZA;U=wp z<&@dO%zmRQ%cHo?3s%pZ-(d9`O&(yC-V#qA?lLveFPsrB#tP#?JJ2>9rKfC^pDL!> zsD;!fY8Q0}b%gpO^$GPIa024{K$NV+1JPK#fbn_R{&$!c8W+P2&VXjWDB!yrB}pehYecL^fuQay}vhz|5}DbIJZn)NJ5<1Ykx; z5@|V1uLa3Ha4v^GBR8;XoZ!yg_QJ=A4|<4m^$p|#|F#%QzC9Y_S+rc19sbK~PTY{-k`EnSKa z8*X^~#xvIoX{+-i1@q?@MDkaYG_d8ojyf^R(2bzDA&k7cIYg_nbMq?_R!0L>^wW_@=9-PQB`;#fx?_>cK-s z^t&#M89APH$vww2W@NmipC$UG z!2O;Q9(nB+%EPDsU9fvJ1cd% zDu-Y4b&@yKoEkN=ZR*sf{7P4CEl6f3oJPCRY4K*4#Dl+Hf4UHy&DUe-U zQ&W%|42PTM%x=nIeyTlyUPAXE140syE!g+K{N3~C?*{O?p`8F@$#j>gQ<1SZWB5wcg}g7N-DozEB||B2sqBUz(_ z7&pL&3K{t4G2+inew<(+5lqfJ)}Fk@-fHzsc?#=OH{{<7!B8_}0_@Tb}9*L%Ii z5pPL&(<;BOxY+lVC3)Fp9%~>sV2y=0uJo6;-8gCO7Te|45gWJGa5);cQYW$dos*_r zGGi${c47MRwzlF#ymiruO3#q6vkH9ctPCzJMBluN|0*ki2Au`qsi)HK8e9ey2f@V7 zPN11Ep|2EZ%5c5(JD(=n+7j?kRaHSjVc`s*9&1)A0j#PjF9&P$@Sh3)O`DdN_ZYZ> zluUP;GJoae=<M6PE&zgXw1nV+5PdU2ipBDAA$gE>H9q4Klu%p)1PAqk@ZKzDB*1UJl0mG&$4Z3q zoI!MOkLhXg0ZqT45k89soW4lF5ukOLq0~Wz-ej|YsZqbvPf}0c-BR7d!&)GfG#j8E zDD_$sJ$5>XWs?*&ZEqMhYe>1HQqQP{@Zbe0+oIs+=drpGtTdDlI#f7HodxS#st*{1 zi*zWNUtYvEgj@u#2jn6jsG1Z)(K;TU8qVh6nFK2Mu%BCc-m<TwsBM zG2Y{k2=N^iF&@p8$oWN5ISr@%6|fSyC%kZYMWe-_lxcxcE|c%ut(CEG=@zD2s*;25 z(o7ZA@?TZ~T1*t(57Y|O1z8ync%KR1&I~>}Zz(4GAOmZ$hKf+b@Jc)p)33{^tEpSW zbr>(GF`^jmiwmo;ukRVhEMSp>pDXB8@9<$!*C<9L{l0>4XzNl;PX9dga^z|Jr z1x2;>A$O6p!>u3IHL@s*nUb!J`T|{bUT}C;VU{unY}2T+3gz<6yKSY~!ri;!qWtjC zWK6ncw?AuCv7P~9 zT2&^s&C{I~3^kV5TGVE(+p1rZ9mod0#a9@YO6UBa(SDa=B^P_} zJ<^*=1Cc%35F05G#xhxDfQi6}5Tvv?@gG&q5El>q8$@{VG82_}iK*(#<`R_L{q8OR zD6O_)Ox7GGDh2YNAC}vtqjBJAKGHG1D)jkt($e-)>AL4);C7q????MyEoq*=d)NGj zvc^4;Xcb2ISpQ5nd%PSk>dw@Y|}bV5(G{D1Yu81Yqxr+=a^$$5P1W)ls07jM zA-)BLDO4vSG5uN`c<|8hNI16N@1Hn8eEt3z65?Kqn|NV?)Wso`28YupL2nT!M=#1b zda+*JB|29S1cD&esA&y@WVlt+2x4k|4-`Z#X`ui~K(@c?e+bk6ULk`}whM>*nn$f! zF^YalxXoRGl9Iq(`aw9ud4eV)(G?(&K$Hl%LOTiNvf=&*|Ue`U!v7E z<`zG>bI;2~IgOl5M(6&TmdRi_xtjP<72bic?!Wp4AITkTs&GOtT5E zn4~Q3)LP2p72cK1kp%8Sz&acRB~HIU`f-Z*Nl+x+|)t`TXJB^ zZI5jE>(+5s2B8AT*p;l5g{xU>mZN-pT@gBn-tX5`|Kt&cO`0tQP(J(2R>9An;6D$H z2Y16$3)faHJT$F)?bhGx7T-TT3PH>hsT=>h2loT{Ekl!hsYIz@73rHTmXHm|LRBkU zG4(&GzlpAsK}E4rsgjNAB$ouGz;SFX8b6>{CCIpZ6p_uEw8VDDpaDeQPP}!nA)a`x z%m~$qFA5n50i&eh=#-D=%H{tfx5?+F?+nCVKT9Q30XT7$B4_$0W#qVMU@6{7%ye)#jH&n+wG8cM4**=lQT)9kqtYI0-E z`1IA6PCT+9H5%5(&-~cD&@}Xq==;gHzp;{yguH>e$rXOhdGg9!yb`aYuA%mc=+O}Y z-;!*e!l)32Q6VCxi(wwK3Lz2Hl@su_E*>Fl3{eB~4Ez(>8Bx`ViJcSr{W8K)r>Ok) zpu?5hn4RVHw-@BM`&~wJ$l}X&IfCt-LYB`fMDl$?k^F*oztdz2lOn&YA>`sJ-R()@ ztw8*jZ0|lp4J(a};2mBEAMAwxF_I!87l++qH<|2Ko5N|f@>;bC#~qnO90JK+A=63zIl_I>k_ZDTw=Ax_7`|Nw2W}Y4Hk3VX|NF#Dr(FDDNS@Iq-L9^fU#% z^UWttqwO)LOlc>e06H4_L63c}2 z86QX-#f+o62n9*7gc(tnR}vy#j|ad+MB5F#W z$tvY?SBXCWh8*8jF|V~bQsydFWL1n`-O=^n>_6^*WMrv*w8jZGqq8^saOJq`e?M>B zb#um*SLBr2y0(p67Od$QH@>M$oXRY>Ilp3F zqgJ=*AVZsT6!v^}MzIkX>&{yP#tHItq7xV@>EE{UnJ@_*5^+Kd0vat|@JxcBfhBEZ zHi~n8VgOE97~ov=BG~bJKlk~=G6oj=<2qpACx_&oA<_1AP&;j=GaRvlQ5Dk~&1In> zZK+YSo|sQFlOMd~>B$B~WzNzG%l00e+r7L%>N92g6Q#{L3--=E&$qxQ57fz30S8nm zpubR~@ehs5orY!YoVIJcQ>t-f+t~8P>k4B~=;S)<1*)5l}4|{OMyt@~y zGEOa@Sk@4-UkyJ!-w=V$$X`WVPa=D;b6j?n)wTScJs9uXFFJge8#l6IXnN=p0 z(JvKGw4kku)~~wy>Q!LV+-I+PhpcI7s(*E(NeEibRp>u;qVLfg==;u*SAn}OpbG}s z`%wadJ!Jvn-C^cw05hO&k6GS<`^+A=H}mLucLXSN>3-Vb`tu$}nD>eL1wIk$NDHQl zh%^d+=Nh8KEzy#(5sG5+9(XvDnGt~UiA{juqm9rDS$GP`B7VaXA+mgueuGm8uO_&S zjpETC%7h3IS~LPrqgTQ{%hB3lTaF&xvh3kIp4OLvB_IoB&6sCo*`r%3s~*(IO&X(5 z|KQ}KKng0+DYOHfYHO@T2lSqo&3$(tL8kzBWa+GJg32REfyc&tC@L&^3_vk)))A0u z%sS&fihe$N{a0gZZUm_m;_W=i% z0xt1nuq2owVsi)T&Kqp^%n3awm*Ct{7sz_~evl|yBFJgsdH#KU7vfIoN{CdFm~ol; ze%UP}%2l1iSf9CXzS+kPV}mXx=nDSBVMwP84u=7z4B&oJI8EV0$~s5(2(W{(!2XDA zo*5_x$!4Jvq|8pI8KqnW1#nT=;Rrj@6VrF5Vk1VxQsNO#>|P9BXvd_lTCH9uq?p!2w|iMCC@@2SVcfQ2_)( z(@!vc@La+^8S$s<{E>(sKIaEgb6*Y#)7Okg?>+DcI{uKE{u4>)TRt9y9@z5jgLA>M zh<~$g^ZV$nyM9CqW;{!Bx8OJ^zWWETYsOK31pcit8f}b@9XmSW^GB||`yur1BmLny z4}Al+_#$J*+=bryU^9@Pi1>vVDE?qG`td}B*gGiBQp^vTZ)?Z>e}#baO`G*Z<|NoM z7vNVT7)NFTeJ7y>r_sb>kE|;aqO~nJk=B(ED-plALE&N&5dqgogbByv#E6rFA&D>J z4h<7`rp&@4Y*U;wUl`MF+gf93Oh~fZnaC zTr;AGH?+;!;#HfoRKc=3ry+W)wc^zNzumGIf2UIPhh+h!GPhye_ztI*vuHJpqoFD* zIUztZ+hkG?92xJp$5SG0DOEZja^}XDj+x?ETjk8YqoZ~63lbZzP}LSx zPr0{m@8a%V?=hF7r;Omm`qIAcc4>|kavZ&NI+`G7!PNJCeLwgQU1L*QTC>`xC*x>; zcFpw%@4W}W+@fZEaZJIwyd@5vVIa@@9X6At;L0KHWiF)>%8x-#9UH!Hq}P*F&ebWs zA5KWjT4!r=Rj<{6WAoZ)rJvDBv>O&(KWo_Z|I6H$2S!ok`*&4$PtScH$t0P~WHK{3 zC&y%F5+KPWgd-$C2&bIkz9HO)2*Zs6id+gPW;oy+V9o3FT7eVRjYZ2y^2$-W&K`Z-)JXfD>kn1O}Jdrn7$$>VidI8ouFlr z_H?QRSPf!>eN5Y8AojqvQGJgs&FFh-!3*^Z+dtn5!dpMzjta>$b_Cky7HVPlAT15^ zeRE4knAmu{9N+pmsO{W?-_omDaq-TyG_%d3YzCJgn^8fzYna|#tGtLGEyO^iv0KdR zT2C&2oQa0|MKREO&1lk7l3q_rO~tnqWUlgWtw~L-+2pS>1@Y8#$UaDM^ndzrX4$)xWc9#@QI})7IH)F{;HCaDu27#{3UVwGH$Ls z?60cwqgf`?V>wmu&hEE&B|<;jyP+18aO!Hdw-c^jVnGoTN=x7+Z$$DCvyWFBRnWnN&;GA}XbMGRt=N@}vv(@%$lTq0d#sUR#Xq7xWOh?5~o z+Z+LMiLej`if@bWIAczLeE@YOdJcj*k3;|tiwj3f5IO~CkOdYHG&n$j_u)m3#mqW_ zKm&Y!!K^cq_bj@g&H@U6pbL5=E+=m>$)L-l;{_kE7z!Y6IIPJ){xxk0b9|@ThK``N1xL<0l*88m%!(qRcYY~wC)9%gTB({!G{4C(%Hw z0lv%`4P4)CVS!ot9xp|8Akf)*4F7TEg`2Ye0NDpN4&~uSQ#yz4kjaeLcvvd6Way1X zqa#VG1jD&>qf7>7@aaYz28;t7$kc%Oa%qyog#R2#5+yne9A=doJ;$YYz6GYCqgpnV zlgW8>J7mGDV8V-12wKmb({_xK@HNBd0y%msg!ZI@0J@*k;P9s=()^UWtxba}{YP}%lbE_xZA1wPGg^!dkmU`GeUMPb4v237+O6``lW z&!3_%J8wi^fRw-dWgwU<=WtzTMeb;1#r+bB%}+4t7}^cuodQ>Q0<+wco8gzB>B-HV zKW=`KyYNWJi&DLzs(g0b<}+Ycd-awVUf7cP7`UHcj3cABzesmB<9>GoBd1!o$$kvS zuw(**=Px{-{^AF`*aUjUB|h+k%Ot=AC4!l~7yTY(tTMg@nl3bg8IuN~>mx5Oo>b8c z1L)W?r~}ip)aWA=S~Z*f!`X+nA6W>7ylHBv;^(bFY3S^AV=sWIZ{1Wieo5pkx_LdtOeqWrmpq8mgFJoJPl7Z?I~ zx*hP@$<7TMb7#qd7f)zJ#c=}F+++z@gqcS+uRnM8&-?fP`RuvyI{ru-fL|Xz{562+ zzc-%0bKL_kw;ep#_VNSk=B{~U{OhMq{Sf@){@Xu!q-E*4w^zJ<{M75*>JDkyg#G&` zlyR3g%$wJ7Z&?)^8Mb@(uue8N&$(bh2D_8H?MQX!NMG@+`MfxvK90xe32}LdiU0F` z=&PQ)0Z=vMy9JmBFeUiI@C;5i<*P#QOjqF7(Y|SlrvS#0Hzkx=Mk7fU&l;h zrs7rod}cATj9G;#^#*1ub0f2xxs^G9sr7N@67CUX3&=(9eus%jmsxsWL5q-h5p_X{ z7a;guzj6_OpDFkYz81pIViK-#xneUd3Q}W(0W&$m^Ed@6L+;1ZXNgQd%J%>Y*{>FS7gV=r=Hrl>B%S2`<{L^{XET6t!#S#DQUq{XRu*-FgweX zQLDkT@=TdcZ8a;?f_{gDY2Sk$0*zJd(ave;13v4u*U-DmmhDgY-I7t@P-l2E$fa_4 zGcvr6g2~$c*z0Fb3A=1Y{V?NQ7hHKRlg5zJzqaEASDGd|rzN_<3BP|XGnSTm zuBb0E4Nz9GzJP*&5Uh|G);t$A4O9aH#r?;X5F>RJAjrn{R%{$uj&nqLF4?`H`gN%# z@}{7A92X=1GIR6Cgkn2UqpKg~1G zxJwNC@Mrho$)*7?1iG4u?E8;%ZP*K3!~=b}*MMX0Vhkj{jQ@GwMLiedJf3LER8m}8O#4v)bhgASL2r4xIXcw|mBZx9>-NAX3t7+nNkgGrHrH@=D5Q5zemZSPGI{yj}Q40vqLX5sZ z*U1=-9HT4HLx#v%;!FzP;<2cfxs7ST12oy57d#Xy`qytkQF!$iZ?42ZI+h%p>wH87 zsEI&z5*-Sxt~>N^eG-^lyq^p+f&o`@c>Ktb`hb4qNNoSb8wvDl{v+G-6GDaF(HU*0 z!{T93__WQad&iI%)31IGga8r4LAbq$5gLB!`W4?b#J920U}y{h7wBUxm-hj=M0gur z>LV|=qF2y|dhFTwtC4V45gIer|M-}$mHy01hH)5hNg6Z&L=`khJueM1%SL}oD&2RX8Q;H|HL!Oeq2$Q;$;xuzO z-)6C;&RuH2pS8MARi;?qk96F+INhF(S9D|p{<+@U?os_ie3);;bKK!%ByE$yki-rfBN*ooAP@a-x(Q=A(r_E@zWu_}Rb&@4Tj$^{{DV>4g>~KVseTBty33B=C z>c9z6YZZ*^lu4o7Qw{>LCt^){9Ju~dfT(N5U@-$c<`Do{iJ-tE0y$N1M6n#9rGh0J z=?p01;$K7J@T>62>EQ(2p=+9 zQ%tDv$gLk;&aDk)W`=5WFOxYO>|(eu--+ilKC&ys2s&S^RmV5%;<&gvFMw1tET_*T zXGZwq!sz|?+qywrMC-wSZd59Eezx@_$a$!f5nCKN17cf0Mo;6mln_*8C*rgZ0sWC} zU+&cy_M*S(#Zw*fR^oXmk=N^~uaRmhh8bQ+4}vWq3RL40)5d7|R;!zS0Bu@7;mD=G zT{%n>&O?$XIFL7QJj?m_E zQNB%Y!bNEMl_K=J8Om{nDGp)Tu@S04DTyG7C7P|c^)xP25mAADRNie zrf5%he3XzS+8*dwQ_Tz^XU|cF_gFRvxZ7{!k2H}0Lx_Nj^zT@vIEKiy$7*B!weol1 zpPQ6gV1HxfN8^~TZEAgFdqUmd#)4~yHkoZ*M_;>k25}?O9eESvTGZ78kzU==lvrCZ zF8?{7pnLo$c_Vcf^ayciU{jA>_t;<%j3WvM>^%#C|LsD+mAt-WrpziYlmpq^#ncBA zAv^KhI&VzWV|>|Bu=nVHSW2WBymr*TSPrCl(iHi!=54gi$I>-_a@1pb>H76ol_J^u zfrQ_Qk1(Z71yjc~(i0jplw6B+IDUbMkQRbRO*4ZBNsmO!7Sjodn-07{NA~1&pcvbU zBp8{NNRV>lKMy8Q48-&zH#*>X>-+-`oPP^=I``qJOY5@PhY!zQMn_h7<;GR3ZiJzy zNiLqI9_&Akpzj{i_8>)96QuJX-(Xs{%w#}+jJ&=XEZDpm?MFYC9shINePv>i;|V#Z z89rQtIzf~+l-<|%=i_B$-UhlP0%>mpnFeMuv*2274o{yYj3CMMc-f#hbh_evm^~Y( zCEB4t37x1|DuByqw%}4@g5=Z-(?y0z^3g_Y1Ckyst-jKnj(&LZ9dxY!iVOQ1q_Ug- zynW?|*U|Qq7_M)|6MLy6Vz|3Mz`xG$C&yW!e#8Iqc3hBbD=t9nfPTOZTvK9OoAO=w z3Djv#`{0aZ_OVY^ZU5T=jo1f6iJ^u}kuAe+sKw|`ZoiM-PIOw*Z0~?d*Xq6KN~eHl zL81#fi(POTN}}f*LvR^RWaj)z8R9ncZxJS{4n!+he0b)Hr`a;G@zKYg{S=qo zW2iGFW8E;#)ty!MG|0I7S)fVFST~jS#=l0JAy`bBU)g=2^}e#sc+*3n`^tLo5cQ=9 z?}=lk5NDPYdXApKZjQ-c97iwhlF7W72<;lyb37e(N_0PU>DR~AcX!FHIG}9z@SfxA zuv4P@sY|~w&cZH^jqXA1H_I|nT2+%*I6|3#| zMDd;142IXlh$bGV9v$JH;}Bla31M!1EH4zTTugNWxs))3pHG}^nJqql>@d_31B;5) zjj+&QKp)6bWchOW)98aJjsJx-0{7E$c|H!@5$etoT!=G_J`g>g7O5Z}haLhs@$wNJ zpBBH;`R!HXDyVw_e?jkQZM>kC= z@VIz->t*YDK zkDNn4CZ{Fa%uwSSo@-_wSa9a%IVD?BOVd*)Hx3PzdiLc`&uy$N=H+*$Py7Omw^hv< zxpzcGb$dnS$l@_`R?IDU@GOeFn%7vED@z^EY8vM+jO|OW#bvh*uO})9st6;Zhr|#L z@akC97iOkhiGXH^VgX?XHW7zb2%7aVm@tAzXP`_-?3>p6d8pGaDk$4JZBPARzz#}E zl_UuUjZ|7ZfX}EYouZU$nm2rXV#bUUUn6X+9{$5oOxA(r_0_9iM_(WM{Yf-s$AZLIDkrMuLqEZyf)6=p23)i3FWT zU%$S3@-}eb(LWx-F;o33QG75F)5k#fh&{Lz@QNkq@H=$)ii;{G*!6KN5UMwZUWC<` zA(zBn+E7~B(4Lg=ApUN@!Vq?9a)l{y%u3>mSL4MWIu-{a?w6nh|-NX{^J zx0c}kf#?)Aftw^Y4me_5BvkphDYlu!`(i5?!kJ1m*G)k$en!yqVF)y-36u!SIn5wKTB7R|8!0DB{AM;;a@a=K4wfp{zyyI01;I}#Om{xRMIX+&`{}~ z4!M)|$`cl_bdZ=)vz=y>PQJSH`S=x?Y==yxmR-3bQ>(C*SbDicOpm)Le*%N5GZ9A1k6tFn~^#L{|N16~>yL zBhFC+7zrNVyO?%N$mu2!3?009@Zd#$%x8B+Limv&m4yHy^Aw8=nThYg&|RNld$=3x zme4UX<#u6xCWqiKIb@`*dmMfrOIcqGcvNd`Mc)NMEt-jr;QyJRHi*7!Z3PVI57vVI zh*|KSgh8R!aBF8POAOE&!P&yYRgAuf-yvg-lh9|5&}TfSp;c8Ws=dzi>0_EdalSb+ z@9%i*l2&W(XftcImmcfD^Rn-$vLzfdruENm?F?^viho^`m8E%|e`*sO-ui5NE7h$8 zE)WQ&I38TWw{ykah--fzCVZdy&9wYk)F~Q@w6RE3IT|8TDA!DusEQT5NRkyve2AUZ z+=S`SN~$L%mB`1??Y6kOZL&#Xw#XpS@9uGtv04U1M>sk;NvA~xrZl5LZ3A6w2$~~* zy!7y%}O1z;6;6r2U`fv-RWDslA@JRUa%*D>>Cx0`56_P8ZMYNsG5 z5-|*6KnR$DFGGle(0HQ9nI&$#)DkM74FEHqJDbHAITuwTO|aF;;v#x45!bgCe{|R* zXQ6l+M~1ozK(>E8B|&fWJ-q5O+E@z#L2?Te2g%EMG6@t?&{x4$Qa~ZPr3wTS;YP(N zCV_kvz(##2N~zN*1jKKe2(lhdpd|o|K{RaLL)-CuYX3^cvoB+-e z$PD5>;WyFGQcypSTI!T|)U1#p$-oxTjjZ?0Y=D6Oxz)fT)(+*{CGX)mf|(*hIdPIK z9MvE%q3<|N#V(R7A>bDg?TCg(92FlBp<9h&D#0gGw?5eqL1PNeQ;FaMpznPN7V zsm5mH57}OrRnWdvHAb|0;cFnUCQDcR*rx_NDTs*5DpZM zGe<^5Ub2iW8uKiGyg@2SR;LIuMQWN&Wl42f^+tu@AE%JXG{azqJC#>?)hv`}%QYHH z4X9X>YBx!>Lo9t*7IFfgQdC%+wYH#q)~z=hb4nZ)N;neur}Z1133!2n5U_nLwR${m zq%Q6^C`qkTaEUHi`rpLQOKpKDhv8a)@b8WQjPXu z&SX`8n~G;keVQRQb&kSh*4nPTU~7~)45=wuX*H^3r%U4ta_Xg(81%fPzQ2K@KG{K`GTr4cxpkPHEGoLdb#tN`ircJf&18>yrjXu(}#g z_L_0Lb5p=KMrGlC|MIlsQzaIdE>q^o4FIx+(a;EIqKE1mq|&O;g$n?1EnJe?09cJC zM=eW-TIHMn^$Kj_$F0tB574plF}}d2om!V5OE#FRdCq4_u#ZcrlBt{y??Rp*osnSY zsx{L56lZa+#V};<-2HPuSeW0xU#%o-Vf#mlbc?QZ$v_ATa*~s?3n6=Cq*fC3nwgFB>D zRm4jrJkdW1WJaAq!9t)btCUH-Dpgu0E|bU>wRX@-h0;Gi;BSDi-$#|DOUg@jOyy({ zQ+9(zp;Cxj9JDQqy zM8=oR-+tro-vS;`_TJ7v-ZnL#%^9>{-O#6JrcIgDG|;Uaei)rTfj;`^`Ay4eY8(Z* zC|(-1so$78&YqYFhLzLh{2Z=jvi$K;(2CXwGx z1fa$<{@9b-F6oU`$YrC4(3_ub+43nU0ga%9*dhzBMqys6)!MaMaQ(bGXBu7Jr#VN6 zQq3_j>368}=4Uoj^E~?KJlo{9c7|hM=X~pyPtlvbzV^~JFqOhGPo+KcuLPRkje-prlMC8adH^gTIcVT zgh*4*Gy?noMS57gto{EfJrK`E|Ig9`8JRIvZn_sKpI&s{I#J_D-9 z!w^$vNwtl*qiWeL+(N3FW7BJLW76s5Ld6+$&R|t4v$B-R6g~LX=E*{t*trgSgO{)$ zugl@va&){w#Fl2sJ|EE^U^fx8DxJ}R?{<&G;q?3LejUE+N~qluz&>mUwT8nW6bhm5 zo14-1p%4g#!>ART+U91U4e{YN)D(`iwT1WY4Yxsi7_?BUSe!B0hL|RXT#9(nm+qPp zOc=_9q$52Qn|=pxqKcCJI=|E8!U>_=tT>fa=WSG8otRX7-6X|57KJ+)L=@15c?J+H zU9z1b!B>Z9BJA3UL$P6^z%+tea2F0w^!18waSVv*ux%$B{@6j($3ScmhPI$EB&~?N zz=*gxIAb_Z>GAy`UsS)u*q*uSnKzv?mP3%3OQ*@_a&%{vX!v#D3%4`BBN`Q6iThMi|_nDSoQB5!g|a z=vtc9*;G2X5j$#_M0pzt)qTtm1#Oie;EL^h5ZXG+{r3{rDN{r_5ByD@$bma0fXV|(`PPNyLQ3M>4kGrQ#U+0EiZ4{lN)BT zwPUKwLXFj|o=0Wi??a~ageNK~aq(~$@$|J;oJ_y~Ic;fFxZLm+?SPfsld;}UZTJn-@C=l}LR{$)poWP`WSi|7X&!~3i5 z0_r>OMD;s=y0__W^zJhcpbt;Zy#E_k(h~!V?J-xwb4$J#ZNCcN+2rgNVlz|BzHVHq zutC+)N_IB6kjfCAT-`xQJ%@(_+;?JrEiEy}CK4>_%nj`hJQ-B9w8VVEQMafrRw<#~ zgpbwFlry85g=8Ow?9dUMcU^q%H@@SG*WU353Lg>+!o~Kp#M2haR2V3>*f_qogQOMH zPUZ@spbU6iU6}>xEUcZ5Zm=n1pB*b+PY~b@OOH2SXo_AP+h?7nRN5ME&Fbs zG;ryRIh?*;&&`>!bYKT_Emtl?G$TYpY#2w`{!=$J5wE}>rM9v`gUYByTR@`koLalQ z+To~PUaQ#k_7l$t4u|l}6L0TQT+=mie>0yMid(G~3TAzb-Jx4OmR28hLtVlFKJ^9_ ztlxqAw8ciG?$oTwft$9+i-YjtOD!#z#4@2tZi+wiqD zF80KSQ3qN)Zys8VIuekXcyKH35w`+90img1+J;Ae*s|q^M>nJijx2}J^D%K>HJ^@0 z|FazC0*BG!AmY=|rVMJ)|%0$sG;P#yxiQp>q;7m`eayHuJc;1)4JaZ>D6Ik;#(*4dp?&I3rLb+%n^5Um2=TDrjh4F$!eW z&T5;!8%)_`8qj^t(}e4|h#_EHq*$Dy97r;V0WbnuGPqd$Q3(-ef*CK109hgltT-j} zfT+ZuctjCkk4~(%S5K@y><;iKHX-Tv5)W$6aX^xboBlh&(m7!hgc zw=ffheFx_aE8acbVo2x1)!s-m)DqFq$oE~$TfRDfZU$m}c^Tk5go%kSzn3U zEJ26JE*?jj=A*1i0xx07{8NN5B8M@w$p}2f=Os=RfOW+nsd-ZrcO*!TCRyq$%J~aX z-4f-%N5vw^Mi0*wojz7+si@^q$Gn3F=Pk(_GU4DnZ$4a(JMh5;W6*;WZ#icmibj=Ws=!nm+yk=2wjmv%h%q;3mR*|$lL&4g1)&U zlazZ|$pEh#y&m3OPR1}=F(41#;jdfoC_?Xf zD+YQmTo{-q9pTRztlJ%LdvraRNwM*8O9F8Pd*#3tpRABd@Q8MxE5S{RPPquaECDt& zIiko(J_qHfh^`7qwTJb!>EL`Ao{&|_hvdcSXh8L3+?R{ADo~!3Mi|Pi zZV6Lb)cMc5&Y?SrMwZjJG&k5+-5=gQefVs9L-UnZF#XOAtg6IqwL87Wbhq7Y%~R*~ zDb3PoTGL#UtL;{|a8%_@d6{ltiFkNqZdb)Dr!)&^&){TZ7*S>`&XB8D->d+ne~Q2* ztTVxiUjq&*#3VASa~9SuYRe^LECoaX_O{tS-Gbm#Ib`z=&g+0 zlDbmRk&y$RaFj@ANI79STV3F;kWII4VMB%Pa@nmL?va(lDUl(gYY<;tc5rTTQAVLT zD8F7tl`5og=%$V5BRgYu%-TNZFwsAM5*>x`&?)abgI<_)rIcJz3`;F@JiSR*14N2=I&Q0Y}#A_ zGR~w)H_68?n>_-J0ux8fUNBm|W0EZeInDW)0xqtb5=-LEvOoQwsb@xkGB{wCNbI6Qo0{zq_tX{@k)^83pdqCKGzA}O4En-ecxk_a-Imd&o#P@i<{kWp?%=$J&8a#} ztWrz^Ry^Yfs)q~;7B^t}RQ<5oWwJ_DTjbSV?A#&?byP_&&&sWQ1yiQF&^dK=mcNcm z%^RQ?ZP=|FoZ}xM%^P^(f_Gqr7rj^HSYPL7*H|i#ot``qJve5;K|EiA%k#bS4o(=7 zw}cR5)WO#VGi}F?R2G3oqt#ozU8~L2r=m}YJ<|r7^v2>!Fx#9ISvg>__iJb&v^Nrl zYFB<;``-h(U}SCM1oXPwJD{YDjC`3p(3}3cI3A4f7{@TlbPj2{Hs?;UnKzgP>grJt ze6I{_P~|%wx8EQFhZ^Xiv_Zs%xz3`p%2=MR3ZX)S!#;Fo^4F8I!~G5#iWB@2ba7hl}Qb^8>KHE(W^y1Xm_|`^t92nl6-U# zegE=`6)yuV$OBqx``{WU5p2~shaUZP$opugPOa5}h3IY)4}rr;O21>)#C@4^Hn8Gl z^nI`RP+hNxuq`p)`Iy#FZB(E*7$_h@et3}L<1k0*L|sxPo*@!-Fr>RU{=HyV6-}=* zBsl5N9JL}}qSq=oPGd~5xeWEwnufRrXtfHBR_a%2SZ$uaF@OI{FS1G;RGu%@{YKDz zFTd!yx-cX6Tz!B93g+nbjVcbRSWc!+ux)d~QW!;A(_o1SbuyJzni5=zbf zRw%CM8pRGw*Qi6%k3wB-LMv~lJSB{bvj`p;2+CMb&>{l@{)cUZ&_$YH%ZaAJ$PU`h zqEBH9Y>71CXV8Z1XMv*$g<%`n=p-IA7;#P~fuh04Yo9fNFwv643=xbof8oL4YVe`N%s1N#YV8O1yg1*ig%hq2blTQ#~ zlyPTp5b|Oezfuie!LR-|j_wSO4!<}KT)9T0B>UAL$rwHpr_;csMzvrLU`FB=8t$nT zAa=6KN7>5)RLL*Zl|n-is-GFP`9wB*HK0IjfIxH=+n}kW0>(Ib4GuMBPbWKqgrx&7 z&nbK{^i#GO2USiEcLv>_V9?_Za+`v~g27>(o+T|y@Q>TLq+$5dB`uu;jxAe$?4B== zahr}UUv>;XbbgBd`^*g&*R8vF!x{Dggx*1C(TaoSwl{pe^$5Crc#*6k4=g+Y?)Y;XxCy3+pASOv^}uBE%_U0!O+zdF z@G*d|FOQ)tupVgEU24Cyj#DgNG~w{Y70cefeR4z~&bS)zXF1Nd!FSs;cc9CMnx~gu zZ(ie?zT^;)-to+B*nP&5X540GburvwN*4`;Uzmb6;+x6X&71>lfM^UCEK%lnyaJ6f zmj?;gk(U+ukZc^LrG&A_2H1XR2l^Sv!D=8!2cO!!`KiqyPsORS@;%GW)dGdhrc57` z-v1o>DSZsKrUS*`HX)6dU63yy4_ zG;#ChiIXDtrQ~O3JCbWngJ~=(o2}*?`q73hV@Q0a+GIy|W`2s%rq)|IwbN?$B_~_; zYFh%1n7{;>3d*e-JGu7)iJ*oV?gDBfoJSVIC1k{O509w$5#IwP1(3{Lq1J7eXwCMk zwvg|dv}MwyEx;$w?3*rkuiLaTB_+LYrrey>f8;H`n~Th5nYrA2X6aCTmzm9HN_LOx zpEc+O^y3RJ03}?T2zkmP64Ru}&&DJ^S(=oUsn;j-NyhxXd46@t&4tkjmeq?VYW;Hi_Af!`5h#QvcD&~x zK#N5K9O!ira11E&WuSGAD3AK>mgA_>1w10Xqq-S#KeF@ccZfCPv`jMeir0pQ?br5gi|6ny@?%z(Jl7C0Z-E zAwT^Cv*Fz|_b~|i^*1>d*cVkM)l31QOZyBJOC6U~UkKo7^`O31@FoB|D&45)@NQ`_Ozq?B+qq{(IXIHz0iXK^z+zAUz21TUsCoB5um}p75&()| zMKK!ah#(z%#a*NZn5yJ)yE{U433%FaCW%>!XSI71C>~jTsyP8va4w@j;IVP}<6P2J zK{`EhC4e{-H5=2bAgL-1ndb)yHX(i}pc?SVOt*lp3#ckL!iz|iV^rdfDROxvj@Ug$ z1NL!8velhYjH8__Td{5D6c!y5R&Uug8QwI9O-<%heTRI!S&JtG5}+MC)6Ovl zGgJeP-HyIM0~Ykr54?T0La|hp^X>A$W+A!GH(IJuB=eT>rJ9|3ldmD$H@VhTUM9oK zCv-~BfXIo)z#eoC&ifBx7RDVkev1em07aP-~pp|86bkbikI7zGA^+)3!KYF0O5 zDa`*vKPjI00e*y2uoTLl@1HxgG)0j4Jdo>?2?f1M%1#-fD9=r=o#mhK#zSuR$U!H; z_{BrfeDv~$F6N_C(_{NNQ5^puE&<$gILhKm*gx_36r_S5ZbI+~{A^!bZ@>sCltMu7 zFM%GaEl|&2I{xAj^v$fg>p1SZx>>+@pa|S^c*mTT zH?BPV>MMs=ZC^Ei`)z#cqP-g?weQZ^-9Bl<-bD*m1L^+nK+WkVNJ|2%Ixn}P2i8}P zDh1O%{|lH_HnQplbSk<&(c*ghp2=nWOeHgr>br4>t5!U1A*sfRB>WaZy-ULC8N50n zKxPC6$IMcaP3jHMeLuqC3LJD%i-}^##t-*Tf3O(bSNa7yf8yEuKfm|eeBH!Xf$^z- zR)VKNvQ5KuJsO%by0C8Mz|OK50N<5YrjA*5+uA3+)4*l;9{=7gd;SE+mKN@P zdD5u6e%v~8IS`h$^t&I-`FS|{77sX6zzS<{TJ`diPk={8P8(Qo|KjZ(>&8qPIrx)p zZ^0oqzwknAuPrQydPWE?z%@@cO;?>6`V$YQ8H4HyJ++jGCz=sEpobBi^e_T6MeO9z zQWC134D2io*h$Vb*|$1H9+=pfLpaL!BBslX$Hl+lbXmyhvB5{q(?lj{{2%>#c3j*s z!19Ez&qI&fMD^6TSGn9by*#iq)2n8a^ac+4Y-Ll>_k}ez+*hCk8-^$O}yv z$O#j7R4j@voqcm~XU)@Zu(54xW82x-_{O&FY_zenv2EM7ZQHh!o9AWK@2&gZs@tcg zyU(2YboI=czh6grMbTqUp8cvjvb4n#`rGTqE z?!;Ky-}>6%B3rNtsVNiNUV&X+*FWCq+B=%$2$k~&%6O9;CNq2d561~mHR=maW~>|9 zTsu5$lK7z{58&%4H}VZJR;@CU1QxljdK)Y^tubS+WRfURRT89=*_qpY&IVC=$-PQt zp0*s{BB4iSZ{>??TimbC8A}w+sq}^r)YvUGvg=twl*VhoF|6__6O&Z$G>R2qZc8n! zQ!}e7XIB)1%C%Trh5PzL;UXQ+XHhfQoIT($peA1vTR==m@Zr<3bP`W-*_1Y)eZ#XSwz05n&fOZTf@E3K zKt+7hd{guu3*w-lR%qqx?u#=K!dRoZ!@{8nSJhA$6!ilHIOXe*BL~YBl&yH~Pezru zcwIb2gW}_cl|9cus?l)0f!8aiv6wx%I>rIndou8rnM4@k^NLvX`szTWcVQi8(}}1_ znia27iwypPIWASJHKupzVYBw^<(sS>%khjV2B)gCa?yOlI9;FjijC4Fd%#V($1#lRS7t{Tk>e_3a4*5*ei4BIIqC0$ z#kBE|l6F2G&h}A4Gl$p~EL7uOLnac?Vw+6*^OX_}DP zaY3fSQBjn`%oK8C^c^_ZFog`EZ(Xv|5Ku{r?>|zeF>P|6b z3_Y8b6uH3+^W5YX7YcmXr5D{|Ez8oOhC($d*Xti_=*PCGKk2C95um@zi2R_)L8*cs zk#%xiToL{N>{upZy8zSHFuV?PP zj?wFGzRGb2kty$vGEt1jvwU>oxuSXbpVG_cKC{p!te2wbJ|k8?T@Q@=&x&aZPY8e+>G5Q~)N8uELt;jJwP_G>aU$7fkNAJWB4*tc zikv`Z|8g7`U(NukP+^yzRX1>LdVoGiNMf+DJW{#NUbPms|{)ijP6CmkR&m<~-aL%nh%~amUA3X6Fu2 z$A>H{8Mcn!qFu>$d`;3HZ3mxjcqQ(a6Gd)zv`TFKE+;DXd)W-56*F-6D9b%?rYBBJ zfIvBzdtcXqzl>}D%8|cGtT}7z>MzA5+?ieJd(Dj~5ORzzV$qO2T+*^W$B7E*%3lR6 zr(rtr8sOC*mu2|Tcog}_!^dz`B|r3k`B9u*5apq=!r=UwfvHk1>O4urmxY3qO{8 zT>7RJCvN)#*wGZ=4MCU2SC-7+TkkG3*&<~mZa2NXY*u`4*?aDrw!lfmgCG_={8qzD z-DHr5ZUx{I>u6@@;l3026d^ZS7=ituMb1{@pEvBB8=)CY#OJ0{UP#JNnhk zkdN@BD#e(wQ=bkl2UFlJRpM&5=q%u1H`i2TGRgBmTOo!ubp6#!E8jbeg_bkR^$t4X zn<^ZEvEw67zrIrmnmKHKkKab+fNf+i7K#Tic7>waYP-C=K;`}yL4k`DID*;Vx$du- zZAFM=$LYX>41+J;L%aHIHg1RS=UI4K(Lp2*k4BfB*(}r*US1JR(|(G-a_0(jL1}|= z&Vrs1#M&oZYM3Zc4j2Gb;)7+*TAf|O7{@htYEbKC<4W|Z-VXz+TkhrloeM%|Sj0cZsJboQ`DEno zh@xnTvgrB3+i5xz7T-Yyfo`?6pk(u>>Vn@QC^9~X-Qb66XuNV^cLMOA;A71(@o+`n zzoeO#&JkLvS}KX{PWgEyC&?Y%sO63&NgE6tG$Lv9l7taBdEmZ#`#j6IDz$Kwl;&ZR zThTpdgesJOW>ZXhLTpsVvaMhzo?sE5 ztTRbo(u4f5y&h)2w-_lBJqhei@QB6h;QqE@xD<(_s=yaDp!B;%CT3%HHnyUA1TAcR zjXXNdGtGTt+5P}+Z#&Pcko0$W^!MQfJn%`3pWl9o7q%*3lP;JkArWt9bf_kx0@JV7 zs41aJz^8x!D>xOEEl?{nE+K&=X>1OyWq?Wj#`w0T=FIFj{xlfb)UE?1DK`Qd4W}Qm z7CbyoI8ME6ZvPw~h&U<$vlFm(?F$;6HgnGY$2jlJ5PydXHtq`+~1G)=)jNqYmbr+12@CSmG+NO>fjxWv#-~|Ka4(}2P>6F=meJans0B@kK2ft z#b7e@A3&lqXHD+6(+|I-DzJf`chYRa84|5G7+`HoW=?*XM+k?I@+sVoB#$g4 z-RuWJ+9NWeL1kvW!?dmFD+N?1`@>T8`k4w?TQ9`zwPzsA)KO3<{Td=|wX;73!r#LZ z)2cCJOo9*P;Mx{oL~$BuKwjkx4=+|xbQHy*PyidV9Cab}=Zezx3(BpeFj#Ardxwmw z@>5(ZV1l~!Wzd*~ztj!j!-??b@xT#+KmdVk2U`4-e_*!gTK4I1czHNFde}Dg9@tT7 zrLfJ?%z0ZZ^hx&GnI^5{oit~0SX6hcD<>)nykd&ux`7h8zuh^}r1ku#^8+t3Bry-~ zsE#(Q0cU^;lFL^NVwMpu0KWSw95-_~%G&3h@{(?^bC_L^SkYw@!KB)&r*MsnUwtwv znv`AUq#Xk`7>A4hkC&k_MpWiQ>;uVy3cji(O4FUNVxU8d9t!_ni`Do&MRIF%qd^>K z8&(Fqw6jNG4?vtnUu`XafPc7uT)erZfKw>FjlN<-d$$p^LM6O&$pYmgyHRHCBiu|d zgrPh~C8UqF&%_gj-Y$jtQ3m*Ktwwk;O8l*hXxX?Yl!vcL58Wis1=6m@L4iJ^F0G z-?YmsIcFSD>bOi2y2BddNNsPsYDGl4NrHc(6xC#7jhAb~fm0n~u{C0;5uIiuVQjG{ zYm^om^%@(<>MclZL_wKwQsOYS>RP$=c+~9&?x-`Y$esj%FvahDp0;FneZTm;n!+mv zLhJhCPS#WRF7_%V;~vpdK81jrrIw<4Py()-h_z-^Q+@@5xu+^?5JJd2<{pUG{Tn|z zI%ee$uKV@4+F_{}tS;n!*b0h)K!fjc*W$D8bL@Dhl$E#j#rm?sig0CL?3A#`2{c)w zVpLkrzLcG>$_#jgKI8pPzine#AX_Ef;}|kd_nokDwo}AyRa}f~7E}aRH221rf|%ZD zFQR(C5VSNr{_gLdi;tC5q=5&gqi<54q7ERfB(h;S|6S~iV6A$m=0TU9dw2Qmp|_|q z3*C;&xa5W8i1n~QoVEmpM|}+b^bRzRVxiC?af^qW`*&}n>QW`&cV)-5M4aI{!O$L! z*b^C6i@_Ex);Y)h%hU(MGuvc8r!K(03aAPO@CV)IS>z~E9 z##}J39`jgWlx&bDtQvQB>jN)XR74!!Cy{Z%7b`ps<@xrTT3JnO>@svqZJ>sr8lXUE zeOeNi0{UC^`?Uf;IT+;6q~beJj2El8Xzd<6WC87Pnh&RRt+PL#;XU{Qf1fSe_|;Rm z+JcB&WS1q8UtG4N4eO%hBj4LYxee+7*Xy+FL1@%bD~M_AZVKIFq2I?FLWl{fylr+| z9P@fYY{jtDyHJE}K5s%@xtZDiey`Byjm^}%V$>x|g{`6*!KWJg70T$ls7qZ|HX3}P z%-5yH)g$~ezC{%&vhnglfGTL~{S!lJl7S8s&7jck6i9BF@~Cn68J|6T!iZUX-dAi) zydL7*WMoKoQBS-LS(X`7t;lFLnL2NH+6)L3~QS7 zAwYf*{vhuL>seOG3{DtOTraO7px_Y zDS6t>1HL2`w6kE-EGxq$*-egS%s zT@}MhM;0&n?exA(?0_>M28ydKks)&yC8ROlf0^Bk)bVHWws4@<`F5T2cVBWF{VrP#@2L@q*Vf z3t*Df0E_X4e4Xow?!(*{f$4FsHUJs*#gi4u{t+pX75T*3KzhOL4BONMQt?HDnf`sf zFnp9tBNN{ge%@uoECP$NMHzO5De==I>(9B%%!g3znn(yU#=}m^E9b+5Bk{xh_9;I~ z%nMs7*D9>bI*4+5Mrur9@l+bA7O#~5Qr@LvF4qHJqp5aU zI3<=3Zv#}2K#kv~A_E_cb!BDY=VozYCBsRyofP`hLq@B0qv3Jr7pN$JyPD zGaPPZZZXSM&Pc;BP{(W|rjX2(Au?4XZ^9&xW;3MTp;!I{C7hx8im}^b=li>%n$1N7 zor`);A~g)L%iIx|_-*QBGp6r0_B7)Sbhr2vgLuR{%g2uIYa2I+?3@Hrrb3u>J8xY8 z*&FIq^r#aylsoEsC(SX6Lf#%-zcx16F@4X-uYz{%J!p}=n>eXs7uA~`x0MPRnlv>m zVS3uFGP>NI!8z*mzX&xnzepqMRo#b1iFV##ab$l6Uvh;WanD2)BwRgC^%*mf>4?^} zJNZQK6NYcbL>#CJ!nRV`(_uC)rNd=zi{cN#Yy}d#6 ziSqJ?5qtA;)iE^QsFQiJpoj8eKEw!n;six zq2*|&TI3&5i<}s@TyU+|im&M;a0K1KKfnuV*}JOUf35gTkas0JC%3AF9TK~XoR|$@ zOBAF#m!+3Dho-1^4w4|Uu2#iSxt|ofZ)2@T*db`iJ-|Afs{roQQv>=j3uB`C9rZ(4&{sjLq7ULlcH~n|{G@u-@5P5YF*b>(dG)Mt2y3|L_mo0@ z2RmF^6E$!rPb|20L+En*-M^J4vgK9E{pt4kdodI%Sjmw2LgRv1a!7mDvW@*wa?3Zs zcE!+KVp#LA;TA1&?N8Rxo?D&4W!JUoXY{AFG-zE?3uLJvvl}E+H9^|QciAMzqZXG= z0w4M{b)!~aYnJQX-2){M)bw= z#JR-8ijqh(R3c%;;xQU$U`Qpz-=rZdToBTnORN)S_H~t(5_s@+arZvRd&Hgeq}BPv zyT$qENS&+vXPP`)(fMAK7dPG6eA^st(F?cX(MU!XZ^zw9$}Qc2<7jl2g8QJ1sTIeb zT~ehsv9?PV=gxSf_M1z_@3NK)Enm?WC-c;b)8x(fm0O{KvB+7A|76DR%R$GdN63fdmAr@ck)sNptE0@i-3(s3xFQ@gZYKi&ramie1#Ij;y%xO@JT-yu{&D{EI{OcJW;l3lw4s`+Z}89gY%*$xZxj`ZZ??;f&AfvHGA79-e^x z{Rjz$4ogi{XGzQTdiGU{J?fmrVRqP5^b*_M2~ebvkVl+{9;v}@F?8IS7dewgm*%jt zITozdc^5WIZ4%ML7&my{QTvt9q}Aeh-d~eeb*sgCSh}KmLBM`+YPb|oxgx*S=I!wj z_DZq@-{~^h&_;fr{5PfAt#=TrVktqF{iSuNikoGIpOMYJ?_r}V>-R_L8NzpxG7Ya^ z7;nsPL3wdQGCCMKECqM*riJg>(h6*%qr{*jcf><^nuffFH_ONid4=-@H##?i&ppB- z1}eMa4r)wkT5<1^ca}ko(rY}<%kw8nPb>fyVeH1D_7aH__Y!S$-B$9A>Cb_S7{Vm?YoB;>;!2uj)Tcq)FxJM6VEBUCN}NP{S}rrylj@| z<$-lBn{2O*WK9^s+`RF~rst{Qj$Qz?hgjrwyN`ZAc;hmE6_CAA&(^b3a z&3V9Cy82ynJ}^UXv&LZFcM1ogW8q!mZ1{e_NPo2nXfdBC{HTKUCVLniRHfF@Zgk(W zyHmD&-7XMP*&87(^$_6 z1iRz$@g+X`C@Pu16r*eiJNt%J9gE&h*R69`rBYj;;7Lmqfz_-n6u_j|(x zs<>V6&xu*1KG=_Qxw@~{NgC~VQ}tg?vmdRNJ~Ma@#5ykVF4Ib2Jh*-tT?IxsKgnfX ztm7rg#u@_WbyH7P@k^5G2OIA4GiT|R9+4lDEsvzevd0^|6fxA!R>2famv>i16m^%+ zRtshcTkY_E*8!qPwBA@tkSSUp(MN(Ewcead5HUC&`2*+Ck|g`cv_~arV~NZag(PQ3 zsq>LyiCHD7)RSTpVhrYWh+YaL-?lKW0PDg!08}fNg5_vd$`K<4#i?(0am_NRL!xJKKmW?cP z;}dF2ndfg@mKK|mRm43h5=G{`iY{HPqvvvd$G1s>DrVymz_El$QcqjsMk~7-^p_Qw z@1sO&B*)B$@?X8uf9+g6j)+JAN#5nR<#Wz%%zB>aAa-}5t--u(`-A)pApRMI{4)@K zR?A~*9n^RliL1wa8cR0VfdjO)J7pTJRnV0K=6ow1@<<4Q1Hq&BWg3RgcXJxzwYMsp zKnwC+)ha&ABqoe%4@WchU>~bI!cy;#W_a@62L>n`-x0(h%4~rjxrm@>yMKL2%^1+I3Bk;V zePyd^%u!J~<0ZR+P-un)NmvA#>${zrk!<|Z^ugc3ZT@WaN;jjK^jI_C*aUNL%O-=m z_GmTZ9QN=s5L^a=U305Jb_I)EL#V+%^&mGBB=&+{6TTzi`vvP`y+bATkyL|x!cy-j zsDVZI>|OsT52DbAdk0(WRjP*ngqG{u+Qxe3=7E{&xw{4_55~|3ZU2F@W4!$1%U5+< zc^S5<2i*;?u@|QrZZqKG8vWe2NuQz}v~6444dD~2ZO3aFl%QMZ8S$}4?3&RN0^)3@)M%o9wv59t{^s<-JH&lBN0+r|#&JLJ#~#WU9DuPbE%;XnA} zzvvJ15MZhi!>ci+s!_T1uw43O-LPE-=W1}L{(9(P@SwCAu%Abn?yR`Mt8BL{gHH8j zy74{s!c?LD7#>a#BD(ZcuZ?h&>_LhKE2{0QDOlg zMlSD@vL}t|opHm`iBjFhY)2m2Rpx-N8oY6XTik2l0Iuo_b>o%o#j#@wvWKR^jB(LJ zH7qv3MM)NhD>48rWQfF?XAGa47C@mL*C%1qXKvhfYDco|O|u981h?(k+LdlcGu^S~ zNV{z3zLrh*ciquy$2r>J;w{?y6&dnD-wR86jQaOZS584@k zb7Q<7@YSt)t-KylwS(@7*R+e%47b&P@r-`i-DFSE>ECv(?TPRe+IHi$?oY6-^N#qm zBlgVb?e})0>juO>;Qx$;-#b-<*45qjOy(V^yNC1+9=+T2jOQKAzuk3%`57{FL-CIF zMe>sc5>?1eIP*Hpa|Z=1R~|LgK!I3N1VVwFD@=BmWkx-nZgc=EH=IMs32j5z)jp9! zGo6I0za=-ABf9e`o!%o9M%Z>n>>jNP`J+EDw+oYyN+jVr+!qpBJwUjj7^%S^`?&#= zln&W{V89>*lPV~5#~`3tcs^8WK%7xB0zD~oYyiz5qFFHlO*Pbh*Md<;i{x~m!N9Ls zRvL9FTw)iTQ9WP)H76t_BrI88M2l2d(afOK43RPh9V;iiJeeF;A6jZZKk%g`LPedk zKGxC4*jQ8N;Lw{Lq1kH| zZJ}WcxGOsI;3_xvbg4X|$r;+yQIax>j}JKwD!r`?6tBKJhdDI+U??s7|Yd_b_bw4Cq~j%Rv4 zS{@O-r5V;3j`D12j@z!sVD2Meyi8qEG8|pqq7F^ARD;+YZPg_Xy)HIzK5;le$zq+# zWxP1G29P&QiMig*uXFa)ohHQAt#gRfhwu z$#m0p^ox#+(U5_meoY+?Is2c5UtC&){U&YtTO_NTr@}ZfXLdX}DYXjyhz?y_l8$Af zk6PFeVTsO3Tzlc!(K9JkcmQyK+Gz%48}GJ)GUo-AnvCb$Bs4RKp@IEyD(?-6HD^Za zn@&4-M&&H*fX*^JsWhTG?SE|rbs-HFtd-% zDD6Lqz$}%sCdxs=0kaZTYAr#JQ)SX1*LR&F@i77D0whXOk`3J8$WZ3yUKDsU$fG*U z$zl{Ldf9vqYAN1_&q!J{WlAj)rWfnf@tGtc8aZUC0C1+Y#7*5&$J=!63am7dCg;bA zajiKr6faaIAc~$Gsr!QE&+D`nqd69h1YG zT0w^5ND>k7aNHc^uyd#*n0U~Npq%u3p~WQth4>9@iXjaP{a7=n1?#l(M$ffT;|y#U zaWS!&ow%@bC&@@&fncRlhZQA39@qgp-dv9~SgyMf9w|l~X?hXBsB@aY0C> z(oyynIVf|?V>!t^KSpaDM*%GikvO$3WR%8TWMuVqrWRkx900SzzXJ)?@CUUBC!b=x zKweIvpP?RnL2}kN)JQODH&(E(v_42&a)RW>LIL`&#q1aGjQCm3o~B1{?S@X`^uv#f zLt)sT7OF8~xTUm#`;H5>uBVRDT=`M@1O`L(ULr?9LT-ci$*qEldHtLejUvHC7bbP| z32YVaW*b~kvDg@?hgqLVxA*grIO6?&G zBgDIT%>q0W^NMQ&JB>Ky%amM_6Gvq%=}~A%i;}10oVpJwoD&9vo-|aMGdKm|lFBDR zGn7KwvdLkp zg9}lNycqhF#>;z+pRy(P_pXv?Cs*-IS7q0voyB<5OF=(*R#^E9Q{kMf-IOE~nKgf^ z*lR>zcb?Cwou95PYJOjc+qC@RF6?8zV2jI{;PARTew1rKZO!q;Ra)fxv8rFJjk)iT zvzmUObX+ab6Y788nEniY@Syx+g{?de!$M@lYL|7|B>ejZR>f01jiG8a=-%uo`_ z5OP;XS9Citha0Kj>tKshcQG@25|7O;&``Atw9shZjtR9HniId$Sezes!B8ARakfrMq`)nPMO~KT$KR4lsNbB8qlb8FbrI^+K9MSM zI#v&g(x+ZDZ^}Y)QEQ48=8!+2cdGP!6U{c18%nih6Cg8nNgJW!5wq%7KI-Ndpi&5%&T6SQnu*pa;&0PbyB_erXP@ zQJI%D8rlshNxE1;Lx2d%?(d?v$~YpqlGyajNwZ+EH1YDv-s_tl4vEv;7Z?7OrSE9m z7O|zFqJSm4h@4An>_L=_5E4^%RyG%|Bj$AJkOCFyjaS$=a#0SBmqp2FFOXbKa9nw; zC@-sZF+K`mpJ7(DWx6{_#%@I)%kz)1EHt)2>eL($N~F=Y@R(#MItXF(fd30{vQ6)G zkbJP~#b_=t4ooq$_?6@N>5#`-N*pVtXZTAeu2jV7b@y-1SIMu2uKCU1&DM8X7(5&5 zifb8Z4wtw#&W1gJi;QudW3UxaLBm$Cw zxI4tRtsUvom!x!k{jz7;m-_&6W#X63q(6jv1mP6+zPdk;<+P2S*>s>zFUlBC&3NA^ zY%CTjv$)CMal#ZqCVJNX5JVE82uMcaeY%E88$T8|QbE5djF&O2~@R8`@ga>)RMP*qR&B8#tR=8PS_M=o?uX)9dRy z&{`Wi=^N=g>C@Rc*xDI8IGGzeN=ef=jM0zE&_I1B5||vHs$-pJ-j73l0{uL4?AV{A2{c+~Iq5L!IKPdkX z*|#S6?=zIqw=p*{c66e1v$pzI1OB6gh;I2nKw&jNKrsJ_{+9WFuD`jVmA<2+u_K*@ zzQex){~7zA&O-e2@^6F)bRig100i_8%*m1de*+=>CkE&rQ1gF-%nfb7{dNBzU;<~( z@*+`Spl2!&AiDno|KsY>{{;WX&!znjW3(o=HctAk#*Vhu#&k|jCjaW#ziyQOG@t)x d^&I&Bf7{4Qfr0;H3gY|O1qK2Ny7*>5{|C9)D0lz> diff --git a/libraries/libs/libs/ustwo-clockwise-debug.aar b/libraries/libs/libs/ustwo-clockwise-debug.aar deleted file mode 100644 index 8257a991be6e1ff5490cafa8f66372d72b49e003..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90266 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 z 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 U0-rk*OpE&|;B3@zHvoYD10>zvIRF3v diff --git a/libraries/libs/libs/wearpreferenceactivity-0.5.0.aar b/libraries/libs/libs/wearpreferenceactivity-0.5.0.aar deleted file mode 100644 index 66b3cad816ca298c74a9f5c4d8c11fb1bfde068b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30815 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 Date: Mon, 31 Oct 2022 20:20:41 +0100 Subject: [PATCH 49/77] ui, implementation module --- app/build.gradle | 2 + .../nightscout/androidaps/di/AppComponent.kt | 4 +- .../nightscout/androidaps/di/AppModule.kt | 6 +++ .../androidaps/di/FragmentsModule.kt | 4 -- .../androidaps/dialogs/CareDialog.kt | 2 +- .../androidaps/dialogs/ExtendedBolusDialog.kt | 2 +- .../androidaps/dialogs/InsulinDialog.kt | 11 ++--- .../androidaps/dialogs/TempBasalDialog.kt | 4 +- .../androidaps/dialogs/TreatmentDialog.kt | 6 +-- .../androidaps/dialogs/WizardDialog.kt | 2 +- .../nsclient/NSClientAddUpdateWorker.kt | 2 +- .../general/overview/OverviewFragment.kt | 4 +- .../wear/wearintegration/DataHandlerMobile.kt | 10 ++--- .../androidaps/plugins/source/DexcomPlugin.kt | 2 +- .../plugins/source/EversensePlugin.kt | 2 +- .../androidaps/plugins/source/GlimpPlugin.kt | 2 +- .../plugins/source/GlunovoPlugin.kt | 2 +- .../plugins/source/IntelligoPlugin.kt | 2 +- .../androidaps/plugins/source/MM640gPlugin.kt | 2 +- .../plugins/source/NSClientSourcePlugin.kt | 2 +- .../plugins/source/PoctechPlugin.kt | 2 +- .../plugins/source/RandomBgPlugin.kt | 2 +- .../androidaps/plugins/source/TomatoPlugin.kt | 2 +- .../androidaps/utils/wizard/BolusWizard.kt | 12 +++--- app/src/main/res/layout/dialog_care.xml | 4 +- app/src/main/res/layout/dialog_treatment.xml | 4 +- app/src/main/res/layout/dialog_wizard.xml | 12 +++--- app/src/main/res/layout/dialog_wizardinfo.xml | 4 +- .../res/layout/overview_buttons_layout.xml | 4 +- app/src/main/res/values-bg-rBG/strings.xml | 4 +- app/src/main/res/values-cs-rCZ/strings.xml | 4 +- app/src/main/res/values-da-rDK/strings.xml | 4 +- app/src/main/res/values-de-rDE/strings.xml | 4 +- app/src/main/res/values-es-rES/strings.xml | 4 +- app/src/main/res/values-fr-rFR/strings.xml | 4 +- app/src/main/res/values-it-rIT/strings.xml | 4 +- app/src/main/res/values-iw-rIL/strings.xml | 4 +- app/src/main/res/values-lt-rLT/strings.xml | 4 +- app/src/main/res/values-nl-rNL/strings.xml | 4 +- app/src/main/res/values-no-rNO/strings.xml | 4 +- app/src/main/res/values-pl-rPL/strings.xml | 4 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-pt-rPT/strings.xml | 4 +- app/src/main/res/values-ro-rRO/strings.xml | 4 +- app/src/main/res/values-ru-rRU/strings.xml | 4 +- app/src/main/res/values-sk-rSK/strings.xml | 4 +- app/src/main/res/values-sv-rSE/strings.xml | 4 +- app/src/main/res/values-tr-rTR/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values/strings.xml | 31 +------------- app/src/main/res/xml/pref_overview.xml | 6 +-- app/src/main/res/xml/pref_wear.xml | 2 +- .../SmsCommunicatorPluginTest.kt | 2 +- .../androidaps/interfaces/BolusTimer.kt | 14 +++++++ .../androidaps/interfaces/CarbTimer.kt | 21 ++++++++++ .../androidaps/interfaces/XDripBroadcast.kt | 13 ++++++ .../androidaps/receivers/Intents.kt | 0 .../nightscout/androidaps/utils/TimerUtil.kt | 6 +-- core/src/main/res/values/strings.xml | 11 +++++ implementation/.gitignore | 1 + implementation/build.gradle | 20 +++++++++ implementation/consumer-rules.pro | 0 implementation/proguard-rules.pro | 21 ++++++++++ implementation/src/main/AndroidManifest.xml | 4 ++ .../implementation/BolusTimerImpl.kt | 16 ++++---- .../implementation/CarbTimerImpl.kt | 34 ++++++++++----- .../implementation/XDripBroadcastImpl.kt | 27 ++++++------ .../src/main/res/values/strings.xml | 15 +++++++ settings.gradle | 4 +- ui/.gitignore | 1 + ui/build.gradle | 19 +++++++++ ui/consumer-rules.pro | 0 ui/proguard-rules.pro | 21 ++++++++++ ui/src/main/AndroidManifest.xml | 4 ++ .../java/info/nightscout/ui/di/UiModule.kt | 14 +++++++ .../ui}/dialogs/CalibrationDialog.kt | 41 +++++++++++-------- .../nightscout/ui}/dialogs/CarbsDialog.kt | 33 +++++++-------- .../main/res/layout/dialog_calibration.xml | 6 +-- .../src/main/res/layout/dialog_carbs.xml | 8 ++-- ui/src/main/res/values/strings.xml | 10 +++++ 80 files changed, 396 insertions(+), 206 deletions(-) create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/BolusTimer.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/CarbTimer.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/XDripBroadcast.kt rename {app => core}/src/main/java/info/nightscout/androidaps/receivers/Intents.kt (100%) create mode 100644 implementation/.gitignore create mode 100644 implementation/build.gradle create mode 100644 implementation/consumer-rules.pro create mode 100644 implementation/proguard-rules.pro create mode 100644 implementation/src/main/AndroidManifest.xml rename app/src/main/java/info/nightscout/androidaps/utils/BolusTimer.kt => implementation/src/main/java/info/nightscout/implementation/BolusTimerImpl.kt (84%) rename app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt => implementation/src/main/java/info/nightscout/implementation/CarbTimerImpl.kt (81%) rename app/src/main/java/info/nightscout/androidaps/utils/XDripBroadcast.kt => implementation/src/main/java/info/nightscout/implementation/XDripBroadcastImpl.kt (88%) create mode 100644 implementation/src/main/res/values/strings.xml create mode 100644 ui/.gitignore create mode 100644 ui/build.gradle create mode 100644 ui/consumer-rules.pro create mode 100644 ui/proguard-rules.pro create mode 100644 ui/src/main/AndroidManifest.xml create mode 100644 ui/src/main/java/info/nightscout/ui/di/UiModule.kt rename {app/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/dialogs/CalibrationDialog.kt (71%) rename {app/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/dialogs/CarbsDialog.kt (92%) rename {app => ui}/src/main/res/layout/dialog_calibration.xml (94%) rename {app => ui}/src/main/res/layout/dialog_carbs.xml (97%) create mode 100644 ui/src/main/res/values/strings.xml diff --git a/app/build.gradle b/app/build.gradle index 196a0503e6..8c4b7cee20 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -176,6 +176,8 @@ dependencies { implementation project(':libraries') implementation project(':shared') implementation project(':core') + implementation project(':ui') + implementation project(':implementation') implementation project(':automation') implementation project(':combo') implementation project(':database') diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt index fb5bc21397..ce05242c68 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt @@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule import info.nightscout.androidaps.plugins.pump.omnipod.dash.di.OmnipodDashModule import info.nightscout.androidaps.plugins.pump.omnipod.eros.di.OmnipodErosModule import info.nightscout.shared.di.SharedModule +import info.nightscout.ui.di.UiModule import javax.inject.Singleton @Singleton @@ -65,7 +66,8 @@ import javax.inject.Singleton WorkersModule::class, DiaconnG8Module::class, OpenHumansModule::class, - SharedModule::class + SharedModule::class, + UiModule::class ] ) interface AppComponent : AndroidInjector { diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt index 6e80c5767a..25509a99ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt @@ -33,10 +33,13 @@ import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.ConfigImpl import info.nightscout.androidaps.utils.resources.IconsProviderImplementation import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.implementation.XDripBroadcastImpl import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.DefaultAapsSchedulers import info.nightscout.androidaps.utils.storage.FileStorage import info.nightscout.androidaps.utils.storage.Storage +import info.nightscout.implementation.BolusTimerImpl +import info.nightscout.implementation.CarbTimerImpl import info.nightscout.shared.sharedPreferences.SP import javax.inject.Singleton @@ -107,6 +110,9 @@ open class AppModule { @Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector @Binds fun bindPumpSync(pumpSyncImplementation: PumpSyncImplementation): PumpSync + @Binds fun bindXDripBroadcast(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast + @Binds fun bindCarbTimer(carbTimer: CarbTimerImpl): CarbTimer + @Binds fun bindBolusTimer(bolusTimer: BolusTimerImpl): BolusTimer } } diff --git a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt index 4e4afffa2e..a4a9da1115 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt @@ -10,8 +10,6 @@ import info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFr import info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment import info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment import info.nightscout.androidaps.activities.fragments.TreatmentsUserEntryFragment -import info.nightscout.androidaps.dialogs.CalibrationDialog -import info.nightscout.androidaps.dialogs.CarbsDialog import info.nightscout.androidaps.dialogs.CareDialog import info.nightscout.androidaps.dialogs.ExtendedBolusDialog import info.nightscout.androidaps.dialogs.FillDialog @@ -88,8 +86,6 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment - @ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog - @ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog @ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog @ContributesAndroidInjector abstract fun contributesEditActionDialog(): EditActionDialog @ContributesAndroidInjector abstract fun contributesEditEventDialog(): EditEventDialog diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt index 102177366f..6e80ae72b5 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt @@ -203,7 +203,7 @@ class CareDialog : DialogFragmentWithDate() { else -> TherapyEvent.MeterType.MANUAL } actions.add(rh.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(meterType)) - actions.add(rh.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, binding.bg.value) + " " + rh.gs(unitResId)) + actions.add(rh.gs(R.string.bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, binding.bg.value) + " " + rh.gs(unitResId)) therapyEvent.glucoseType = meterType therapyEvent.glucose = binding.bg.value valuesWithUnit.add(ValueWithUnit.fromGlucoseUnit(binding.bg.value, profileFunction.getUnits().asText)) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt index d068a8b1d1..4e5e82d903 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt @@ -93,7 +93,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { actions.add(rh.gs(R.string.formatinsulinunits, insulinAfterConstraint)) actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes)) if (abs(insulinAfterConstraint - insulin) > 0.01) - actions.add(rh.gs(R.string.constraintapllied).formatColor(context, rh, R.attr.warningColor)) + actions.add(rh.gs(R.string.constraint_applied).formatColor(context, rh, R.attr.warningColor)) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("
    ").join(actions)), { diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 25143f9feb..2e28e6a0d9 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -31,6 +31,7 @@ import info.nightscout.androidaps.utils.extensions.toSignedString import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.BolusTimer import info.nightscout.shared.SafeParse import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -83,11 +84,11 @@ class InsulinDialog : DialogFragmentWithDate() { val maxInsulin = constraintChecker.getMaxBolusAllowed().value() if (abs(binding.time.value.toInt()) > 12 * 60) { binding.time.value = 0.0 - ToastUtils.warnToast(context, R.string.constraintapllied) + ToastUtils.warnToast(context, R.string.constraint_applied) } if (binding.amount.value > maxInsulin) { binding.amount.value = 0.0 - ToastUtils.warnToast(context, R.string.bolusconstraintapplied) + ToastUtils.warnToast(context, R.string.bolus_constraint_applied) } } @@ -181,7 +182,7 @@ class InsulinDialog : DialogFragmentWithDate() { val eatingSoonTTDuration = defaultValueHelper.determineEatingSoonTTDuration() val eatingSoonTT = defaultValueHelper.determineEatingSoonTT() if (eatingSoonChecked) - actions.add(rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, eatingSoonTTDuration) + ")") + actions.add(rh.gs(R.string.temp_target_short) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, eatingSoonTTDuration) + ")") .formatColor(context, rh, R.attr.tempTargetConfirmation)) val timeOffset = binding.time.value.toInt() @@ -234,7 +235,7 @@ class InsulinDialog : DialogFragmentWithDate() { { aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it) } ) if (timeOffset == 0) - bolusTimer.removeBolusReminder() + bolusTimer.removeAutomationEventBolusReminder() } else { uel.log(Action.BOLUS, Sources.InsulinDialog, notes, @@ -244,7 +245,7 @@ class InsulinDialog : DialogFragmentWithDate() { if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else { - bolusTimer.removeBolusReminder() + bolusTimer.removeAutomationEventBolusReminder() } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt index 8940d1fb94..c22b3653fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt @@ -111,14 +111,14 @@ class TempBasalDialog : DialogFragmentWithDate() { percent = constraintChecker.applyBasalPercentConstraints(Constraint(basalPercentInput), profile).value() actions.add(rh.gs(R.string.tempbasal_label) + ": $percent%") actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes)) - if (percent != basalPercentInput) actions.add(rh.gs(R.string.constraintapllied)) + if (percent != basalPercentInput) actions.add(rh.gs(R.string.constraint_applied)) } else { val basalAbsoluteInput = SafeParse.stringToDouble(binding.basalAbsoluteInput.text) absolute = constraintChecker.applyBasalConstraints(Constraint(basalAbsoluteInput), profile).value() actions.add(rh.gs(R.string.tempbasal_label) + ": " + rh.gs(R.string.pump_basebasalrate, absolute)) actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes)) if (abs(absolute - basalAbsoluteInput) > 0.01) - actions.add(rh.gs(R.string.constraintapllied).formatColor(context, rh, R.attr.warningColor)) + actions.add(rh.gs(R.string.constraint_applied).formatColor(context, rh, R.attr.warningColor)) } activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.tempbasal_label), HtmlHelper.fromHtml(Joiner.on("
    ").join(actions)), { diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index 14f18a193d..de5a2a5457 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -72,11 +72,11 @@ class TreatmentDialog : DialogFragmentWithDate() { val maxInsulin = constraintChecker.getMaxBolusAllowed().value() if (SafeParse.stringToInt(binding.carbs.text) > maxCarbs) { binding.carbs.value = 0.0 - ToastUtils.warnToast(context, R.string.carbsconstraintapplied) + ToastUtils.warnToast(context, R.string.carbs_constraint_applied) } if (SafeParse.stringToDouble(binding.insulin.text) > maxInsulin) { binding.insulin.value = 0.0 - ToastUtils.warnToast(context, R.string.bolusconstraintapplied) + ToastUtils.warnToast(context, R.string.bolus_constraint_applied) } } @@ -137,7 +137,7 @@ class TreatmentDialog : DialogFragmentWithDate() { if (carbsAfterConstraints > 0) { actions.add(rh.gs(R.string.carbs) + ": " + rh.gs(R.string.format_carbs, carbsAfterConstraints).formatColor(context, rh, R.attr.carbsColor)) if (carbsAfterConstraints != carbs) - actions.add(rh.gs(R.string.carbsconstraintapplied).formatColor(context, rh, R.attr.warningColor)) + actions.add(rh.gs(R.string.carbs_constraint_applied).formatColor(context, rh, R.attr.warningColor)) } if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) { activity?.let { activity -> diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index d6788dd0ce..ac8adc39d3 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -411,7 +411,7 @@ class WizardDialog : DaggerDialogFragment() { val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value() if (abs(carbs - carbsAfterConstraint) > 0.01) { binding.carbsInput.value = 0.0 - ToastUtils.warnToast(ctx, R.string.carbsconstraintapplied) + ToastUtils.warnToast(ctx, R.string.carbs_constraint_applied) return } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt index 14b289546b..2424a667ba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt @@ -28,7 +28,7 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper.safeGetLong import info.nightscout.androidaps.interfaces.BuildHelper -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.shared.sharedPreferences.SP import java.util.concurrent.TimeUnit import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index 664a03ef92..9c6693f8b7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -35,8 +35,8 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.databinding.OverviewFragmentBinding -import info.nightscout.androidaps.dialogs.CalibrationDialog -import info.nightscout.androidaps.dialogs.CarbsDialog +import info.nightscout.ui.dialogs.CalibrationDialog +import info.nightscout.ui.dialogs.CarbsDialog import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.dialogs.LoopDialog import info.nightscout.androidaps.dialogs.ProfileSwitchDialog diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index 64623dbf12..cd4169347b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -12,7 +12,7 @@ import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction -import info.nightscout.androidaps.dialogs.CarbsDialog +import info.nightscout.ui.dialogs.CarbsDialog import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.events.EventMobileToWear import info.nightscout.androidaps.extensions.convertedToAbsolute @@ -469,7 +469,7 @@ class DataHandlerMobile @Inject constructor( message += rh.gs(R.string.bolus) + ": " + insulinAfterConstraints + "U\n" message += rh.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g" if (insulinAfterConstraints - command.insulin != 0.0 || carbsAfterConstraints - command.carbs != 0) - message += "\n" + rh.gs(R.string.constraintapllied) + message += "\n" + rh.gs(R.string.constraint_applied) rxBus.send( EventMobileToWear( EventData.ConfirmAction( @@ -487,7 +487,7 @@ class DataHandlerMobile @Inject constructor( "\n" + rh.gs(R.string.time) + ": " + dateUtil.timeString(startTimeStamp) + "\n" + rh.gs(R.string.duration) + ": " + command.duration + "h" if (carbsAfterConstraints - command.carbs != 0) { - message += "\n" + rh.gs(R.string.constraintapllied) + message += "\n" + rh.gs(R.string.constraint_applied) } if (carbsAfterConstraints <= 0) { sendError("Carbs = 0! No action taken!") @@ -512,7 +512,7 @@ class DataHandlerMobile @Inject constructor( } val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value() var message = rh.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U" - if (insulinAfterConstraints - amount != 0.0) message += "\n" + rh.gs(R.string.constraintapllied) + if (insulinAfterConstraints - amount != 0.0) message += "\n" + rh.gs(R.string.constraint_applied) rxBus.send( EventMobileToWear( EventData.ConfirmAction( @@ -526,7 +526,7 @@ class DataHandlerMobile @Inject constructor( private fun handleFillPreCheck(command: EventData.ActionFillPreCheck) { val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(command.insulin)).value() var message = rh.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U" - if (insulinAfterConstraints - command.insulin != 0.0) message += "\n" + rh.gs(R.string.constraintapllied) + if (insulinAfterConstraints - command.insulin != 0.0) message += "\n" + rh.gs(R.string.constraint_applied) rxBus.send( EventMobileToWear( EventData.ConfirmAction( diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt index aba5f07102..b48dc49fd4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt @@ -31,7 +31,7 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt index a339180fd0..92b24df2df 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt @@ -19,7 +19,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import java.util.* diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt index 8efc9651df..2daf641769 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt @@ -16,7 +16,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index 6a02daa322..12dabeff51 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -23,8 +23,8 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt index 3f328b2fc5..1183c22fa7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt @@ -25,7 +25,7 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt index 2e7b8300cf..b21599a57f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt @@ -17,7 +17,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.json.JSONArray diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt index 247c65adb2..8d8ba5ef8c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt @@ -24,7 +24,7 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.json.JSONObject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt index 072d1953bc..2047be6e7a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt @@ -17,7 +17,7 @@ import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.utils.JsonHelper.safeGetString -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.json.JSONArray diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt index c2115d53e3..751c4463fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt @@ -12,7 +12,7 @@ import info.nightscout.androidaps.interfaces.* import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt index da48d8f46a..719357cf81 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt @@ -15,7 +15,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag -import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt index 449af8dd64..e0d66a5cb7 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt @@ -1,7 +1,6 @@ package info.nightscout.androidaps.utils.wizard import android.content.Context -import android.content.Intent import android.text.Spanned import com.google.common.base.Joiner import dagger.android.HasAndroidInjector @@ -32,6 +31,7 @@ import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.BolusTimer import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -349,11 +349,11 @@ class BolusWizard @Inject constructor( } accepted = true if (calculatedTotalInsulin > 0.0) - bolusTimer.removeBolusReminder() + bolusTimer.removeAutomationEventBolusReminder() if (carbs > 0.0) - carbTimer.removeEatReminder() + carbTimer.removeAutomationEventEatReminder() if (sp.getBoolean(R.string.key_usebolusadvisor, false) && Profile.toMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0) - OKDialog.showYesNoCancel(ctx, rh.gs(R.string.bolusadvisor), rh.gs(R.string.bolusadvisormessage), + OKDialog.showYesNoCancel(ctx, rh.gs(R.string.bolus_advisor), rh.gs(R.string.bolus_advisor_message), { bolusAdvisorProcessing(ctx) }, { commonProcessing(ctx) } ) @@ -390,7 +390,7 @@ class BolusWizard @Inject constructor( if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else - carbTimer.scheduleEatReminder() + carbTimer.scheduleAutomationEventEatReminder() } }) } @@ -487,7 +487,7 @@ class BolusWizard @Inject constructor( } if (useAlarm && carbs > 0 && carbTime > 0) { - carbTimer.scheduleReminder(T.mins(carbTime.toLong()).secs().toInt()) + carbTimer.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt()) } } }) diff --git a/app/src/main/res/layout/dialog_care.xml b/app/src/main/res/layout/dialog_care.xml index 63478f5441..b0cb311f67 100644 --- a/app/src/main/res/layout/dialog_care.xml +++ b/app/src/main/res/layout/dialog_care.xml @@ -90,7 +90,7 @@ android:layout_gravity="center_horizontal" android:width="120dp" android:padding="10dp" - android:text="@string/treatments_wizard_bg_label" + android:text="@string/bg_label" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="bold" /> @@ -99,7 +99,7 @@ android:layout_width="130dp" android:layout_height="40dp" android:layout_marginBottom="2dp" - app:customContentDescription="@string/treatments_wizard_bg_label" /> + app:customContentDescription="@string/bg_label" /> @@ -112,7 +112,7 @@ android:id="@+id/carbs" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/treatments_wizard_carbs_label" /> + app:customContentDescription="@string/carbs" /> @@ -95,7 +95,7 @@ android:layout_weight="1" android:labelFor="@id/carbs_input" android:padding="10dp" - android:text="@string/treatments_wizard_carbs_label" + android:text="@string/carbs" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="bold" /> @@ -105,7 +105,7 @@ android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_marginBottom="2dp" - app:customContentDescription="@string/treatments_wizard_carbs_label" /> + app:customContentDescription="@string/carbs" /> @@ -436,7 +436,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" - android:text="@string/treatments_wizard_bg_label" /> + android:text="@string/bg_label" /> diff --git a/app/src/main/res/layout/dialog_wizardinfo.xml b/app/src/main/res/layout/dialog_wizardinfo.xml index 4931058f2a..bc36dc0873 100644 --- a/app/src/main/res/layout/dialog_wizardinfo.xml +++ b/app/src/main/res/layout/dialog_wizardinfo.xml @@ -62,7 +62,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:width="24dp" - android:text="@string/treatments_wizard_bg_label" + android:text="@string/bg_label" android:textAppearance="?android:attr/textAppearanceSmall" /> @@ -102,7 +102,7 @@ android:drawableTop="@drawable/ic_calibration" android:ellipsize="end" android:singleLine="true" - android:text="@string/overview_calibration" + android:text="@string/calibration" android:textColor="?attr/icCalibrationColor" android:visibility="gone" app:iconPadding="-4dp" /> diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 7a274f7bc9..b3d6e507a9 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -652,7 +652,7 @@ Възстанови настройките по подразбиране Грешка в NSClient. Рестартирайте Nightscout и NSClient времево отместване - Напомни за болус по-късно + Напомни за болус по-късно Предпочитаният режим на APS Общо Калк @@ -809,7 +809,7 @@ Използвай напомняне за старт на хранене вместо съветника по време на висока гликемия (\"пре-болус\") Време за ядене!\nИзпълнете болус съветника и направете изчисления отново. Време е за ядене - Болус подсещане + Болус подсещане Включи подсещането за болус Използвай подсещане за болус по-късно със съветник (\"след-болус\") Време е за болус!\nВключи болус съветника и направи изчисление отново. diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 4e292bed02..7ad657dcda 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -692,7 +692,7 @@ Obnovit výchozí Chyba NSClienta. Zvažte restart NS a NSClienta. Časový posun - Upozornit později na bolus + Upozornit později na bolus Preferovaný režim APS Výsledek Kalk @@ -864,7 +864,7 @@ Při vysoké glykémii použijte připomenutí, abyste začali jíst později, namísto výsledku z kalkulátoru („prebolus“) Čas k jídlu!\nSpusťte Bolusovou kalkulačku a proveďte výpočet znovu. Čas k jídlu - Připomenutí bolusu + Připomenutí bolusu Povolit připomínání bolusu Použijte připomenutí pro pozdější bolus s kalkulátorem (\"zpožděný bolus\") diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index c29ea202df..0a7e65b4c5 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -679,7 +679,7 @@ Nulstil til standardindstillinger NSClient funktionsfejl. Overvej NS og NSClient genstart. Tidsforskydning - Påmind om at bolus senere + Påmind om at bolus senere Foretrukket APS-tilstand I alt Beregn @@ -847,7 +847,7 @@ Brug påmindelse om at begynde at spise senere i stedet for guiden under høj glykæmi (\"pre-bolus\") Tid til at spise!\nKør Bolus guiden og lav beregning igen. Tid til at spise - Boluspåminder + Boluspåminder Aktivér boluspåminder Brug påmindelse til bolus senere med guiden (\"post-bolus\") diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 3bb76ddb15..535ac15aed 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -679,7 +679,7 @@ Auf Standardwerte zurücksetzen NSClient Störung. Ziehe einen Neustart von NS und NSClient in Betracht. Zeitversatz - Später an Bolus erinnern + Später an Bolus erinnern Bevorzugter APS-Modus Gesamt Berech. @@ -848,7 +848,7 @@ Unerwartetes Verhalten. Option zur Erinnerung an späteres Essen (z.B. bei hohen BZ-Werten) im Bolus-Rechner (\"Spritz-Ess-Abstand\") Zeit zum Essen!\nStarte den Bolus-Rechner und gib die KH ein. Zeit zum Essen - Bolus-Erinnerung + Bolus-Erinnerung Bolus-Erinnerung aktivieren Erinnerung an späteren Bolus mit dem Assistenten verwenden (\"Post-Bolus\") diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index c1fba36884..f9569554b5 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -692,7 +692,7 @@ Restablecer valores predeterminados NSClient fallando. Considera reiniciar NS y NSClient. Retardo - Recordar ejecutar el bolo más tarde + Recordar ejecutar el bolo más tarde Modo preferido de APS Total Cálculo @@ -864,7 +864,7 @@ Utiliza un recordatorio para empezar a comer más tarde, en lugar del resultado del asistente durante una glucemia alta (\"pre-bolo\") ¡Hora de comer!\nEjecutar el asistente de bolo y calcular de nuevo. Hora de comer - Recordatorio de bolo + Recordatorio de bolo Habilitar recordatorio de bolo Usa recordatorio de bolo más tarde con el asistente (\"post-bolus\") diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 323627ac2f..7f12aeff28 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -693,7 +693,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Réinitialiser les valeurs par défaut Dysfonctionnement NSClient. Redémarrez NS et NSClient. Décalage horaire - Rappel du bolus plus tard + Rappel du bolus plus tard Mode APS préféré Total Calc @@ -865,7 +865,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Utiliser un rappel pour commencer le repas à la place du résultat de l\'assistant quand la glycémie est élevée (\"pré-bolus\") Il est temps de manger !\nExécutez l\'assistant Bolus et refaites le calcul. Il est temps de manger - Rappel bolus + Rappel bolus Activer le rappel bolus Utiliser un rappel pour faire le bolus plus tard avec l\'Assistant (\"post-bolus\") Il est temps de faire le bolus !\nExécutez l\'Assistant et faites de nouveau le calcul. diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 96c3b36c66..0d0991ebc6 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -682,7 +682,7 @@ Ripristina valori predefiniti Malfunzionamento NSClient. Considera il riavvio di NS e NSClient. Offset - Ricorda di fare il bolo + Ricorda di fare il bolo Modalità APS preferita Totale Calc @@ -850,7 +850,7 @@ Usa un promemoria per iniziare a mangiare invece del risultato del calcolatore durante la glicemia alta (\"pre-bolo\") Tempo di mangiare!\nEsegui il calcolatore e fai di nuovi i calcoli. Tempo di mangiare - Promemoria bolo + Promemoria bolo Abilita promemoria bolo Usa promemoria bolo con calcolatore (\"post-bolo\") diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index 11170d158b..1c27e4e33c 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -681,7 +681,7 @@ אפס לברירת המחדל תקלה ב-NSClient. שקלו להפעיל את Nightscout ו-NSClient מחדש. היסט זמן - תזכורת להזרקת בולוס אח\"כ + תזכורת להזרקת בולוס אח\"כ מצב APS מועדף סה\"כ חישוב @@ -849,7 +849,7 @@ מציג תזכורת לאכול אחר כך במקום להזריק את המינון שהומלץ ע\"י האשף בעת היפרגליקמיה (\"בולוס מקדים\") זמן לאכול!\nהפעילו את אשף הבולוסים וחשבו בולוס חדש. זמן לאכול - תזכורת בולוס + תזכורת בולוס אפשר את תזכורת בולוס השתמש בתזכורת כדי להזריק בולוס מאוחר יותר במחשבון (\"פוסט-בולוס\") diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index 5febaf52c1..9845e822fe 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -659,7 +659,7 @@ Atkurti numatytuosius NSClient sutrikimas. Reikėtų paleisti iš naujo NS ir NSClient. Laiko poslinkis - Priminti apie bolusą vėliau + Priminti apie bolusą vėliau Pageidaujamas DKS režimas Viso Skaič. @@ -819,7 +819,7 @@ Galimybė priminti jums valgyti vėliau (pvz., esant aukštai glikemijai) boliuso vedlyje („po susileidimo palaukti ir valgyti vėliau“) Laikas valgyti!\nĮjunkite Boluso patarėją ir atlikite skaičiavimą dar kartą. Laikas valgyti - Priminimas apie bolusą + Priminimas apie bolusą Įgalinti priminimą apie bolusą Naudoti priminimus apie bolusą su skaičiuotuvu („post-bolusas“) Laikas bolusui!\nĮjunkite Skaičiuotuvą ir pakartokite skaičiavimus. diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index b78d4afb99..cd676a86be 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -679,7 +679,7 @@ Terug naar standaardinstellingen NSClient werkt niet goed. Overweg een herstart van NS en NSClient. Tijdverschuiving - Herinner later te bolussen + Herinner later te bolussen Voorkeur APS-modus Totaal Calc @@ -847,7 +847,7 @@ Gebruik bij een hoge bloedglucose niet het resultaat van de wizard, maar een herinnering om later met eten te beginnen (\"pre-bolus\") Tijd om te eten!\nVoer de boluswizard opnieuw uit. Tijd om te eten - Bolus herinnering + Bolus herinnering Bolus herinnering inschakelen Gebruik herinnering om later te bolussen met de wizard (\"post-bolus\") diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml index e7010322d2..bc8bc16995 100644 --- a/app/src/main/res/values-no-rNO/strings.xml +++ b/app/src/main/res/values-no-rNO/strings.xml @@ -682,7 +682,7 @@ Gjenopprett standardinnstillinger NSClient feil. Vurder omstart av NS og NSClient. Tidsforskyvning - Påminnelse til å gi bolus senere + Påminnelse til å gi bolus senere Foretrukket APS modus Total Kalkyle @@ -850,7 +850,7 @@ Bruk en påminnelse om å spise senere enn kalkulator resultatet fra wizard ved høyt blodsukker (\"pre-bolus\") Nå må du spise!\Bruk bolus veiviseren og beregn på nytt. Nå må du spise - Bolus påminnelse + Bolus påminnelse Aktiver bolus påminnelse Bruk påminnelse for å sette bolus dosen senere med veiviseren («post bolus») diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 1d143fc45c..7db90e36d4 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -661,7 +661,7 @@ Przywróć ustawienia domyślne Usterka NSClient. Spróbuj zrestartować NS i NSClient. Przesunięcie czasu - Przypomnij o bolusie + Przypomnij o bolusie Preferowany tryb APS Razem Kalk @@ -824,7 +824,7 @@ Użyj przypomnienia, aby rozpocząć jedzenie później podczas wysokiej glikemii (\"pre-bolus\") Czas jeść!\nUruchom kreatora bolusa i zrób obliczenia ponownie. Czas na jedzenie - Przypomnienie bolusa + Przypomnienie bolusa Włącz przypomnienie bolusa Użyj przypomnienia o potrzebie obliczenia i podania bolusa kalkulatorem (\"opóźniony bolus\") Czas na bolus!\nUruchom Kalkulator bolusa aby ponownie wykonać obliczenia. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index f25b33ced0..2d607714f2 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -785,7 +785,7 @@ Ativar o assistente de bolus Hora de comer!\nAbra o assistente de bolus e faça o cálculo novamente. Hora de comer - Lembrete de bolus + Lembrete de bolus Ativar lembrete de bolus Usar lembrete para adiar o bolus com o assistente (\"pós-bolus\") diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index e2a9e97583..1490f8b74e 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -659,7 +659,7 @@ Repor definições por defeito Erro de funcionamento do ClienteNS. Pondere reiniciar o NS e ClienteNS. Fuso horário - Lembrete para bólus mais tarde + Lembrete para bólus mais tarde Modo APS preferido Total Calc @@ -819,7 +819,7 @@ Use lembrete para começar a comer mais tarde em vez di resultado do assistente durante a glicemia alta (\"pré-bolus\") Hora de comer!\nExecutar assistente de Bólus e fazer cálculo novamente. Hora de comer - Lembrete de bólus + Lembrete de bólus Ativar lembrete de bólus Usar lembrete para bólus mais tarde com o assistente (\"pós-bólus\") diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index efe5cb7a15..4f9363be6a 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -659,7 +659,7 @@ Resetare la setările implicite Funcționare incorectă a NSClient. Aveți în vedere un restart al NS și al NSClient. Decalaj - Amintește-mi sa fac bolus mai târziu + Amintește-mi sa fac bolus mai târziu Modul APS preferat Total Calc @@ -819,7 +819,7 @@ Folosește o alarma de reamintire pentru a începe sa mănânci mai târziu în loc de alerta de la calculatorul de bolus din timpul hiperglicemiei (\"pre-bolus\") Timpul sa mănânci!\nRuleaza Calculatorul de Bolus pentru a face calculele din nou. Timpul sa mănânci - Memento bolus + Memento bolus Activează memento bolus Folosește memento pentru a bolusa mai târziu cu asistentul (\"post-bolus\") diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 3d4c783324..3b7967b2f5 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -682,7 +682,7 @@ Восстановить значения по умолчанию Некорректная работа NSClient. Возможно следует перезапустить NS и NSClient. Смещение по времени - Напомнить о болюсе позже + Напомнить о болюсе позже Предпочитаемый режим APS Итого Кальк @@ -850,7 +850,7 @@ Используйте напоминание для того, чтобы начать есть позже, вместо того, чтобы воспользоваться помощником болюса на высоких значениях ГК (\"пре-болюс\") Пора есть!\nЗапустите помощник болюса снова для подсчета. Пора есть - Напоминание о болюсе + Напоминание о болюсе Включить напоминание о болюсе Применить напоминание о болюсе с помощью мастера (постболюс) Пора дать болюс!\nЗапустите помощник болюса и повторите расчет. diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 124171c210..905deb7fe0 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -692,7 +692,7 @@ Obnoviť predvolené Chyba NSClienta. Zvážte reštart NS a NSClienta. Časový posun - Upozorniť na bolus neskôr + Upozorniť na bolus neskôr Preferovaný režim APS Spolu Kalk @@ -864,7 +864,7 @@ Pri vysokej glykémii spustiť pripomienku namiesto výsledku z kalkulačky, aby ste začali jesť neskôr (tzv. \"prebolus\") Čas na jedlo!\nSpustite Bolusovú kalkulačku a urobte výpočet znova. Čas na jedlo - Pripomenutie bolusu + Pripomenutie bolusu Zapnúť pripomínanie bolusu Použite pripomenutie pre neskorší bolus s kalkulačkou (\"oneskorený bolus\") diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 22fa8f03d6..db64001d80 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -664,7 +664,7 @@ Eversense-appen. Återställ standardinställningar Fel på NSClient. Överväg att starta om NSClient och Nightscout-webbplatsen. KH-tid - Påminn om bolus senare + Påminn om bolus senare Föredraget APS-läge Total Kalkyl @@ -826,7 +826,7 @@ Eversense-appen. Få en påminnelse om att börja äta senare (istället för kalkylatorns resultat) om du ligger högt i BG Dags att äta!\nKör bolusguiden igen för ny beräkning. Dags att äta - Boluspåminnelse + Boluspåminnelse Aktivera boluspåminnelse Använd påminnelse för att ge bolus senare (\"post-bolus\") diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 1bc93bc24b..e0650e303e 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -679,7 +679,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Varsayılanlara sıfırla NSClient arızası. NS ve NSClient yeniden başlatmayı düşünün. Saat farkı - Bolusu daha sonra hatırlat + Bolusu daha sonra hatırlat Tercih edilen APS modu Toplam Hesap @@ -846,7 +846,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Yüksek glisemi sırasında sihirbaz sonucu yerine daha sonra yemeye başlamak için hatırlatıcı kullanın (\"pre-bolus\") Yemek zamanı!\nBolus sihirbazını çalıştırın ve yeniden hesaplama yapın. Yemek zamanı - Bolus hatırlatıcısı + Bolus hatırlatıcısı Bolus hatırlatıcıyı etkinleştir Sihirbazla daha sonra bolus için hatırlatıcı kullanın (\"bolus sonrası\") diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9ac12f84aa..f7842dace8 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -669,7 +669,7 @@ 重置为默认值 NSClient故障。 考虑Nightscout和NSClient重启。 时区偏移 - 稍后提醒输注大剂量 + 稍后提醒输注大剂量 首选的APS模式 总计 计算 @@ -833,7 +833,7 @@ 在高血糖期间(\"预测大剂量\"),使用延迟吃饭的提醒功能,来替代大剂量向导结果 吃饭时间到了!\n请运行大剂量向导,然后进行计算。 吃饭时间 - 大剂量提醒 + 大剂量提醒 启用大剂量提醒 使用大剂量向导稍后推注的提醒功能 (“稍后注射大剂量”) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5a94b2dadf..a5db896d96 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -108,9 +108,7 @@ Ins: IOB: Total IOB: - BG TT - Carbs Corr Bolus IOB Run now @@ -151,11 +149,9 @@ Safety Plugin is disabled Constraints violation - Bolus reported an error. Manually check real delivered amount Accept new temp basal: Treatment Calculator - Constraint applied! Bolus: Basal: Change your input! @@ -171,8 +167,6 @@ Carbs Suggestion Unsupported version of Nightscout Basal IOB - Bolus constraint applied - Carbs constraint applied Other Meter Sensor @@ -345,9 +339,6 @@ Attention!\nNormally you do not have to change these values below. Please CLICK HERE and READ the text and make sure you UNDERSTAND it before change any of these values. http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html Invalid SMS phone number - Calibration - xDrip+ not installed - Calibration sent to xDrip+ Calibration sent. Receiving must be enabled in xDrip+. xDrip+ is not receiving calibrations Pump suspended @@ -496,7 +487,6 @@ Interval for autosens [h] Amount of hours in the past for sensitivity detection (carbs absorption time is excluded) openapsama_autosens_period - nsclient_localbroadcasts OpenAPS Uploader Sensitivity detection @@ -593,7 +583,6 @@ Minimum Carbs Required For Suggestion Minimum grams of carbs to display a carbs suggestion alert. Carbs suggestions below this number will not trigger a notification. Send BG data to xDrip+ - dexcomg5_xdripupload In xDrip+ select 640g/Eversense data source NSClient BG NS BG @@ -642,9 +631,6 @@ insulin_button_increment_1 insulin_button_increment_2 insulin_button_increment_3 - carbs_button_increment_1 - carbs_button_increment_2 - carbs_button_increment_3 Number of carbs to add when button is pressed Amount of insulin to add when button is pressed Could not launch CGM application. Make sure it is installed. @@ -671,7 +657,6 @@ Dexcom app is not installed. Start Activity TT Start Eating soon TT - TT Do not bolus, record only Category Subcategory @@ -684,7 +669,6 @@ Carbs On Board Insulin On Board Basals - No action selected, nothing will happen Start Hypo TT Running dev version. Closed loop is disabled. Engineering mode enabled @@ -846,7 +830,7 @@ Reset to defaults NSClient malfunction. Consider NS and NSClient restart. Time offset - Remind to bolus later + Remind to bolus later aps_mode Preferred APS mode Total @@ -1048,20 +1032,10 @@ Send SMS if unreachable pump event is triggered Report pump unreachable Run alarm when is time to eat - Run alarm in %1$d min - Bolus advisor - You have high glycemia. Instead of eating now it\'s recommended to wait for better glycemia. Do you want to do a correction bolus now and remind you when it\'s time to eat? In this case no carbs will be recorded and you must use wizard again when we remind you. use_bolus_advisor - Enable bolus advisor - Use reminder to start eating later instead of wizard result during high glycemia ("pre-bolus") Time to eat!\nRun Bolus wizard and do calculation again. - Time to eat - Bolus reminder - use_bolus_reminder Enable bolus reminder - Use reminder to bolus later with wizard - ("post-bolus") - Time to bolus!\nRun Bolus wizard and do calculation again. + Use reminder to bolus later with wizard ("post-bolus") Crash logs upload disabled! Graph Chart menu @@ -1219,7 +1193,6 @@ Show loop %1$d selected Sort - Dialog canceled Very low Low High diff --git a/app/src/main/res/xml/pref_overview.xml b/app/src/main/res/xml/pref_overview.xml index bfeee6b32e..bd9cda2bf9 100644 --- a/app/src/main/res/xml/pref_overview.xml +++ b/app/src/main/res/xml/pref_overview.xml @@ -132,7 +132,7 @@ android:defaultValue="true" android:key="@string/key_show_calibration_button" android:summary="@string/show_calibration_button_summary" - android:title="@string/overview_calibration" /> + android:title="@string/calibration" /> @@ -489,8 +489,8 @@ + android:summary="@string/enable_bolus_advisor_summary" + android:title="@string/enable_bolus_advisor" /> + android:title="@string/bg_label" /> autotune_additional_log key_autotune_plugin key_autotune_last_run + dexcomg5_xdripupload + nsclient_localbroadcasts + use_bolus_reminder + carbs_button_increment_1 + carbs_button_increment_2 + carbs_button_increment_3 Refresh @@ -188,6 +194,11 @@ Add new Add new above Data is coming from different pump. Change pump driver to reset pump state. + BG + Calibration + Run alarm in %1$d min + Bolus reported an error. Manually check real delivered amount + Bolus reminder Limiting max basal rate to %1$.2f U/h because of %2$s diff --git a/implementation/.gitignore b/implementation/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/implementation/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/implementation/build.gradle b/implementation/build.gradle new file mode 100644 index 0000000000..be1039c0b6 --- /dev/null +++ b/implementation/build.gradle @@ -0,0 +1,20 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-allopen' +apply plugin: 'com.hiya.jacoco-android' + +apply from: "${project.rootDir}/core/android_dependencies.gradle" +apply from: "${project.rootDir}/core/android_module_dependencies.gradle" +apply from: "${project.rootDir}/core/test_dependencies.gradle" +apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.implementation' +} + +dependencies { + implementation project(':core') + implementation project(':shared') + implementation project(':database') + implementation project(':automation') +} \ No newline at end of file diff --git a/implementation/consumer-rules.pro b/implementation/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/implementation/proguard-rules.pro b/implementation/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/implementation/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/implementation/src/main/AndroidManifest.xml b/implementation/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a5918e68ab --- /dev/null +++ b/implementation/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/BolusTimer.kt b/implementation/src/main/java/info/nightscout/implementation/BolusTimerImpl.kt similarity index 84% rename from app/src/main/java/info/nightscout/androidaps/utils/BolusTimer.kt rename to implementation/src/main/java/info/nightscout/implementation/BolusTimerImpl.kt index a582bfa40c..5eca0312ae 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/BolusTimer.kt +++ b/implementation/src/main/java/info/nightscout/implementation/BolusTimerImpl.kt @@ -1,7 +1,7 @@ -package info.nightscout.androidaps.utils +package info.nightscout.implementation import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R +import info.nightscout.androidaps.interfaces.BolusTimer import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.plugins.general.automation.AutomationEvent import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin @@ -17,15 +17,15 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class BolusTimer @Inject constructor( +class BolusTimerImpl @Inject constructor( private val injector: HasAndroidInjector, private val rh: ResourceHelper, private val automationPlugin: AutomationPlugin, -) { +) : BolusTimer { - fun scheduleBolusReminder() { + override fun scheduleAutomationEventBolusReminder() { val event = AutomationEvent(injector).apply { - title = rh.gs(R.string.bolusreminder) + title = rh.gs(R.string.bolus_reminder) readOnly = true systemAction = true autoRemove = true @@ -46,9 +46,9 @@ class BolusTimer @Inject constructor( automationPlugin.addIfNotExists(event) } - fun removeBolusReminder() { + override fun removeAutomationEventBolusReminder() { val event = AutomationEvent(injector).apply { - title = rh.gs(R.string.bolusreminder) + title = rh.gs(R.string.bolus_reminder) } automationPlugin.removeIfExists(event) } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt b/implementation/src/main/java/info/nightscout/implementation/CarbTimerImpl.kt similarity index 81% rename from app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt rename to implementation/src/main/java/info/nightscout/implementation/CarbTimerImpl.kt index 0652e312db..4dc0ce1a00 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt +++ b/implementation/src/main/java/info/nightscout/implementation/CarbTimerImpl.kt @@ -1,35 +1,44 @@ -package info.nightscout.androidaps.utils +package info.nightscout.implementation import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R +import info.nightscout.androidaps.interfaces.CarbTimer import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.plugins.general.automation.AutomationEvent import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.actions.ActionAlarm -import info.nightscout.androidaps.plugins.general.automation.elements.Comparator import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBg import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDelta +import info.nightscout.androidaps.plugins.general.automation.elements.Comparator import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.utils.TimerUtil import java.text.DecimalFormat import javax.inject.Inject import javax.inject.Singleton @Singleton -class CarbTimer @Inject constructor( +class CarbTimerImpl @Inject constructor( private val injector: HasAndroidInjector, private val rh: ResourceHelper, private val automationPlugin: AutomationPlugin, private val timerUtil: TimerUtil -) { +) : CarbTimer { - fun scheduleReminder(seconds: Int, text: String? = null) = - timerUtil.scheduleReminder(seconds, text ?: rh.gs(R.string.timetoeat)) + /** + * Generate reminder via [info.nightscout.androidaps.utils.TimerUtil] + * + * @param seconds seconds to the future + */ + override fun scheduleTimeToEatReminder(seconds: Int) = + timerUtil.scheduleReminder(seconds, rh.gs(R.string.time_to_eat)) - fun scheduleEatReminder() { + /** + * Create new Automation event to alarm when is time to eat + */ + override fun scheduleAutomationEventEatReminder() { val event = AutomationEvent(injector).apply { - title = rh.gs(R.string.bolusadvisor) + title = rh.gs(R.string.bolus_advisor) readOnly = true systemAction = true autoRemove = true @@ -60,9 +69,12 @@ class CarbTimer @Inject constructor( automationPlugin.addIfNotExists(event) } - fun removeEatReminder() { + /** + * Remove Automation event + */ + override fun removeAutomationEventEatReminder() { val event = AutomationEvent(injector).apply { - title = rh.gs(R.string.bolusadvisor) + title = rh.gs(R.string.bolus_advisor) } automationPlugin.removeIfExists(event) } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/XDripBroadcast.kt b/implementation/src/main/java/info/nightscout/implementation/XDripBroadcastImpl.kt similarity index 88% rename from app/src/main/java/info/nightscout/androidaps/utils/XDripBroadcast.kt rename to implementation/src/main/java/info/nightscout/implementation/XDripBroadcastImpl.kt index aa67a1964a..92ea49f14b 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/XDripBroadcast.kt +++ b/implementation/src/main/java/info/nightscout/implementation/XDripBroadcastImpl.kt @@ -1,16 +1,17 @@ -package info.nightscout.androidaps.utils +package info.nightscout.implementation import android.content.Context import android.content.Intent import android.os.Bundle -import info.nightscout.androidaps.R import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.extensions.safeQueryBroadcastReceivers import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.receivers.Intents +import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP @@ -25,15 +26,15 @@ import javax.inject.Singleton @Suppress("SpellCheckingInspection") @OpenForTesting @Singleton -class XDripBroadcast @Inject constructor( +class XDripBroadcastImpl @Inject constructor( private val context: Context, private val aapsLogger: AAPSLogger, private val sp: SP, private val rh: ResourceHelper, private val profileFunction: ProfileFunction -) { +) : XDripBroadcast { - fun sendCalibration(bg: Double): Boolean { + override fun sendCalibration(bg: Double): Boolean { val bundle = Bundle() bundle.putDouble("glucose_number", bg) bundle.putString("units", if (profileFunction.getUnits() == GlucoseUnit.MGDL) "mgdl" else "mmol") @@ -44,18 +45,18 @@ class XDripBroadcast @Inject constructor( context.sendBroadcast(intent) val q = context.packageManager.safeQueryBroadcastReceivers(intent, 0) return if (q.isEmpty()) { - ToastUtils.errorToast(context, R.string.xdripnotinstalled) - aapsLogger.debug(rh.gs(R.string.xdripnotinstalled)) + ToastUtils.errorToast(context, R.string.xdrip_not_installed) + aapsLogger.debug(rh.gs(R.string.xdrip_not_installed)) false } else { - ToastUtils.errorToast(context, R.string.calibrationsent) - aapsLogger.debug(rh.gs(R.string.calibrationsent)) + ToastUtils.errorToast(context, R.string.calibration_sent) + aapsLogger.debug(rh.gs(R.string.calibration_sent)) true } } // sent in 640G mode - fun send(glucoseValue: GlucoseValue) { + override fun send(glucoseValue: GlucoseValue) { if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) { val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US) try { @@ -89,7 +90,7 @@ class XDripBroadcast @Inject constructor( } // sent in NSClient dbaccess mode - fun sendProfile(profileStoreJson: JSONObject) { + override fun sendProfile(profileStoreJson: JSONObject) { if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) broadcast( Intent(Intents.ACTION_NEW_PROFILE).apply { @@ -101,7 +102,7 @@ class XDripBroadcast @Inject constructor( } // sent in NSClient dbaccess mode - fun sendTreatments(addedOrUpdatedTreatments: JSONArray) { + override fun sendTreatments(addedOrUpdatedTreatments: JSONArray) { if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) splitArray(addedOrUpdatedTreatments).forEach { part -> broadcast( @@ -114,7 +115,7 @@ class XDripBroadcast @Inject constructor( } // sent in NSClient dbaccess mode - fun sendSgvs(sgvs: JSONArray) { + override fun sendSgvs(sgvs: JSONArray) { if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) splitArray(sgvs).forEach { part -> broadcast( diff --git a/implementation/src/main/res/values/strings.xml b/implementation/src/main/res/values/strings.xml new file mode 100644 index 0000000000..4ccd5d28b4 --- /dev/null +++ b/implementation/src/main/res/values/strings.xml @@ -0,0 +1,15 @@ + + + xDrip+ not installed + Calibration sent to xDrip+ + + BG + + Time to eat + Enable bolus advisor + Use reminder to start eating later instead of wizard result during high glycemia ("pre-bolus") + Bolus advisor + You have high glycemia. Instead of eating now it\'s recommended to wait for better glycemia. Do you want to do a correction bolus now and remind you when it\'s time to eat? In this case no carbs will be recorded and you must use wizard again when we remind you. + Time to bolus!\nRun Bolus wizard and do calculation again. + + diff --git a/settings.gradle b/settings.gradle index d9bc0fcfdf..9225e1de8c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,4 +18,6 @@ include ':diaconn' include ':openhumans' include ':shared' include ':graphview' -include ':libraries' \ No newline at end of file +include ':libraries' +include ':ui' +include ':implementation' diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/ui/build.gradle b/ui/build.gradle new file mode 100644 index 0000000000..cae8d77b2a --- /dev/null +++ b/ui/build.gradle @@ -0,0 +1,19 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-allopen' +apply plugin: 'com.hiya.jacoco-android' + +apply from: "${project.rootDir}/core/android_dependencies.gradle" +apply from: "${project.rootDir}/core/android_module_dependencies.gradle" +apply from: "${project.rootDir}/core/test_dependencies.gradle" +apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.ui' +} + +dependencies { + implementation project(':core') + implementation project(':shared') + implementation project(':database') +} \ No newline at end of file diff --git a/ui/consumer-rules.pro b/ui/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ui/proguard-rules.pro b/ui/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/ui/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/ui/src/main/AndroidManifest.xml b/ui/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a5918e68ab --- /dev/null +++ b/ui/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ui/src/main/java/info/nightscout/ui/di/UiModule.kt b/ui/src/main/java/info/nightscout/ui/di/UiModule.kt new file mode 100644 index 0000000000..f2c4c70594 --- /dev/null +++ b/ui/src/main/java/info/nightscout/ui/di/UiModule.kt @@ -0,0 +1,14 @@ +package info.nightscout.ui.di + +import dagger.Module +import dagger.android.ContributesAndroidInjector +import info.nightscout.ui.dialogs.CalibrationDialog +import info.nightscout.ui.dialogs.CarbsDialog + +@Module +@Suppress("unused") +abstract class UiModule { + + @ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog + @ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/CalibrationDialog.kt similarity index 71% rename from app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt rename to ui/src/main/java/info/nightscout/ui/dialogs/CalibrationDialog.kt index 23aa3a8874..3d1aafa0d1 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/CalibrationDialog.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.dialogs +package info.nightscout.ui.dialogs import android.os.Bundle import android.view.LayoutInflater @@ -6,20 +6,21 @@ import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R +import info.nightscout.ui.R +import info.nightscout.ui.databinding.DialogCalibrationBinding import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.ValueWithUnit -import info.nightscout.androidaps.databinding.DialogCalibrationBinding +import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.androidaps.utils.XDripBroadcast import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.interfaces.ResourceHelper import java.text.DecimalFormat import java.util.* import javax.inject.Inject @@ -44,8 +45,10 @@ class CalibrationDialog : DialogFragmentWithDate() { savedInstanceState.putDouble("bg", binding.bg.value) } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { onCreateViewGeneral() _binding = DialogCalibrationBinding.inflate(inflater, container, false) return binding.root @@ -55,14 +58,20 @@ class CalibrationDialog : DialogFragmentWithDate() { super.onViewCreated(view, savedInstanceState) val units = profileFunction.getUnits() - val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose - ?: 0.0, units) + val bg = Profile.fromMgdlToUnits( + glucoseStatusProvider.glucoseStatusData?.glucose + ?: 0.0, units + ) if (units == GlucoseUnit.MMOL) - binding.bg.setParams(savedInstanceState?.getDouble("bg") - ?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok) + binding.bg.setParams( + savedInstanceState?.getDouble("bg") + ?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok + ) else - binding.bg.setParams(savedInstanceState?.getDouble("bg") - ?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok) + binding.bg.setParams( + savedInstanceState?.getDouble("bg") + ?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok + ) binding.units.text = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl) binding.bgLabel.labelFor = binding.bg.editTextId } @@ -78,17 +87,17 @@ class CalibrationDialog : DialogFragmentWithDate() { val unitLabel = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl) val actions: LinkedList = LinkedList() val bg = binding.bg.value - actions.add(rh.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, bg) + " " + unitLabel) + actions.add(rh.gs(R.string.bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, bg) + " " + unitLabel) if (bg > 0) { activity?.let { activity -> - OKDialog.showConfirmation(activity, rh.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("
    ").join(actions)), { + OKDialog.showConfirmation(activity, rh.gs(R.string.calibration), HtmlHelper.fromHtml(Joiner.on("
    ").join(actions)), { uel.log(Action.CALIBRATION, Sources.CalibrationDialog, ValueWithUnit.fromGlucoseUnit(bg, units.asText)) xDripBroadcast.sendCalibration(bg) }) } } else activity?.let { activity -> - OKDialog.show(activity, rh.gs(R.string.overview_calibration), rh.gs(R.string.no_action_selected)) + OKDialog.show(activity, rh.gs(R.string.calibration), rh.gs(R.string.no_action_selected)) } return true } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt similarity index 92% rename from app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt rename to ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt index db221159ce..93dbe027c9 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.dialogs +package info.nightscout.ui.dialogs import android.content.Context import android.os.Bundle @@ -8,7 +8,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner -import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository @@ -17,7 +16,7 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction -import info.nightscout.androidaps.databinding.DialogCarbsBinding +import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.interfaces.* import info.nightscout.shared.logging.LTag @@ -30,6 +29,8 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.ui.R +import info.nightscout.ui.databinding.DialogCarbsBinding import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.text.DecimalFormat @@ -78,15 +79,15 @@ class CarbsDialog : DialogFragmentWithDate() { val time = binding.time.value.toInt() if (time > 12 * 60 || time < -7 * 24 * 60) { binding.time.value = 0.0 - ToastUtils.warnToast(ctx, R.string.constraintapllied) + ToastUtils.warnToast(ctx, R.string.constraint_applied) } if (binding.duration.value > 10) { binding.duration.value = 0.0 - ToastUtils.warnToast(ctx, R.string.constraintapllied) + ToastUtils.warnToast(ctx, R.string.constraint_applied) } if (binding.carbs.value.toInt() > maxCarbs) { binding.carbs.value = 0.0 - ToastUtils.warnToast(ctx, R.string.carbsconstraintapplied) + ToastUtils.warnToast(ctx, R.string.carbs_constraint_applied) } } @@ -143,7 +144,7 @@ class CarbsDialog : DialogFragmentWithDate() { ) val plus1text = toSignedString(sp.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)) binding.plus1.text = plus1text - binding.plus1.contentDescription = rh.gs(R.string.treatments_wizard_carbs_label) + " " + plus1text + binding.plus1.contentDescription = rh.gs(R.string.carbs) + " " + plus1text binding.plus1.setOnClickListener { binding.carbs.value = max( 0.0, binding.carbs.value @@ -155,7 +156,7 @@ class CarbsDialog : DialogFragmentWithDate() { val plus2text = toSignedString(sp.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)) binding.plus2.text = plus2text - binding.plus2.contentDescription = rh.gs(R.string.treatments_wizard_carbs_label) + " " + plus2text + binding.plus2.contentDescription = rh.gs(R.string.carbs) + " " + plus2text binding.plus2.setOnClickListener { binding.carbs.value = max( 0.0, binding.carbs.value @@ -166,7 +167,7 @@ class CarbsDialog : DialogFragmentWithDate() { } val plus3text = toSignedString(sp.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)) binding.plus3.text = plus3text - binding.plus2.contentDescription = rh.gs(R.string.treatments_wizard_carbs_label) + " " + plus3text + binding.plus2.contentDescription = rh.gs(R.string.carbs) + " " + plus3text binding.plus3.setOnClickListener { binding.carbs.value = max( 0.0, binding.carbs.value @@ -233,7 +234,7 @@ class CarbsDialog : DialogFragmentWithDate() { val activitySelected = binding.activityTt.isChecked if (activitySelected) actions.add( - rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, activityTTDuration) + ")").formatColor( + rh.gs(R.string.temp_target_short) + ": " + (DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, activityTTDuration) + ")").formatColor( context, rh, R.attr.tempTargetConfirmation @@ -242,7 +243,7 @@ class CarbsDialog : DialogFragmentWithDate() { val eatingSoonSelected = binding.eatingSoonTt.isChecked if (eatingSoonSelected) actions.add( - rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + rh.gs( + rh.gs(R.string.temp_target_short) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + rh.gs( R.string.format_mins, eatingSoonTTDuration ) + ")").formatColor(context, rh, R.attr.tempTargetConfirmation) @@ -250,7 +251,7 @@ class CarbsDialog : DialogFragmentWithDate() { val hypoSelected = binding.hypoTt.isChecked if (hypoSelected) actions.add( - rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(hypoTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, hypoTTDuration) + ")").formatColor( + rh.gs(R.string.temp_target_short) + ": " + (DecimalFormatter.to1Decimal(hypoTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, hypoTTDuration) + ")").formatColor( context, rh, R.attr.tempTargetConfirmation @@ -266,7 +267,7 @@ class CarbsDialog : DialogFragmentWithDate() { if (carbsAfterConstraints > 0) { actions.add(rh.gs(R.string.carbs) + ": " + "" + rh.gs(R.string.format_carbs, carbsAfterConstraints) + "") if (carbsAfterConstraints != carbs) - actions.add("" + rh.gs(R.string.carbsconstraintapplied) + "") + actions.add("" + rh.gs(R.string.carbs_constraint_applied) + "") } val notes = binding.notesLayout.notes.text.toString() if (notes.isNotEmpty()) @@ -364,16 +365,16 @@ class CarbsDialog : DialogFragmentWithDate() { ValueWithUnit.Hour(duration).takeIf { duration != 0 }) commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { - carbTimer.removeEatReminder() + carbTimer.removeAutomationEventEatReminder() if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else if (sp.getBoolean(R.string.key_usebolusreminder, false) && remindBolus) - bolusTimer.scheduleBolusReminder() + bolusTimer.scheduleAutomationEventBolusReminder() } }) } if (useAlarm && carbs > 0 && timeOffset > 0) { - carbTimer.scheduleReminder(T.mins(timeOffset.toLong()).secs().toInt()) + carbTimer.scheduleTimeToEatReminder(T.mins(timeOffset.toLong()).secs().toInt()) } }, null) } diff --git a/app/src/main/res/layout/dialog_calibration.xml b/ui/src/main/res/layout/dialog_calibration.xml similarity index 94% rename from app/src/main/res/layout/dialog_calibration.xml rename to ui/src/main/res/layout/dialog_calibration.xml index dc4fc27176..cdfb3c95ea 100644 --- a/app/src/main/res/layout/dialog_calibration.xml +++ b/ui/src/main/res/layout/dialog_calibration.xml @@ -33,7 +33,7 @@ android:layout_gravity="center" android:layout_marginStart="10dp" android:layout_marginEnd="10dp" - android:text="@string/overview_calibration" + android:text="@string/calibration" android:textAlignment="center" android:textAppearance="?android:attr/textAppearanceLarge" /> @@ -60,7 +60,7 @@ android:layout_gravity="center_horizontal" android:width="120dp" android:padding="10dp" - android:text="@string/treatments_wizard_bg_label" + android:text="@string/bg_label" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="bold" /> @@ -68,7 +68,7 @@ android:id="@+id/bg" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/treatments_wizard_bg_label" /> + app:customContentDescription="@string/bg_label" /> + tools:context="info.nightscout.ui.dialogs.CarbsDialog"> @@ -194,7 +194,7 @@ android:id="@+id/carbs" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/treatments_wizard_carbs_label" /> + app:customContentDescription="@string/carbs" /> diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml new file mode 100644 index 0000000000..d43cb2176d --- /dev/null +++ b/ui/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ + + + No action selected, nothing will happen + Constraint applied! + Bolus constraint applied + Carbs constraint applied + TT + Dialog canceled + + From 950fedfef33cba14c2db4b1d9f0b80a90b8e8c47 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 31 Oct 2022 21:27:05 +0100 Subject: [PATCH 50/77] add tests --- crowdin.yml | 4 + .../info/nightscout/androidaps/TestBase.kt | 39 ++++++++++ .../implementation/BolusTimerImplTest.kt | 72 +++++++++++++++++ .../implementation/CarbTimerImplTest.kt | 78 +++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 implementation/src/test/java/info/nightscout/androidaps/TestBase.kt create mode 100644 implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt create mode 100644 implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt diff --git a/crowdin.yml b/crowdin.yml index 61f98bf0b8..d211896605 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -49,4 +49,8 @@ files: translation: /pump-common/src/main/res/values-%android_code%/strings.xml - source: /openhumans/src/main/res/values/strings.xml translation: /openhumans/src/main/res/values-%android_code%/strings.xml + - source: /implementation/src/main/res/values/strings.xml + translation: /implementation/src/main/res/values-%android_code%/strings.xml + - source: /ui/src/main/res/values/strings.xml + translation: /ui/src/main/res/values-%android_code%/strings.xml translate_attributes: 0 diff --git a/implementation/src/test/java/info/nightscout/androidaps/TestBase.kt b/implementation/src/test/java/info/nightscout/androidaps/TestBase.kt new file mode 100644 index 0000000000..3d78d1b4f6 --- /dev/null +++ b/implementation/src/test/java/info/nightscout/androidaps/TestBase.kt @@ -0,0 +1,39 @@ +package info.nightscout.androidaps + +import info.nightscout.shared.logging.AAPSLoggerTest +import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.androidaps.utils.rx.TestAapsSchedulers +import org.junit.Before +import org.junit.Rule +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule +import java.util.* + +open class TestBase { + + val aapsLogger = AAPSLoggerTest() + val aapsSchedulers: AapsSchedulers = TestAapsSchedulers() + + // Add a JUnit rule that will setup the @Mock annotated vars and log. + // Another possibility would be to add `MockitoAnnotations.initMocks(this) to the setup method. + @get:Rule + val mockitoRule: MockitoRule = MockitoJUnit.rule() + + @Before + fun setupLocale() { + Locale.setDefault(Locale.ENGLISH) + System.setProperty("disableFirebase", "true") + } + + // Workaround for Kotlin nullability. + // https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791 + // https://stackoverflow.com/questions/30305217/is-it-possible-to-use-mockito-in-kotlin + fun anyObject(): T { + Mockito.any() + return uninitialized() + } + + @Suppress("Unchecked_Cast") + fun uninitialized(): T = null as T +} \ No newline at end of file diff --git a/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt b/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt new file mode 100644 index 0000000000..a5cfb3c152 --- /dev/null +++ b/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt @@ -0,0 +1,72 @@ +package info.nightscout.implementation + +import android.content.Context +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.TestBase +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.GlucoseUnit +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin +import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger +import info.nightscout.androidaps.services.LocationServiceHelper +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.shared.sharedPreferences.SP +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.`when` + +class BolusTimerImplTest : TestBase() { + + @Mock lateinit var rh: ResourceHelper + @Mock lateinit var context: Context + @Mock lateinit var sp: SP + @Mock lateinit var fabricPrivacy: FabricPrivacy + @Mock lateinit var loop: Loop + @Mock lateinit var rxBus: RxBus + @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var config: Config + @Mock lateinit var locationServiceHelper: LocationServiceHelper + @Mock lateinit var activePlugin: ActivePlugin + @Mock lateinit var profileFunction: ProfileFunction + + private val injector = HasAndroidInjector { + AndroidInjector { + if (it is Trigger) { + it.profileFunction = profileFunction + it.rh = rh + } + } + } + private lateinit var dateUtil: DateUtil + + private lateinit var automationPlugin: AutomationPlugin + private lateinit var sut: BolusTimerImpl + + @Before + fun init() { + `when`(rh.gs(anyInt())).thenReturn("") + `when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL) + dateUtil = DateUtil(context) + automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, activePlugin) + sut = BolusTimerImpl(injector, rh, automationPlugin) + } + + @Test + fun doTest() { + Assert.assertEquals(0, automationPlugin.size()) + sut.scheduleAutomationEventBolusReminder() + Assert.assertEquals(1, automationPlugin.size()) + sut.removeAutomationEventBolusReminder() + Assert.assertEquals(0, automationPlugin.size()) + } +} \ No newline at end of file diff --git a/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt b/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt new file mode 100644 index 0000000000..a6923ad2ee --- /dev/null +++ b/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt @@ -0,0 +1,78 @@ +package info.nightscout.implementation + +import android.content.Context +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.TestBase +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.GlucoseUnit +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin +import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger +import info.nightscout.androidaps.services.LocationServiceHelper +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.TimerUtil +import info.nightscout.shared.sharedPreferences.SP +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.`when` + +class CarbTimerImplTest : TestBase() { + + @Mock lateinit var rh: ResourceHelper + @Mock lateinit var context: Context + @Mock lateinit var sp: SP + @Mock lateinit var fabricPrivacy: FabricPrivacy + @Mock lateinit var loop: Loop + @Mock lateinit var rxBus: RxBus + @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var config: Config + @Mock lateinit var locationServiceHelper: LocationServiceHelper + @Mock lateinit var activePlugin: ActivePlugin + @Mock lateinit var profileFunction: ProfileFunction + @Mock lateinit var timerUtil: TimerUtil + + private val injector = HasAndroidInjector { + AndroidInjector { + if (it is Trigger) { + it.profileFunction = profileFunction + it.rh = rh + } + } + } + private lateinit var dateUtil: DateUtil + + private lateinit var automationPlugin: AutomationPlugin + private lateinit var sut: CarbTimerImpl + + @Before + fun init() { + `when`(rh.gs(anyInt())).thenReturn("") + `when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL) + dateUtil = DateUtil(context) + automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, activePlugin) + sut = CarbTimerImpl(injector, rh, automationPlugin, timerUtil) + } + + @Test + fun doTest() { + Assert.assertEquals(0, automationPlugin.size()) + sut.scheduleAutomationEventEatReminder() + Assert.assertEquals(1, automationPlugin.size()) + sut.removeAutomationEventEatReminder() + Assert.assertEquals(0, automationPlugin.size()) + + sut.scheduleTimeToEatReminder(1) + Mockito.verify(timerUtil, Mockito.times(1)).scheduleReminder(1, "") + } +} \ No newline at end of file From 32f3aee6ef0b59024e01d9c057615221c5446aad Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 31 Oct 2022 21:54:53 +0100 Subject: [PATCH 51/77] move strings --- .../info/nightscout/androidaps/dialogs/CareDialog.kt | 2 +- app/src/main/res/layout/autotune_fragment.xml | 2 +- app/src/main/res/layout/dialog_care.xml | 4 ++-- app/src/main/res/layout/dialog_extendedbolus.xml | 4 ++-- app/src/main/res/layout/dialog_profileswitch.xml | 4 ++-- app/src/main/res/layout/dialog_tempbasal.xml | 4 ++-- app/src/main/res/layout/dialog_temptarget.xml | 4 ++-- app/src/main/res/values/strings.xml | 9 --------- core/src/main/res/values/strings.xml | 2 ++ ui/src/main/res/layout/dialog_carbs.xml | 4 ++-- ui/src/main/res/values/strings.xml | 8 ++++++++ 11 files changed, 24 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt index 6e80ae72b5..41eef58548 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt @@ -210,7 +210,7 @@ class CareDialog : DialogFragmentWithDate() { valuesWithUnit.add(ValueWithUnit.TherapyEventMeterType(meterType)) } if (options == EventType.NOTE || options == EventType.EXERCISE) { - actions.add(rh.gs(R.string.careportal_newnstreatment_duration_label) + ": " + rh.gs(R.string.format_mins, binding.duration.value.toInt())) + actions.add(rh.gs(R.string.duration_label) + ": " + rh.gs(R.string.format_mins, binding.duration.value.toInt())) therapyEvent.duration = T.mins(binding.duration.value.toLong()).msecs() valuesWithUnit.add(ValueWithUnit.Minute(binding.duration.value.toInt()).takeIf { !binding.duration.value.equals(0.0) } ) } diff --git a/app/src/main/res/layout/autotune_fragment.xml b/app/src/main/res/layout/autotune_fragment.xml index 744b9a260e..f72b666298 100644 --- a/app/src/main/res/layout/autotune_fragment.xml +++ b/app/src/main/res/layout/autotune_fragment.xml @@ -90,7 +90,7 @@ android:layout_weight="1" android:paddingStart="5dp" android:paddingEnd="5dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> diff --git a/app/src/main/res/layout/dialog_care.xml b/app/src/main/res/layout/dialog_care.xml index b0cb311f67..6f2c623fab 100644 --- a/app/src/main/res/layout/dialog_care.xml +++ b/app/src/main/res/layout/dialog_care.xml @@ -128,7 +128,7 @@ android:layout_gravity="center_horizontal" android:width="120dp" android:padding="10dp" - android:text="@string/careportal_newnstreatment_duration_label" + android:text="@string/duration_label" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="bold" /> @@ -136,7 +136,7 @@ android:id="@+id/duration" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> @@ -100,7 +100,7 @@ android:id="@+id/duration" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> @@ -102,7 +102,7 @@ android:layout_width="130dp" android:layout_height="40dp" android:layout_marginBottom="2dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> @@ -139,7 +139,7 @@ android:id="@+id/duration" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> @@ -102,7 +102,7 @@ android:id="@+id/duration" android:layout_width="130dp" android:layout_height="40dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> Meter Sensor Carb time - Duration Profile Glucose type TempBasal @@ -547,7 +546,6 @@ Controls from Watch Set Temp-Targets and enter Treatments from the watch. Food - g ]]> kJ En @@ -655,8 +653,6 @@ Allow automated crash reporting and feature usage data to be sent to the developers via the fabric.io service. Please update your Dexcom app to supported version Dexcom app is not installed. - Start Activity TT - Start Eating soon TT Do not bolus, record only Category Subcategory @@ -669,7 +665,6 @@ Carbs On Board Insulin On Board Basals - Start Hypo TT Running dev version. Closed loop is disabled. Engineering mode enabled ProfileSwitch missing. Please do a profile switch or press \"Activate Profile\" in the LocalProfile. @@ -829,8 +824,6 @@ Log settings Reset to defaults NSClient malfunction. Consider NS and NSClient restart. - Time offset - Remind to bolus later aps_mode Preferred APS mode Total @@ -906,7 +899,6 @@ %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Profile name: Selected: Units @@ -1131,7 +1123,6 @@ insulin blood glucose outdated - set reminder add new profile clone current profile delete current profile diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 10d9f2b8b6..c53f59bf2d 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -199,6 +199,8 @@ Run alarm in %1$d min Bolus reported an error. Manually check real delivered amount Bolus reminder + Duration + g Limiting max basal rate to %1$.2f U/h because of %2$s diff --git a/ui/src/main/res/layout/dialog_carbs.xml b/ui/src/main/res/layout/dialog_carbs.xml index 479f03323e..f364866639 100644 --- a/ui/src/main/res/layout/dialog_carbs.xml +++ b/ui/src/main/res/layout/dialog_carbs.xml @@ -148,7 +148,7 @@ android:layout_weight="1" android:padding="10dp" android:width="120dp" - android:text="@string/careportal_newnstreatment_duration_label" + android:text="@string/duration_label" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="bold" /> @@ -158,7 +158,7 @@ android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_marginBottom="2dp" - app:customContentDescription="@string/careportal_newnstreatment_duration_label" /> + app:customContentDescription="@string/duration_label" /> Carbs constraint applied TT Dialog canceled + Start Activity TT + Start Eating soon TT + Start Hypo TT + Time offset + min + Remind to bolus later + + set reminder From 369bf2564755b34196ca1d239ef14b28fb4d6d0f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 31 Oct 2022 22:53:10 +0100 Subject: [PATCH 52/77] remove StacktraceLoggerWrapper --- .../history/history_events/HistoryEvent.java | 7 +--- .../shared/logging/StacktraceLoggerWrapper.kt | 39 ------------------- 2 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt diff --git a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java index 1ac0d12f7f..896f2ec21e 100644 --- a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java +++ b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java @@ -1,14 +1,11 @@ package info.nightscout.androidaps.plugins.pump.insight.app_layer.history.history_events; -import info.nightscout.shared.logging.StacktraceLoggerWrapper; import info.nightscout.androidaps.plugins.pump.insight.ids.HistoryEventIDs; import info.nightscout.androidaps.plugins.pump.insight.utils.BOCUtil; import info.nightscout.androidaps.plugins.pump.insight.utils.ByteBuf; -import org.slf4j.Logger; public class HistoryEvent implements Comparable { - @SuppressWarnings("deprecation") - private static final Logger log = StacktraceLoggerWrapper.Companion.getLogger(HistoryEvent.class); + //private static final Logger log = StacktraceLoggerWrapper.Companion.getLogger(HistoryEvent.class); private int eventYear; private int eventMonth; @@ -27,7 +24,7 @@ public class HistoryEvent implements Comparable { try { event = eventClass.newInstance(); } catch (IllegalAccessException | InstantiationException e) { - log.error("Unhandled exception", e); + //log.error("Unhandled exception", e); } } event.parseHeader(byteBuf); diff --git a/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt b/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt deleted file mode 100644 index 2301a3f008..0000000000 --- a/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt +++ /dev/null @@ -1,39 +0,0 @@ -package info.nightscout.shared.logging - -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -/** - * Created by adrian on 2020-01-13. - */ - -class StacktraceLoggerWrapper(private val delegate: Logger) : Logger by delegate { - - override fun debug(msg: String?) { - delegate.debug(stackLogMarker() + msg) - } - - override fun debug(format: String?, arg: Any?) { - delegate.debug(stackLogMarker() + format, arg) - } - - override fun info(msg: String?) { - delegate.info(stackLogMarker() + msg) - } - - override fun error(msg: String?) { - delegate.error(stackLogMarker() + msg) - } - - override fun warn(msg: String?) { - delegate.warn(stackLogMarker() + msg) - } - - // all other methods will be implemented by delegate - - companion object { - - @Deprecated("please inject AAPSLogger") - fun getLogger(clazz: Class<*>) = StacktraceLoggerWrapper(LoggerFactory.getLogger(clazz)) - } -} \ No newline at end of file From 4c5d015b40e04232c016073da4c6f7e27c810be1 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 1 Nov 2022 11:39:40 +0100 Subject: [PATCH 53/77] CommandQueueImpl -> implementation module --- .../nightscout/androidaps/MainActivity.kt | 6 +- .../info/nightscout/androidaps/MainApp.kt | 4 +- .../nightscout/androidaps/di/AppComponent.kt | 1 + .../nightscout/androidaps/di/AppModule.kt | 43 +++- .../androidaps/di/OverviewModule.kt | 1 - .../maintenance/ImportExportPrefsImpl.kt | 24 ++- .../general/overview/OverviewPlugin.kt | 28 ++- .../general/smsCommunicator/AuthRequest.kt | 16 +- .../SmsCommunicatorFragment.kt | 1 + .../smsCommunicator/SmsCommunicatorPlugin.kt | 4 +- .../androidaps/receivers/KeepAliveWorker.kt | 2 +- .../androidaps/setupwizard/SWDefinition.kt | 36 +++- .../androidaps/utils/AndroidPermission.kt | 167 ---------------- app/src/main/res/values/strings.xml | 17 -- app/src/main/res/xml/pref_smscommunicator.xml | 2 +- .../smsCommunicator/AuthRequestTest.kt | 1 + .../SmsCommunicatorPluginTest.kt | 1 + .../general/smsCommunicator/SmsTest.kt | 1 + core/android_module_dependencies.gradle | 5 + .../info/nightscout/androidaps/data}/Sms.kt | 8 +- .../interfaces/AndroidPermission.kt | 17 ++ .../androidaps/interfaces/Insight.kt | 10 + .../androidaps/interfaces/LocalAlertUtils.kt | 17 ++ .../androidaps/interfaces/Overview.kt | 4 + .../androidaps/interfaces/SmsCommunicator.kt | 3 + core/src/main/res/values/strings.xml | 7 + .../implementation/AndroidPermissionImpl.kt | 185 ++++++++++++++++++ .../implementation/LocalAlertUtilsImpl.kt | 26 +-- .../implementation}/di/CommandQueueModule.kt | 22 ++- .../queue/CommandQueueImplementation.kt | 49 +++-- .../implementation}/queue/QueueThread.kt | 8 +- .../queue/commands/CommandBolus.kt | 7 +- .../commands/CommandCancelExtendedBolus.kt | 7 +- .../queue/commands/CommandCancelTempBasal.kt | 7 +- .../queue/commands/CommandCustomCommand.kt | 6 +- .../queue/commands/CommandExtendedBolus.kt | 7 +- .../CommandInsightSetTBROverNotification.kt | 11 +- .../queue/commands/CommandLoadEvents.kt | 7 +- .../queue/commands/CommandLoadHistory.kt | 7 +- .../queue/commands/CommandLoadTDDs.kt | 7 +- .../queue/commands/CommandReadStatus.kt | 9 +- .../queue/commands/CommandSMBBolus.kt | 7 +- .../queue/commands/CommandSetProfile.kt | 14 +- .../queue/commands/CommandSetUserSettings.kt | 7 +- .../queue/commands/CommandStartPump.kt | 9 +- .../queue/commands/CommandStopPump.kt | 9 +- .../commands/CommandTempBasalAbsolute.kt | 9 +- .../queue/commands/CommandTempBasalPercent.kt | 9 +- .../src/main/res/values/strings.xml | 11 ++ .../androidaps/TestBaseWithProfile.kt | 177 +++++++++++++++++ .../nightscout/androidaps/TestPumpPlugin.kt | 68 +++++++ .../queue/CommandQueueImplementationTest.kt | 58 +++--- .../implementation}/queue/QueueThreadTest.kt | 15 +- .../pump/insight/LocalInsightPlugin.java | 4 +- 54 files changed, 832 insertions(+), 356 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.kt rename {app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator => core/src/main/java/info/nightscout/androidaps/data}/Sms.kt (77%) create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/AndroidPermission.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/Insight.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/LocalAlertUtils.kt create mode 100644 implementation/src/main/java/info/nightscout/implementation/AndroidPermissionImpl.kt rename app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt => implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt (89%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/di/CommandQueueModule.kt (58%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/CommandQueueImplementation.kt (92%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/QueueThread.kt (98%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandBolus.kt (92%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandCancelExtendedBolus.kt (84%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandCancelTempBasal.kt (84%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandCustomCommand.kt (83%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandExtendedBolus.kt (86%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandInsightSetTBROverNotification.kt (78%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandLoadEvents.kt (89%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandLoadHistory.kt (89%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandLoadTDDs.kt (83%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandReadStatus.kt (85%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandSMBBolus.kt (93%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandSetProfile.kt (83%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandSetUserSettings.kt (88%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandStartPump.kt (73%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandStopPump.kt (73%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandTempBasalAbsolute.kt (89%) rename {app/src/main/java/info/nightscout/androidaps => implementation/src/main/java/info/nightscout/implementation}/queue/commands/CommandTempBasalPercent.kt (90%) create mode 100644 implementation/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt create mode 100644 implementation/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt rename {app/src/test/java/info/nightscout/androidaps => implementation/src/test/java/info/nightscout/implementation}/queue/CommandQueueImplementationTest.kt (90%) rename {app/src/test/java/info/nightscout/androidaps => implementation/src/test/java/info/nightscout/implementation}/queue/QueueThreadTest.kt (86%) diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index 8822e8b7f3..90e09659e2 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -44,9 +44,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus -import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.setupwizard.SetupWizardActivity -import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest @@ -72,7 +70,7 @@ class MainActivity : NoSplashAppCompatActivity() { @Inject lateinit var androidPermission: AndroidPermission @Inject lateinit var sp: SP @Inject lateinit var versionCheckerUtils: VersionCheckerUtils - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin + @Inject lateinit var smsCommunicator: SmsCommunicator @Inject lateinit var loop: Loop @Inject lateinit var nsSettingsStatus: NSSettingsStatus @Inject lateinit var buildHelper: BuildHelper @@ -152,7 +150,7 @@ class MainActivity : NoSplashAppCompatActivity() { androidPermission.notifyForBatteryOptimizationPermission(this) if (!config.NSCLIENT) androidPermission.notifyForLocationPermissions(this) if (config.PUMPDRIVERS) { - androidPermission.notifyForSMSPermissions(this, smsCommunicatorPlugin) + androidPermission.notifyForSMSPermissions(this, smsCommunicator) androidPermission.notifyForSystemWindowPermissions(this) androidPermission.notifyForBtConnectPermission(this) } diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.kt b/app/src/main/java/info/nightscout/androidaps/MainApp.kt index ec4215aaba..674cc9a10a 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.kt @@ -23,8 +23,10 @@ import info.nightscout.androidaps.database.transactions.VersionChangeTransaction import info.nightscout.androidaps.db.CompatDBHelper import info.nightscout.androidaps.di.DaggerAppComponent import info.nightscout.androidaps.di.StaticInjector +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.ConfigBuilder +import info.nightscout.androidaps.interfaces.LocalAlertUtils import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger @@ -41,9 +43,7 @@ import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver import info.nightscout.androidaps.services.AlarmSoundServiceHelper import info.nightscout.androidaps.utils.ActivityMonitor import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.LocalAlertUtils import info.nightscout.androidaps.utils.ProcessLifecycleListener -import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.widget.updateWidget import info.nightscout.shared.logging.AAPSLogger diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt index ce05242c68..2f06684f31 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt @@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule import info.nightscout.androidaps.plugins.pump.omnipod.dash.di.OmnipodDashModule import info.nightscout.androidaps.plugins.pump.omnipod.eros.di.OmnipodErosModule +import info.nightscout.implementation.di.CommandQueueModule import info.nightscout.shared.di.SharedModule import info.nightscout.ui.di.UiModule import javax.inject.Singleton diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt index 25509a99ce..5c119b31c8 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt @@ -8,8 +8,28 @@ import dagger.Provides import dagger.android.HasAndroidInjector import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.interfaces.* -import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.Autotune +import info.nightscout.androidaps.interfaces.BolusTimer +import info.nightscout.androidaps.interfaces.BuildHelper +import info.nightscout.androidaps.interfaces.CarbTimer +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.ConfigBuilder +import info.nightscout.androidaps.interfaces.DataSyncSelector +import info.nightscout.androidaps.interfaces.IconsProvider +import info.nightscout.androidaps.interfaces.ImportExportPrefs +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.LocalAlertUtils +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.NotificationHolder +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.SmsCommunicator +import info.nightscout.androidaps.interfaces.XDripBroadcast import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin @@ -23,23 +43,24 @@ import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation -import info.nightscout.androidaps.queue.CommandQueueImplementation import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl -import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.ConfigImpl import info.nightscout.androidaps.utils.resources.IconsProviderImplementation -import info.nightscout.androidaps.interfaces.ResourceHelper -import info.nightscout.implementation.XDripBroadcastImpl import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.DefaultAapsSchedulers import info.nightscout.androidaps.utils.storage.FileStorage import info.nightscout.androidaps.utils.storage.Storage +import info.nightscout.implementation.AndroidPermissionImpl import info.nightscout.implementation.BolusTimerImpl import info.nightscout.implementation.CarbTimerImpl +import info.nightscout.implementation.LocalAlertUtilsImpl +import info.nightscout.implementation.XDripBroadcastImpl +import info.nightscout.implementation.queue.CommandQueueImplementation +import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import javax.inject.Singleton @@ -109,10 +130,12 @@ open class AppModule { @Binds fun bindSmsCommunicatorInterface(smsCommunicatorPlugin: SmsCommunicatorPlugin): SmsCommunicator @Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector - @Binds fun bindPumpSync(pumpSyncImplementation: PumpSyncImplementation): PumpSync - @Binds fun bindXDripBroadcast(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast - @Binds fun bindCarbTimer(carbTimer: CarbTimerImpl): CarbTimer - @Binds fun bindBolusTimer(bolusTimer: BolusTimerImpl): BolusTimer + @Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync + @Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast + @Binds fun bindCarbTimerInterface(carbTimer: CarbTimerImpl): CarbTimer + @Binds fun bindBolusTimerInterface(bolusTimer: BolusTimerImpl): BolusTimer + @Binds fun bindAndroidPermissionInterface(androidPermission: AndroidPermissionImpl): AndroidPermission + @Binds fun bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils } } diff --git a/app/src/main/java/info/nightscout/androidaps/di/OverviewModule.kt b/app/src/main/java/info/nightscout/androidaps/di/OverviewModule.kt index 7b80d781ea..8bbc28a25d 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/OverviewModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/OverviewModule.kt @@ -9,6 +9,5 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific @Suppress("unused") abstract class OverviewModule { @ContributesAndroidInjector abstract fun notificationWithActionInjector(): NotificationWithAction - @ContributesAndroidInjector abstract fun graphDataInjector(): GraphData } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt index 25a75d17ce..7ae9c83d2a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt @@ -13,7 +13,12 @@ import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity -import androidx.work.* +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkManager +import androidx.work.Worker +import androidx.work.WorkerParameters +import androidx.work.workDataOf import dagger.android.HasAndroidInjector import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.R @@ -25,13 +30,21 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.diaconn.events.EventDiaconnG8PumpLogReset import info.nightscout.androidaps.events.EventAppExit +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.ImportExportPrefs import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.general.maintenance.formats.* -import info.nightscout.androidaps.utils.AndroidPermission +import info.nightscout.androidaps.plugins.general.maintenance.formats.EncryptedPrefsFormat +import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefFileNotFoundError +import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefIOError +import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefMetadata +import info.nightscout.androidaps.plugins.general.maintenance.formats.Prefs +import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsFormat +import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey +import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsStatus import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.T @@ -40,7 +53,6 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog import info.nightscout.androidaps.utils.alertDialogs.TwoMessagesAlertDialog import info.nightscout.androidaps.utils.alertDialogs.WarningDialog -import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper @@ -251,13 +263,13 @@ class ImportExportPrefsImpl @Inject constructor( activity, rh.gs(R.string.preferences_export_canceled) + "\n\n" + rh.gs(R.string.filenotfound) + ": " + e.message - + "\n\n" + rh.gs(R.string.needstoragepermission) + + "\n\n" + rh.gs(R.string.need_storage_permission) ) log.error(LTag.CORE, "File system exception", e) } catch (e: PrefIOError) { ToastUtils.Long.errorToast( activity, rh.gs(R.string.preferences_export_canceled) - + "\n\n" + rh.gs(R.string.needstoragepermission) + + "\n\n" + rh.gs(R.string.need_storage_permission) + ": " + e.message ) log.error(LTag.CORE, "File system exception", e) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt index 58b2de95d6..9131b131df 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt @@ -1,12 +1,23 @@ package info.nightscout.androidaps.plugins.general.overview +import androidx.annotation.StringRes import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventPumpStatusChanged -import info.nightscout.androidaps.extensions.* -import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.extensions.putDouble +import info.nightscout.androidaps.extensions.putInt +import info.nightscout.androidaps.extensions.putString +import info.nightscout.androidaps.extensions.storeDouble +import info.nightscout.androidaps.extensions.storeInt +import info.nightscout.androidaps.extensions.storeString +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.Overview +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginDescription +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification @@ -15,6 +26,7 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOve import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore +import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.rx.AapsSchedulers @@ -56,6 +68,18 @@ class OverviewPlugin @Inject constructor( private var disposable: CompositeDisposable = CompositeDisposable() override val overviewBus = RxBus(aapsSchedulers, aapsLogger) + override fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable) { + rxBus.send( + EventNewNotification( + NotificationWithAction(injector, id, text, level).apply { + action(actionButtonId, action) + }) + ) + } + + override fun dismissNotification(id: Int) { + rxBus.send(EventDismissNotification(id)) + } class DeviationDataPoint(x: Double, y: Double, var color: Int, scale: Scale) : ScaledDataPoint(x, y, scale) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt index f4c41c42c4..fd61e12c9f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt @@ -4,14 +4,16 @@ import android.os.SystemClock import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Sms import info.nightscout.androidaps.interfaces.CommandQueue -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.SmsCommunicator import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import javax.inject.Inject class AuthRequest internal constructor( @@ -22,7 +24,7 @@ class AuthRequest internal constructor( val action: SmsAction) { @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin + @Inject lateinit var smsCommunicator: SmsCommunicator @Inject lateinit var rh: ResourceHelper @Inject lateinit var otp: OneTimePassword @Inject lateinit var dateUtil: DateUtil @@ -34,7 +36,7 @@ class AuthRequest internal constructor( init { injector.androidInjector().inject(this) date = dateUtil.now() - smsCommunicatorPlugin.sendSMS(Sms(requester.phoneNumber, requestText)) + smsCommunicator.sendSMS(Sms(requester.phoneNumber, requestText)) } private fun codeIsValid(toValidate: String): Boolean = @@ -48,7 +50,7 @@ class AuthRequest internal constructor( if (!codeIsValid(codeReceived)) { processed = true aapsLogger.debug(LTag.SMS, "Wrong code") - smsCommunicatorPlugin.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrongcode))) + smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrongcode))) return } if (dateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) { @@ -62,7 +64,7 @@ class AuthRequest internal constructor( } if (commandQueue.size() != 0) { aapsLogger.debug(LTag.SMS, "Command timed out: " + requester.text) - smsCommunicatorPlugin.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_wating))) + smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_wating))) return } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt index 666097d017..67e2ea7518 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import dagger.android.support.DaggerFragment +import info.nightscout.androidaps.data.Sms import info.nightscout.androidaps.databinding.SmscommunicatorFragmentBinding import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index 63a5d28493..0bcc5b3c82 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -15,6 +15,7 @@ import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.data.DetailedBolusInfo +import info.nightscout.androidaps.data.Sms import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.OfflineEvent import info.nightscout.androidaps.database.entities.TemporaryTarget @@ -184,7 +185,6 @@ class SmsCommunicatorPlugin @Inject constructor( (context.applicationContext as HasAndroidInjector).androidInjector().inject(this) } - @Suppress("SpellCheckingInspection") override fun doWork(): Result { val bundle = dataWorkerStorage.pickupBundle(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) ?: return Result.failure(workDataOf("Error" to "missing input data")) @@ -1099,7 +1099,7 @@ class SmsCommunicatorPlugin @Inject constructor( } } - fun sendSMS(sms: Sms): Boolean { + override fun sendSMS(sms: Sms): Boolean { sms.text = stripAccents(sms.text) try { aapsLogger.debug(LTag.SMS, "Sending SMS to " + sms.phoneNumber + ": " + sms.text) diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt index 8a07fe9afe..8cf63218e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt @@ -22,6 +22,7 @@ import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.LocalAlertUtils import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.ProfileFunction @@ -32,7 +33,6 @@ import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.LocalAlertUtils import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.widget.updateWidget import info.nightscout.shared.logging.AAPSLogger diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt index 8e26f60532..547db33f78 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt @@ -12,7 +12,15 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.dialogs.ProfileSwitchDialog import info.nightscout.androidaps.events.EventPumpStatusChanged -import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.ConfigBuilder +import info.nightscout.androidaps.interfaces.ImportExportPrefs +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment @@ -24,15 +32,25 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin -import info.nightscout.androidaps.setupwizard.elements.* +import info.nightscout.androidaps.setupwizard.elements.SWBreak +import info.nightscout.androidaps.setupwizard.elements.SWButton +import info.nightscout.androidaps.setupwizard.elements.SWEditEncryptedPassword +import info.nightscout.androidaps.setupwizard.elements.SWEditIntNumber +import info.nightscout.androidaps.setupwizard.elements.SWEditNumber +import info.nightscout.androidaps.setupwizard.elements.SWEditNumberWithUnits +import info.nightscout.androidaps.setupwizard.elements.SWEditString +import info.nightscout.androidaps.setupwizard.elements.SWEditUrl +import info.nightscout.androidaps.setupwizard.elements.SWFragment +import info.nightscout.androidaps.setupwizard.elements.SWHtmlLink +import info.nightscout.androidaps.setupwizard.elements.SWInfoText +import info.nightscout.androidaps.setupwizard.elements.SWPlugin +import info.nightscout.androidaps.setupwizard.elements.SWPreference +import info.nightscout.androidaps.setupwizard.elements.SWRadioButton import info.nightscout.androidaps.setupwizard.events.EventSWUpdate -import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.CryptoUtil import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.extensions.isRunningTest -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP -import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -110,7 +128,7 @@ class SWDefinition @Inject constructor( private val screenPermissionWindow = SWScreen(injector, R.string.permission) .skippable(false) .add(SWInfoText(injector) - .label(rh.gs(R.string.needsystemwindowpermission))) + .label(rh.gs(R.string.need_system_window_permission))) .add(SWBreak(injector)) .add(SWButton(injector) .text(R.string.askforpermission) @@ -121,7 +139,7 @@ class SWDefinition @Inject constructor( private val screenPermissionBattery = SWScreen(injector, R.string.permission) .skippable(false) .add(SWInfoText(injector) - .label(rh.gs(R.string.needwhitelisting, rh.gs(R.string.app_name)))) + .label(rh.gs(R.string.need_whitelisting, rh.gs(R.string.app_name)))) .add(SWBreak(injector)) .add(SWButton(injector) .text(R.string.askforpermission) @@ -132,7 +150,7 @@ class SWDefinition @Inject constructor( private val screenPermissionBt = SWScreen(injector, R.string.permission) .skippable(false) .add(SWInfoText(injector) - .label(rh.gs(R.string.needlocationpermission))) + .label(rh.gs(R.string.need_location_permission))) .add(SWBreak(injector)) .add(SWButton(injector) .text(R.string.askforpermission) @@ -143,7 +161,7 @@ class SWDefinition @Inject constructor( private val screenPermissionStore = SWScreen(injector, R.string.permission) .skippable(false) .add(SWInfoText(injector) - .label(rh.gs(R.string.needstoragepermission))) + .label(rh.gs(R.string.need_storage_permission))) .add(SWBreak(injector)) .add(SWButton(injector) .text(R.string.askforpermission) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.kt b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.kt deleted file mode 100644 index cea1f8bb35..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.kt +++ /dev/null @@ -1,167 +0,0 @@ -package info.nightscout.androidaps.utils - -import android.Manifest -import android.annotation.SuppressLint -import android.bluetooth.BluetoothAdapter -import android.content.ActivityNotFoundException -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.net.Uri -import android.os.Build -import android.os.PowerManager -import android.provider.Settings -import androidx.core.content.ContextCompat -import androidx.fragment.app.FragmentActivity -import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult -import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification -import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification -import info.nightscout.androidaps.plugins.general.overview.notifications.Notification -import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction -import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.interfaces.ResourceHelper -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class AndroidPermission @Inject constructor( - val rh: ResourceHelper, - val rxBus: RxBus, - val injector: HasAndroidInjector -) { - - private var permissionBatteryOptimizationFailed = false - - @SuppressLint("BatteryLife") - fun askForPermission(activity: FragmentActivity, permissions: Array) { - var test = false - var testBattery = false - for (s in permissions) { - test = test || ContextCompat.checkSelfPermission(activity, s) != PackageManager.PERMISSION_GRANTED - if (s == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) { - val powerManager = activity.getSystemService(Context.POWER_SERVICE) as PowerManager - val packageName = activity.packageName - testBattery = testBattery || !powerManager.isIgnoringBatteryOptimizations(packageName) - } - } - if (test) { - if (activity is DaggerAppCompatActivityWithResult) - try { - activity.requestMultiplePermissions.launch(permissions) - } catch (ignored: IllegalStateException) { - ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions)) - } - } - if (testBattery) { - try { - if (activity is DaggerAppCompatActivityWithResult) - try { - activity.callForBatteryOptimization.launch(null) - } catch (ignored: IllegalStateException) { - ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions)) - } - } catch (e: ActivityNotFoundException) { - permissionBatteryOptimizationFailed = true - OKDialog.show(activity, rh.gs(R.string.permission), rh.gs(R.string.alert_dialog_permission_battery_optimization_failed)) { activity.recreate() } - } - } - } - - fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission)) - - fun permissionNotGranted(context: Context, permission: String): Boolean { - var selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED - if (permission == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) { - if (!permissionBatteryOptimizationFailed) { - val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager - val packageName = context.packageName - selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName) - } - } - return !selfCheck - } - - @Synchronized - fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicatorPlugin: SmsCommunicatorPlugin) { - if (smsCommunicatorPlugin.isEnabled()) { - if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS)) { - val notification = NotificationWithAction(injector, Notification.PERMISSION_SMS, rh.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT) - notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_MMS)) } - rxBus.send(EventNewNotification(notification)) - } else rxBus.send(EventDismissNotification(Notification.PERMISSION_SMS)) - // Following is a bug in Android 8 -// if (permissionNotGranted(activity, Manifest.permission.READ_PHONE_STATE)) { -// val notification = NotificationWithAction(injector, Notification.PERMISSION_PHONE_STATE, rh.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT) -// notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_PHONE_STATE)) } -// rxBus.send(EventNewNotification(notification)) -// } else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONE_STATE)) - } - } - - @SuppressLint("MissingPermission") - @Synchronized - fun notifyForBtConnectPermission(activity: FragmentActivity) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - // Manifest.permission.BLUETOOTH_CONNECT - if (permissionNotGranted(activity, Manifest.permission.BLUETOOTH_CONNECT) || permissionNotGranted(activity, Manifest.permission.BLUETOOTH_SCAN)) { - val notification = NotificationWithAction(injector, Notification.PERMISSION_BT, rh.gs(R.string.needconnectpermission), Notification.URGENT) - notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)) } - rxBus.send(EventNewNotification(notification)) - } else { - activity.startActivity(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)) - rxBus.send(EventDismissNotification(Notification.PERMISSION_BT)) - } - } - } - - @Synchronized - fun notifyForBatteryOptimizationPermission(activity: FragmentActivity) { - if (permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) { - val notification = NotificationWithAction(injector, Notification.PERMISSION_BATTERY, rh.gs(R.string.needwhitelisting, rh.gs(R.string.app_name)), Notification.URGENT) - notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) } - rxBus.send(EventNewNotification(notification)) - } else rxBus.send(EventDismissNotification(Notification.PERMISSION_BATTERY)) - } - - @Synchronized fun notifyForStoragePermission(activity: FragmentActivity) { - if (permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { - val notification = NotificationWithAction(injector, Notification.PERMISSION_STORAGE, rh.gs(R.string.needstoragepermission), Notification.URGENT) - notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) } - rxBus.send(EventNewNotification(notification)) - } else rxBus.send(EventDismissNotification(Notification.PERMISSION_STORAGE)) - } - - @Synchronized fun notifyForLocationPermissions(activity: FragmentActivity) { - if (permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION)) { - val notification = NotificationWithAction(injector, Notification.PERMISSION_LOCATION, rh.gs(R.string.needlocationpermission), Notification.URGENT) - notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)) } - rxBus.send(EventNewNotification(notification)) - } else rxBus.send(EventDismissNotification(Notification.PERMISSION_LOCATION)) - } - - @Synchronized fun notifyForSystemWindowPermissions(activity: FragmentActivity) { - // Check if Android Q or higher - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - if (!Settings.canDrawOverlays(activity)) { - val notification = NotificationWithAction(injector, Notification.PERMISSION_SYSTEM_WINDOW, rh.gs(R.string.needsystemwindowpermission), Notification.URGENT) - notification.action(R.string.request) { - // Check if Android Q or higher - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - // Show alert dialog to the user saying a separate permission is needed - // Launch the settings activity if the user prefers - val intent = Intent( - Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - Uri.parse("package:" + activity.packageName) - ) - activity.startActivity(intent) - } - } - rxBus.send(EventNewNotification(notification)) - } else rxBus.send(EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW)) - } - } -} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a4bc2cc03f..95603b7207 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,7 +67,6 @@ Reset Databases Do you really want to reset the databases? Exit - This device does not appear to support battery optimization whitelisting - you may experience performance issues. Some buttons to quickly access common features Used for configuring the active plugins Learning program @@ -225,7 +224,6 @@ Minimum number of minutes that must elapse between one remote bolus and the next How many minutes must elapse, at least, between one bolus and the next For your safety, to edit this preference you need to add at least 2 phone numbers. - Going to deliver %1$.2f U Bolus %1$.2f U delivered successfully Meal Bolus %1$.2f U delivered successfully Target %1$s for %2$d minutes @@ -295,7 +293,6 @@ Resend All Data Open Settings on Wear Basal rate - Basal value below minimum. Profile not set! BG: Last BG: MM640g @@ -386,7 +383,6 @@ patient_name I_understand Glimp - %1$s needs battery optimization whitelisting for proper performance Loop suspended Suspended (%1$d m) Suspend loop for 1h @@ -460,7 +456,6 @@ ABS DEVSLOPE About - Missing SMS permission Missing phone state permission xDrip+ Status (watch) xDrip+ Statusline (watch) @@ -551,14 +546,9 @@ En Pr Fat - Command is executed right now - Missed BG readings raise_urgent_alarms_as_android_notification Use system notifications for alerts and notifications Gradually increase the volume for alerts and notifications - enable_pump_unreachable_alert - enable_missed_bg_readings - enable_carbs_required_alert_local Local alerts Alert if no BG data is received Alert if pump is unreachable @@ -765,12 +755,7 @@ Please configure your RileyLink below. After selecting a RileyLink, it will be possible to continue setup once the RileyLink status is \"Connected\". This might take a minute.\n Note: You can continue setup once the pump has been set up.\n Start your first objective - Permission Ask for permission - Application needs system window permission for notifications - Application needs location permission for BT scan and WiFi identification - Application needs storage permission to be able store log files and export settings - Request Open navigation Close navigation Plugin preferences @@ -1020,7 +1005,6 @@ Filter Unable to create profile. Profile is invalid. Don\'t kill my app? - smscommunicator_report_pump_ureachable Send SMS if unreachable pump event is triggered Report pump unreachable Run alarm when is time to eat @@ -1220,7 +1204,6 @@ Blocked by charging options Blocked by connectivity options (No Watch Connected) - Error asking for permissions dynisf_adjust_sensitivity Adjust sensitivity and BG Database cleanup diff --git a/app/src/main/res/xml/pref_smscommunicator.xml b/app/src/main/res/xml/pref_smscommunicator.xml index e0fb8ea94c..396c8ab3f2 100644 --- a/app/src/main/res/xml/pref_smscommunicator.xml +++ b/app/src/main/res/xml/pref_smscommunicator.xml @@ -44,7 +44,7 @@ diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt index c29ca22e65..33af627a8c 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt @@ -5,6 +5,7 @@ import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBase +import info.nightscout.androidaps.data.Sms import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.utils.DateUtil diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt index 9b70fcfbfd..f4ef917cfc 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt @@ -8,6 +8,7 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.data.IobTotal import info.nightscout.androidaps.data.PumpEnactResult +import info.nightscout.androidaps.data.Sms import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.transactions.CancelCurrentOfflineEventIfAnyTransaction diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt index 31b315a8df..ea3f5d582d 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt @@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.smsCommunicator import android.telephony.SmsMessage import info.nightscout.androidaps.TestBase +import info.nightscout.androidaps.data.Sms import org.junit.Assert import org.junit.Test import org.mockito.Mockito diff --git a/core/android_module_dependencies.gradle b/core/android_module_dependencies.gradle index a1912540c7..26c180a46b 100644 --- a/core/android_module_dependencies.gradle +++ b/core/android_module_dependencies.gradle @@ -15,6 +15,11 @@ android { dimension "standard" } } + + // disable for modules here + buildFeatures { + buildConfig = true + } } dependencies { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt b/core/src/main/java/info/nightscout/androidaps/data/Sms.kt similarity index 77% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt rename to core/src/main/java/info/nightscout/androidaps/data/Sms.kt index cfbfbd163b..370b591f31 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.kt +++ b/core/src/main/java/info/nightscout/androidaps/data/Sms.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.androidaps.data import android.telephony.SmsMessage @@ -12,21 +12,21 @@ class Sms { var processed = false var ignored = false - internal constructor(message: SmsMessage) { + constructor(message: SmsMessage) { phoneNumber = message.originatingAddress ?: "" text = message.messageBody date = message.timestampMillis received = true } - internal constructor(phoneNumber: String, text: String) { + constructor(phoneNumber: String, text: String) { this.phoneNumber = phoneNumber this.text = text date = System.currentTimeMillis() sent = true } - internal constructor(other: Sms, number: String? = null) { + constructor(other: Sms, number: String? = null) { phoneNumber = number ?: other.phoneNumber text = other.text date = other.date diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/AndroidPermission.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/AndroidPermission.kt new file mode 100644 index 0000000000..2dfa77836c --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/AndroidPermission.kt @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.interfaces + +import android.content.Context +import androidx.fragment.app.FragmentActivity + +interface AndroidPermission { + + fun askForPermission(activity: FragmentActivity, permissions: Array) + fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission)) + fun permissionNotGranted(context: Context, permission: String): Boolean + fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicator: SmsCommunicator) + fun notifyForBtConnectPermission(activity: FragmentActivity) + fun notifyForBatteryOptimizationPermission(activity: FragmentActivity) + fun notifyForStoragePermission(activity: FragmentActivity) + fun notifyForLocationPermissions(activity: FragmentActivity) + fun notifyForSystemWindowPermissions(activity: FragmentActivity) +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/Insight.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/Insight.kt new file mode 100644 index 0000000000..911f2b32ff --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/Insight.kt @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.interfaces + +import info.nightscout.androidaps.data.PumpEnactResult + +interface Insight { + + fun setTBROverNotification(enabled: Boolean): PumpEnactResult + fun startPump(): PumpEnactResult + fun stopPump(): PumpEnactResult +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/LocalAlertUtils.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/LocalAlertUtils.kt new file mode 100644 index 0000000000..928bac8726 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/LocalAlertUtils.kt @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.interfaces + +interface LocalAlertUtils { + + fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) + + /* Pre-snoozes the alarms with 5 minutes if no snooze exists. + * Call only at startup! + */ + fun preSnoozeAlarms() + + /* shortens alarm times in case of setting changes or future data + */ + fun shortenSnoozeInterval() + fun notifyPumpStatusRead() + fun checkStaleBGAlert() +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/Overview.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/Overview.kt index ac2e321155..780bb5caea 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/Overview.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/Overview.kt @@ -1,8 +1,12 @@ package info.nightscout.androidaps.interfaces +import androidx.annotation.StringRes import info.nightscout.androidaps.plugins.bus.RxBus interface Overview : ConfigExportImport { val overviewBus: RxBus + + fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable) + fun dismissNotification(id: Int) } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt index e753ea049f..1f272e4e31 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt @@ -1,6 +1,9 @@ package info.nightscout.androidaps.interfaces +import info.nightscout.androidaps.data.Sms + interface SmsCommunicator { fun sendNotificationToAllNumbers(text: String): Boolean + fun sendSMS(sms: Sms): Boolean } \ No newline at end of file diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index c53f59bf2d..69811b2488 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -80,6 +80,10 @@ carbs_button_increment_1 carbs_button_increment_2 carbs_button_increment_3 + enable_pump_unreachable_alert + enable_missed_bg_readings + enable_carbs_required_alert_local + smscommunicator_report_pump_unreachable Refresh @@ -617,6 +621,9 @@ Another run of Autotune is detected, run cancelled Application needs bluetooth permission + + Missing SMS permission + %1$d day %1$d days diff --git a/implementation/src/main/java/info/nightscout/implementation/AndroidPermissionImpl.kt b/implementation/src/main/java/info/nightscout/implementation/AndroidPermissionImpl.kt new file mode 100644 index 0000000000..7d5c100abc --- /dev/null +++ b/implementation/src/main/java/info/nightscout/implementation/AndroidPermissionImpl.kt @@ -0,0 +1,185 @@ +package info.nightscout.implementation + +import android.Manifest +import android.annotation.SuppressLint +import android.bluetooth.BluetoothAdapter +import android.content.ActivityNotFoundException +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build +import android.os.PowerManager +import android.provider.Settings +import androidx.core.content.ContextCompat +import androidx.fragment.app.FragmentActivity +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.SmsCommunicator +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.general.overview.notifications.Notification +import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AndroidPermissionImpl @Inject constructor( + val rh: ResourceHelper, + val rxBus: RxBus, + val injector: HasAndroidInjector, + val activePlugin: ActivePlugin +) : AndroidPermission { + + private var permissionBatteryOptimizationFailed = false + + @SuppressLint("BatteryLife") + override fun askForPermission(activity: FragmentActivity, permissions: Array) { + var test = false + var testBattery = false + for (s in permissions) { + test = test || ContextCompat.checkSelfPermission(activity, s) != PackageManager.PERMISSION_GRANTED + if (s == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) { + val powerManager = activity.getSystemService(Context.POWER_SERVICE) as PowerManager + val packageName = activity.packageName + testBattery = testBattery || !powerManager.isIgnoringBatteryOptimizations(packageName) + } + } + if (test) { + if (activity is DaggerAppCompatActivityWithResult) + try { + activity.requestMultiplePermissions.launch(permissions) + } catch (ignored: IllegalStateException) { + ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions)) + } + } + if (testBattery) { + try { + if (activity is DaggerAppCompatActivityWithResult) + try { + activity.callForBatteryOptimization.launch(null) + } catch (ignored: IllegalStateException) { + ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions)) + } + } catch (e: ActivityNotFoundException) { + permissionBatteryOptimizationFailed = true + OKDialog.show(activity, rh.gs(R.string.permission), rh.gs(R.string.alert_dialog_permission_battery_optimization_failed)) { activity.recreate() } + } + } + } + + override fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission)) + + override fun permissionNotGranted(context: Context, permission: String): Boolean { + var selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED + if (permission == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) { + if (!permissionBatteryOptimizationFailed) { + val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager + val packageName = context.packageName + selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName) + } + } + return !selfCheck + } + + @Synchronized + override fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicator: SmsCommunicator) { + if ((smsCommunicator as PluginBase).isEnabled()) { + if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS)) + activePlugin.activeOverview.addNotification( + id = Notification.PERMISSION_SMS, + text = rh.gs(R.string.smscommunicator_missingsmspermission), + level = Notification.URGENT, + actionButtonId = R.string.request + ) { + askForPermission( + activity, + arrayOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_MMS) + ) + } + else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_SMS) + } + } + + @SuppressLint("MissingPermission") + @Synchronized + override fun notifyForBtConnectPermission(activity: FragmentActivity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // Manifest.permission.BLUETOOTH_CONNECT + if (permissionNotGranted(activity, Manifest.permission.BLUETOOTH_CONNECT) || permissionNotGranted(activity, Manifest.permission.BLUETOOTH_SCAN)) + activePlugin.activeOverview.addNotification( + id = Notification.PERMISSION_BT, + text = rh.gs(R.string.needconnectpermission), + level = Notification.URGENT, + actionButtonId = R.string.request + ) { askForPermission(activity, arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)) } + else { + activity.startActivity(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)) + activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_BT) + } + } + } + + @Synchronized + override fun notifyForBatteryOptimizationPermission(activity: FragmentActivity) { + if (permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) + activePlugin.activeOverview.addNotification( + id = Notification.PERMISSION_BATTERY, + text = rh.gs(R.string.need_whitelisting, rh.gs(R.string.app_name)), + level = Notification.URGENT, + actionButtonId = R.string.request + ) { askForPermission(activity, arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) } + else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_BATTERY) + } + + @Synchronized override fun notifyForStoragePermission(activity: FragmentActivity) { + if (permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) + activePlugin.activeOverview.addNotification( + id = Notification.PERMISSION_STORAGE, + text = rh.gs(R.string.need_storage_permission), + level = Notification.URGENT, + actionButtonId = R.string.request + ) { askForPermission(activity, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) } + else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_STORAGE) + } + + @Synchronized override fun notifyForLocationPermissions(activity: FragmentActivity) { + if (permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION)) { + activePlugin.activeOverview.addNotification( + id = Notification.PERMISSION_LOCATION, + text = rh.gs(R.string.need_location_permission), + level = Notification.URGENT, + actionButtonId = R.string.request + ) { askForPermission(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)) } + } else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_LOCATION) + } + + @Synchronized override fun notifyForSystemWindowPermissions(activity: FragmentActivity) { + // Check if Android Q or higher + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + if (!Settings.canDrawOverlays(activity)) + activePlugin.activeOverview.addNotification( + id = Notification.PERMISSION_SYSTEM_WINDOW, + text = rh.gs(R.string.need_location_permission), + level = Notification.URGENT, + actionButtonId = R.string.request + ) { + // Check if Android Q or higher + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + // Show alert dialog to the user saying a separate permission is needed + // Launch the settings activity if the user prefers + val intent = Intent( + Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + activity.packageName) + ) + activity.startActivity(intent) + } + } + else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_SYSTEM_WINDOW) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt b/implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt rename to implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt index 512f1b2d53..85b9961a53 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt +++ b/implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.utils +package info.nightscout.implementation import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.entities.TherapyEvent @@ -11,14 +10,17 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.LocalAlertUtils import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.SmsCommunicator import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification -import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.T import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP @@ -32,19 +34,19 @@ import kotlin.math.min * Created by adrian on 17/12/17. */ @Singleton -class LocalAlertUtils @Inject constructor( +class LocalAlertUtilsImpl @Inject constructor( private val aapsLogger: AAPSLogger, private val sp: SP, private val rxBus: RxBus, private val rh: ResourceHelper, private val activePlugin: ActivePlugin, private val profileFunction: ProfileFunction, - private val smsCommunicatorPlugin: SmsCommunicatorPlugin, + private val smsCommunicatorPlugin: SmsCommunicator, private val config: Config, private val repository: AppRepository, private val dateUtil: DateUtil, private val uel: UserEntryLogger -) { +) : LocalAlertUtils { private val disposable = CompositeDisposable() @@ -56,7 +58,7 @@ class LocalAlertUtils @Inject constructor( return T.mins(sp.getInt(R.string.key_pump_unreachable_threshold_minutes, Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs() } - fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) { + override fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) { val alarmTimeoutExpired = isAlarmTimeoutExpired(lastConnection, pumpUnreachableThreshold()) val nextAlarmOccurrenceReached = sp.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis() if (config.APS && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !isDisconnected) { @@ -68,7 +70,7 @@ class LocalAlertUtils @Inject constructor( if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(rh.gs(R.string.pump_unreachable))).subscribe() } - if (sp.getBoolean(R.string.key_smscommunicator_report_pump_ureachable, true)) + if (sp.getBoolean(R.string.key_smscommunicator_report_pump_unreachable, true)) smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable)) } if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE)) @@ -85,7 +87,7 @@ class LocalAlertUtils @Inject constructor( /*Pre-snoozes the alarms with 5 minutes if no snooze exists. * Call only at startup! */ - fun preSnoozeAlarms() { + override fun preSnoozeAlarms() { if (sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) { sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000) } @@ -94,7 +96,7 @@ class LocalAlertUtils @Inject constructor( } } - fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data + override fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data var nextMissedReadingsAlarm = sp.getLong("nextMissedReadingsAlarm", 0L) nextMissedReadingsAlarm = min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm) sp.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm) @@ -103,7 +105,7 @@ class LocalAlertUtils @Inject constructor( sp.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm) } - fun notifyPumpStatusRead() { //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm + override fun notifyPumpStatusRead() { //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm val pump = activePlugin.activePump val profile = profileFunction.getProfile() if (profile != null) { @@ -115,7 +117,7 @@ class LocalAlertUtils @Inject constructor( } } - fun checkStaleBGAlert() { + override fun checkStaleBGAlert() { val bgReadingWrapped = repository.getLastGlucoseValueWrapped().blockingGet() val bgReading = if (bgReadingWrapped is ValueWrapper.Existing) bgReadingWrapped.value else return if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false) diff --git a/app/src/main/java/info/nightscout/androidaps/di/CommandQueueModule.kt b/implementation/src/main/java/info/nightscout/implementation/di/CommandQueueModule.kt similarity index 58% rename from app/src/main/java/info/nightscout/androidaps/di/CommandQueueModule.kt rename to implementation/src/main/java/info/nightscout/implementation/di/CommandQueueModule.kt index 7f68cca9c9..e6864c9508 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/CommandQueueModule.kt +++ b/implementation/src/main/java/info/nightscout/implementation/di/CommandQueueModule.kt @@ -1,9 +1,25 @@ -package info.nightscout.androidaps.di +package info.nightscout.implementation.di import dagger.Module import dagger.android.ContributesAndroidInjector -import info.nightscout.androidaps.queue.CommandQueueImplementation -import info.nightscout.androidaps.queue.commands.* +import info.nightscout.implementation.queue.CommandQueueImplementation +import info.nightscout.implementation.queue.commands.CommandReadStatus +import info.nightscout.implementation.queue.commands.CommandSMBBolus +import info.nightscout.implementation.queue.commands.CommandSetProfile +import info.nightscout.implementation.queue.commands.CommandSetUserSettings +import info.nightscout.implementation.queue.commands.CommandStartPump +import info.nightscout.implementation.queue.commands.CommandStopPump +import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute +import info.nightscout.implementation.queue.commands.CommandTempBasalPercent +import info.nightscout.implementation.queue.commands.CommandBolus +import info.nightscout.implementation.queue.commands.CommandCancelExtendedBolus +import info.nightscout.implementation.queue.commands.CommandCancelTempBasal +import info.nightscout.implementation.queue.commands.CommandCustomCommand +import info.nightscout.implementation.queue.commands.CommandExtendedBolus +import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification +import info.nightscout.implementation.queue.commands.CommandLoadEvents +import info.nightscout.implementation.queue.commands.CommandLoadHistory +import info.nightscout.implementation.queue.commands.CommandLoadTDDs @Module @Suppress("unused") diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt similarity index 92% rename from app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt index fc3e39daa6..e4cbcc9253 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.queue +package info.nightscout.implementation.queue import android.content.Context import android.content.Intent @@ -6,7 +6,6 @@ import android.os.SystemClock import android.text.Spanned import androidx.appcompat.app.AppCompatActivity import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.BolusProgressHelperActivity import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.annotations.OpenForTesting @@ -22,22 +21,48 @@ import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.events.EventMobileToWear import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.extensions.getCustomizedName -import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.BuildHelper +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification -import info.nightscout.androidaps.queue.commands.* +import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.queue.commands.Command.CommandType -import info.nightscout.androidaps.utils.AndroidPermission +import info.nightscout.androidaps.queue.commands.CustomCommand import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.androidaps.interfaces.BuildHelper -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.implementation.R +import info.nightscout.implementation.queue.commands.CommandBolus +import info.nightscout.implementation.queue.commands.CommandCancelExtendedBolus +import info.nightscout.implementation.queue.commands.CommandCancelTempBasal +import info.nightscout.implementation.queue.commands.CommandCustomCommand +import info.nightscout.implementation.queue.commands.CommandExtendedBolus +import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification +import info.nightscout.implementation.queue.commands.CommandLoadEvents +import info.nightscout.implementation.queue.commands.CommandLoadHistory +import info.nightscout.implementation.queue.commands.CommandLoadTDDs +import info.nightscout.implementation.queue.commands.CommandReadStatus +import info.nightscout.implementation.queue.commands.CommandSMBBolus +import info.nightscout.implementation.queue.commands.CommandSetProfile +import info.nightscout.implementation.queue.commands.CommandSetUserSettings +import info.nightscout.implementation.queue.commands.CommandStartPump +import info.nightscout.implementation.queue.commands.CommandStopPump +import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute +import info.nightscout.implementation.queue.commands.CommandTempBasalPercent import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP @@ -45,7 +70,7 @@ import info.nightscout.shared.weardata.EventData import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.subscribeBy -import java.util.* +import java.util.LinkedList import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton @@ -121,7 +146,7 @@ class CommandQueueImplementation @Inject constructor( } private fun executingNowError(): PumpEnactResult = - PumpEnactResult(injector).success(false).enacted(false).comment(R.string.executingrightnow) + PumpEnactResult(injector).success(false).enacted(false).comment(R.string.executing_right_now) override fun isRunning(type: CommandType): Boolean = performing?.commandType == type @@ -300,7 +325,7 @@ class CommandQueueImplementation @Inject constructor( // not when the Bolus command is starting. The command closes the dialog upon completion). showBolusProgressDialog(detailedBolusInfo) // Notify Wear about upcoming bolus - rxBus.send(EventMobileToWear(EventData.BolusProgress(percent = 0, status = rh.gs(R.string.bolusrequested, detailedBolusInfo.insulin)))) + rxBus.send(EventMobileToWear(EventData.BolusProgress(percent = 0, status = rh.gs(R.string.goingtodeliver, detailedBolusInfo.insulin)))) } } notifyAboutNewCommand() @@ -421,9 +446,9 @@ class CommandQueueImplementation @Inject constructor( val basalValues = profile.getBasalValues() for (basalValue in basalValues) { if (basalValue.value < activePlugin.activePump.pumpDescription.basalMinimumRate) { - val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, rh.gs(R.string.basalvaluebelowminimum), Notification.URGENT) + val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, rh.gs(R.string.basal_value_below_minimum), Notification.URGENT) rxBus.send(EventNewNotification(notification)) - callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.basalvaluebelowminimum))?.run() + callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.basal_value_below_minimum))?.run() return false } } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.kt b/implementation/src/main/java/info/nightscout/implementation/queue/QueueThread.kt similarity index 98% rename from app/src/main/java/info/nightscout/androidaps/queue/QueueThread.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/QueueThread.kt index edf8fac07c..86e7887daf 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/QueueThread.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.queue +package info.nightscout.implementation.queue import android.bluetooth.BluetoothManager import android.content.Context @@ -6,19 +6,19 @@ import android.os.Build import android.os.PowerManager import android.os.SystemClock import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.extensions.safeDisable import info.nightscout.androidaps.extensions.safeEnable import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.queue.events.EventQueueChanged -import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.implementation.R import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandBolus.kt similarity index 92% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandBolus.kt index 03c852754d..66c933aa16 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandBolus.kt @@ -1,14 +1,15 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandBolus( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCancelExtendedBolus.kt similarity index 84% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCancelExtendedBolus.kt index 9513083a5d..4a88bee589 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCancelExtendedBolus.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandCancelExtendedBolus constructor( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCancelTempBasal.kt similarity index 84% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCancelTempBasal.kt index 2496f36e7f..41092b6311 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCancelTempBasal.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandCancelTempBasal( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCustomCommand.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCustomCommand.kt similarity index 83% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCustomCommand.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCustomCommand.kt index 59df7544d8..318131629e 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCustomCommand.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandCustomCommand.kt @@ -1,9 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.androidaps.queue.commands.CustomCommand +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandCustomCommand( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandExtendedBolus.kt similarity index 86% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandExtendedBolus.kt index 7cd755b50b..62d7aef111 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandExtendedBolus.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandExtendedBolus constructor( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandInsightSetTBROverNotification.kt similarity index 78% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandInsightSetTBROverNotification.kt index 7ea827e510..c4fbdf7c7d 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandInsightSetTBROverNotification.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin +import info.nightscout.androidaps.interfaces.Insight import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R import javax.inject.Inject class CommandInsightSetTBROverNotification constructor( @@ -17,14 +18,14 @@ class CommandInsightSetTBROverNotification constructor( override fun execute() { val pump = activePlugin.activePump - if (pump is LocalInsightPlugin) { + if (pump is Insight) { val result = pump.setTBROverNotification(enabled) callback?.result(result)?.run() } } - @Suppress("SpellCheckingInspection") override fun status(): String = rh.gs(R.string.insight_set_tbr_over_notification) + @Suppress("SpellCheckingInspection") override fun log(): String = "INSIGHTSETTBROVERNOTIFICATION" } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadEvents.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadEvents.kt index 9df10bd36a..a8f515370f 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadEvents.kt @@ -1,12 +1,13 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.Diaconn -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandLoadEvents( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadHistory.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadHistory.kt index 2ff78788e3..89939c2b4c 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadHistory.kt @@ -1,12 +1,13 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.Diaconn -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandLoadHistory( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadTDDs.kt similarity index 83% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadTDDs.kt index 1099c6be59..138cebbfd6 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandLoadTDDs.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandLoadTDDs( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandReadStatus.kt similarity index 85% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandReadStatus.kt index 2c98f7a9cf..8c709856e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandReadStatus.kt @@ -1,13 +1,14 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.LocalAlertUtils import info.nightscout.androidaps.queue.Callback -import info.nightscout.androidaps.utils.LocalAlertUtils +import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.T +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandReadStatus( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSMBBolus.kt similarity index 93% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSMBBolus.kt index 76895ddcce..8d1585c46d 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSMBBolus.kt @@ -1,14 +1,15 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandSMBBolus( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt similarity index 83% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt index cef321bc11..030c751f5a 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt @@ -1,17 +1,19 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.Profile -import info.nightscout.shared.logging.LTag -import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin +import info.nightscout.androidaps.interfaces.SmsCommunicator import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandSetProfile constructor( @@ -21,7 +23,7 @@ class CommandSetProfile constructor( callback: Callback? ) : Command(injector, CommandType.BASAL_PROFILE, callback) { - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin + @Inject lateinit var smsCommunicatorPlugin: SmsCommunicator @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var dateUtil: DateUtil @Inject lateinit var commandQueue: CommandQueue @@ -39,7 +41,7 @@ class CommandSetProfile constructor( // Send SMS notification if ProfileSwitch is coming from NS val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) { - if (smsCommunicatorPlugin.isEnabled()) + if ((smsCommunicatorPlugin as PluginBase).isEnabled()) smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok)) } } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetUserSettings.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetUserSettings.kt similarity index 88% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetUserSettings.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetUserSettings.kt index 2ada46280a..0881228712 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetUserSettings.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetUserSettings.kt @@ -1,12 +1,13 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.Diaconn -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandSetUserSettings( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandStartPump.kt similarity index 73% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandStartPump.kt index 33b8296d05..6c80cd3e8a 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandStartPump.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin +import info.nightscout.androidaps.interfaces.Insight import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R import javax.inject.Inject class CommandStartPump( @@ -16,7 +17,7 @@ class CommandStartPump( override fun execute() { val pump = activePlugin.activePump - if (pump is LocalInsightPlugin) { + if (pump is Insight) { val result = pump.startPump() callback?.result(result)?.run() } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandStopPump.kt similarity index 73% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandStopPump.kt index 80fdd90702..9bab352e82 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandStopPump.kt @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin +import info.nightscout.androidaps.interfaces.Insight import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R import javax.inject.Inject class CommandStopPump( @@ -16,7 +17,7 @@ class CommandStopPump( override fun execute() { val pump = activePlugin.activePump - if (pump is LocalInsightPlugin) { + if (pump is Insight) { val result = pump.stopPump() callback?.result(result)?.run() } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandTempBasalAbsolute.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandTempBasalAbsolute.kt index 25e66b9565..3ac8bd25ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandTempBasalAbsolute.kt @@ -1,12 +1,13 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R -import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandTempBasalAbsolute( diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandTempBasalPercent.kt similarity index 90% rename from app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.kt rename to implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandTempBasalPercent.kt index edc12d1c16..09351cf5b3 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandTempBasalPercent.kt @@ -1,12 +1,13 @@ -package info.nightscout.androidaps.queue.commands +package info.nightscout.implementation.queue.commands import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R -import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.implementation.R +import info.nightscout.shared.logging.LTag import javax.inject.Inject class CommandTempBasalPercent( diff --git a/implementation/src/main/res/values/strings.xml b/implementation/src/main/res/values/strings.xml index 4ccd5d28b4..62774daa74 100644 --- a/implementation/src/main/res/values/strings.xml +++ b/implementation/src/main/res/values/strings.xml @@ -4,6 +4,7 @@ Calibration sent to xDrip+ BG + Missed BG readings Time to eat Enable bolus advisor @@ -11,5 +12,15 @@ Bolus advisor You have high glycemia. Instead of eating now it\'s recommended to wait for better glycemia. Do you want to do a correction bolus now and remind you when it\'s time to eat? In this case no carbs will be recorded and you must use wizard again when we remind you. Time to bolus!\nRun Bolus wizard and do calculation again. + Command is executed right now + Basal value below minimum. Profile not set! + Request + Permission + %1$s needs battery optimization whitelisting for proper performance + Application needs system window permission for notifications + Application needs location permission for BT scan and WiFi identification + Application needs storage permission to be able store log files and export settings + Error asking for permissions + This device does not appear to support battery optimization whitelisting - you may experience performance issues. diff --git a/implementation/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt b/implementation/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt new file mode 100644 index 0000000000..0eb177fb7c --- /dev/null +++ b/implementation/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt @@ -0,0 +1,177 @@ +package info.nightscout.androidaps + +import android.content.Context +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.ProfileSealed +import info.nightscout.androidaps.database.embedments.InsulinConfiguration +import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch +import info.nightscout.androidaps.extensions.pureProfileFromJson +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ProfileStore +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.interfaces.ResourceHelper +import org.json.JSONObject +import org.junit.Before +import org.mockito.ArgumentMatchers.anyDouble +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyString +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.`when` +import org.mockito.invocation.InvocationOnMock + +@Suppress("SpellCheckingInspection") +open class TestBaseWithProfile : TestBase() { + + @Mock lateinit var activePluginProvider: ActivePlugin + @Mock lateinit var rh: ResourceHelper + @Mock lateinit var iobCobCalculator: IobCobCalculator + @Mock lateinit var fabricPrivacy: FabricPrivacy + @Mock lateinit var profileFunction: ProfileFunction + @Mock lateinit var config: Config + @Mock lateinit var context: Context + + lateinit var dateUtil: DateUtil + val rxBus = RxBus(aapsSchedulers, aapsLogger) + + val profileInjector = HasAndroidInjector { AndroidInjector { } } + + private lateinit var validProfileJSON: String + lateinit var validProfile: ProfileSealed.Pure + lateinit var effectiveProfileSwitch: EffectiveProfileSwitch + + @Suppress("PropertyName") val TESTPROFILENAME = "someProfile" + + @Before + fun prepareMock() { + validProfileJSON = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," + + "{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," + + "\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + dateUtil = Mockito.spy(DateUtil(context)) + `when`(dateUtil.now()).thenReturn(1656358822000) + validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!) + effectiveProfileSwitch = EffectiveProfileSwitch( + timestamp = dateUtil.now(), + basalBlocks = validProfile.basalBlocks, + isfBlocks = validProfile.isfBlocks, + icBlocks = validProfile.icBlocks, + targetBlocks = validProfile.targetBlocks, + glucoseUnit = EffectiveProfileSwitch.GlucoseUnit.MMOL, + originalProfileName = "", + originalCustomizedName = "", + originalTimeshift = 0, + originalPercentage = 100, + originalDuration = 0, + originalEnd = 0, + insulinConfiguration = InsulinConfiguration("", 0, 0) + ) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + String.format(rh.gs(string), arg1) + }.`when`(rh).gs(anyInt(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + String.format(rh.gs(string), arg1) + }.`when`(rh).gs(anyInt(), anyDouble()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + String.format(rh.gs(string), arg1) + }.`when`(rh).gs(anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyString(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyString(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyDouble(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyDouble(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyInt(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyInt(), anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyInt(), anyString(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyDouble(), anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyString(), anyInt(), anyString()) + + } + + fun getValidProfileStore(): ProfileStore { + val json = JSONObject() + val store = JSONObject() + store.put(TESTPROFILENAME, JSONObject(validProfileJSON)) + json.put("defaultProfile", TESTPROFILENAME) + json.put("store", store) + return ProfileStore(profileInjector, json, dateUtil) + } +} diff --git a/implementation/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/implementation/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt new file mode 100644 index 0000000000..c533893b3f --- /dev/null +++ b/implementation/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt @@ -0,0 +1,68 @@ +package info.nightscout.androidaps + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.DetailedBolusInfo +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.data.PumpEnactResult +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.Pump +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.plugins.common.ManufacturerType +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.androidaps.utils.TimeChangeType +import org.json.JSONObject + +@Suppress("MemberVisibilityCanBePrivate") +class TestPumpPlugin(val injector: HasAndroidInjector) : Pump { + + var connected = false + var isProfileSet = true + + override fun isConnected() = connected + override fun isConnecting() = false + override fun isHandshakeInProgress() = false + val lastData = 0L + + val baseBasal = 0.0 + override val pumpDescription = PumpDescription() + + override fun isInitialized(): Boolean = true + override fun isSuspended(): Boolean = false + override fun isBusy(): Boolean = false + override fun connect(reason: String) { + connected = true + } + + override fun disconnect(reason: String) { + connected = false + } + + override fun stopConnecting() { + connected = false + } + + override fun waitForDisconnectionInSeconds(): Int = 0 + override fun getPumpStatus(reason: String) {} + override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector) + override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet + override fun lastDataTime(): Long = lastData + override val baseBasalRate: Double = baseBasal + override val reservoirLevel: Double = 0.0 + override val batteryLevel: Int = 0 + override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun stopBolusDelivering() {} + override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() + override fun manufacturer(): ManufacturerType = ManufacturerType.AAPS + override fun model(): PumpType = PumpType.GENERIC_AAPS + override fun serialNumber(): String = "1" + override fun shortStatus(veryShort: Boolean): String = "" + override val isFakingTempsByExtendedBoluses: Boolean = false + override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun canHandleDST(): Boolean = true + override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {} +} \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt similarity index 90% rename from app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt rename to implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt index 7c694189da..0113dc3f62 100644 --- a/app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt @@ -1,10 +1,10 @@ -package info.nightscout.androidaps.queue +package info.nightscout.implementation.queue import android.content.Context import android.os.PowerManager import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R +import info.nightscout.implementation.R import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.data.DetailedBolusInfo @@ -13,30 +13,35 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider +import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.commands.* -import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.interfaces.BuildHelper -import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.implementation.queue.commands.CommandBolus +import info.nightscout.implementation.queue.commands.CommandCustomCommand +import info.nightscout.implementation.queue.commands.CommandExtendedBolus +import info.nightscout.implementation.queue.commands.CommandLoadHistory +import info.nightscout.implementation.queue.commands.CommandTempBasalPercent +import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.core.Single import org.junit.Assert import org.junit.Before import org.junit.Test import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.anyLong +import org.mockito.Mockito.`when` import java.util.* class CommandQueueImplementationTest : TestBaseWithProfile() { @@ -47,6 +52,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { @Mock lateinit var powerManager: PowerManager @Mock lateinit var repository: AppRepository @Mock lateinit var fileListProvider: PrefFileListProvider + @Mock lateinit var buildHelper: BuildHelper @Mock lateinit var androidPermission: AndroidPermission class CommandQueueMocked( @@ -66,8 +72,10 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { fabricPrivacy: FabricPrivacy, config: Config, androidPermission: AndroidPermission - ) : CommandQueueImplementation(injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, - activePlugin, context, sp, buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission) { + ) : CommandQueueImplementation( + injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, + activePlugin, context, sp, buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission + ) { override fun notifyAboutNewCommand() {} @@ -95,7 +103,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { if (it is CommandLoadHistory) { it.activePlugin = activePlugin } - if (it is PumpEnactResult) { + if (it is PumpEnactResult) { it.rh = rh } } @@ -106,11 +114,13 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { @Before fun prepare() { - commandQueue = CommandQueueMocked(injector, aapsLogger, rxBus, aapsSchedulers, rh, - constraintChecker, profileFunction, activePlugin, context, sp, - BuildHelperImpl(config, fileListProvider), dateUtil, - repository, - fabricPrivacy, config, androidPermission) + commandQueue = CommandQueueMocked( + injector, aapsLogger, rxBus, aapsSchedulers, rh, + constraintChecker, profileFunction, activePlugin, context, sp, + buildHelper, dateUtil, + repository, + fabricPrivacy, config, androidPermission + ) testPumpPlugin = TestPumpPlugin(injector) testPumpPlugin.pumpDescription.basalMinimumRate = 0.1 @@ -136,18 +146,20 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint) val percentageConstraint = Constraint(0) `when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint) - `when`(rh.gs(R.string.connectiontimedout)).thenReturn("Connection timed out") + val thenReturn = `when`(rh.gs(R.string.connectiontimedout)).thenReturn("Connection timed out") `when`(rh.gs(R.string.formatinsulinunits)).thenReturn("%1\$.2f U") - `when`(rh.gs(R.string.bolusrequested)).thenReturn("Going to deliver %1\$.2f U") + `when`(rh.gs(R.string.goingtodeliver)).thenReturn("Going to deliver %1\$.2f U") } @Test fun commandIsPickedUp() { - val commandQueue = CommandQueueImplementation(injector, aapsLogger, rxBus, aapsSchedulers, rh, - constraintChecker, profileFunction, activePlugin, context, sp, - BuildHelperImpl(config, fileListProvider), - dateUtil, repository, - fabricPrivacy, config, androidPermission) + val commandQueue = CommandQueueImplementation( + injector, aapsLogger, rxBus, aapsSchedulers, rh, + constraintChecker, profileFunction, activePlugin, context, sp, + buildHelper, + dateUtil, repository, + fabricPrivacy, config, androidPermission + ) // start with empty queue Assert.assertEquals(0, commandQueue.size()) diff --git a/app/src/test/java/info/nightscout/androidaps/queue/QueueThreadTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt similarity index 86% rename from app/src/test/java/info/nightscout/androidaps/queue/QueueThreadTest.kt rename to implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt index 2f41e05e2f..cb34c49793 100644 --- a/app/src/test/java/info/nightscout/androidaps/queue/QueueThreadTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt @@ -1,23 +1,22 @@ -package info.nightscout.androidaps.queue +package info.nightscout.implementation.queue import android.content.Context import android.os.PowerManager import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.AndroidPermission +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker -import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import info.nightscout.androidaps.queue.commands.Command -import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute -import info.nightscout.androidaps.utils.AndroidPermission -import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl +import info.nightscout.implementation.R +import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before @@ -31,9 +30,9 @@ class QueueThreadTest : TestBaseWithProfile() { @Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var sp: SP - @Mock lateinit var fileListProvider: PrefFileListProvider @Mock lateinit var powerManager: PowerManager @Mock lateinit var repository: AppRepository + @Mock lateinit var buildHelper: BuildHelper @Mock lateinit var androidPermission: AndroidPermission val injector = HasAndroidInjector { @@ -59,7 +58,7 @@ class QueueThreadTest : TestBaseWithProfile() { commandQueue = CommandQueueImplementation( injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, activePlugin, context, sp, - BuildHelperImpl(config, fileListProvider), dateUtil, repository, fabricPrivacy, config, androidPermission + buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission ) val pumpDescription = PumpDescription() diff --git a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 772a3282c0..8ef2bc3e8f 100644 --- a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -31,6 +31,7 @@ import javax.inject.Singleton; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.interfaces.Insight; import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventInitializationChanged; @@ -134,7 +135,8 @@ import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.shared.sharedPreferences.SP; @Singleton -public class LocalInsightPlugin extends PumpPluginBase implements Pump, Constraints, InsightConnectionService.StateCallback { +public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, Constraints, + InsightConnectionService.StateCallback { private final AAPSLogger aapsLogger; private final RxBus rxBus; From bd2a7fc19884d7966fe275ca1691e9facc22cb0a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 1 Nov 2022 14:42:49 +0100 Subject: [PATCH 54/77] SmsCommunicator -> plugins module --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 14 -- .../activities/MyPreferenceFragment.kt | 2 +- .../fragments/TreatmentsBolusCarbsFragment.kt | 4 +- .../fragments/TreatmentsCareportalFragment.kt | 2 +- .../TreatmentsProfileSwitchFragment.kt | 2 +- .../fragments/TreatmentsTempTargetFragment.kt | 2 +- .../androidaps/di/ActivitiesModule.kt | 2 - .../nightscout/androidaps/di/AppComponent.kt | 3 +- .../nightscout/androidaps/di/AppModule.kt | 2 +- .../androidaps/di/FragmentsModule.kt | 2 - .../nightscout/androidaps/di/PluginsModule.kt | 2 +- .../androidaps/di/ReceiversModule.kt | 8 +- .../nightscout/androidaps/di/SMSModule.kt | 12 -- .../nightscout/androidaps/di/WorkersModule.kt | 12 +- .../general/nsclient/NSClientFragment.kt | 2 +- .../plugins/general/nsclient/acks/NSAddAck.kt | 2 +- .../nsclient/services/NSClientService.kt | 2 +- .../events/EventSmsCommunicatorUpdateGui.kt | 5 - .../androidaps/receivers/DataReceiver.kt | 2 +- app/src/main/res/values/strings.xml | 111 ----------- .../automation/actions/ActionSendSMS.kt | 4 +- .../automation/actions/ActionSendSMSTest.kt | 2 +- .../automation/actions/ActionsTestBase.kt | 4 +- .../nightscout/androidaps/data/IobTotal.kt | 1 - .../nightscout/androidaps/interfaces/Loop.kt | 1 + .../androidaps/interfaces/SmsCommunicator.kt | 1 + .../androidaps/receivers/DataWorkerStorage.kt | 0 core/src/main/res/values/strings.xml | 3 + crowdin.yml | 2 + .../implementation/LocalAlertUtilsImpl.kt | 4 +- .../queue/commands/CommandSetProfile.kt | 6 +- {app/src/main => logo}/blueowl-web.png | Bin {app/src/main => logo}/ic_launcher-web.png | Bin .../main => logo}/ic_launcher_round-web.png | Bin plugins/.gitignore | 1 + plugins/build.gradle | 20 ++ plugins/consumer-rules.pro | 0 plugins/proguard-rules.pro | 21 +++ plugins/src/main/AndroidManifest.xml | 22 +++ .../plugins/di/SMSCommunicatorModule.kt | 18 ++ .../nsclient/events/EventNSClientRestart.kt | 2 +- .../general/smsCommunicator/AuthRequest.kt | 15 +- .../general/smsCommunicator/SmsAction.kt | 8 +- .../SmsCommunicatorFragment.kt | 29 +-- .../smsCommunicator/SmsCommunicatorPlugin.kt | 104 +++++----- .../activities/SmsCommunicatorOtpActivity.kt | 16 +- .../events/EventSmsCommunicatorUpdateGui.kt | 5 + .../smsCommunicator/otp/OneTimePassword.kt | 6 +- .../otp/OneTimePasswordValidationResult.kt | 2 +- .../layout/activity_smscommunicator_otp.xml | 2 +- .../res/layout/smscommunicator_fragment.xml | 2 +- plugins/src/main/res/values/strings.xml | 114 +++++++++++ .../src/main/res/xml/pref_smscommunicator.xml | 10 +- .../info/nightscout/androidaps/TestBase.kt | 39 ++++ .../androidaps/TestBaseWithProfile.kt | 177 ++++++++++++++++++ .../nightscout/androidaps/TestPumpPlugin.kt | 68 +++++++ .../smsCommunicator/AuthRequestTest.kt | 23 +-- .../general/smsCommunicator/SmsActionTest.kt | 2 +- .../SmsCommunicatorPluginTest.kt | 89 +++++---- .../general/smsCommunicator/SmsTest.kt | 2 +- settings.gradle | 1 + 62 files changed, 692 insertions(+), 328 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/di/SMSModule.kt delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/events/EventSmsCommunicatorUpdateGui.kt rename {app => core}/src/main/java/info/nightscout/androidaps/receivers/DataWorkerStorage.kt (100%) rename {app/src/main => logo}/blueowl-web.png (100%) rename {app/src/main => logo}/ic_launcher-web.png (100%) rename {app/src/main => logo}/ic_launcher_round-web.png (100%) create mode 100644 plugins/.gitignore create mode 100644 plugins/build.gradle create mode 100644 plugins/consumer-rules.pro create mode 100644 plugins/proguard-rules.pro create mode 100644 plugins/src/main/AndroidManifest.xml create mode 100644 plugins/src/main/java/info/nightscout/plugins/di/SMSCommunicatorModule.kt rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/nsclient/events/EventNSClientRestart.kt (56%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/AuthRequest.kt (86%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/SmsAction.kt (90%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt (77%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt (96%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt (89%) create mode 100644 plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/events/EventSmsCommunicatorUpdateGui.kt rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/otp/OneTimePassword.kt (97%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt (62%) rename {app => plugins}/src/main/res/layout/activity_smscommunicator_otp.xml (97%) rename {app => plugins}/src/main/res/layout/smscommunicator_fragment.xml (80%) create mode 100644 plugins/src/main/res/values/strings.xml rename {app => plugins}/src/main/res/xml/pref_smscommunicator.xml (89%) create mode 100644 plugins/src/test/java/info/nightscout/androidaps/TestBase.kt create mode 100644 plugins/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt create mode 100644 plugins/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/general/smsCommunicator/AuthRequestTest.kt (81%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/general/smsCommunicator/SmsActionTest.kt (96%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt (94%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/general/smsCommunicator/SmsTest.kt (96%) diff --git a/app/build.gradle b/app/build.gradle index 8c4b7cee20..572f6c08a8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -177,6 +177,7 @@ dependencies { implementation project(':shared') implementation project(':core') implementation project(':ui') + implementation project(':plugins') implementation project(':implementation') implementation project(':automation') implementation project(':combo') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ed8747157d..c2622522a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,11 +10,6 @@ - - - - - @@ -240,15 +235,6 @@ - - - - - - - ns_glucose_value_new_data_id ns_food_last_sync ns_therapy_event_last_sync - smscommunicator_remotebolusmindistance bolussnooze_dia_divisor autosens_adjust_targets ns_bolus_calculator_result_last_synced_id @@ -95,11 +94,9 @@ Saves all treatments that were made Monitor and control AAPS using your WearOS watch. Show information about your loop on your xDrip+ watchface. - Remote control AAPS using SMS commands. Insulin: Carbs: IOB: - IOB: Total IOB: Total IOB activity: Dur: @@ -124,7 +121,6 @@ No glucose data available Request Delta - Delta: Config Builder Overview Treatments @@ -151,8 +147,6 @@ Accept new temp basal: Treatment Calculator - Bolus: - Basal: Change your input! BG Source Where should AAPS gain it\'s data from? @@ -210,59 +204,6 @@ I UNDERSTAND AND AGREE Save Reload profile - SMS Communicator - Allowed phone numbers - +XXXXXXXXXX;+YYYYYYYYYY - To deliver bolus %1$.2fU reply with code %2$s - To deliver meal bolus %1$.2fU reply with code %2$s - To set the Temp Target %1$s reply with code %2$s - To cancel Temp Target reply with code %1$s - To disable the SMS Remote Service reply with code %1$s.\n\nKeep in mind that you\'ll able to reactivate it directly from the AAPS master smartphone only. - SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone. - To send calibration %1$.2f reply with code %2$s - Bolus failed - Minimum number of minutes that must elapse between one remote bolus and the next - How many minutes must elapse, at least, between one bolus and the next - For your safety, to edit this preference you need to add at least 2 phone numbers. - Bolus %1$.2f U delivered successfully - Meal Bolus %1$.2f U delivered successfully - Target %1$s for %2$d minutes - Target %1$s for %2$d minutes set successfully - Temp Target canceled successfully - Allow remote commands via SMS - Loop has been disabled - Loop has been enabled - Loop is enabled - To connect pump reply with code %1$s - Connection to pump failed - To disconnect pump for %1$d minutes reply with code %2$s - Pump disconnected - Pump reconnected - Remote command is not allowed - Remote bolus not available. Try again later. - To start basal %1$.2f U/h for %2$d min reply with code %3$s - To switch profile to %1$s %2$d%% reply with code %3$s - To start extended bolus %1$.2f U for %2$d min reply with code %3$s - To enter %1$dg at %2$s reply with code %3$s - To start basal %1$d%% for %2$d min reply with code %3$s - To suspend loop for %1$d minutes reply with code %2$s - To resume loop reply with code %1$s - To enable loop reply with code %1$s - To disable loop reply with code %1$s - Temp basal %1$.2fU/h for %2$d min started successfully - Extended bolus %1$.2fU for %2$d min started successfully - Carbs %1$d g entered successfully - Entering %1$dg of carbs failed - Temp basal %1$d%% for %2$d min started successfully - Temp basal start failed - Extended bolus start failed - To stop temp basal reply with code %1$s - To stop extended bolus reply with code %1$s - Temp basal canceled - Extended bolus canceled - Canceling temp basal failed - Canceling extended bolus failed - Unknown command or wrong reply QuickWizard QuickWizard settings Button text: @@ -293,12 +234,9 @@ Resend All Data Open Settings on Wear Basal rate - BG: - Last BG: MM640g Ongoing Notification OLD DATA - %1$dmin ago Profile OpenAPS AMA Array of %1$d elements.\nActual value: @@ -318,7 +256,6 @@ TREAT OBJ WEAR - SMS Shorten tab titles Always use short average delta instead of simple delta Useful when data from unfiltered sources like xDrip+ gets noisy. @@ -334,10 +271,6 @@ Default value: 3.0 (AMA) or 8.0 (SMB). This is a setting for default carb absorption impact per 5 minutes. The default is an expected 3mg/dl/5min. This affects how fast COB are decayed, and how much carb absorption is assumed in calculating future predicted BG, when BG is falling more than expected, or not rising as much as expected. Attention!\nNormally you do not have to change these values below. Please CLICK HERE and READ the text and make sure you UNDERSTAND it before change any of these values. http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html - Invalid SMS phone number - Calibration sent. Receiving must be enabled in xDrip+. - xDrip+ is not receiving calibrations - Pump suspended Executing Virtual pump settings Upload status to NS @@ -368,8 +301,6 @@ Break down IOB into bolus and basal IOB on the watchface not successful - please check phone n/a - smscommunicator_allowednumbers - smscommunicator_remotecommandsallowed Patient type Child Teenage @@ -379,12 +310,8 @@ Please select patient type to setup safety limits Patient name Please provide patient name or nickname to differentiate among multiple setups - User - patient_name I_understand Glimp - Loop suspended - Suspended (%1$d m) Suspend loop for 1h Suspend loop for 2h Suspend loop for 3h @@ -403,9 +330,6 @@ 10 hours Resume Reconnect Pump - Wrong duration - Loop suspended - Loop resumed 15min trend COB Superbolus @@ -680,7 +604,6 @@ max value in preferences hard limit openapsama_useautosens - Read status failed Record pump site change Record insulin cartridge change SMB always and after carbs disabled because active BG source doesn\'t support advanced filtering @@ -857,11 +780,6 @@ Daylight Saving time change less than 3 hours ago - Closed loop disabled internal storage constraint Free at least %1$d MB from internal storage! Loop disabled! - Wrong format - TBR duration must be a multiple of %1$d minutes and greater than 0. - Wrong code. Command cancelled. - Not configured - Profile switch created Version Checker old version very old version @@ -879,7 +797,6 @@ Bolus wizard performs calculation but only this part of calculated insulin is delivered. Useful with SMB algorithm. Snooze Increasing max basal value because setting is lower than your max basal in profile - Invalid message body %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f @@ -948,29 +865,6 @@ SMB execution time Temp basal request time Temp basal execution time - - smscommunicator_otp_password - smscommunicator_otp_secret - from Authenticator app for: %1$s followed by PIN - Additional mandatory PIN at token end - Additional digits that should be memorised and glued at end of each generated One Time Password - Authenticator setup - Code to check: - OTP + PIN - The verification code consist of 6 digits displayed by Authenticator app (known as OTP) followed by 3 or more digits of mandatory PIN. - Reset Authenticators - Reset Authenticator Key - Are you sure to reset Authenticator key? It will render all currently configured Authenticators invalid, and you will need to set them up again. - New Authenticator Key was generated! Please use updated QRCode to provision authenticators. - Exporting OTP secret - Are you sure you want to copy OTP secret to clipboard?\n\nYou may only need that if your authenticator app have issues scanning QRCode, you want to enter it manually or you want to configure hardware OTP token using dedicated app. - OTP secret (in Base32 format) exported and copied into clipboard. Paste it into authenticator or hardware OTP burner! - 1. Install Authenticator - 2. Scan code to setup AAPS OTP codes - 3. Test One-Time-Password - Reset Authenticators - On each follower phone install Authenticator app that support RFC 6238 TOTP tokens. Popular free apps are:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator - By resetting authenticator you make all already provisioned authenticators invalid. You will need to set up them again! Predictions Treatments Deviation slope @@ -1005,8 +899,6 @@ Filter Unable to create profile. Profile is invalid. Don\'t kill my app? - Send SMS if unreachable pump event is triggered - Report pump unreachable Run alarm when is time to eat use_bolus_advisor Time to eat!\nRun Bolus wizard and do calculation again. @@ -1058,8 +950,6 @@ ns_receive_cgm Receive/backfill CGM data Accept CGM data from NS - Timeout while waiting for finish of previous pump communication - There is another bolus in queue. Try again later. Calculation in progress Missing profile name Error in IC values @@ -1186,7 +1076,6 @@ Login Remove all Reset start - QR Code for setup one time password open settings set carb timer alarm All diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt index 47d87e619b..cf7055c7e1 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt @@ -15,7 +15,7 @@ import javax.inject.Inject class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) { - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicator + @Inject lateinit var smsCommunicator: SmsCommunicator var text = InputString() @@ -24,7 +24,7 @@ class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) { override fun icon(): Int = R.drawable.ic_notifications override fun doAction(callback: Callback) { - val result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.value) + val result = smsCommunicator.sendNotificationToAllNumbers(text.value) callback.result(PumpEnactResult(injector).success(result).comment(if (result) R.string.ok else R.string.error)).run() } diff --git a/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.kt b/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.kt index 7c7e675826..d6ef7fd7a2 100644 --- a/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.kt +++ b/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.kt @@ -36,7 +36,7 @@ class ActionSendSMSTest : ActionsTestBase() { } @Test fun doActionTest() { - `when`(smsCommunicatorPlugin.sendNotificationToAllNumbers(anyString())).thenReturn(true) + `when`(smsCommunicator.sendNotificationToAllNumbers(anyString())).thenReturn(true) sut.text = InputString("Asd") sut.doAction(object : Callback() { override fun run() { diff --git a/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionsTestBase.kt b/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionsTestBase.kt index 6174cccc16..dcd0e94cba 100644 --- a/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionsTestBase.kt +++ b/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionsTestBase.kt @@ -54,7 +54,7 @@ ActionsTestBase : TestBaseWithProfile() { @Mock lateinit var configBuilder: ConfigBuilder @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var profilePlugin: ProfileSource - @Mock lateinit var smsCommunicatorPlugin: SmsCommunicator + @Mock lateinit var smsCommunicator: SmsCommunicator @Mock lateinit var loopPlugin: TestLoopPlugin @Mock lateinit var uel: UserEntryLogger @@ -82,7 +82,7 @@ ActionsTestBase : TestBaseWithProfile() { if (it is ActionSendSMS) { it.aapsLogger = aapsLogger it.rh = rh - it.smsCommunicatorPlugin = smsCommunicatorPlugin + it.smsCommunicator = smsCommunicator } if (it is ActionProfileSwitch) { it.aapsLogger = aapsLogger diff --git a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt index 44540e1e27..569ed71a09 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt +++ b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt @@ -4,7 +4,6 @@ import android.content.Context import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.Round import org.json.JSONException import org.json.JSONObject diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/Loop.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/Loop.kt index 284cb71ae7..77fb178729 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/Loop.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/Loop.kt @@ -6,6 +6,7 @@ import info.nightscout.androidaps.plugins.aps.loop.APSResult interface Loop { + fun isEnabled(): Boolean class LastRun { var request: APSResult? = null diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt index 1f272e4e31..9c40035e1b 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/SmsCommunicator.kt @@ -4,6 +4,7 @@ import info.nightscout.androidaps.data.Sms interface SmsCommunicator { + var messages: ArrayList fun sendNotificationToAllNumbers(text: String): Boolean fun sendSMS(sms: Sms): Boolean } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/DataWorkerStorage.kt b/core/src/main/java/info/nightscout/androidaps/receivers/DataWorkerStorage.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/receivers/DataWorkerStorage.kt rename to core/src/main/java/info/nightscout/androidaps/receivers/DataWorkerStorage.kt diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 69811b2488..2f69ade6be 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -205,6 +205,9 @@ Bolus reminder Duration g + Pump suspended + Not configured + Loop suspended Limiting max basal rate to %1$.2f U/h because of %2$s diff --git a/crowdin.yml b/crowdin.yml index d211896605..684c1c27fc 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -53,4 +53,6 @@ files: translation: /implementation/src/main/res/values-%android_code%/strings.xml - source: /ui/src/main/res/values/strings.xml translation: /ui/src/main/res/values-%android_code%/strings.xml + - source: /plugins/src/main/res/values/strings.xml + translation: /plugins/src/main/res/values-%android_code%/strings.xml translate_attributes: 0 diff --git a/implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt b/implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt index 85b9961a53..c61e70cd63 100644 --- a/implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt +++ b/implementation/src/main/java/info/nightscout/implementation/LocalAlertUtilsImpl.kt @@ -41,7 +41,7 @@ class LocalAlertUtilsImpl @Inject constructor( private val rh: ResourceHelper, private val activePlugin: ActivePlugin, private val profileFunction: ProfileFunction, - private val smsCommunicatorPlugin: SmsCommunicator, + private val smsCommunicator: SmsCommunicator, private val config: Config, private val repository: AppRepository, private val dateUtil: DateUtil, @@ -71,7 +71,7 @@ class LocalAlertUtilsImpl @Inject constructor( disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(rh.gs(R.string.pump_unreachable))).subscribe() } if (sp.getBoolean(R.string.key_smscommunicator_report_pump_unreachable, true)) - smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable)) + smsCommunicator.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable)) } if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE)) } diff --git a/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt index 030c751f5a..ee9a44b921 100644 --- a/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/commands/CommandSetProfile.kt @@ -23,7 +23,7 @@ class CommandSetProfile constructor( callback: Callback? ) : Command(injector, CommandType.BASAL_PROFILE, callback) { - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicator + @Inject lateinit var smsCommunicator: SmsCommunicator @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var dateUtil: DateUtil @Inject lateinit var commandQueue: CommandQueue @@ -41,8 +41,8 @@ class CommandSetProfile constructor( // Send SMS notification if ProfileSwitch is coming from NS val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) { - if ((smsCommunicatorPlugin as PluginBase).isEnabled()) - smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok)) + if ((smsCommunicator as PluginBase).isEnabled()) + smsCommunicator.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok)) } } diff --git a/app/src/main/blueowl-web.png b/logo/blueowl-web.png similarity index 100% rename from app/src/main/blueowl-web.png rename to logo/blueowl-web.png diff --git a/app/src/main/ic_launcher-web.png b/logo/ic_launcher-web.png similarity index 100% rename from app/src/main/ic_launcher-web.png rename to logo/ic_launcher-web.png diff --git a/app/src/main/ic_launcher_round-web.png b/logo/ic_launcher_round-web.png similarity index 100% rename from app/src/main/ic_launcher_round-web.png rename to logo/ic_launcher_round-web.png diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/plugins/build.gradle b/plugins/build.gradle new file mode 100644 index 0000000000..2200db2aa1 --- /dev/null +++ b/plugins/build.gradle @@ -0,0 +1,20 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-allopen' +apply plugin: 'com.hiya.jacoco-android' + +apply from: "${project.rootDir}/core/android_dependencies.gradle" +apply from: "${project.rootDir}/core/android_module_dependencies.gradle" +apply from: "${project.rootDir}/core/test_dependencies.gradle" +apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.plugins' +} + +dependencies { + implementation project(':shared') + implementation project(':database') + implementation project(':graphview') + implementation project(':core') +} \ No newline at end of file diff --git a/plugins/consumer-rules.pro b/plugins/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/proguard-rules.pro b/plugins/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/plugins/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/plugins/src/main/AndroidManifest.xml b/plugins/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..5638a39c06 --- /dev/null +++ b/plugins/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/src/main/java/info/nightscout/plugins/di/SMSCommunicatorModule.kt b/plugins/src/main/java/info/nightscout/plugins/di/SMSCommunicatorModule.kt new file mode 100644 index 0000000000..28ab8fea4e --- /dev/null +++ b/plugins/src/main/java/info/nightscout/plugins/di/SMSCommunicatorModule.kt @@ -0,0 +1,18 @@ +package info.nightscout.plugins.di + +import dagger.Module +import dagger.android.ContributesAndroidInjector +import info.nightscout.plugins.general.smsCommunicator.AuthRequest +import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorFragment +import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin +import info.nightscout.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity + +@Module +@Suppress("unused") +abstract class SMSCommunicatorModule { + + @ContributesAndroidInjector abstract fun authRequestInjector(): AuthRequest + @ContributesAndroidInjector abstract fun contributesSmsCommunicatorOtpActivity(): SmsCommunicatorOtpActivity + @ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment + @ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/events/EventNSClientRestart.kt b/plugins/src/main/java/info/nightscout/plugins/general/nsclient/events/EventNSClientRestart.kt similarity index 56% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/events/EventNSClientRestart.kt rename to plugins/src/main/java/info/nightscout/plugins/general/nsclient/events/EventNSClientRestart.kt index 49333b6840..59f9afe26a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/events/EventNSClientRestart.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/nsclient/events/EventNSClientRestart.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.nsclient.events +package info.nightscout.plugins.general.nsclient.events import info.nightscout.androidaps.events.Event diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/AuthRequest.kt similarity index 86% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/AuthRequest.kt index fd61e12c9f..b5fdecd49e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/AuthRequest.kt @@ -1,17 +1,17 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import android.os.SystemClock import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Sms import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.SmsCommunicator -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T +import info.nightscout.plugins.R import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import javax.inject.Inject @@ -21,7 +21,8 @@ class AuthRequest internal constructor( var requester: Sms, requestText: String, var confirmCode: String, - val action: SmsAction) { + val action: SmsAction +) { @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var smsCommunicator: SmsCommunicator @@ -50,7 +51,7 @@ class AuthRequest internal constructor( if (!codeIsValid(codeReceived)) { processed = true aapsLogger.debug(LTag.SMS, "Wrong code") - smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrongcode))) + smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrong_code))) return } if (dateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) { @@ -64,7 +65,7 @@ class AuthRequest internal constructor( } if (commandQueue.size() != 0) { aapsLogger.debug(LTag.SMS, "Command timed out: " + requester.text) - smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_wating))) + smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_waiting))) return } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsAction.kt similarity index 90% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsAction.kt index a38d9858c1..5f895f23ec 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsAction.kt @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator abstract class SmsAction(val pumpCommand: Boolean) : Runnable { var aDouble: Double? = null var anInteger: Int? = null - var secondInteger: Int? = null - var secondLong: Long? = null - var aString: String? = null + private var secondInteger: Int? = null + private var secondLong: Long? = null + private var aString: String? = null internal constructor(pumpCommand: Boolean, aDouble: Double) : this(pumpCommand) { this.aDouble = aDouble diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt similarity index 77% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt index 67e2ea7518..ca957b1786 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorFragment.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import android.os.Bundle import android.view.LayoutInflater @@ -6,16 +6,17 @@ import android.view.View import android.view.ViewGroup import dagger.android.support.DaggerFragment import info.nightscout.androidaps.data.Sms -import info.nightscout.androidaps.databinding.SmscommunicatorFragmentBinding +import info.nightscout.androidaps.interfaces.SmsCommunicator import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.HtmlHelper -import io.reactivex.rxjava3.kotlin.plusAssign import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.plugins.databinding.SmscommunicatorFragmentBinding +import info.nightscout.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui import io.reactivex.rxjava3.disposables.CompositeDisposable -import java.util.* +import io.reactivex.rxjava3.kotlin.plusAssign +import java.util.Collections import javax.inject.Inject import kotlin.math.max @@ -24,7 +25,7 @@ class SmsCommunicatorFragment : DaggerFragment() { @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var rxBus: RxBus - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin + @Inject lateinit var smsCommunicator: SmsCommunicator @Inject lateinit var dateUtil: DateUtil private val disposable = CompositeDisposable() @@ -35,8 +36,10 @@ class SmsCommunicatorFragment : DaggerFragment() { // onDestroyView. private val binding get() = _binding!! - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { _binding = SmscommunicatorFragmentBinding.inflate(inflater, container, false) return binding.root @@ -63,7 +66,7 @@ class SmsCommunicatorFragment : DaggerFragment() { _binding = null } - fun updateGui() { + private fun updateGui() { if (_binding == null) return class CustomComparator : Comparator { @@ -71,12 +74,12 @@ class SmsCommunicatorFragment : DaggerFragment() { return (object1.date - object2.date).toInt() } } - Collections.sort(smsCommunicatorPlugin.messages, CustomComparator()) + Collections.sort(smsCommunicator.messages, CustomComparator()) val messagesToShow = 40 - val start = max(0, smsCommunicatorPlugin.messages.size - messagesToShow) + val start = max(0, smsCommunicator.messages.size - messagesToShow) var logText = "" - for (x in start until smsCommunicatorPlugin.messages.size) { - val sms = smsCommunicatorPlugin.messages[x] + for (x in start until smsCommunicator.messages.size) { + val sms = smsCommunicator.messages[x] when { sms.ignored -> { logText += dateUtil.timeString(sms.date) + " <<< " + "░ " + sms.phoneNumber + " " + sms.text + "
    " diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt similarity index 96% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index 0bcc5b3c82..7ff8da4c91 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import android.content.Context import android.telephony.SmsManager @@ -12,7 +12,7 @@ import androidx.work.WorkerParameters import androidx.work.workDataOf import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R +import info.nightscout.plugins.R import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Sms @@ -35,11 +35,10 @@ import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker -import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification -import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword +import info.nightscout.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.receivers.DataWorkerStorage @@ -48,6 +47,7 @@ import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.sharedPreferences.SP import info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference +import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart import info.nightscout.shared.SafeParse import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -101,7 +101,7 @@ class SmsCommunicatorPlugin @Inject constructor( var allowedNumbers: MutableList = ArrayList() @Volatile var messageToConfirm: AuthRequest? = null @Volatile var lastRemoteBolusTime: Long = 0 - var messages = ArrayList() + override var messages = ArrayList() val commands = mapOf( "BG" to "BG", @@ -135,7 +135,7 @@ class SmsCommunicatorPlugin @Inject constructor( override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) { super.preprocessPreferences(preferenceFragment) - val distance = preferenceFragment.findPreference(rh.gs(R.string.key_smscommunicator_remotebolusmindistance)) as ValidatingEditTextPreference? + val distance = preferenceFragment.findPreference(rh.gs(R.string.key_smscommunicator_remote_bolus_min_distance)) as ValidatingEditTextPreference? ?: return val allowedNumbers = preferenceFragment.findPreference(rh.gs(R.string.key_smscommunicator_allowednumbers)) as EditTextPreference? ?: return @@ -243,67 +243,67 @@ class SmsCommunicatorPlugin @Inject constructor( messages.add(receivedSms) aapsLogger.debug(LTag.SMS, receivedSms.toString()) val divided = receivedSms.text.split(Regex("\\s+")).toTypedArray() - val remoteCommandsAllowed = sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false) + val remoteCommandsAllowed = sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false) val minDistance = if (areMoreNumbers(sp.getString(R.string.key_smscommunicator_allowednumbers, ""))) - T.mins(sp.getLong(R.string.key_smscommunicator_remotebolusmindistance, T.msecs(Constants.remoteBolusMinDistance).mins())).msecs() + T.mins(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).msecs() else Constants.remoteBolusMinDistance if (divided.isNotEmpty() && isCommand(divided[0].uppercase(Locale.getDefault()), receivedSms.phoneNumber)) { when (divided[0].uppercase(Locale.getDefault())) { "BG" -> if (divided.size == 1) processBG(receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "LOOP" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2 || divided.size == 3) processLOOP(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "NSCLIENT" -> if (divided.size == 2) processNSCLIENT(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "PUMP" -> if (!remoteCommandsAllowed && divided.size > 1) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size <= 3) processPUMP(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "PROFILE" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2 || divided.size == 3) processPROFILE(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "BASAL" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2 || divided.size == 3) processBASAL(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "EXTENDED" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2 || divided.size == 3) processEXTENDED(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "BOLUS" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (commandQueue.bolusInQueue()) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_another_bolus_in_queue))) else if (divided.size == 2 && dateUtil.now() - lastRemoteBolusTime < minDistance) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotebolusnotallowed))) else if (divided.size == 2 && pump.isSuspended()) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.pumpsuspended))) else if (divided.size == 2 || divided.size == 3) processBOLUS(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "CARBS" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2 || divided.size == 3) processCARBS(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "CAL" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2) processCAL(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "TARGET" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2) processTARGET(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "SMS" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed))) else if (divided.size == 2) processSMS(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) "HELP" -> if (divided.size == 1 || divided.size == 2) processHELP(divided, receivedSms) - else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) else -> if (messageToConfirm?.requester?.phoneNumber == receivedSms.phoneNumber) { val execute = messageToConfirm @@ -324,11 +324,11 @@ class SmsCommunicatorPlugin @Inject constructor( var reply = "" val units = profileFunction.getUnits() if (actualBG != null) { - reply = rh.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsString(units) + ", " + reply = rh.gs(R.string.sms_actual_bg) + " " + actualBG.valueToUnitsString(units) + ", " } else if (lastBG != null) { val agoMilliseconds = dateUtil.now() - lastBG.timestamp val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt() - reply = rh.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsString(units) + " " + rh.gs(R.string.sms_minago, agoMin) + ", " + reply = rh.gs(R.string.sms_last_bg) + " " + lastBG.valueToUnitsString(units) + " " + rh.gs(R.string.sms_min_ago, agoMin) + ", " } val glucoseStatus = glucoseStatusProvider.glucoseStatusData if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", " @@ -389,7 +389,7 @@ class SmsCommunicatorPlugin @Inject constructor( "STATUS" -> { val reply = if (loop.enabled) { - if (loop.isSuspended) rh.gs(R.string.loopsuspendedfor, loop.minutesToEndOfSuspend()) + if (loop.isSuspended) rh.gs(R.string.sms_loop_suspended_for, loop.minutesToEndOfSuspend()) else rh.gs(R.string.smscommunicator_loopisenabled) } else rh.gs(R.string.loopisdisabled) @@ -467,7 +467,7 @@ class SmsCommunicatorPlugin @Inject constructor( } } - else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } } @@ -477,7 +477,7 @@ class SmsCommunicatorPlugin @Inject constructor( sendSMS(Sms(receivedSms.phoneNumber, "NSCLIENT RESTART SENT")) receivedSms.processed = true } else - sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } private fun processHELP(divided: Array, receivedSms: Sms) { @@ -494,7 +494,7 @@ class SmsCommunicatorPlugin @Inject constructor( } } - else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } } @@ -507,7 +507,7 @@ class SmsCommunicatorPlugin @Inject constructor( val reply = pump.shortStatus(true) sendSMS(Sms(receivedSms.phoneNumber, reply)) } else { - val reply = rh.gs(R.string.readstatusfailed) + val reply = rh.gs(R.string.sms_read_status_failed) sendSMS(Sms(receivedSms.phoneNumber, reply)) } } @@ -561,7 +561,7 @@ class SmsCommunicatorPlugin @Inject constructor( }) } } else { - sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) return } } @@ -593,9 +593,9 @@ class SmsCommunicatorPlugin @Inject constructor( val pIndex = SafeParse.stringToInt(divided[1]) var percentage = 100 if (divided.size > 2) percentage = SafeParse.stringToInt(divided[2]) - if (pIndex > list.size) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) - else if (percentage == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) - else if (pIndex == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + if (pIndex > list.size) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) + else if (percentage == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) + else if (pIndex == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) else { val profile = store.getSpecificProfile(list[pIndex - 1] as String) if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.noprofile))) @@ -607,11 +607,11 @@ class SmsCommunicatorPlugin @Inject constructor( messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = true, list[pIndex - 1] as String, finalPercentage) { override fun run() { if (profileFunction.createProfileSwitch(store, list[pIndex - 1] as String, 0, finalPercentage, 0, dateUtil.now())) { - val replyText = rh.gs(R.string.profileswitchcreated) + val replyText = rh.gs(R.string.sms_profile_switch_created) sendSMS(Sms(receivedSms.phoneNumber, replyText)) uel.log( - Action.PROFILE_SWITCH, Sources.SMS, rh.gs(R.string.profileswitchcreated), - ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.profileswitchcreated)) + Action.PROFILE_SWITCH, Sources.SMS, rh.gs(R.string.sms_profile_switch_created), + ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.sms_profile_switch_created)) ) } else { sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.invalidprofile))) @@ -657,8 +657,8 @@ class SmsCommunicatorPlugin @Inject constructor( if (divided.size > 2) duration = SafeParse.stringToInt(divided[2]) val profile = profileFunction.getProfile() if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.noprofile))) - else if (tempBasalPct == 0 && divided[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) - else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongTbrDuration, durationStep))) + else if (tempBasalPct == 0 && divided[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) + else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep))) else { tempBasalPct = constraintChecker.applyBasalPercentConstraints(Constraint(tempBasalPct), profile).value() val passCode = generatePassCode() @@ -701,8 +701,8 @@ class SmsCommunicatorPlugin @Inject constructor( if (divided.size > 2) duration = SafeParse.stringToInt(divided[2]) val profile = profileFunction.getProfile() if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.noprofile))) - else if (tempBasal == 0.0 && divided[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) - else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongTbrDuration, durationStep))) + else if (tempBasal == 0.0 && divided[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) + else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep))) else { tempBasal = constraintChecker.applyBasalConstraints(Constraint(tempBasal), profile).value() val passCode = generatePassCode() @@ -765,12 +765,12 @@ class SmsCommunicatorPlugin @Inject constructor( } }) } else if (divided.size != 3) { - sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } else { var extended = SafeParse.stringToDouble(divided[1]) val duration = SafeParse.stringToInt(divided[2]) extended = constraintChecker.applyExtendedBolusConstraints(Constraint(extended)).value() - if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) else { val passCode = generatePassCode() val reply = rh.gs(R.string.smscommunicator_extendedreplywithcode, extended, duration, passCode) @@ -813,13 +813,13 @@ class SmsCommunicatorPlugin @Inject constructor( val isMeal = divided.size > 2 && divided[2].equals("MEAL", ignoreCase = true) bolus = constraintChecker.applyBolusConstraints(Constraint(bolus)).value() if (divided.size == 3 && !isMeal) { - sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } else if (bolus > 0.0) { val passCode = generatePassCode() val reply = if (isMeal) - rh.gs(R.string.smscommunicator_mealbolusreplywithcode, bolus, passCode) + rh.gs(R.string.smscommunicator_meal_bolus_reply_with_code, bolus, passCode) else - rh.gs(R.string.smscommunicator_bolusreplywithcode, bolus, passCode) + rh.gs(R.string.smscommunicator_bolus_reply_with_code, bolus, passCode) receivedSms.processed = true messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = true, bolus) { override fun run() { @@ -884,7 +884,7 @@ class SmsCommunicatorPlugin @Inject constructor( }) } }) - } else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + } else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } private fun toTodayTime(hh_colon_mm: String): Long { @@ -912,12 +912,12 @@ class SmsCommunicatorPlugin @Inject constructor( if (divided.size > 2) { time = toTodayTime(divided[2].uppercase(Locale.getDefault())) if (time == 0L) { - sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) return } } grams = constraintChecker.applyCarbsConstraints(Constraint(grams)).value() - if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) else { val passCode = generatePassCode() val reply = rh.gs(R.string.smscommunicator_carbsreplywithcode, grams, dateUtil.timeString(time), passCode) @@ -1039,7 +1039,7 @@ class SmsCommunicatorPlugin @Inject constructor( } }) } else - sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } private fun processSMS(divided: Array, receivedSms: Sms) { @@ -1051,14 +1051,14 @@ class SmsCommunicatorPlugin @Inject constructor( receivedSms.processed = true messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) { override fun run() { - sp.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false) + sp.putBoolean(R.string.key_smscommunicator_remote_commands_allowed, false) val replyText = rh.gs(R.string.smscommunicator_stoppedsms) sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) uel.log(Action.STOP_SMS, Sources.SMS, rh.gs(R.string.smscommunicator_stoppedsms), ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.smscommunicator_stoppedsms))) } }) - } else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + } else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } private fun processCAL(divided: Array, receivedSms: Sms) { @@ -1081,7 +1081,7 @@ class SmsCommunicatorPlugin @Inject constructor( ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.smscommunicator_calibrationfailed))) } }) - } else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat))) + } else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } override fun sendNotificationToAllNumbers(text: String): Boolean { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt index c286fc2c64..6236eabbf9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator.activities +package info.nightscout.plugins.general.smsCommunicator.activities import android.content.ClipData import android.content.ClipboardManager @@ -12,25 +12,25 @@ import android.view.View import android.view.WindowManager import com.google.common.primitives.Ints.min import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel -import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources -import info.nightscout.androidaps.databinding.ActivitySmscommunicatorOtpBinding +import info.nightscout.androidaps.interfaces.SmsCommunicator import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.plugins.R +import info.nightscout.plugins.databinding.ActivitySmscommunicatorOtpBinding +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import net.glxn.qrgen.android.QRCode import javax.inject.Inject class SmsCommunicatorOtpActivity : NoSplashAppCompatActivity() { @Inject lateinit var fabricPrivacy: FabricPrivacy - @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin + @Inject lateinit var smsCommunicator: SmsCommunicator @Inject lateinit var otp: OneTimePassword @Inject lateinit var uel: UserEntryLogger @@ -105,7 +105,7 @@ class SmsCommunicatorOtpActivity : NoSplashAppCompatActivity() { updateGui() } - fun updateGui() { + private fun updateGui() { val displayMetrics = Resources.getSystem().displayMetrics val width = displayMetrics.widthPixels val height = displayMetrics.heightPixels diff --git a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/events/EventSmsCommunicatorUpdateGui.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/events/EventSmsCommunicatorUpdateGui.kt new file mode 100644 index 0000000000..719303492b --- /dev/null +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/events/EventSmsCommunicatorUpdateGui.kt @@ -0,0 +1,5 @@ +package info.nightscout.plugins.general.smsCommunicator.events + +import info.nightscout.androidaps.events.EventUpdateGui + +internal class EventSmsCommunicatorUpdateGui : EventUpdateGui() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/otp/OneTimePassword.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/otp/OneTimePassword.kt similarity index 97% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/otp/OneTimePassword.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/otp/OneTimePassword.kt index b6f97584c9..a50f4bd05e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/otp/OneTimePassword.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/otp/OneTimePassword.kt @@ -1,13 +1,13 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator.otp +package info.nightscout.plugins.general.smsCommunicator.otp import android.util.Base64 import com.eatthepath.otp.HmacOneTimePasswordGenerator import com.google.common.io.BaseEncoding import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.annotations.OpenForTesting -import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.plugins.R import info.nightscout.shared.sharedPreferences.SP import java.net.URLEncoder import javax.crypto.KeyGenerator diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt similarity index 62% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt rename to plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt index f023849624..ec84c2c1ff 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/otp/OneTimePasswordValidationResult.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator.otp +package info.nightscout.plugins.general.smsCommunicator.otp enum class OneTimePasswordValidationResult { OK, diff --git a/app/src/main/res/layout/activity_smscommunicator_otp.xml b/plugins/src/main/res/layout/activity_smscommunicator_otp.xml similarity index 97% rename from app/src/main/res/layout/activity_smscommunicator_otp.xml rename to plugins/src/main/res/layout/activity_smscommunicator_otp.xml index d62fa269b1..ee2a05b4e8 100644 --- a/app/src/main/res/layout/activity_smscommunicator_otp.xml +++ b/plugins/src/main/res/layout/activity_smscommunicator_otp.xml @@ -2,7 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" - tools:context=".plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity"> + tools:context="info.nightscout.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity"> + tools:context="info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorFragment"> + + + + smscommunicator_otp_password + smscommunicator_otp_secret + patient_name + smscommunicator_remotebolusmindistance + smscommunicator_allowednumbers + smscommunicator_remotecommandsallowed + + SMS Communicator + SMS + Remote control AAPS using SMS commands. + from Authenticator app for: %1$s followed by PIN + Additional mandatory PIN at token end + Additional digits that should be memorised and glued at end of each generated One Time Password + Authenticator setup + Code to check: + OTP + PIN + The verification code consist of 6 digits displayed by Authenticator app (known as OTP) followed by 3 or more digits of mandatory PIN. + Reset Authenticators + Reset Authenticator Key + Are you sure to reset Authenticator key? It will render all currently configured Authenticators invalid, and you will need to set them up again. + New Authenticator Key was generated! Please use updated QRCode to provision authenticators. + Exporting OTP secret + Are you sure you want to copy OTP secret to clipboard?\n\nYou may only need that if your authenticator app have issues scanning QRCode, you want to enter it manually or you want to configure hardware OTP token using dedicated app. + OTP secret (in Base32 format) exported and copied into clipboard. Paste it into authenticator or hardware OTP burner! + 1. Install Authenticator + 2. Scan code to setup AAPS OTP codes + 3. Test One-Time-Password + Reset Authenticators + On each follower phone install Authenticator app that support RFC 6238 TOTP tokens. Popular free apps are:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + By resetting authenticator you make all already provisioned authenticators invalid. You will need to set up them again! + Wrong code. Command cancelled. + Timeout while waiting for finish of previous pump communication + User + Allowed phone numbers + +XXXXXXXXXX;+YYYYYYYYYY + To deliver bolus %1$.2fU reply with code %2$s + To deliver meal bolus %1$.2fU reply with code %2$s + To set the Temp Target %1$s reply with code %2$s + To cancel Temp Target reply with code %1$s + To disable the SMS Remote Service reply with code %1$s.\n\nKeep in mind that you\'ll able to reactivate it directly from the AAPS master smartphone only. + SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone. + To send calibration %1$.2f reply with code %2$s + Bolus failed + Minimum number of minutes that must elapse between one remote bolus and the next + How many minutes must elapse, at least, between one bolus and the next + For your safety, to edit this preference you need to add at least 2 phone numbers. + Bolus %1$.2f U delivered successfully + Meal Bolus %1$.2f U delivered successfully + Target %1$s for %2$d minutes + Target %1$s for %2$d minutes set successfully + Temp Target canceled successfully + Allow remote commands via SMS + Loop has been disabled + Loop has been enabled + Loop is enabled + To connect pump reply with code %1$s + Connection to pump failed + To disconnect pump for %1$d minutes reply with code %2$s + Pump disconnected + Pump reconnected + Remote command is not allowed + Remote bolus not available. Try again later. + To start basal %1$.2f U/h for %2$d min reply with code %3$s + To switch profile to %1$s %2$d%% reply with code %3$s + To start extended bolus %1$.2f U for %2$d min reply with code %3$s + To enter %1$dg at %2$s reply with code %3$s + To start basal %1$d%% for %2$d min reply with code %3$s + To suspend loop for %1$d minutes reply with code %2$s + To resume loop reply with code %1$s + To enable loop reply with code %1$s + To disable loop reply with code %1$s + Temp basal %1$.2fU/h for %2$d min started successfully + Extended bolus %1$.2fU for %2$d min started successfully + Carbs %1$d g entered successfully + Entering %1$dg of carbs failed + Temp basal %1$d%% for %2$d min started successfully + Temp basal start failed + Extended bolus start failed + To stop temp basal reply with code %1$s + To stop extended bolus reply with code %1$s + Temp basal canceled + Extended bolus canceled + Canceling temp basal failed + Canceling extended bolus failed + Unknown command or wrong reply + There is another bolus in queue. Try again later. + Wrong duration + Loop suspended + Loop resumed + Invalid SMS phone number + Calibration sent. Receiving must be enabled in xDrip+. + xDrip+ is not receiving calibrations + Invalid message body + Send SMS if unreachable pump event is triggered + Report pump unreachable + Wrong format + BG: + Last BG: + Delta: + IOB: + Bolus: + Basal: + %1$dmin ago + Suspended (%1$d m) + Read status failed + Profile switch created + TBR duration must be a multiple of %1$d minutes and greater than 0. + QR Code for setup one time password + + \ No newline at end of file diff --git a/app/src/main/res/xml/pref_smscommunicator.xml b/plugins/src/main/res/xml/pref_smscommunicator.xml similarity index 89% rename from app/src/main/res/xml/pref_smscommunicator.xml rename to plugins/src/main/res/xml/pref_smscommunicator.xml index 396c8ab3f2..1d01046631 100644 --- a/app/src/main/res/xml/pref_smscommunicator.xml +++ b/plugins/src/main/res/xml/pref_smscommunicator.xml @@ -16,12 +16,12 @@ + android:title="@string/smscommunicator_tab_otp_label"> diff --git a/plugins/src/test/java/info/nightscout/androidaps/TestBase.kt b/plugins/src/test/java/info/nightscout/androidaps/TestBase.kt new file mode 100644 index 0000000000..3d78d1b4f6 --- /dev/null +++ b/plugins/src/test/java/info/nightscout/androidaps/TestBase.kt @@ -0,0 +1,39 @@ +package info.nightscout.androidaps + +import info.nightscout.shared.logging.AAPSLoggerTest +import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.androidaps.utils.rx.TestAapsSchedulers +import org.junit.Before +import org.junit.Rule +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule +import java.util.* + +open class TestBase { + + val aapsLogger = AAPSLoggerTest() + val aapsSchedulers: AapsSchedulers = TestAapsSchedulers() + + // Add a JUnit rule that will setup the @Mock annotated vars and log. + // Another possibility would be to add `MockitoAnnotations.initMocks(this) to the setup method. + @get:Rule + val mockitoRule: MockitoRule = MockitoJUnit.rule() + + @Before + fun setupLocale() { + Locale.setDefault(Locale.ENGLISH) + System.setProperty("disableFirebase", "true") + } + + // Workaround for Kotlin nullability. + // https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791 + // https://stackoverflow.com/questions/30305217/is-it-possible-to-use-mockito-in-kotlin + fun anyObject(): T { + Mockito.any() + return uninitialized() + } + + @Suppress("Unchecked_Cast") + fun uninitialized(): T = null as T +} \ No newline at end of file diff --git a/plugins/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt b/plugins/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt new file mode 100644 index 0000000000..0eb177fb7c --- /dev/null +++ b/plugins/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt @@ -0,0 +1,177 @@ +package info.nightscout.androidaps + +import android.content.Context +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.ProfileSealed +import info.nightscout.androidaps.database.embedments.InsulinConfiguration +import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch +import info.nightscout.androidaps.extensions.pureProfileFromJson +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ProfileStore +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.interfaces.ResourceHelper +import org.json.JSONObject +import org.junit.Before +import org.mockito.ArgumentMatchers.anyDouble +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyString +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.`when` +import org.mockito.invocation.InvocationOnMock + +@Suppress("SpellCheckingInspection") +open class TestBaseWithProfile : TestBase() { + + @Mock lateinit var activePluginProvider: ActivePlugin + @Mock lateinit var rh: ResourceHelper + @Mock lateinit var iobCobCalculator: IobCobCalculator + @Mock lateinit var fabricPrivacy: FabricPrivacy + @Mock lateinit var profileFunction: ProfileFunction + @Mock lateinit var config: Config + @Mock lateinit var context: Context + + lateinit var dateUtil: DateUtil + val rxBus = RxBus(aapsSchedulers, aapsLogger) + + val profileInjector = HasAndroidInjector { AndroidInjector { } } + + private lateinit var validProfileJSON: String + lateinit var validProfile: ProfileSealed.Pure + lateinit var effectiveProfileSwitch: EffectiveProfileSwitch + + @Suppress("PropertyName") val TESTPROFILENAME = "someProfile" + + @Before + fun prepareMock() { + validProfileJSON = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," + + "{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," + + "\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + dateUtil = Mockito.spy(DateUtil(context)) + `when`(dateUtil.now()).thenReturn(1656358822000) + validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!) + effectiveProfileSwitch = EffectiveProfileSwitch( + timestamp = dateUtil.now(), + basalBlocks = validProfile.basalBlocks, + isfBlocks = validProfile.isfBlocks, + icBlocks = validProfile.icBlocks, + targetBlocks = validProfile.targetBlocks, + glucoseUnit = EffectiveProfileSwitch.GlucoseUnit.MMOL, + originalProfileName = "", + originalCustomizedName = "", + originalTimeshift = 0, + originalPercentage = 100, + originalDuration = 0, + originalEnd = 0, + insulinConfiguration = InsulinConfiguration("", 0, 0) + ) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + String.format(rh.gs(string), arg1) + }.`when`(rh).gs(anyInt(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + String.format(rh.gs(string), arg1) + }.`when`(rh).gs(anyInt(), anyDouble()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + String.format(rh.gs(string), arg1) + }.`when`(rh).gs(anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyString(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyString(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyDouble(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyDouble(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyInt(), anyInt()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + String.format(rh.gs(string), arg1, arg2) + }.`when`(rh).gs(anyInt(), anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyInt(), anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyInt(), anyString(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyDouble(), anyInt(), anyString()) + + Mockito.doAnswer { invocation: InvocationOnMock -> + val string = invocation.getArgument(0) + val arg1 = invocation.getArgument(1) + val arg2 = invocation.getArgument(2) + val arg3 = invocation.getArgument(3) + String.format(rh.gs(string), arg1, arg2, arg3) + }.`when`(rh).gs(anyInt(), anyString(), anyInt(), anyString()) + + } + + fun getValidProfileStore(): ProfileStore { + val json = JSONObject() + val store = JSONObject() + store.put(TESTPROFILENAME, JSONObject(validProfileJSON)) + json.put("defaultProfile", TESTPROFILENAME) + json.put("store", store) + return ProfileStore(profileInjector, json, dateUtil) + } +} diff --git a/plugins/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/plugins/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt new file mode 100644 index 0000000000..c533893b3f --- /dev/null +++ b/plugins/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt @@ -0,0 +1,68 @@ +package info.nightscout.androidaps + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.DetailedBolusInfo +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.data.PumpEnactResult +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.Pump +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.plugins.common.ManufacturerType +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.androidaps.utils.TimeChangeType +import org.json.JSONObject + +@Suppress("MemberVisibilityCanBePrivate") +class TestPumpPlugin(val injector: HasAndroidInjector) : Pump { + + var connected = false + var isProfileSet = true + + override fun isConnected() = connected + override fun isConnecting() = false + override fun isHandshakeInProgress() = false + val lastData = 0L + + val baseBasal = 0.0 + override val pumpDescription = PumpDescription() + + override fun isInitialized(): Boolean = true + override fun isSuspended(): Boolean = false + override fun isBusy(): Boolean = false + override fun connect(reason: String) { + connected = true + } + + override fun disconnect(reason: String) { + connected = false + } + + override fun stopConnecting() { + connected = false + } + + override fun waitForDisconnectionInSeconds(): Int = 0 + override fun getPumpStatus(reason: String) {} + override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector) + override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet + override fun lastDataTime(): Long = lastData + override val baseBasalRate: Double = baseBasal + override val reservoirLevel: Double = 0.0 + override val batteryLevel: Int = 0 + override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun stopBolusDelivering() {} + override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() + override fun manufacturer(): ManufacturerType = ManufacturerType.AAPS + override fun model(): PumpType = PumpType.GENERIC_AAPS + override fun serialNumber(): String = "1" + override fun shortStatus(veryShort: Boolean): String = "" + override val isFakingTempsByExtendedBoluses: Boolean = false + override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun canHandleDST(): Boolean = true + override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {} +} \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/AuthRequestTest.kt similarity index 81% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt rename to plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/AuthRequestTest.kt index 33af627a8c..2e00b52e3b 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/AuthRequestTest.kt @@ -1,38 +1,39 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.data.Sms -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.SmsCommunicator +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.plugins.R import org.junit.Assert import org.junit.Before import org.junit.Test import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.doAnswer +import org.mockito.Mockito.`when` import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer class AuthRequestTest : TestBase() { - @Mock lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin + @Mock lateinit var smsCommunicator: SmsCommunicator @Mock lateinit var rh: ResourceHelper @Mock lateinit var otp: OneTimePassword @Mock lateinit var dateUtil: DateUtil - var injector: HasAndroidInjector = HasAndroidInjector { + private var injector: HasAndroidInjector = HasAndroidInjector { AndroidInjector { if (it is AuthRequest) { it.aapsLogger = aapsLogger it.rh = rh - it.smsCommunicatorPlugin = smsCommunicatorPlugin + it.smsCommunicator = smsCommunicator it.otp = otp it.dateUtil = dateUtil } @@ -43,11 +44,11 @@ class AuthRequestTest : TestBase() { private var actionCalled = false @Before fun prepareTests() { - `when`(rh.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.") + `when`(rh.gs(R.string.sms_wrong_code)).thenReturn("Wrong code. Command cancelled.") doAnswer(Answer { invocation: InvocationOnMock -> sentSms = invocation.getArgument(0) null - } as Answer<*>).`when`(smsCommunicatorPlugin).sendSMS(anyObject()) + } as Answer<*>).`when`(smsCommunicator).sendSMS(anyObject()) } @Test fun doTests() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsActionTest.kt similarity index 96% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.kt rename to plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsActionTest.kt index e0563c27c9..459880b988 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsActionTest.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import org.junit.Assert import org.junit.Test diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt similarity index 94% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt rename to plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt index f4ef917cfc..0975a57510 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt @@ -1,11 +1,12 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import android.telephony.SmsManager import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R +import info.nightscout.plugins.R import info.nightscout.androidaps.TestBaseWithProfile +import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.data.IobTotal import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.Sms @@ -17,16 +18,13 @@ import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTe import info.nightscout.androidaps.database.transactions.Transaction import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword -import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword +import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider -import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.pump.common.defs.PumpType -import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T @@ -52,9 +50,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { @Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var commandQueue: CommandQueue - @Mock lateinit var loop: LoopPlugin - @Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin - @Mock lateinit var localProfilePlugin: LocalProfilePlugin + @Mock lateinit var loop: Loop + @Mock lateinit var testPumpPlugin: TestPumpPlugin + @Mock lateinit var profileSource: ProfileSource @Mock lateinit var otp: OneTimePassword @Mock lateinit var xDripBroadcast: XDripBroadcast @Mock lateinit var uel: UserEntryLogger @@ -70,7 +68,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { } if (it is AuthRequest) { it.aapsLogger = aapsLogger - it.smsCommunicatorPlugin = smsCommunicatorPlugin + it.smsCommunicator = smsCommunicatorPlugin it.rh = rh it.otp = otp it.dateUtil = dateUtil @@ -147,17 +145,17 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { null }.`when`(commandQueue).extendedBolus(ArgumentMatchers.anyDouble(), ArgumentMatchers.anyInt(), ArgumentMatchers.any(Callback::class.java)) - `when`(activePlugin.activePump).thenReturn(virtualPumpPlugin) + `when`(activePlugin.activePump).thenReturn(testPumpPlugin) - `when`(virtualPumpPlugin.shortStatus(ArgumentMatchers.anyBoolean())).thenReturn("Virtual Pump") - `when`(virtualPumpPlugin.isSuspended()).thenReturn(false) - `when`(virtualPumpPlugin.pumpDescription).thenReturn(PumpDescription()) - `when`(virtualPumpPlugin.model()).thenReturn(PumpType.GENERIC_AAPS) + `when`(testPumpPlugin.shortStatus(ArgumentMatchers.anyBoolean())).thenReturn("Virtual Pump") + `when`(testPumpPlugin.isSuspended()).thenReturn(false) + `when`(testPumpPlugin.pumpDescription).thenReturn(PumpDescription()) + `when`(testPumpPlugin.model()).thenReturn(PumpType.GENERIC_AAPS) `when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(0)) `when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(0)) - `when`(activePlugin.activeProfileSource).thenReturn(localProfilePlugin) + `when`(activePlugin.activeProfileSource).thenReturn(profileSource) `when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL) @@ -165,23 +163,24 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { `when`(otp.checkOTP(anyString())).thenReturn(OneTimePasswordValidationResult.OK) `when`(rh.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed") - `when`(rh.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.") + `when`(rh.gs(R.string.sms_wrong_code)).thenReturn("Wrong code. Command cancelled.") `when`(rh.gs(R.string.sms_iob)).thenReturn("IOB:") - `when`(rh.gs(R.string.sms_lastbg)).thenReturn("Last BG:") - `when`(rh.gs(R.string.sms_minago)).thenReturn("%1\$dmin ago") + `when`(rh.gs(R.string.sms_last_bg)).thenReturn("Last BG:") + `when`(rh.gs(R.string.sms_min_ago)).thenReturn("%1\$dmin ago") `when`(rh.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed") `when`(rh.gs(R.string.smscommunicator_stopsmswithcode)).thenReturn("To disable the SMS Remote Service reply with code %1\$s.\\n\\nKeep in mind that you\\'ll able to reactivate it directly from the AAPS master smartphone only.") - `when`(rh.gs(R.string.smscommunicator_mealbolusreplywithcode)).thenReturn("To deliver meal bolus %1$.2fU reply with code %2\$s.") + `when`(rh.gs(R.string.smscommunicator_meal_bolus_reply_with_code)).thenReturn("To deliver meal bolus %1$.2fU reply with code %2\$s.") `when`(rh.gs(R.string.smscommunicator_temptargetwithcode)).thenReturn("To set the Temp Target %1\$s reply with code %2\$s") `when`(rh.gs(R.string.smscommunicator_temptargetcancel)).thenReturn("To cancel Temp Target reply with code %1\$s") `when`(rh.gs(R.string.smscommunicator_stoppedsms)).thenReturn("SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone.") `when`(rh.gs(R.string.smscommunicator_tt_set)).thenReturn("Target %1\$s for %2\$d minutes set successfully") `when`(rh.gs(R.string.smscommunicator_tt_canceled)).thenReturn("Temp Target canceled successfully") - `when`(rh.gs(R.string.loopsuspendedfor)).thenReturn("Suspended (%1\$d m)") + `when`(rh.gs(R.string.sms_loop_suspended_for)).thenReturn("Suspended (%1\$d m)") `when`(rh.gs(R.string.loopisdisabled)).thenReturn("Loop is disabled") `when`(rh.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled") - `when`(rh.gs(R.string.wrongformat)).thenReturn("Wrong format") - `when`(rh.gs(eq(R.string.wrongTbrDuration), ArgumentMatchers.any())).thenAnswer { i: InvocationOnMock -> "TBR duration must be a multiple of " + i.arguments[1] + " minutes and greater than 0." } + `when`(rh.gs(R.string.wrong_format)).thenReturn("Wrong format") + `when`(rh.gs(eq(R.string.sms_wrong_tbr_duration), ArgumentMatchers.any())).thenAnswer { i: InvocationOnMock -> "TBR duration must be a multiple of " + i.arguments[1] + " minutes and greater than " + + "0." } `when`(rh.gs(R.string.smscommunicator_loophasbeendisabled)).thenReturn("Loop has been disabled") `when`(rh.gs(R.string.smscommunicator_loophasbeenenabled)).thenReturn("Loop has been enabled") `when`(rh.gs(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled") @@ -192,7 +191,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { `when`(rh.gs(R.string.smscommunicator_unknowncommand)).thenReturn("Unknown command or wrong reply") `when`(rh.gs(R.string.notconfigured)).thenReturn("Not configured") `when`(rh.gs(R.string.smscommunicator_profilereplywithcode)).thenReturn("To switch profile to %1\$s %2\$d%% reply with code %3\$s") - `when`(rh.gs(R.string.profileswitchcreated)).thenReturn("Profile switch created") + `when`(rh.gs(R.string.sms_profile_switch_created)).thenReturn("Profile switch created") `when`(rh.gs(R.string.smscommunicator_basalstopreplywithcode)).thenReturn("To stop temp basal reply with code %1\$s") `when`(rh.gs(R.string.smscommunicator_basalpctreplywithcode)).thenReturn("To start basal %1\$d%% for %2\$d min reply with code %3\$s") `when`(rh.gs(R.string.smscommunicator_tempbasalset_percent)).thenReturn("Temp basal %1\$d%% for %2\$d min started successfully") @@ -202,7 +201,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { `when`(rh.gs(R.string.smscommunicator_extendedcanceled)).thenReturn("Extended bolus canceled") `when`(rh.gs(R.string.smscommunicator_extendedreplywithcode)).thenReturn("To start extended bolus %1$.2fU for %2\$d min reply with code %3\$s") `when`(rh.gs(R.string.smscommunicator_extendedset)).thenReturn("Extended bolus %1$.2fU for %2\$d min started successfully") - `when`(rh.gs(R.string.smscommunicator_bolusreplywithcode)).thenReturn("To deliver bolus %1$.2fU reply with code %2\$s") + `when`(rh.gs(R.string.smscommunicator_bolus_reply_with_code)).thenReturn("To deliver bolus %1$.2fU reply with code %2\$s") `when`(rh.gs(R.string.smscommunicator_bolusdelivered)).thenReturn("Bolus %1$.2fU delivered successfully") `when`(rh.gs(R.string.smscommunicator_remotebolusnotallowed)).thenReturn("Remote bolus not available. Try again later.") `when`(rh.gs(R.string.smscommunicator_calibrationreplywithcode)).thenReturn("To send calibration %1$.2f reply with code %2\$s") @@ -217,8 +216,8 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { `when`(rh.gs(R.string.cob)).thenReturn("COB") `when`(rh.gs(R.string.smscommunicator_mealbolusdelivered)).thenReturn("Meal Bolus %1\$.2fU delivered successfully") `when`(rh.gs(R.string.smscommunicator_mealbolusdelivered_tt)).thenReturn("Target %1\$s for %2\$d minutes") - `when`(rh.gs(R.string.sms_actualbg)).thenReturn("BG:") - `when`(rh.gs(R.string.sms_lastbg)).thenReturn("Last BG:") + `when`(rh.gs(R.string.sms_actual_bg)).thenReturn("BG:") + `when`(rh.gs(R.string.sms_last_bg)).thenReturn("Last BG:") `when`(rh.gs(R.string.smscommunicator_loopdisablereplywithcode)).thenReturn("To disable loop reply with code %1\$s") `when`(rh.gs(R.string.smscommunicator_loopenablereplywithcode)).thenReturn("To enable loop reply with code %1\$s") `when`(rh.gs(R.string.smscommunicator_loopresumereplywithcode)).thenReturn("To resume loop reply with code %1\$s") @@ -233,7 +232,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { `when`(rh.gs(R.string.sms)).thenReturn("SMS") `when`(rh.gsNotLocalised(R.string.loopsuspended)).thenReturn("Loop suspended") `when`(rh.gsNotLocalised(R.string.smscommunicator_stoppedsms)).thenReturn("SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone.") - `when`(rh.gsNotLocalised(R.string.profileswitchcreated)).thenReturn("Profile switch created") + `when`(rh.gsNotLocalised(R.string.sms_profile_switch_created)).thenReturn("Profile switch created") `when`(rh.gsNotLocalised(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled") `when`(rh.gsNotLocalised(R.string.smscommunicator_calibrationsent)).thenReturn("Calibration sent. Receiving must be enabled in xDrip+.") `when`(rh.gsNotLocalised(R.string.smscommunicator_tt_canceled)).thenReturn("Temp Target canceled successfully") @@ -291,14 +290,14 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("COB: 10(2)g")) // LOOP : test remote control disabled - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(false) smsCommunicatorPlugin.messages = ArrayList() sms = Sms("1234", "LOOP STATUS") smsCommunicatorPlugin.processSms(sms) Assert.assertFalse(sms.ignored) Assert.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text) Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("Remote command is not allowed")) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //LOOP STATUS : disabled `when`(loop.enabled).thenReturn(false) @@ -470,7 +469,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text) //NSCLIENT RESTART - `when`((loop as PluginBase).isEnabled()).thenReturn(true) + `when`(loop.isEnabled()).thenReturn(true) `when`(loop.isSuspended).thenReturn(false) smsCommunicatorPlugin.messages = ArrayList() sms = Sms("1234", "NSCLIENT RESTART") @@ -480,7 +479,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("NSCLIENT RESTART")) //NSCLIENT BLA BLA - `when`((loop as PluginBase).isEnabled()).thenReturn(true) + `when`(loop.isEnabled()).thenReturn(true) `when`(loop.isSuspended).thenReturn(false) smsCommunicatorPlugin.messages = ArrayList() sms = Sms("1234", "NSCLIENT BLA BLA") @@ -490,7 +489,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text) //NSCLIENT BLABLA - `when`((loop as PluginBase).isEnabled()).thenReturn(true) + `when`(loop.isEnabled()).thenReturn(true) `when`(loop.isSuspended).thenReturn(false) smsCommunicatorPlugin.messages = ArrayList() sms = Sms("1234", "NSCLIENT BLABLA") @@ -651,7 +650,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("PROFILE", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //PROFILE smsCommunicatorPlugin.messages = ArrayList() @@ -667,7 +666,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { Assert.assertEquals("PROFILE LIST", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Not configured", smsCommunicatorPlugin.messages[1].text) - `when`(localProfilePlugin.profile).thenReturn(getValidProfileStore()) + `when`(profileSource.profile).thenReturn(getValidProfileStore()) `when`(profileFunction.getProfileName()).thenReturn(TESTPROFILENAME) //PROFILE STATUS @@ -733,7 +732,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("BASAL", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //BASAL smsCommunicatorPlugin.messages = ArrayList() @@ -830,7 +829,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("EXTENDED", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //EXTENDED smsCommunicatorPlugin.messages = ArrayList() @@ -885,7 +884,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("BOLUS", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //BOLUS smsCommunicatorPlugin.messages = ArrayList() @@ -895,7 +894,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text) `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(1.0)) `when`(dateUtilMocked.now()).thenReturn(1000L) - `when`(sp.getLong(R.string.key_smscommunicator_remotebolusmindistance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L) + `when`(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L) //BOLUS 1 smsCommunicatorPlugin.messages = ArrayList() sms = Sms("1234", "BOLUS 1") @@ -934,13 +933,13 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { //BOLUS 1 (Suspended pump) smsCommunicatorPlugin.lastRemoteBolusTime = 0 - `when`(virtualPumpPlugin.isSuspended()).thenReturn(true) + `when`(testPumpPlugin.isSuspended()).thenReturn(true) smsCommunicatorPlugin.messages = ArrayList() sms = Sms("1234", "BOLUS 1") smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("BOLUS 1", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Pump suspended", smsCommunicatorPlugin.messages[1].text) - `when`(virtualPumpPlugin.isSuspended()).thenReturn(false) + `when`(testPumpPlugin.isSuspended()).thenReturn(false) //BOLUS 1 a smsCommunicatorPlugin.messages = ArrayList() @@ -970,7 +969,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("CAL", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //CAL smsCommunicatorPlugin.messages = ArrayList() @@ -1001,14 +1000,14 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { @Test fun processCarbsTest() { `when`(dateUtilMocked.now()).thenReturn(1000000L) `when`(dateUtilMocked.timeString(anyLong())).thenReturn("03:01AM") - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(false) //CAL smsCommunicatorPlugin.messages = ArrayList() var sms = Sms("1234", "CARBS") smsCommunicatorPlugin.processSms(sms) Assert.assertEquals("CARBS", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text) - `when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true) //CARBS smsCommunicatorPlugin.messages = ArrayList() diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsTest.kt similarity index 96% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt rename to plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsTest.kt index ea3f5d582d..21b30b1c79 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsTest.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.smsCommunicator +package info.nightscout.plugins.general.smsCommunicator import android.telephony.SmsMessage import info.nightscout.androidaps.TestBase diff --git a/settings.gradle b/settings.gradle index 9225e1de8c..04c5fb7e1b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -21,3 +21,4 @@ include ':graphview' include ':libraries' include ':ui' include ':implementation' +include ':plugins' From d2b20b6232b907ee333516a4dd96aa100cbccfea Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 1 Nov 2022 22:46:31 +0100 Subject: [PATCH 55/77] SMS: add missing permission --- plugins/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/src/main/AndroidManifest.xml b/plugins/src/main/AndroidManifest.xml index 5638a39c06..58a76272b2 100644 --- a/plugins/src/main/AndroidManifest.xml +++ b/plugins/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ + - Date: Tue, 1 Nov 2022 22:56:21 +0100 Subject: [PATCH 56/77] New Crowdin updates (#2151) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Romanian) * New translations strings.xml (Hebrew) * New translations strings.xml (Italian) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (French) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Portuguese) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Romanian) * New translations strings.xml (Hebrew) * New translations strings.xml (Polish) * New translations strings.xml (Norwegian) * New translations strings.xml (Dutch) * New translations strings.xml (Lithuanian) * New translations strings.xml (French) * New translations strings.xml (Italian) * New translations strings.xml (Korean) * New translations strings.xml (Irish) * New translations strings.xml (German) * New translations strings.xml (Danish) * New translations strings.xml (Czech) * New translations strings.xml (Catalan) * New translations strings.xml (Bulgarian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Spanish) * New translations strings.xml (Greek) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Portuguese) * New translations strings.xml (Turkish) * New translations strings.xml (Swedish) * New translations strings.xml (Slovak) * New translations strings.xml (Russian) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (Romanian) * New translations strings.xml (Greek) * New translations strings.xml (Romanian) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Irish) * New translations strings.xml (Hebrew) * New translations strings.xml (Hungarian) * New translations strings.xml (Italian) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Greek) * New translations strings.xml (Hebrew) * New translations strings.xml (Italian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Serbian (Latin)) * Update source file strings.xml * Update source file strings.xml * Update source file strings.xml * New translations strings.xml (Turkish) * New translations exam.xml (Turkish) * New translations objectives.xml (Turkish) * New translations strings.xml (Czech) * New translations strings.xml (Turkish) * New translations strings.xml (Turkish) * New translations strings.xml (Romanian) * New translations strings.xml (Italian) * New translations strings.xml (Hebrew) * New translations strings.xml (Greek) * New translations strings.xml (German) * New translations strings.xml (Danish) * New translations strings.xml (Czech) * New translations strings.xml (Catalan) * New translations strings.xml (Bulgarian) * New translations strings.xml (Spanish) * New translations strings.xml (French) * New translations strings.xml (Afrikaans) * New translations strings.xml (Swedish) * New translations strings.xml (Slovak) * New translations strings.xml (Russian) * New translations strings.xml (Turkish) * New translations strings.xml (Polish) * New translations strings.xml (Norwegian) * New translations strings.xml (Dutch) * New translations strings.xml (Lithuanian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Korean) * New translations strings.xml (Portuguese) * New translations strings.xml (Serbian (Latin)) * New translations strings.xml (Turkish) * New translations strings.xml (Romanian) * New translations strings.xml (Croatian) * New translations strings.xml (Serbian (Latin)) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (French) * New translations strings.xml (Hungarian) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Greek) * New translations strings.xml (Irish) * New translations strings.xml (Hebrew) * New translations strings.xml (Italian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Hungarian) * New translations strings.xml (Croatian) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Turkish) * New translations strings.xml (Swedish) * New translations strings.xml (Slovak) * New translations strings.xml (Russian) * New translations strings.xml (Portuguese) * New translations strings.xml (Polish) * New translations strings.xml (Norwegian) * New translations strings.xml (Dutch) * New translations strings.xml (Lithuanian) * New translations strings.xml (Korean) * New translations strings.xml (Italian) * New translations strings.xml (Hebrew) * New translations strings.xml (Spanish) * New translations strings.xml (Romanian) * New translations strings.xml (French) * New translations strings.xml (Afrikaans) * New translations strings.xml (Irish) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Greek) * New translations strings.xml (Serbian (Latin)) * Update source file strings.xml * Update source file strings.xml * Update source file strings.xml * New translations strings.xml (Slovak) * New translations strings.xml (Slovak) * New translations strings.xml (Slovak) * New translations strings.xml (Slovak) * New translations strings.xml (Slovak) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Italian) * New translations strings.xml (Romanian) * New translations strings.xml (French) * New translations strings.xml (Hungarian) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Greek) * New translations strings.xml (Irish) * New translations strings.xml (Hebrew) * New translations strings.xml (Greek) * New translations strings.xml (Romanian) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Irish) * New translations strings.xml (Hebrew) * New translations strings.xml (Hungarian) * New translations strings.xml (Italian) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Serbian (Latin)) --- app/src/main/res/values-af-rZA/strings.xml | 71 -------- app/src/main/res/values-bg-rBG/strings.xml | 139 --------------- app/src/main/res/values-ca-rES/strings.xml | 74 -------- app/src/main/res/values-cs-rCZ/strings.xml | 150 +--------------- app/src/main/res/values-da-rDK/strings.xml | 144 ---------------- app/src/main/res/values-de-rDE/strings.xml | 145 ---------------- app/src/main/res/values-el-rGR/strings.xml | 72 -------- app/src/main/res/values-es-rES/strings.xml | 149 ---------------- app/src/main/res/values-fr-rFR/strings.xml | 147 ---------------- app/src/main/res/values-ga-rIE/strings.xml | 1 - app/src/main/res/values-hr-rHR/strings.xml | 1 - app/src/main/res/values-hu-rHU/strings.xml | 1 - app/src/main/res/values-it-rIT/strings.xml | 149 ---------------- app/src/main/res/values-iw-rIL/strings.xml | 145 ---------------- app/src/main/res/values-ko-rKR/strings.xml | 135 --------------- app/src/main/res/values-lt-rLT/strings.xml | 140 --------------- app/src/main/res/values-nl-rNL/strings.xml | 144 ---------------- app/src/main/res/values-no-rNO/strings.xml | 145 ---------------- app/src/main/res/values-pl-rPL/strings.xml | 140 --------------- app/src/main/res/values-pt-rBR/strings.xml | 137 --------------- app/src/main/res/values-pt-rPT/strings.xml | 141 --------------- app/src/main/res/values-ro-rRO/strings.xml | 141 --------------- app/src/main/res/values-ru-rRU/strings.xml | 148 ---------------- app/src/main/res/values-sk-rSK/strings.xml | 147 ---------------- app/src/main/res/values-sr-rCS/strings.xml | 1 - app/src/main/res/values-sv-rSE/strings.xml | 142 --------------- app/src/main/res/values-tr-rTR/exam.xml | 33 ++++ app/src/main/res/values-tr-rTR/objectives.xml | 2 + app/src/main/res/values-tr-rTR/strings.xml | 162 ++---------------- app/src/main/res/values-zh-rCN/strings.xml | 144 ---------------- .../src/main/res/values-sr-rCS/strings.xml | 4 +- core/src/main/res/values-af-rZA/strings.xml | 5 + core/src/main/res/values-bg-rBG/strings.xml | 7 + core/src/main/res/values-ca-rES/strings.xml | 7 + core/src/main/res/values-cs-rCZ/strings.xml | 12 ++ core/src/main/res/values-da-rDK/strings.xml | 7 + core/src/main/res/values-de-rDE/strings.xml | 7 + core/src/main/res/values-el-rGR/strings.xml | 6 + core/src/main/res/values-es-rES/strings.xml | 7 + core/src/main/res/values-fr-rFR/strings.xml | 11 ++ core/src/main/res/values-ga-rIE/strings.xml | 4 + core/src/main/res/values-hr-rHR/strings.xml | 1 + core/src/main/res/values-hu-rHU/strings.xml | 2 + core/src/main/res/values-it-rIT/strings.xml | 7 + core/src/main/res/values-iw-rIL/strings.xml | 7 + core/src/main/res/values-ko-rKR/strings.xml | 6 + core/src/main/res/values-lt-rLT/strings.xml | 7 + core/src/main/res/values-nl-rNL/strings.xml | 7 + core/src/main/res/values-no-rNO/strings.xml | 7 + core/src/main/res/values-pl-rPL/strings.xml | 7 + core/src/main/res/values-pt-rBR/strings.xml | 7 + core/src/main/res/values-pt-rPT/strings.xml | 7 + core/src/main/res/values-ro-rRO/strings.xml | 7 + core/src/main/res/values-ru-rRU/strings.xml | 7 + core/src/main/res/values-sk-rSK/strings.xml | 12 ++ core/src/main/res/values-sr-rCS/strings.xml | 3 + core/src/main/res/values-sv-rSE/strings.xml | 7 + core/src/main/res/values-tr-rTR/strings.xml | 18 ++ core/src/main/res/values-zh-rCN/strings.xml | 7 + .../src/main/res/values-af-rZA/strings.xml | 6 + .../src/main/res/values-bg-rBG/strings.xml | 8 + .../src/main/res/values-ca-rES/strings.xml | 7 + .../src/main/res/values-cs-rCZ/strings.xml | 23 +++ .../src/main/res/values-da-rDK/strings.xml | 9 + .../src/main/res/values-de-rDE/strings.xml | 9 + .../src/main/res/values-el-rGR/strings.xml | 7 + .../src/main/res/values-es-rES/strings.xml | 9 + .../src/main/res/values-fr-rFR/strings.xml | 17 ++ .../src/main/res/values-ga-rIE/strings.xml | 2 + .../src/main/res/values-hr-rHR/strings.xml | 5 + .../src/main/res/values-hu-rHU/strings.xml | 2 + .../src/main/res/values-it-rIT/strings.xml | 9 + .../src/main/res/values-iw-rIL/strings.xml | 9 + .../src/main/res/values-ko-rKR/strings.xml | 7 + .../src/main/res/values-lt-rLT/strings.xml | 8 + .../src/main/res/values-nl-rNL/strings.xml | 9 + .../src/main/res/values-no-rNO/strings.xml | 9 + .../src/main/res/values-pl-rPL/strings.xml | 8 + .../src/main/res/values-pt-rBR/strings.xml | 9 + .../src/main/res/values-pt-rPT/strings.xml | 8 + .../src/main/res/values-ro-rRO/strings.xml | 8 + .../src/main/res/values-ru-rRU/strings.xml | 9 + .../src/main/res/values-sk-rSK/strings.xml | 23 +++ .../src/main/res/values-sr-rCS/strings.xml | 4 + .../src/main/res/values-sv-rSE/strings.xml | 8 + .../src/main/res/values-tr-rTR/strings.xml | 23 +++ .../src/main/res/values-zh-rCN/strings.xml | 8 + .../src/main/res/values-tr-rTR/strings.xml | 1 + .../src/main/res/values-af-rZA/strings.xml | 40 +++++ .../src/main/res/values-bg-rBG/strings.xml | 88 ++++++++++ .../src/main/res/values-ca-rES/strings.xml | 88 ++++++++++ .../src/main/res/values-cs-rCZ/strings.xml | 105 ++++++++++++ .../src/main/res/values-da-rDK/strings.xml | 91 ++++++++++ .../src/main/res/values-de-rDE/strings.xml | 89 ++++++++++ .../src/main/res/values-el-rGR/strings.xml | 67 ++++++++ .../src/main/res/values-es-rES/strings.xml | 92 ++++++++++ .../src/main/res/values-fr-rFR/strings.xml | 92 ++++++++++ .../src/main/res/values-ga-rIE/strings.xml | 15 ++ .../src/main/res/values-hr-rHR/strings.xml | 9 + .../src/main/res/values-hu-rHU/strings.xml | 6 + .../src/main/res/values-it-rIT/strings.xml | 91 ++++++++++ .../src/main/res/values-iw-rIL/strings.xml | 89 ++++++++++ .../src/main/res/values-ko-rKR/strings.xml | 88 ++++++++++ .../src/main/res/values-lt-rLT/strings.xml | 88 ++++++++++ .../src/main/res/values-nl-rNL/strings.xml | 90 ++++++++++ .../src/main/res/values-no-rNO/strings.xml | 90 ++++++++++ .../src/main/res/values-pl-rPL/strings.xml | 88 ++++++++++ .../src/main/res/values-pt-rBR/strings.xml | 92 ++++++++++ .../src/main/res/values-pt-rPT/strings.xml | 88 ++++++++++ .../src/main/res/values-ro-rRO/strings.xml | 88 ++++++++++ .../src/main/res/values-ru-rRU/strings.xml | 92 ++++++++++ .../src/main/res/values-sk-rSK/strings.xml | 105 ++++++++++++ .../src/main/res/values-sr-rCS/strings.xml | 46 +++++ .../src/main/res/values-sv-rSE/strings.xml | 88 ++++++++++ .../src/main/res/values-tr-rTR/strings.xml | 92 ++++++++++ .../src/main/res/values-zh-rCN/strings.xml | 89 ++++++++++ ui/src/main/res/values-af-rZA/strings.xml | 9 + ui/src/main/res/values-bg-rBG/strings.xml | 10 ++ ui/src/main/res/values-ca-rES/strings.xml | 9 + ui/src/main/res/values-cs-rCZ/strings.xml | 16 ++ ui/src/main/res/values-da-rDK/strings.xml | 12 ++ ui/src/main/res/values-de-rDE/strings.xml | 12 ++ ui/src/main/res/values-el-rGR/strings.xml | 9 + ui/src/main/res/values-es-rES/strings.xml | 12 ++ ui/src/main/res/values-fr-rFR/strings.xml | 16 ++ ui/src/main/res/values-ga-rIE/strings.xml | 4 + ui/src/main/res/values-hr-rHR/strings.xml | 2 + ui/src/main/res/values-hu-rHU/strings.xml | 2 + ui/src/main/res/values-it-rIT/strings.xml | 12 ++ ui/src/main/res/values-iw-rIL/strings.xml | 12 ++ ui/src/main/res/values-ko-rKR/strings.xml | 9 + ui/src/main/res/values-lt-rLT/strings.xml | 11 ++ ui/src/main/res/values-nl-rNL/strings.xml | 12 ++ ui/src/main/res/values-no-rNO/strings.xml | 12 ++ ui/src/main/res/values-pl-rPL/strings.xml | 10 ++ ui/src/main/res/values-pt-rBR/strings.xml | 11 ++ ui/src/main/res/values-pt-rPT/strings.xml | 10 ++ ui/src/main/res/values-ro-rRO/strings.xml | 10 ++ ui/src/main/res/values-ru-rRU/strings.xml | 12 ++ ui/src/main/res/values-sk-rSK/strings.xml | 16 ++ ui/src/main/res/values-sr-rCS/strings.xml | 2 + ui/src/main/res/values-sv-rSE/strings.xml | 11 ++ ui/src/main/res/values-tr-rTR/strings.xml | 16 ++ ui/src/main/res/values-zh-rCN/strings.xml | 12 ++ 144 files changed, 2998 insertions(+), 3236 deletions(-) create mode 100644 implementation/src/main/res/values-af-rZA/strings.xml create mode 100644 implementation/src/main/res/values-bg-rBG/strings.xml create mode 100644 implementation/src/main/res/values-ca-rES/strings.xml create mode 100644 implementation/src/main/res/values-cs-rCZ/strings.xml create mode 100644 implementation/src/main/res/values-da-rDK/strings.xml create mode 100644 implementation/src/main/res/values-de-rDE/strings.xml create mode 100644 implementation/src/main/res/values-el-rGR/strings.xml create mode 100644 implementation/src/main/res/values-es-rES/strings.xml create mode 100644 implementation/src/main/res/values-fr-rFR/strings.xml create mode 100644 implementation/src/main/res/values-ga-rIE/strings.xml create mode 100644 implementation/src/main/res/values-hr-rHR/strings.xml create mode 100644 implementation/src/main/res/values-hu-rHU/strings.xml create mode 100644 implementation/src/main/res/values-it-rIT/strings.xml create mode 100644 implementation/src/main/res/values-iw-rIL/strings.xml create mode 100644 implementation/src/main/res/values-ko-rKR/strings.xml create mode 100644 implementation/src/main/res/values-lt-rLT/strings.xml create mode 100644 implementation/src/main/res/values-nl-rNL/strings.xml create mode 100644 implementation/src/main/res/values-no-rNO/strings.xml create mode 100644 implementation/src/main/res/values-pl-rPL/strings.xml create mode 100644 implementation/src/main/res/values-pt-rBR/strings.xml create mode 100644 implementation/src/main/res/values-pt-rPT/strings.xml create mode 100644 implementation/src/main/res/values-ro-rRO/strings.xml create mode 100644 implementation/src/main/res/values-ru-rRU/strings.xml create mode 100644 implementation/src/main/res/values-sk-rSK/strings.xml create mode 100644 implementation/src/main/res/values-sr-rCS/strings.xml create mode 100644 implementation/src/main/res/values-sv-rSE/strings.xml create mode 100644 implementation/src/main/res/values-tr-rTR/strings.xml create mode 100644 implementation/src/main/res/values-zh-rCN/strings.xml create mode 100644 plugins/src/main/res/values-af-rZA/strings.xml create mode 100644 plugins/src/main/res/values-bg-rBG/strings.xml create mode 100644 plugins/src/main/res/values-ca-rES/strings.xml create mode 100644 plugins/src/main/res/values-cs-rCZ/strings.xml create mode 100644 plugins/src/main/res/values-da-rDK/strings.xml create mode 100644 plugins/src/main/res/values-de-rDE/strings.xml create mode 100644 plugins/src/main/res/values-el-rGR/strings.xml create mode 100644 plugins/src/main/res/values-es-rES/strings.xml create mode 100644 plugins/src/main/res/values-fr-rFR/strings.xml create mode 100644 plugins/src/main/res/values-ga-rIE/strings.xml create mode 100644 plugins/src/main/res/values-hr-rHR/strings.xml create mode 100644 plugins/src/main/res/values-hu-rHU/strings.xml create mode 100644 plugins/src/main/res/values-it-rIT/strings.xml create mode 100644 plugins/src/main/res/values-iw-rIL/strings.xml create mode 100644 plugins/src/main/res/values-ko-rKR/strings.xml create mode 100644 plugins/src/main/res/values-lt-rLT/strings.xml create mode 100644 plugins/src/main/res/values-nl-rNL/strings.xml create mode 100644 plugins/src/main/res/values-no-rNO/strings.xml create mode 100644 plugins/src/main/res/values-pl-rPL/strings.xml create mode 100644 plugins/src/main/res/values-pt-rBR/strings.xml create mode 100644 plugins/src/main/res/values-pt-rPT/strings.xml create mode 100644 plugins/src/main/res/values-ro-rRO/strings.xml create mode 100644 plugins/src/main/res/values-ru-rRU/strings.xml create mode 100644 plugins/src/main/res/values-sk-rSK/strings.xml create mode 100644 plugins/src/main/res/values-sr-rCS/strings.xml create mode 100644 plugins/src/main/res/values-sv-rSE/strings.xml create mode 100644 plugins/src/main/res/values-tr-rTR/strings.xml create mode 100644 plugins/src/main/res/values-zh-rCN/strings.xml create mode 100644 ui/src/main/res/values-af-rZA/strings.xml create mode 100644 ui/src/main/res/values-bg-rBG/strings.xml create mode 100644 ui/src/main/res/values-ca-rES/strings.xml create mode 100644 ui/src/main/res/values-cs-rCZ/strings.xml create mode 100644 ui/src/main/res/values-da-rDK/strings.xml create mode 100644 ui/src/main/res/values-de-rDE/strings.xml create mode 100644 ui/src/main/res/values-el-rGR/strings.xml create mode 100644 ui/src/main/res/values-es-rES/strings.xml create mode 100644 ui/src/main/res/values-fr-rFR/strings.xml create mode 100644 ui/src/main/res/values-ga-rIE/strings.xml create mode 100644 ui/src/main/res/values-hr-rHR/strings.xml create mode 100644 ui/src/main/res/values-hu-rHU/strings.xml create mode 100644 ui/src/main/res/values-it-rIT/strings.xml create mode 100644 ui/src/main/res/values-iw-rIL/strings.xml create mode 100644 ui/src/main/res/values-ko-rKR/strings.xml create mode 100644 ui/src/main/res/values-lt-rLT/strings.xml create mode 100644 ui/src/main/res/values-nl-rNL/strings.xml create mode 100644 ui/src/main/res/values-no-rNO/strings.xml create mode 100644 ui/src/main/res/values-pl-rPL/strings.xml create mode 100644 ui/src/main/res/values-pt-rBR/strings.xml create mode 100644 ui/src/main/res/values-pt-rPT/strings.xml create mode 100644 ui/src/main/res/values-ro-rRO/strings.xml create mode 100644 ui/src/main/res/values-ru-rRU/strings.xml create mode 100644 ui/src/main/res/values-sk-rSK/strings.xml create mode 100644 ui/src/main/res/values-sr-rCS/strings.xml create mode 100644 ui/src/main/res/values-sv-rSE/strings.xml create mode 100644 ui/src/main/res/values-tr-rTR/strings.xml create mode 100644 ui/src/main/res/values-zh-rCN/strings.xml diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index d5fec50e50..d3371fa980 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -37,7 +37,6 @@ Insulien: Karbs: IAB: - IAB: Totale IAB: Totale IAB aktiwiteit: Dur: @@ -45,9 +44,7 @@ Ins: IAB: Totale IOB: - BG TT - Karbs Corr Begin nou VIRTUELE POMP @@ -62,7 +59,6 @@ Geen beskikbare glukose data Versoek Delta - Delta: Konfigurasie bouer Oorsig Behandelings @@ -86,9 +82,6 @@ Aanvaar nuwe tydelike basale: Behandeling Rekenaar - Beperking toegepas! - Bolus: - Basale: Verander jou insette! BG bron APS modus @@ -98,12 +91,9 @@ Nuwe voorstel beskikbaar Weergawe van Nightscout nie ondersteun Basale IAB - Bolus beperking toegepas - Karbs beperking toegepas Ander Meter Sensor - Duur Glukose tipe TydelikeBasaal Verlengde Bolus @@ -123,33 +113,6 @@ EK VERSTAAN en STEM IN Stoor Herlaai profiel - SMS Communicator - Toegelate telefoon nommers - +XXXXXXXXXX;+YYYYYYYYYY - Om %1$.2fU bolus te lewer antwoord met kode %2$s - Om kalibrasie %1$.2f te stuur antwoord met kode %2$s - Bolus het misluk - Laat afstandbeheerde bevele toe via SMS - Loop is gedeaktiveer - Loop is geaktiveerd - Lus geaktiveer - Afstandbeheerde bevel word nie toegelaat nie - Afstandbeheerde bolus nie beskikbaar nie. Probeer later weer. - Om profiel te verander na %1$s %2$d%% antwoord met %3$s - Om basal e %1$d%% vir %2$d min te begin kies %3$s - Om lus op te skort vir %1$d minute antwoord met kode %2$s - Temp basale %1$.2fU/h vir %2$d min suksesvol geaktiveerd - Verlengde bolus %1$.2fU vir %2$d min is begin - Tydelike basale %1$d%% vir %2$d min hardloop - Tydelike basale aktivering het gefaal - Verlengde bolus het misluk - Stop tydelike basale antwoord met kode %1$s - Stop tydelike basale antwoord met kode %1$s - Tydelike basale gekanselleer - Verlengde bolus gekanselleer - Kansellassie van tydelike basale het gefaal - Kansellasie van verlengde bolus het misluk - Onbekende opdrag of verkeerde opsie SlimNutsman SlimNutsman instellings Knoppie teks: @@ -173,13 +136,9 @@ Wear Stuur alle Data weer Oop instellings op Wear - Basale waarde onder minimum. Profiel nie gestel nie! - BG: - Laaste BG: MM640g Voortgesette kennisgewing OU DATA - %1$d min terug OpenAPS AMA Matriks van %1$d elemente. \nWerklike waarde: Autosens data @@ -196,7 +155,6 @@ BEHANDEL OBJ WEAR - SMS Verkort oortjie titels Gebruik altyd kort gemiddelde delta in plaas van eenvoudige delta Profiel @@ -208,10 +166,6 @@ Verstek waarde: 2\nBolus sluimer is verorden nadat jy \'n maaltyd bolus gedoen het, so die lus sal nie werk met lae tydelike wanneer jy nou net geëet het nie. Die voorbeeld hier se verstek is 2; so \'n 3 uur DIA beteken dat bolus sluimer sal geleidelik uitgefaseer sal word oor 1.5 uur (3DIA/2). Verstek waarde: 3.0 (AMA) of 8.0 (SMB). Dit is \'n instelling vir verstek karb absorpsie impak per 5 minute. Die verstek is \'n verwagte 3mg/dl / 5min. Dit beïnvloed hoe vinnig KOB opgeneem word, en hoeveel karb absorpsie word aanvaar sodat in die berekening van toekomstige BG, voorspel wanneer BG val meer as verwagte, of nie soveel styg as verwag. Aandag! \nNormaalweg hoef jy nie die waardes hieronder te verander nie. KLIEK HIER Asseblief en LEES die teks en maak seker jy verstaan dit voor enige verandering aan hierdie waardes. - Ongeldige SMS selfoon nommer - Kalibrasie - xDrip + nie geïnstalleerd nie - Pomp opgeskort Besig met uitvoering Virtuele pomp instellings Oplaaistatus aan NS @@ -242,8 +196,6 @@ Volwassene Insulien weerstandige volwasse Glimp - Lus opgeskort - Opgeskort (%1$d m) Skort lus vir 1h Skort lus vir 2h Skort lus vir 3h @@ -255,9 +207,6 @@ Ontkoppel pomp vir 3 h Hervat Herverbind Pomp - Verkeerde duur - Lus opgeskort - Lus hervat KOB Superbolus Log app begin na NS @@ -272,7 +221,6 @@ Drempel waarskuwings stoor vlak [U] Drempel kritieke stoor vlak [U] Omtrent - Vermiste SMS toestemming Toestemming vir foon status nog nie gegee nie xds Wys BGI @@ -328,14 +276,11 @@ Kontroles van horlosie Stel tydeleike doelwitte en behandelings vanaf horlosie. Kos - g ]]> kJ En Pr Vet - Opdrag word nou uitgevoer - Gemiste BG lesings Gebruik stelsel kennisgewings vir waarskuwings en kennisgewings Lokale alarms Stel in kennis as geen BG data ontvang is @@ -395,9 +340,6 @@ Laat outomatiese Foutverslagdoening en kenmerk data stuur na die ontwikkelaars via die fabric.io diens. Hernuwe asseblief jou G5 toepassing na \'n ondersteunde weergawe Dexcom toep is nie geïnstalleer nie. - Begin aktiwiteit TT - Begin eet gou TT - TT Moet nie bolus. Rekord alleen Kategorie Subkategorie @@ -408,8 +350,6 @@ Karbs AanBoord Insulien AanBoord Basale - Geen aksie gekies, niks sal gebeur - Begin hipo TT Veranderende ontwikkelende weergawe. Geslote lus is gedeaktiveerd. Ingenieurswese modus geaktiveer ProfileSwitch ontbreek. Doen \'n profiel skakelaar of druk \"Aktiveer profiel\" in die LokaleProfiel. @@ -428,7 +368,6 @@ Beperk IAB tot %1$.1f U agv %2$s maks waarde in voorkeure harde limiet - Lees status gefaal Rekord pomp ligging verandering Rekord insulien kasset verandering SMB is altyd na koolhidrate versper omdat aktiewe BG bron nie gevorderde filter ondersteun nie @@ -476,9 +415,7 @@ Onthou asseblief: dat nuwe insulien profiele vereis DIA van minstens 5h. DIA 5 – 6h op nuwe profiel is gelyk aan DIA 3h op ou insulien profiele. Kies een van beskikbare algoritmes. Hulle is gesorteer vanaf oudste tot jongste. Nuwer algoritmes is gewoonlik kragtiger en meer aggressief. Dus as jy nuut is met jou lus, sal jy waarskynlik begin met AMA en nie met jongste een. Moenie vergeet om die OpenAPS dokumentasie te lees en te konfigureer voor gebruik. Begin jou eerste doelwit - Toestemming Vra vir toestemming - Versoek Open navigasie Sluit navigasie Plugin voorkeure @@ -507,7 +444,6 @@ Logboekinstellings Herstel na verstek NSClient onklaar. Oorweeg om NS en NSClient te herlaai. - Tyd verskil Verkose APS modus Totaal Bereken @@ -535,22 +471,15 @@ Laai BG toetse op interne berging beperking Bevry ten minste %1$d MB van intene stoorspasie! Lus gedeaktiveer! - Verkeerde formaat - Verkeerde kode. Opdrag gekanselleer. - Nie gekonfigureer nie - Profiel skakelaar geskep Weergawe Navolger ou weergawe baie ou weergawe 2h Sluimer - Ongeldig boodskap teks %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min - Projeksies Prima diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index b3d6e507a9..f8b1d3d8f1 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -12,7 +12,6 @@ Нулирай базата данни Сигурни ли сте че искате да изтриете всички данни? Изход - Вашият телефон не поддържа оптимизация на батерията - може да се появят проблеми! Бутони за бърз достъп до основни функции За конфигурация на активните плъгини Разучаване на програмата @@ -42,7 +41,6 @@ Инсулин: Вълехидрати: IOB: - IOB: Общо IOB: Общо активен IOB: Прод.: @@ -50,9 +48,7 @@ Инс: IOB: Общо IOB: - КЗ Вр.цел - ВХ Корекция IOB от болуси Старт сега @@ -69,7 +65,6 @@ Няма данни за КЗ Искане Изменение (Δ) - Изменение (делта): Конфигурация Общ Лечения @@ -93,9 +88,6 @@ Приложи нов временен базал: Болус Калкулатор - Приложено ограничение! - Болус: - Базал: Променете данните! Източник на данни за КЗ xDrip+ @@ -108,13 +100,10 @@ Предложение Несъвместима версия на Nightscout Базален IOB - Приложено ограничение на болус - Приложено ограничение на въглехидрати Друго Глюкомер Сензор ВХ след - Продължителност Профил Тип КЗ Временен базал @@ -153,60 +142,6 @@ НЕ ТРЯБВА ДА СЕ ИЗПОЛЗВА ЗА ВЗЕМАНЕ НА МЕДИЦИНСКИ РЕШЕНИЯ. НЯМА ГАРАНЦИЯ ЗА ПРОГРАМАТА, ДО СТЕПЕНТА, ПОЗВОЛЕНА ОТ ПРИЛОЖИМОТО ПРАВО. ОСВЕН КОГАТО Е ПОСОЧЕНО ДРУГО В ПИСМЕН ВИД, ПРИТЕЖАТЕЛИТЕ НА АВТОРСКОТО ПРАВО И/ИЛИ ДРУГИ СТРАНИ ПРЕДОСТАВЯТ ПРОГРАМАТА \"КАКТО Е\", БЕЗ ГАРАНЦИИ ОТ ВСЯКАКЪВ ВИД, ИЗРАЗЕНИ ИЛИ ПОДРАЗБИРАЩИ СЕ, ВКЛЮЧИТЕЛНО, НО НЕ САМО, ПОДРАЗБИРАЩИ СЕ ГАРАНЦИИ ЗА ПРОДАВАЕМОСТ И ПРИГОДНОСТ ЗА КОНКРЕТНА ЦЕЛ. ЦЕЛИЯ РИСК ПО ОТНОШЕНИЕ НА КАЧЕСТВОТО И ЕФЕКТИВНОСТТА НА ПРОГРАМАТА Е САМО ВАШ. АКО ПРОГРАМАТА НЕ СРАБОТИ, ВИЕ ПОЕМАТЕ ВСИЧКИ НЕОБХОДИМИ РАЗХОДИ ЗА ОБСЛУЖВАНЕ, РЕМОНТ ИЛИ КОРЕКЦИЯ. Разбирам и приемам Презареди профил - SMS комуникатор - Разрешени телефонни номера - +XXXXXXXXXX;+YYYYYYYYYY - За да доставите болус от %1$.2fЕ отговорете с код %2$s - За да стартирате болус от %1$.2fЕ отговорете с код %2$s - Зa zадаване на временна цел %1$s отговорете с код %2$s - За да спрете временната цел отговорете с код %1$s - За да изключите услугата за отдалечен SMS контрол отговорете с код %1$s.\n\nИмайте предвид, че можете да го активирате само от AAPS смартфона. - Отдалечен SMS контрол е изключен. Можете да го включите от AndroidAPS телефона. - За да изпратите калибрация %1$.2f отговорете с код %2$s - Болус отказан - Минимално време в минути, което трябва да е изминало след отдалечен болус, преди да може да бъде доставен следващият - Колко най-малко минути трябва да минат между доставката на два болуса - За вашата сигурност, променете тази настройка, трябва да добавите най-малко 2 телефонни номера. - Ще стартира %1$.2fЕ болус - Болус от %1$.2fЕ доставен успешно - Болус от %1$.2fЕ доставен успешно - Временна цел от %1$s за %2$d минути - Временна цел от %1$s за %2$d минути стартирана успешно - Временна цел успешно спряна - Позволи отдалечени команди чрез SMS - APS е деактивиран - APS е активиран - APS е включен - За свързване с помпа отговорете с код %1$s - Връзката с помпата е неуспешна - За да спрете помпата за %1$d минути отговорете с код %2$s - Помпата е разкачена - Връзката с помпа е възстановена - Отдалеченото управление е забранено - Отдалечено стартиране на болус не е възможно. Опитайте отново по-късно. - За да стартирате базал от %1$.2fЕ/ч за %2$d мин отговорете с код %3$s - За да превключите профила към %1$s %2$d%% отговорете с код %3$s - За да започнете удължен болус %1$.2fЕ за %2$d мин отговорете с код %3$s - За да въведете %1$dг в %2$s отговорете с код %3$s - За да стартирате базал от %1$d%%Е/ч за %2$d мин отговорете с код %3$s - За да спрете APS за %1$d минути отговорете с код %2$s - За възстановяване на кръга отговорете с код %1$s - За активирнае на кръга отговорете с код %1$s - За изключване на кръга отговорете с код %1$s - Временен базал от %1$.2fЕ/ч за %2$d мин стартиран успешно - Удължен болус %1$.2fU за %2$d мин стартиран успешно - Въглехидрати %1$dг въведени - Въвеждане на%1$dг въглехидрати - НЕУСПЕШНО - Временен базал от %1$d%%Е/ч за %2$d мин стартиран успешно - Неуспешно стартиране на временен базал - Неуспешно стартиране на удължен болус - За да спрете времен базал отговорете с код %1$s - За да спрете удължения болус отговорете с код %1$s - Временният базал е отменен - Удължен болус спрян - Спирането на временния базал е неуспешно - Неуспешно спиране на удължен болус - Непозната команда или грешен отговор Бърз болус Настройки за бърз болус Текст на бутона: @@ -236,13 +171,9 @@ Часовник Изпрати отново всички дани Отвори настройките на часовника - Базалните стойности са под минимума. Не е зададен профил! - КЗ: - Последна КЗ: MM640g Текущи известия СТАРИ ДАННИ - преди %1$d мин Профил OpenAPS AMA Общо %1$d елемента.\nАктуална стойност: @@ -261,7 +192,6 @@ Леч Цел WEAR - SMS Използвай къси имена Използвай краткоср. Δ вместо разлика от последната КЗ Полезно при данни за КЗ с много шум. @@ -275,13 +205,6 @@ По подразбиране: 2\nBolus snooze се активира след като поставите болус за основно хранене, така Loop няма да пуснка/намаля базалите веднага след като сте се хранили. Примерът тук е с 2; така при 3 часа DIA това ще означава че bolus snooze ще бъде внимателно изместен 1.5 часа (3DIA/2). Стойност по подразбиране: 3.0 (АМА) или 8.0 (SMB). Това е настройка на количеството на покачване на КЗ при усвояване на въглехидратите за всеки 5 минути. По подразбиране 3мг/дл за 5мин. Това се отразява на това колко бързо се усвояват COB според алгоритъма, и как това се отразява в предвиждането на КЗ, когато тя не се покачва или пада с различен темп от очакваното. Внимание! Обикновено Вие не трябва да променяте тези стойности. Моля НАТИСНЕТЕ ТУК, прочетете текста и бъдете сигурни, че го РАЗБИРАТЕ преди да направите каквито и да е промени! - Грешен тел номер за SMS - Калибрация - xDrip+ не е инсталиран - Калибрацията е изпратена към xDrip+ - Калибрацията е изпратена. Получаването трябва да бъде разрешено в xDrip +. - xDrip+ не получава калибрации - Помпата е спряна Изпълнява Настойки Виртуална Помпа Качва статуса в NS @@ -317,10 +240,7 @@ Моля, изберете тип на пациента за настройка на границите за безопастност Име на пациента Моля, посочете име на пациента или измислено име, за да се различават - Потребител Glimp - Loop изключен - Изключен (%1$d мин) Изключи APS за 1ч Изключи APS за 2ч Изключи APS за 3ч @@ -339,9 +259,6 @@ 10 часа Възстанови Свържи помпа - Грешна продължителност - APS забранен - APS възобновен Δ за 15мин СОВ Суперболус @@ -375,7 +292,6 @@ АБС ОТК.НАКЛ За приложението - SMS команда забранена Липсва разрешение до данни от телефона xDrip+ статус (часовник) xDrip+ линия със статута (часовник) @@ -443,14 +359,11 @@ Контролиране от часовник Задаване временни цели и въвеждане Лечения от часовник Android wear Храна - гр. ]]> килодж. Ен Бел. Маз. - Командата се изпълнява в момента - Липсват данни за КЗ Използвай системни известия за аларми и съобщения Постепенно увеличаване на звука за сигнали и аларми Локални аларми @@ -525,9 +438,6 @@ Позволява автоматично изпращане на данни за грешки и статистически данни до разработчиците чрез услугата fabric.io . Моля обновете Dexcom приложението до поддържана версия Приложението на Dexcom не е инсталирано. - Старт на вр.цел за физ. активност - Старт на вр. цел за Eating soon - Вр.цел Не стартирай болус, а само запиши в базата данни Категория Подкатегория @@ -540,8 +450,6 @@ Активни въглехидрати Действащ инсулин Базали - Няма избрано действие, нищо няма да се изпълни - Старт на вр. цел при хипо Използвате dev версия. Затворения кръг е недостъпен за Вас. Режим за раработчици (Engineering mode) включен Смяната на профила не е отразена. Моля, направете превключване на потребителския профил или натиснете \"Активирай профил\" в Локален профил. @@ -560,7 +468,6 @@ Ограничаване на IOB до %1$.1f Е поради %2$s макс. стойност в настройките твърд лимит - Четенето на статуса се провали Запис смяна на сет Запис смяна на резервоар SMB \"винаги включен\" и \"след въглехидрати\" е забранен, защото е активен източник на КЗ, който не поддържа необходимата филтрация @@ -612,12 +519,7 @@ Конфигурация на RileyLink. След избиране на RileyLink, ще е възможно неговото конфигуриране, след като статуса му е \"Свързан\". Може да отнеме време \n Заб: Можете да продължите след като помпата се инициализира.\n Започнете първа цел - Разрешение Питане за разрешение - ААПС изисква разрешение за да може да Ви уведомява - Приложение се нуждае от достъп до местоположението Ви за сканиране и WiFi идентификация - Приложението се нуждае от разрешение да съхранява данни за да може съхранява лог файлове и експортира настройки - Искане Отвори меню Затвори меню Настройки на модул @@ -651,8 +553,6 @@ Настройки на логовете Възстанови настройките по подразбиране Грешка в NSClient. Рестартирайте Nightscout и NSClient - времево отместване - Напомни за болус по-късно Предпочитаният режим на APS Общо Калк @@ -682,11 +582,6 @@ Смяна на времето след по-малко от 3 часа - минавам в отворен режим Ограничение поради липса на памет Освободете поне %1$d Мб в паметта на телефона! Loop изключен! - Грешен формат - Продължителността на временния база; трябва да бъде кратна на %1$d минути и по-голяма от 0. - Грешен код. Командата не е изпълнена. - Не е конфигуриран - Създаден запис - Промяна на профил Проверка на версията стара версия много стара версия @@ -700,12 +595,10 @@ Калкулатора изчислява нужния инсулин, но само тази част ще бъде доставена. Полезно със SMB алгоритъма. Отложи Повишавам максималната стойност на базал, защото тя е по-ниска от най-високата в базалния профил - Невалиден текст на съобщение %1$s ISF: %2$.1f %1$.0fгр Чувств: %2$.1f %1$.1fгр Чувств: %2$.1f %1$d %% - мин Име на профила: Избрано: Единици @@ -751,25 +644,6 @@ Макс. време за изпълнение за SMB Диапазон между временни базали Продължителност на временни базали - - от приложението AUTHENTICATOR за: %1$s , последвано от PIN - Допълнителен PIN в края на токен - Допълнителни цифри, които следва да бъдат залепени в края на всяка генерирана еднократна парола - Настройка на удостоверителя - Код за проверка: - OTP + PIN - Кодът за проверката се състои от 6 цифри, от приложението за аудиентикация (известно като OTP), следвани от 3 или повече цифри на задължителния PIN. - Нулиране на удостоверители - Нулиране на ключва - Сигурни ли сте, че ще анулирате ключа на Authenticator? Той ще направи всички конфигурирани в момента аудиентикатори невалидни, и вие ще трябва да ги настроите отново. - Генериран е нов ключ! Моля, използвайте актуализирания QRCode. - Експортиране на OTP парола - Сигурни ли сте, че искате да копирате OTP паролата в клипборда?\n\nВие може да се нуждаете само от това, ако вашето приложение за автентичност има проблеми със сканирането на QRCode, искате да го въведете ръчно или искате да конфигурирате хардуерен OTP токен чрез специално приложение. - OTP парола (във Base32 формат) е експортирана и копирана в клипборда. Поставете го в автентикатор или хардуерен OTP! - 1. Инсталиране на удостоверител - 3. Тест на еднократна парола - Нулиране на удостоверители - На всеки следящ телефона инсталирайте приложение Аутентификатор, който поддържа RFC 6238 ТОТР токени. Популярни безплатни приложения:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Прогнозни КЗ Наклон на отклонението Удостоверяването неуспешно @@ -799,20 +673,9 @@ Филтър Създаването на профила невъзможно. Профилът е невалиден. Не убивай приложението? - Изпращане на SMS, ако помпата е недостъпна - Докладвай недостъпна помпа Алармата, когато е време за хранене. - Сларма след %1$d мин - Съветник на болус - Имаш висока захар. Вместо да се яде сега, се препоръчва да се изчака за по-добра захар. Искате ли да направите корекция сега и да ви напомня кога е време за ядене? В този случай няма да бъдат записвани въглехидрати и трябва да използвате съветника отново, когато ви напомня. - Активиране на болус съветник - Използвай напомняне за старт на хранене вместо съветника по време на висока гликемия (\"пре-болус\") Време за ядене!\nИзпълнете болус съветника и направете изчисления отново. - Време е за ядене - Болус подсещане Включи подсещането за болус - Използвай подсещане за болус по-късно със съветник (\"след-болус\") - Време е за болус!\nВключи болус съветника и направи изчисление отново. Качването на данни за проблеми е забранено!(Fabric) Графика Меню на графиката @@ -845,8 +708,6 @@ Приемай смени (канула, инсулин, батерия и др.) зададени от NS или NS Клиент Приеми история от данни от сензора Приемай постояни данни от сензора идващи от NS - Изтичане на времето на предишна комуникация с помпата - В момента се обработва друг болус. Моля опитай по-късни. Калкулация в прогресс Липсва име на профила Грешка в стойността на ВЧ (IC) diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index c4fb83ca83..a78386e5e9 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -12,7 +12,6 @@ Restablir bases de dades Esteu segurs que voleu restablir les bases de dades? Sortir - Sembla que aquest dispositiu no permet optimitzar la bateria amb llistes blanques, això pot provocar problemes de rendiment. Alguns botons per accedir ràpid a funcions habituals Utilitzat per configurar plugins actius Programa d\'aprenentatge @@ -42,7 +41,6 @@ Insulina: Carbs: IOB: - IOB: IOB total: Activitat total IOB: Durada: @@ -50,9 +48,7 @@ Ins: IOB: IOB total: - Glucèmia OT - Carbs Corr IOB Bolus Executar ara @@ -69,7 +65,6 @@ Dades de glucèmia no disponibles Petició Delta - Delta: Configurador Inici Tractaments @@ -92,9 +87,6 @@ Acceptar nova basal temporal: Tractament Calculadora - Restricció aplicada! - Bolus: - Basal: Modifiqueu les dades! Origen glucèmia xDrip+ @@ -107,12 +99,9 @@ Proposta de carbs Versió no compatible de Nightscout IOB Basal - Restricció de bolus aplicada - Restricció de carbs. aplicada Altres Glucòmetre Sensor - Durada Tipus de glucèmia BasalTemp Bolus estès @@ -150,55 +139,6 @@ ENTENC I ACCEPTO Desar Recarregar perfil - Comunicador SMS - Nrs. de telèfon permesos - +XXXXXXXXXX;+YYYYYYYYYY - Per lliurar bolus %1$.2fU contesteu amb el codi %2$s - Per lliurar bolus d\'àpat %1$.2fU contesteu amb el codi %2$s - Per definir un Objectiu Temporal %1$s contesteu amb el codi %2$s - Per cancel·lar Objectiu Temporal contesteu amb el codi %1$s - Per desactivar el Servei Remot d\'SMS contesteu amb el codi %1$s.\n\nRecordeu que només el podreu reactivar des del mòbil amb AAPS principal. - Servei Remot d\'SMS aturat. Per reactivar-lo, utilitzeu AAPS des del mòbil principal. - Per enviar calibració %1$.2f contesteu amb el codi %2$s - Error de bolus - Mínim nr. de minuts que han de passar entre un bolus remot i el següent - Quants minuts han de passar, com a mínim, entre un bolus i el següent - Per la vostra seguretat, per editar aquesta configuració haureu d\'afegir al menys 2 nrs. de telèfon. - A punt de lliurar %1$.2f U - Bolus %1$.2f U llliurat correctament - Bolus d\'àpat %1$.2f U lliurat correctament - Objectiu %1$s per %2$d minuts - Objectiu %1$s per %2$d minuts definit correctament - Permetre ordres remotes via SMS - El llaç s\'ha desactivat - El llaç s\'ha activat - Llaç activat - Per connectar la bomba, contesteu amb el codi %1$s - La connexió a la bomba ha fallat - Per desconnectar la bomba %1$d minuts contesteu amb el codi %2$s - Bomba desconnectada - Bomba reconnectada - Ordre remota no permesa - Bolus remot no disponible. Torneu-ho a intentar més tard. - Per iniciar basal de %1$.2f U/h durant %2$d min. contesteu amb el codi %3$s - Per canviar el perfil a %1$s %2$d%% contesteu amb el codi %3$s - Per iniciar bolus estès de %1$.2f U durant %2$d min. contesteu amb el codi %3$s - Per introduir %1$dg en %2$s contesteu amb el codi %3$s - Per iniciar basal %1$d%% durant %2$d min. contesteu amb el codi %3$s - Per interrompre el llaç durant %1$d minuts contesteu amb el codi %2$s - Per reprendre el llaç contesteu amb el codi %1$s - Per activar el llaç contesteu amb el codi %1$s - Per desactivar el llaç contesteu amb el codi %1$s - Error en introduir %1$dg de carbs - Error en iniciar basal temporal - Error en iniciar bolus estès - Per aturar basal temporal contesteu amb el codi %1$s - Per aturar bolus estès contesteu amb el codi %1$s - Basal temporal cancel·lada - Bolus estès cancel·lat - Error en cancel·lar basal temporal - Error en cancel·lar bolus estès - Ordre desconeguda o resposta incorrecta Assistent Configuració de l\'assistent Text del botó: @@ -213,7 +153,6 @@ MM640g Avís en curs DADES ANTIGUES - fa %1$dmin Perfil OpenAPS AMA Array de %1$d elements.\nValor actual: @@ -232,7 +171,6 @@ TRACT OBJ WEAR - SMS Escurçar títol pestanyes Utilitzar sempre delta mitjana curta enlloc de delta simple Útil quan les dades de fonts no filtrades, com xDrip+, esdevenen sorolloses. @@ -245,13 +183,6 @@ Valor per defecte: 2\nEl retard de bolus s\'activa després d\'un bolus d\'àpat, de manera que el llaç no contrarresti amb basals temporals baixes just després d\'haver menjat. El valor per defecte i el de l\'exemple és 2, d\'aquesta manera amb una DIA de 3 hores el bolus es retardaria gradualment durant 1.5 hores (3DIA/2). Valor per defecte: 3 (AMA) o 8.0 (SMB). Aquest paràmetre indica el valor per defecte d\'absorció de carbohidrats en 5 minuts, quan diem 3 volem dir 3mg/dl/5min. Afecta a com de ràpid decauen els COB i quina absorció de carbohidrats es considera al calcular la predicció de glucèmia futura, quan la glucèmia cau més ràpid de l\'esperat o no puja tant com era de preveure. Atenció!\nNormalment no cal modificar els valors d\'aquí sota. Si us plau FEU CLIC AQUÍ, LLEGIU el text i assegureu-vos de COMPRENDRE\'L abans de modificar-ne qualsevol. - Número de telf. per SMS no vàlid - Calibració - xDrip+ no instal·lat - Calibració enviada a xDrip+ - Calibració enviada. Cal que la recepció a xDrip+ estigui activada. - xDrip+ no està rebent calibracions - Bomba aturada Executant Configuració bomba virtual Enviar estat a NS @@ -261,9 +192,6 @@ 10 hores Reprendre Reconnectar bomba - Durada errònia - Llaç aturat - Llaç reprès COB Superbolus Enregistrar l\'inici de l\'app a NS @@ -296,7 +224,6 @@ ABS PENDENTDESV Quant a - Falta permís SMS Falta permís d\'estat del telèfon Estat d\'xDrip+ (rellotge) Línia d\'estat d\'xDrip+ (rellotge) @@ -306,7 +233,6 @@ Cancel·lar bolus estès Canviar de perfil Sensor - Iniciar sessió diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 7ad657dcda..cb38b7c04a 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -13,7 +13,6 @@ Inicializovat databáze Opravdu resetovat všechny databáze? Konec - Toto zařízení zřejmě neumožňuje vypnout optimalizaci baterie - může docházet k problémům s výkonem. Tlačítka k běžně používaným úkonům Nastavení konfigurace (povolování součástí systému) Výukový program @@ -42,11 +41,9 @@ Ukládá všechny ošetření do databáze Zobrazování stavu a řízení AAPS z hodinek s WearOS. Zobrazování informací o smyčce na xDrip+ watchface. - Vzdálené ovládání AAPS pomocí SMS příkazů. Inzulín: Sacharidy: IOB: - IOB: Celkové IOB: Celková aktivita IOB: Trv: @@ -54,9 +51,7 @@ Inz: IOB: Celkové IOB: - Gly DC - Sacharidy Korekce Bolusové IOB Spustit teď @@ -73,7 +68,6 @@ Nedostupná data o glykémiích Požadavek Rozdíl - Rozdíl: Konfigurace Přehled Ošetření @@ -97,13 +91,9 @@ Bezpečnost Modul zakázán Mimo povolený rozsah - Podání bolusu skončilo chybou. Ručně zkontrolujte, kolik inzulinu se skutečně vydalo. Spustit nový dočasný bazál: Bolus Kalkulačka - Aplikováno omezení! - Bolus: - Bazál: Změňte zadání! Zdroj glykémie Odkud má AAPS získávat glykémie? @@ -117,13 +107,10 @@ Návrh sacharidů Nepodporovaná verze Nightscoutu Bazální IOB - Aplikováno omezení bolusu - Aplikováno omezení sacharidů Jiné Glukoměr Senzor Čas jídla - Trvání Profil Zadání glykémie Dočasný bazál @@ -163,60 +150,6 @@ ROZUMÍM A POTVRZUJI Uložit Obnovit profil - SMS komunikátor - Povolená tel. čísla - +XXXXXXXXXX;+YYYYYYYYYY - K potvrzení bolusu %1$.2fU odpověz SMS s kódem %2$s - Pro potvrzení bolusu na jídlo %1$.2fU odpovězte pomocí SMS s kódem %2$s - Pro nastavení dočasného cíle %1$s odpovězte pomocí SMS s kódem %2$s - Pro zrušení dočasného cíle odpovězte pomocí SMS s kódem %1$s - Chcete-li deaktivovat Vzdálené řízení přes SMS, odpovězte pomocí SMS s kódem %1$s.\n\nUpozornění: tuto funkci budete moci znovu aktivovat pouze z telefonu s hlavní verzí AAPS. - Služba Vzdáleného řízení přes SMS zastavena. Chcete-li ji znovu aktivovat, použijte telefon s hlavní verzí AAPS. - Odeslání kalibrace %1$.2f potvrďte kódem %2$s - Chyba při aplikování bolusu - Minimální počet minut, které musí uplynout mezi dvěma bolusy podanými přes vzdálené řízení - Kolik minut (minimálně) musí uplynout mezi dvěma bolusy - Úprava tohoto nastavení v zájmu vaší bezpečnosti vyžaduje, abyste zadali alespoň 2 telefonní čísla. - Podávání %1$.2f U inzulínu - Bolus %1$.2f U aplikován úspěšně - Bolus na jídlo %1$.2f U byl úspěšně aplikován - Cíl %1$s na %2$d minut - Cíl %1$s na %2$d minut byl úspěšně nastaven - Dočasný cíl byl úspěšně zrušen - Povolit posílání příkazů přes SMS - Smyčka byla zakázána - Smyčka byla povolena - Smyčka je povolena - Chcete-li připojit pumpu, odpovězte pomocí SMS s kódem %1$s - Připojení k pumpě selhalo - Chcete-li odpojit pumpu na %1$d minut, odpovězte pomocí SMS s kódem %2$s - Pumpa odpojena - Pumpa byla znovu připojena - Vzdálený příkaz není povolen - Vzdálený bolus není momentálně povolen. Zkuste to později. - Pro spuštění bazálu %1$.2f U/h na %2$d min odpovězte SMS s kódem %3$s - Pro přepnutí profilu na %1$s %2$d%% odpovězte SMS s kódem %3$s - Pro spuštění prodlouženého bolusu %1$.2f U na %2$d min odpovězte SMS s kódem %3$s - Pro zadání %1$dg na %2$s odpovězte pomocí SMS s kódem %3$s - Pro spuštění bazálu %1$d%% na %2$d min odpovězte SMS s kódem %3$s - K pozastavení smyčky na %1$d minut odpověz SMS s kódem %2$s - Chcete-li obnovit smyčku, odpovězte SMS s kódem %1$s - Chcete-li povolit smyčku, odpovězte SMS s kódem %1$s - Chcete-li zakázat smyčku, odpovězte SMS s kódem %1$s - Dočasný bazál %1$.2fU/h na %2$d minut spuštěn - Prodloužený bolus %1$.2fU na %2$d min úspěšně spuštěn - Sacharidy %1$d g byly úspěšně zadány - Zadání %1$d g sacharidů se nezdařilo - Dočasný bazál %1$d%% na %2$d minut úspěšně spuštěn - Spuštění dočasného bazálu selhalo - Spuštění prodlouženého bolusu selhalo - Na zastavení dočasného bazálu odpovězte SMS s kódem %1$s - Pro zastavení prodlouženého bolusu odpovězte SMS s kódem %1$s - Dočasný bazál zastaven - Prodloužený bolus zastaven - Rušení dočasného bazálu selhalo - Zastavení prodlouženého bolusu selhalo - Neznámý příkaz nebo chybná odpověď Rychlý bolus Nastavení rychlých bolusů Text na tlačítku: @@ -247,13 +180,9 @@ Znovu poslat všechna data Otevřít nastavení na hodinkách Wear Bazál - Hodnota bazálu pod povoleným minimem. Nenastaveno! - Glykémie: - Poslední glykémie: MM640g Průběžné oznámení ZASTARALÉ - před %1$d min Profil OpenAPS AMA Pole %1$d prvků.\nAktuální hodnota: @@ -273,7 +202,6 @@ OŠET CÍLE WEAR - SMS Krátké názvy modulů Vždy používat krátkodobý průměrný rozdíl glykémií místo rozdílu posledních 2 hodnot Výhodné, pokud data z xDripu+ obsahují velký šum. @@ -287,13 +215,6 @@ Výchozí hodnota: 2\nToto nastavení říká, po jakou část z hodnoty DIA smyčka po bolusu čeká a nereaguje na změny glykémií (zde 3DIA/2 = 1,5h). Výchozí hodnota: 3.0 (AMA) nebo 8.0 (SMB) mg/dl/5min. Tato hodnota definuje minimální část strávených sacharidů za každých 5 min. Tato hodnota ovlivňuje výpočet COB. Pozor!\nZa normálních okolností tyto hodnoty nemusíte měnit. Klikněte ZDE, PŘEČTĚTE si informace a UJISTĚTE se, že jim rozumíte dříve, než je začnete měnit. - Špatné telefonní číslo - Kalibrace - xDrip+ není nainstalován - Kalibrace odeslána do xDripu+ - Kalibrace odeslána. Příjem musí být v xDripu+ povolený. - xDrip+ nepřijímá kalibrace - Pumpa pozastavena Provádím Nastavení virtuální pumpy Nahrávat status do NS @@ -329,11 +250,7 @@ Prosím vyberte typ pacienta pro nastavení bezpečnostních limitů Jméno pacienta Zadejte jméno pacienta nebo přezdívku pro rozlišení mezi více nastaveními - Uživatel Glimp - %1$s potřebuje vypnout optimalizace baterie pro optimální výkon - Smyčka pozastavena - Pozastaveno (%1$d min) Pozastavit smyčku na 1 h Pozastavit smyčku na 2 h Pozastavit smyčku na 3 h @@ -352,9 +269,6 @@ 10 hodin Uvolnit Znovu připojit pumpu - Chybná doba trvání - Smyčka pozastavena - Smyčka obnovena 15min trend COB Superbolus @@ -389,7 +303,6 @@ ABS DEVSLOPE O aplikaci - Chybějící povolení SMS Chybí oprávnění pro zjišťování stavu telefonu Status z xDripu+ (hodinky) Stavová řádka xDrip+ (hodinky) @@ -462,14 +375,11 @@ Řízení z hodinek Wear Nastavování dočasných cílů a vkládání ošetření na hodinkách Wear. Jídlo - g ]]> kJ En Pr Tuk - Příkaz je právě prováděn - Chybějící glykémie Používat systémové notifikace pro výstrahy a oznámení Postupně zvyšovat hlasitost výstrah a oznámení Místní výstrahy @@ -547,9 +457,6 @@ Automatické odesílání chyb aplikace a statistiky používání vývojářům pomocí služby fabric.io. Prosím aktualizujte Dexcom aplikaci na podporovanou verzi Aplikace Dexcom není nainstalována. - Spustit dočasný cíl Aktivita - Spustit dočasný cíl Před jídlem - DoCíl Nepouštět bolus, jen zaznamenat Kategorie Podkategorie @@ -562,8 +469,6 @@ Zbývající sacharidy Zbývající inzulín Bazály - Žádná akce nevybrána, nic se neprovede - Spustit dočasný cíl Hypoglykémie Běží DEV verze. Uzavřená smyčka je zakázána. Expertní mód povolen Přepnutí profilu chybí. Proveďte přepnutí profilu nebo ho aktivujte na záložce lokálního profilu. @@ -582,7 +487,6 @@ IOB omezeno na %1$.1f U: %2$s maximální hodnota v nastavení pevný limit - Načtení stavu selhalo Zaznamenat výměnu setu Zaznamenat výměnu inzulínu \"SMB vždy\" a \"po jídle\" zakázáno protože zdroj glykémie nepodporuje rozšířené filtrování @@ -640,12 +544,7 @@ Prosím nakonfigurujte svůj RileyLink níže. Po výběru RileyLinku bude možné pokračovat v nastavení, jakmile stav RileyLinku je \"Připojeno\". Tato akce může chvilku trvat.\n Poznámka: Po nastavení pumpy můžete pokračovat v nastavení.\n Spusťte první cíl - Povolení Získat povolení - Pro oznámení vyžaduje aplikace oprávnění systémového okna - Aplikace potřebuje oprávnění k přístupu k poloze kvůli skenování BT a WiFi identifikaci - Aby bylo možné nahrávat logy a exportovat nastavení, je nutné pro aplikaci povolit oprávnění přístupu k úložišti - Požadavek Otevřít menu Zavřít menu Nastavení pluginu @@ -691,8 +590,6 @@ Nastavení logování Obnovit výchozí Chyba NSClienta. Zvažte restart NS a NSClienta. - Časový posun - Upozornit později na bolus Preferovaný režim APS Výsledek Kalk @@ -723,11 +620,6 @@ Změna letního času za méně než 3 hodiny – Uzavřená smyčka zastavena omezení vnitřního úložiště Uvolněte alespoň %1$d MB z vnitřního úložiště! Smyčka zakázána! - Chybný formát - Trvání dočasného bazálu musí být násobkem %1$d minut a musí být větší než 0. - Nesprávný kód. Příkaz zrušen. - Není nakonfigurováno - Přepnutí profilu vytvořeno Kontrola verze stará verze velmi stará verze @@ -744,12 +636,10 @@ Kalkulátor provede výpočet, ale dodána je pouze tato část inzulínu. Výhodné při používání SMB algoritmu. Ztišit Zvýšena hodnota maximálního bazálu, protože nastavení je nižší než Vaše maximální hodnota bazální profilu - Neplatné tělo zprávy %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Jméno profilu: Vybráno: Jednotky @@ -803,27 +693,6 @@ Čas provedení SMB Čas požadavku dočasného bazálu Čas provedení dočasného bazálu - - z aplikace Authenticator pro: %1$s následováno kódem PIN - Další povinný kód PIN na konci tokenu - Další číslice, které by měly být zapamatovány a přidány na konec každého vygenerovaného jednorázového hesla - Nastavení Autentikátoru - Kód pro kontrolu: - OTP + PIN - Ověřovací kód se skládá ze 6 číslic zobrazených aplikací Authenticator (známé jako OTP) následované 3 nebo více číslicemi povinného kódu PIN. - Resetovat autentikátory - Resetovat klíč pro autentikátory - Opravdu chcete obnovit ověřovací klíč? Vyresetujete všechny aktuálně nakonfigurované autentikátory a budete je muset znovu nastavit. - Byl vygenerován nový klíč autentikátoru! Prosím, použijte aktualizovaný QR kód pro nastavení autentikátorů. - Export OTP tajného klíče - Jste si jisti, že chcete zkopírovat tajný OTP klíč do schránky?\n\nPravděpodobně to budete potřebovat pouze v případě, když bude mít vaše ověřovací aplikace problém se skenováním QR kodu, chcete ho zadat ručně, nebo chcete nakonfigurovat hardwarový OTP token pomocí specializované aplikace. - Tajné OTP heslo (ve formátu Base32) bylo vyexportováno a zkopírováno do schránky. Vložte ho do autentikátoru nebo programátoru OTP hardwaru! - 1. Nainstalujte Autentikátor - 2. Naskenujte kód pro nastavení kódů OTP AAPS - 3. Otestujte jednorázové heslo - Resetovat autentikátory - Na každém sledovacím telefonu nainstalujte Authentikátor, který podporuje tokeny TOTP RFC 6238. Nejoblíbenější bezplatné aplikace jsou:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator - Obnovením autentikátoru uděláte všechny již poskytnuté autentikátory neplatné. Budete je muset znovu nastavit! Predikce Ošetření Odchylka sklonu @@ -854,21 +723,10 @@ Filtr Nelze vytvořit profil. Profil je neplatný. Nezabíjet mou aplikaci? - Odeslat SMS, pokud je detekována nedostupná pumpa - Nahlásit nedostupnou pumpu Spustit alarm, když je čas na jídlo - Spustit alarm za %1$d min - Poradce pro bolus - Máte vysokou glykémii. Namísto jídla doporučujeme vyčkat na lepší glykémii a připomenout, až bude čas na jídlo. Přejete si poslat korekční bolus a připomenout, až bude čas k jídlu? V tomto případě nebudou zapsané žádné sacharidy, a později opět musíte spustit kalkulátor, jakmile vám to připomeneme. - Povolit poradce s bolusem - Při vysoké glykémii použijte připomenutí, abyste začali jíst později, namísto výsledku z kalkulátoru („prebolus“) Čas k jídlu!\nSpusťte Bolusovou kalkulačku a proveďte výpočet znovu. - Čas k jídlu - Připomenutí bolusu Povolit připomínání bolusu - Použijte připomenutí pro pozdější bolus s kalkulátorem - (\"zpožděný bolus\") - Čas na bolus!\nSpusťte Bolusovou kalkulačku a proveďte výpočet znovu. + Použijte připomenutí pro pozdější bolus s kalkulátorem (\"zpožděný bolus\") Nahrávání protokolů o pádech zakázáno! Graf Možnosti grafu @@ -905,8 +763,6 @@ Přijmout léčebné události (výměna setu, inzulínu, baterie atd.) zadané prostřednictvím NS nebo NSClienta Přijímat/doplňovat glykémie Přijmout CGM data z NS - Vypršel časový limit při čekání na dokončení předchozí komunikace s pumpou - Ve frontě je další bolus. Zkuste to znovu později. Probíhá výpočet Chybí název profilu Chyba v hodnotách sach. poměru @@ -951,7 +807,6 @@ inzulín glykémie zastaralé - nastavit připomenutí přidat nový profil klonovat aktuální profil odstranit aktuální profil @@ -1010,7 +865,6 @@ Zobrazit smyčku Vybráno: %1$d Seřadit - Dialog zrušen Velmi nízká Nízká Vysoká @@ -1029,7 +883,6 @@ Přihlášení Odstranit vše Resetovat start - QR kód pro nastavení jednorázového hesla otevřít nastavení nastavit upozornění na sacharidy Vše @@ -1046,7 +899,6 @@ Zablokováno možností nabíjení Zablokováno možností připojení (Žádné hodinky nejsou připojeny) - Chyba žádosti o oprávnění Upravit citlivost a glykémii Vyčištění databáze Chcete vyčistit databázi?\nOdstraní sledované změny a historická data starší než 3 měsíce. diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index 0a7e65b4c5..686ea11617 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -13,7 +13,6 @@ Nulstil databaser Er du sikker på, at du vil nulstille databaserne? Afslut - Denne enhed synes ikke at understøtte batterioptimering whitelisting - du kan opleve problemer med ydeevnen. Nogle knapper til hurtigt at få adgang til almindelige funktioner Bruges til at konfigurere de aktive plugins Oplæringsprogram @@ -44,7 +43,6 @@ Insulin: Kulhydrater: IOB: - IOB: Total IOB: Total IOB aktivitet: Tid: @@ -52,9 +50,7 @@ Ins: IOB: Total IOB: - BG Midlertidig Mål - Kulhydrater Korrektion Bolus IOB Kør nu @@ -71,7 +67,6 @@ Ingen glukosedata tilgængelig Anmod Delta - Delta: Konfigurations bygger Overblik Behandlinger @@ -92,13 +87,9 @@ Sikkerhed Plugin deaktiveret Begrænsninger overtrådt - Bolus fejl. Undersøg manuelt hvor meget insulin der er givet Acceptér ny midlertidig basal: Behandling Beregner - Begrænsning anvendt! - Bolus: - Basal: Skift dit input! BG kilde xDrip+ @@ -111,13 +102,10 @@ Kulhydrat Forslag Ikke understøttet version af Nightscout Basal IOB - Bolus begrænsning påført - Kulhydrat begrænsning påført Andet Meter Sensor Kulhydrat tid - Varighed Profil Glukose type Midlertidig basal @@ -157,60 +145,6 @@ JEG FORSTÅR OG ER ENIG Gem Genindlæs profil - SMS Kommunikator - Tilladte telefonnumre - +XXXXXXXXXX;+YYYYYYYY - For at levere bolus %1$.2fIE svar med koden %2$s - For at levere måltidsbolus %1$.2fE svar med koden %2$s - For at indstille midlertidig mål %1$s svar med koden %2$s - For at annullere midlertidig mål, svar med koden %1$s - For at deaktivere SMS fjernstyring svar med koden %1$s.\n\nHusk på, at du kun vil være i stand til at genaktivere den direkte fra AAPS-master-smartphone. - SMS fjernstyring stoppet. For at genaktivere det, brug AAPS på master smartphone. - For at sende kalibrering %1$.2f svar med kode %2$s - Bolus mislykkedes - Mindste antal minutter, der skal gå mellem én fjernbolus og den næste - Hvor mange minutter der mindst skal gå mellem en bolus og den næste - Af hensyn til din sikkerhed, skal du tilføje mindst 2 telefonnumre for at redigere denne præference. - Leverer %1$.2f IE - Bolus %1$.2fIE leveret succesfuldt - Måltidsbolus %1$.2f IE leveret uden fejl - Mål %1$s i %2$d minutter - Mål %1$s i %2$d minutter er angivet succesfuldt - Midlertidig mål er annulleret succesfuldt - Tillad fjernkommandoer via SMS - Loop er blevet deaktiveret - Loop er blevet aktiveret - Loop er aktiveret - For at forbinde pumpen svar med koden %1$s - Forbindelse til pumpe mislykkedes - For at frakoble pumpen i %1$d minutter, svar med kode %2$s - Pumpe afbrudt - Pumpe tilsluttet igen - Fjernkommandoen er ikke tilladt - Fjernbolus er ikke tilgængelig. Prøv igen senere. - For at starte basal %1$.2f E/t i %2$d minutter svar med kode %3$s - For at skifte profil til %1$s %2$d%% svar med kode %3$s - For at starte udvidet bolus %1$.2f IE i %2$d minnutter svar med koden %3$s - For at indtaste %1$dg ved %2$s svar med kode %3$s - For at starte basal %1$d%% i %2$d minutter svar med kode %3$s - For at suspendere loop i %1$d minutter svar med kode %2$s - For at genoptage loop svar med koden %1$s - For at aktivere loop svar med kode %1$s - For at deaktivere loop, svar med kode %1$s - Temp basal %1$.2fE/t i %2$d min startet med succes - Udvidet bolus %1$.2f IE for %2$d min er startet succesfuldt - Kulhydrater %1$d g angivet med succes - Indtastning af %1$dg kulhydrater mislykkedes - Midlertidig basal %1$d%% E/t i %2$d min startet med succes - Midlertidig basal start mislykkedes - Udvidet bolus start mislykkedes - For at annullere midlertidig blodsukkermål, svar med kode %1$s - For at stoppe forlænget bolus svar med koden %1$s - Midlertidig basal annulleret - Forlænget bolus annulleret - Annullering af midlertidig basal mislykkedes - Annullering af forlænget bolus mislykkedes - Ukendt kommando eller forkert svar Lynguide Indstillinger for lynguide Knap tekst: @@ -241,13 +175,9 @@ Send alle data igen Åbn indstillinger på ur Basalrate - Basal værdi under minimum. Profil ikke angivet! - BG: - Sidste BG: MM640g Igangværende Notifikation GAMLE DATA - %1$dmin siden Profil OpenAPS AMA Række af %1$d elementer.\nFaktisk værdi: @@ -267,7 +197,6 @@ BEHANDL OBJ UR - SMS Forkort titel Brug altid kort gennemsnitlig delta i stedet for simpel delta Nyttigt, når data fra ufiltrerede kilder som xDrip bliver støjende. @@ -281,13 +210,6 @@ Standardværdi: 2\nBolus snooze starter efter du har lavet et måltid bolus, så loop ikke modvirker lave midlertidige mål, når du lige har spist. Eksemplet her og standard er 2; så en 3 timers DIA betyder, at bolus snooze gradvist udfases over 1,5 timer (3DIA/2). Standardværdi: 3.0 (AMA) eller 8.0 (SMB). Dette er en indstilling for standardindvirkningen af kulhydrater pr. 5 minutter. Standardværdien er en forventet 3mg/dl/5min. Det påvirker, hvor hurtigt COB er faldet, og hvor meget kulhydrat absorbering forudsættes ved beregning af forudsagt BG, når BG falder mere end forventet, eller ikke stiger så meget som forventet. Bemærk!\nNormalt behøver du ikke at ændre disse værdier nedenfor. KLIK HER og LÆS teksten og sørg for at du FORSTÅR den, før du ændrer nogen af disse. - Ugyldigt SMS telefonnummer - Kalibrering - xDrip+ ikke installeret - Kalibrering sendt til xDrip+ - Kalibrering sendt. Modtagelse skal være aktiveret i xDrip+. - xDrip+ modtager ikke kalibreringer - Pumpe er afbrudt Udfører Indstillinger for virtuel pumpe Upload status til NS @@ -323,10 +245,7 @@ Vælg venligst patienttype til opsætning af sikkerhedsgrænser Patientens navn Angiv venligst patientnavn eller kaldenavn for at skelne mellem flere opsætninger - Bruger Glimp - Loop suspenderet - Suspenderet (%1$d m) Suspendér loop i 1t Suspendér loop i 2t Suspendér loop i 3t @@ -345,9 +264,6 @@ 10 timer Genoptag Genforbind Pumpe - Forkert varighed - Loop suspenderet - Loop genoptaget 15 min tendens COB Superbolus @@ -382,7 +298,6 @@ ABS AFVHÆL Om - Manglende sms tilladelse Manglende telefonstatus tilladelse xDrip-status (ur) xDrip Statuslinje (ur) @@ -454,14 +369,11 @@ Kontrolleringer fra Ur Sæt midlertidige mål og indtast behandlinger fra uret. Mad - g ]]> kJ En Pr Fedt - Kommando udføres lige nu - Manglende BS målinger Brug systemnotifikationer til advarsler og notifikationer Gradvis øg lydstyrken for advarsler og meddelelser Lokale advarsler @@ -539,9 +451,6 @@ Tillad automatisk nedbruds rapportering og funktionsbrug data som sendes til udviklerne via fabric.io tjenesten. Opdater venligst din Dexcom app til understøttet version Dexcom app er ikke installeret. - Start Aktivitets mål - Start \"Spiser snart\" mål - Midlertidig Mål Ikke bolus, registrer kun Kategori Underkategori @@ -554,8 +463,6 @@ Aktive kulhydrater Aktivt insulin Basaler - Ingen handling valgt, intet vil ske - Begynd Hypo mål Kører dev version. Lukket loop er deaktiveret. Engineering mode aktiveret Profilskift mangler. Venligst lav et profilskift eller tryk \"Aktiver profil\" i LokalProfil. @@ -574,7 +481,6 @@ Begrænser IOB til %1$.1f IE på grund af %2$s max værdi i præferencer hård grænse - Læs status mislykkedes Registrer skift af infusionssæt Registrer skift af insulinampul SMB altid og efter kulhydrater deaktiveret, fordi den aktive BS kilde ikke understøtter avanceret filtrering @@ -631,12 +537,7 @@ Konfigurer venligst din RileyLink nedenfor. Når du har valgt en RileyLink, vil det være muligt at fortsætte opsætningen, når RileyLink-status er \"Tilsluttet\". Dette kan tage et minut.\n Bemærk: Du kan fortsætte opsætningen, når pumpen er konfigureret.\n Start dit første mål - Tilladelse Anmod om tilladelse - Applikationen mangler system vindues tilladelse til notifikationer - Applikationen mangler lokations tilladelse til BT scanning og WIFI identifikation - Applikationen mangler lagerstyrings tilladelse for at gemme logfiler og exporteringsindstillinger - Anmod Åbn navigation Luk navigation Plugin indstillinger @@ -678,8 +579,6 @@ Log indstillinger Nulstil til standardindstillinger NSClient funktionsfejl. Overvej NS og NSClient genstart. - Tidsforskydning - Påmind om at bolus senere Foretrukket APS-tilstand I alt Beregn @@ -709,11 +608,6 @@ Sommertids ændring mindre end 3 timer siden - Lukket loop deaktiveret begrænsning af intern lagerplads Frigør mindst %1$d MB fra intern lagerplads! Loop deaktiveret! - Forkert Format - TBR-varigheden skal være et multiplum af %1$d minutter og større end 0. - Forkert kode. Kommandoen annulleret. - Ikke konfigureret - Profil switch oprettet Versionstjek gammel version meget gammel version @@ -730,12 +624,10 @@ Bolus guiden udfører beregning, men kun denne del af beregnet insulin leveres. Nyttig med SMB algoritme. Udsæt Stigende max basal værdi, fordi indstillingen er lavere end din max basal i profil - Ugyldigt beskedindhold %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min. Profilnavn: Valgt: Enheder @@ -788,25 +680,6 @@ SMB udførelsestid Midlertidig basal anmodningstid Midlertidig basal afviklingstid - - fra Authenticator app til: %1$s efterfulgt af PIN - Yderligere obligatorisk pinkode i slutningen - Yderligere cifre, der skal huskes og påsættes i slutningen af hver genereret engangsadgangskode - Authenticator opsætning - Kode, der skal kontrolleres: - OTP + PIN - Bekræftelseskoden består af 6 cifre som vises af Autentificerings-app (kendt som OTP) efterfulgt af 3 eller flere cifre i obligatorisk PIN-kode. - Nulstil Autentificering - Nulstil Autentificeringsnøgle - Er du sikker på at du vil nulstille autentificeringsnøgle? Det vil gøre alle aktuelt konfigurerede autentificatorer ugyldige, og du bliver nødt til at sætte dem op igen. - Ny autentificeringsnøgle blev genereret! Brug venligst opdateret QR kode til at levere autentificatorer. - Eksporterer OTP hemmelighed - Er du sikker på, at du vil kopiere OTP hemmelighed til udklipsholderen?\n\nDu behøver den kun, hvis din autentificeringsapp har problemer med at scanne QR kode, du vil indtaste den manuelt, eller du vil konfigurere hardware OTP token ved hjælp af en dedikeret app. - OTP hemmelige (i Base32 format) eksporteret og kopieret til udklipsholder. Indsæt det i autentifikatoren eller hardware OTP brænder! - 1. Installer Authenticator - 3. Test Engangsadgangskode - Nulstil Autentificering - På hver follower telefon installeres Authenticator app, der understøtter RFC 6238 TOTP tokens. Populære gratis apps er:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Forudsigelser Behandlinger Afvigelses hældning @@ -837,21 +710,9 @@ Filter Kunne ikke oprette profil. Profilen er ugyldig. Luk ikke min app? - Send sms, hvis der udløses en utilgængelig pumpebegivenhed - Rapportér pumpe utilgængeligt Kør alarm når det er tid til at spise - Kør alarm om %1$d min - Bolus rådgiver - Du har høj glycæmi. I stedet for at spise nu anbefales det at vente på bedre glycæmi. Ønsker du at lave en korrektionsbolus nu og minde dig om, hvornår det er tid til at spise? I dette tilfælde vil ingen kulhydrater blive registreret, og du skal bruge guiden igen, når vi påminder dig. - Aktiver bolus rådgiver - Brug påmindelse om at begynde at spise senere i stedet for guiden under høj glykæmi (\"pre-bolus\") Tid til at spise!\nKør Bolus guiden og lav beregning igen. - Tid til at spise - Boluspåminder Aktivér boluspåminder - Brug påmindelse til bolus senere med guiden - (\"post-bolus\") - Tid til bolus!\nKør Bolus-guiden og lav beregningen igen. Upload af Crash logs deaktiveret! Graf Diagrammenu @@ -888,8 +749,6 @@ Accepter terapihændelser (Kanyle, insulin, batteriskift osv.), der indtastes gennem NS eller NSClient Modtag/tilbagefyld CGM-data Accepter CGM-data fra NS - Timeout mens du venter på afslutning af tidligere pumpe kommunikation - Der er en anden bolus i kø. Prøv igen senere. Beregning i gang Manglende profilnavn Fejl i IC-værdier @@ -934,7 +793,6 @@ insulin blodglucose forældet - Indstil påmindelse tilføj ny profil klon nuværende profil slet nuværende profil @@ -993,7 +851,6 @@ Vis loop %1$d valgt Sortér - Dialog annulleret Meget lav Lav Høj @@ -1011,7 +868,6 @@ Log ind Fjern alle Nulstil start - QR-kode til opsætning af engangs kodeord Åbn indstillinger indstil KH alarm Alle diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 535ac15aed..17ab38bf87 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -13,7 +13,6 @@ Datenbanken zurücksetzen Möchtest du die Datenbank wirklich zurücksetzen? Schließen - Dieses Gerät scheint keine Deaktivierung der Energieoptimierung zu unterstützen - das könnte zu Leistungsproblemen führen. Einige Schaltflächen, um auf häufig verwendete Funktionen zugreifen zu können. Dient zum Konfigurieren der aktiven Plugins Das Programm kennenlernen @@ -44,7 +43,6 @@ Insulin: Kohlenhydrate: IOB: - IOB: Gesamt IOB: Ges. IOB Aktivität: Dauer: @@ -52,9 +50,7 @@ Ins: IOB: Gesamt IOB: - BZ TT - Kohlenhydrate Korr Bolus-IOB Ausführen @@ -71,7 +67,6 @@ Keine BZ-Werte verfügbar Anfrage Delta - Delta: Konfiguration Übersicht Behandlungen @@ -92,13 +87,9 @@ Sicherheit Plugin ist deaktiviert Beschränkungen wurden verletzt oder Limit erreicht. - Fehlermeldung Bolusabgabe. Prüfe manuell die tatsächlich abgegebene Menge. Akzeptiere neue TBR: Bolus Rechner - Beschränkung angewendet! - Bolus: - Basal: Ändere deine Eingabe! BZ-Quelle xDrip+ @@ -111,13 +102,10 @@ Kohlenhydrate Vorschlag Nicht unterstützte Nightscout-Version Basal-IOB - Bolus-Beschränkung angewendet - Kohlenhydrat-Beschränkung erreicht Anderes Messgerät Sensor KH-Zeit - Dauer Profil Glukoseart TBR @@ -157,60 +145,6 @@ Ich verstehe und stimme zu. Speichern Profil neuladen - SMS-Kommunikator - Erlaubte Telefonnummern - +XXXXXXXXXX;+YYYYYYYYYY - Um einen Bolus von %1$.2f IE abzugeben, antworte mit dem Code %2$s. - Um einen Mahlzeitenbolus von %1$.2f IE abzugeben, antworte mit dem Code %2$s. - Um ein temporäres Ziel von %1$s zu setzen, antworte mit dem Code %2$s - Um das temporäre Ziel zu stoppen, antworte mit dem Code %1$s - Um die SMS-Fernsteuerung zu deaktivieren, antworte mit dem Code %1$s\n\nBeachte, dass Du diesen nur am AAPS-Master-Smartphone wieder aktivieren kannst. - SMS-Fernsteuerung gestoppt. Verwende das AAPS-Master-Smartphone, um sie wieder zu aktivieren. - Um die Kalibrierung %1$.2f zu senden, antworte mit dem Code %2$s. - Bolus fehlgeschlagen - Minimale Dauer in Minuten, die nach einem Remote-Bolus verstrichen sein muss, bevor ein neuer abgegeben werden kann. - Anzahl der Minuten, die mindestens zwischen zwei Remote-Bolusabgaben liegen müssen. - Aus Sicherheitsgründen musst Du mindestens zwei Telefonnummern eintragen, um diese Voreinstellung zu ändern. - Werde %1$.2f IE abgeben - Bolus %1$.2f IE erfolgreich abgegeben - Mahlzeiten-Bolus %1$.2f IE erfolgreich abgegeben - Ziel %1$s für %2$d Minuten - Ziel %1$s für %2$d Minuten erfolgreich gesetzt. - Temporäres Ziel wurde erfolgreich abgebrochen - Erlaube Fernsteuerung per SMS - Loop wurde deaktiviert. - Lopp wurde aktiviert. - Loop ist aktiviert. - Um die Pumpe zu verbinden, antworte mit dem Code %1$s - Verbindung zur Pumpe fehlgeschlagen - Um die Verbindung zur Pumpe für %1$d Minuten zu trennen, antworte mit dem Code %2$s - Verbindung zur Pumpe getrennt - Verbindung zur Pumpe wiederhergestellt - Ferngesteuerte Befehle sind nicht erlaubt. - Bolusabgabe aus der Ferne nicht verfügbar. Versuche es später erneut. - Um eine Basalrate von %1$.2f IE/h für %2$d Minuten zu setzen, antworte mit dem Code %3$s - Um das Profil auf %1$s %2$d%% zu setzen, antworte mit dem Code %3$s - Um einen Verzögerungs-Bolus von %1$.2f IE über %2$d Minuten abzugeben, antworte mit dem Code %3$s - Um %1$dg Kohlenhydrate um %2$s einzugeben, antworte mit dem Code %3$s - Um die Basalrate von %1$d%% für %2$d Minuten zu setzen, antworte mit dem Code %3$s - Um das Loopen für %1$d Minuten zu pausieren, antworte mit dem Code %2$s. - Um den Loop fortzusetzen, antworte mit dem Code %1$s - Um den Loop zu aktivieren, antworte mit dem Code %1$s - Um den Loop zu deaktivieren, antworte mit dem Code %1$s - TBR mit %1$.2f IE/h für %2$d min wurde erfolgreich gestartet. - Der erweiterte Bolus %1$.2f IE/h für %2$d Minuten wurde erfolgreich gestartet - %1$d g Kohlenhydrate erfolgreich erfasst - Eingabe von %1$d g Kohlenhydraten ist fehlgeschlagen. - Die temporäre Basalrate wurde erfolgreich für %2$d Minuten auf %1$d%% gesetzt. - Das Starten der TBR ist fehlgeschlagen. - Die Abgabe des erweiterten Bolus ist fehlgeschlagen. - Antworte mit dem Code %1$s, um die temporäre Basalrate zu beenden. - Antworte mit dem Code %1$s, um den erweiterten Bolus zu beenden. - TBR abgebrochen - Die Abgabe des erweiterten Bolus wurde abgebrochen. - Das Abbrechen der TBR ist fehlgeschlagen. - Der Abbruch des erweiterten Bolus ist fehlgeschlagen. - Unbekannter Befehl oder falsche Antwort QuickWizard QuickWizard-Einstellungen Schaltflächen-Text: @@ -241,13 +175,9 @@ Alle Daten erneut senden Öffne Einstellungen auf der Uhr Basalrate - Wert der Basalrate unter Minimum. Profil nicht gesetzt! - BZ: - Letzter BZ: MM640g Anhaltende Benachrichtigung VERALTETE DATEN - %1$d\' her Profil OpenAPS AMA Array mit %1$d Elementen.\nWert: @@ -267,7 +197,6 @@ BEH ZIEL UHR - SMS Kurze Tab-Überschriften Verwende immer das kurze durchschnittliche Delta statt des einfachen Deltas Das ist sinnvoll, wenn die Daten von einer ungefilterten Quelle wie xDrip+ Signalrauschen haben. @@ -281,13 +210,6 @@ Standarwert: 2\nBolus snooze (\"Bolus-Schlummer\") bremst den Loop nach einem Mahleiten-Bolus, damit dieser nicht mit niedrigen TBR reagiert, wenn Du gerade gegessen hast. Beispiel: Der Standardwert 2 bewirkt, dass bei einem 3 Stunden DIA der Bolus snooze während 1.5 Stunden nach dem Bolus linear ausläuft (3 h Dia / 2 = 1.5 h Bolus snooze). Standardwert: 3.0 (AMA) or 8.0 (SMB)\nDies ist eine Einstellung für die Standard-Kohlenhydrat-Absorptionswirkung pro 5 Minuten. Der Standardwert ist 3 mg/dl/5min (AMA) bzw. 8 mg/dl/5min (SMB). Dies wirkt sich darauf aus, wie schnell der COB-Wert fällt und wieviel KH-Absorption bei der Berechnung des vorhergesagten BZ angenommen wird, wenn der BZ stärker als erwartet fällt oder nicht so stark wie erwartet steigt. Achtung!\nNormalerweise musst Du diese Werte nicht ändern. Bitte KLICKE HIER und LESE den Text. Verändere Werte erst, wenn Du den Inhalt des Textes verstanden hast. - Falsche/ungültige Telefonnummer - Kalibrierung - xDrip+ nicht installiert - Kalibrierung an xDrip+ gesendet+ - Kalibrierung gesendet. Das Empfangen von Kalbrierungen muss in xDrip+ aktiviert sein+. - xDrip+ erhält keine Kalibrierungen - Pumpe pausiert Wird ausgeführt Einstellungen der virtuellen Pumpe Status zu Nightscout hochladen @@ -323,10 +245,7 @@ Bitte wähle den Patiententyp, um die Sicherheits-Limits festzulegen Name des Patienten Bitte gib den Namen des Patienten oder einen Spitznamen an, um mehrere Setups unterscheiden zu können. - Nutzer Glimp - Loop pausiert - Pausiert (%1$d min) Pausiere Loop für 1 h Pausiere Loop für 2 h Pausiere Loop für 3 h @@ -345,9 +264,6 @@ 10 Std. Fortsetzen Pumpe erneut verbinden - Falsche Dauer - Loop pausiert - Loop wurde fortgesetzt 15 min Trend COB Superbolus @@ -382,7 +298,6 @@ ABS DEVSLOPE Über - SMS-Steuerung nicht erlaubt Fehlende Berechtigung für den Zugriff auf den Telefonstatus xDrip+ Status (Uhr) xDrip+ Statuszeile (Uhr) @@ -454,14 +369,11 @@ Steuerung durch die Uhr Setze temporäre Ziele und Behandlungen mit der Uhr Essen - g ]]> kJ En Prot Ft - Befehl wird zurzeit ausgeführt - BZ-Werte fehlen Benutze Systemmeldungen für Alarme und Meldungen Lautstärke für Alarme und Benachrichtigungen schrittweise erhöhen Lokale Alarme @@ -539,9 +451,6 @@ Erlauben, dass automatische Fehler-Berichte und Nutzungsstatistiken an die Entwickler über den Service von Fabric.io gesendet werden Bitte aktualisiere deine Dexcom App auf eine unterstützte Version Dexcom App ist nicht installiert. - Starte Aktivitäts-TT - Starte Essens-TT - TT Bolus nur erfassen Kategorie Unterkategorie @@ -554,8 +463,6 @@ Aktive Kohlenhydrate Aktives Insulin Basal - Keine Aktion ausgewählt, nichts wird geschehen. - Starte Hypo-TT Entwickler-Version, Closed Loop ist nicht verfügbar. Entwickler-Modus aktiviert Profil-Wechsel fehlt, bitte nimm einen Profil-Wechsel vor oder drücke \"AKTIVIERE PROFIL\" im lokalen Profil. @@ -574,7 +481,6 @@ Begrenze IOB auf %1$.1f IE wegen %2$s Max. Wert in den Einstellungen festem Grenzwert - Lesen des Status fehlgeschlagen Katheter-Wechsel erfassen Reservoir-Wechsel erfassen SMB wird immer und nach Kohlenhydraten deaktiviert, weil die aktive BZ-Quelle keine geeignete Filterung der Werte unterstützt. @@ -631,12 +537,7 @@ Bitte konfiguriere Deinen RileyLink unten. Nachdem Du einen RileyLink ausgewählt hast, kannst Du die Installation fortsetzen, sobald der RileyLink-Status \"Verbunden\" ist. Das kann eine Minute dauern.\n Hinweis: Du kannst das Setup fortsetzen, sobald die Pumpe initialisiert wurde.\n Starte deine erste Zielsetzung - Berechtigung Nach Berechtigung fragen - Die App benötigt die Systemberechtigung für App-Benachrichtigungen - Die App benötigt die Berechtigung für den Standort, um Bluetooth und WLAN nutzen zu können - Die App benötigt Zugriffsrechte für den Speicher um Log-Dateien zu sichern und die Einstellungen zu exportieren. - Anfordern Menü öffnen Menü schließen Plugin-Einstellungen @@ -678,8 +579,6 @@ Log-Einstellungen Auf Standardwerte zurücksetzen NSClient Störung. Ziehe einen Neustart von NS und NSClient in Betracht. - Zeitversatz - Später an Bolus erinnern Bevorzugter APS-Modus Gesamt Berech. @@ -710,11 +609,6 @@ Unerwartetes Verhalten. Zeitumstellung vor weniger als 3 Stunden - Closed Loop deaktiviert interne Speicherbegrenzung Mindestens %1$d MB freier interer Speicher benötigt! Loop abgeschaltet! - Falsches Format - Die TBR-Dauer muss ein Vielfaches von %1$d Minuten und größer als 0 sein. - Falscher Code. Befehl wurde abgebrochen. - Nicht konfiguriert - Profilwechsel wurde erstellt Versionsprüfer Vorherige Version sehr alte Version @@ -731,12 +625,10 @@ Unerwartetes Verhalten. Der Bolus-Rechner führt Berechnungen durch, aber nur dieser Teil der berechneten Insulin wird abgegeben. Nützlich mit SMB-Algorithmus. Schlummern Der Wert max basal wird erhöht, weil Du ihn niedriger eingestellt hast als die höchste Basalrate in Deinem Profil. - Ungültiger Inhalt %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - Min. Profilname: Ausgewählt: Einheiten @@ -789,25 +681,6 @@ Unerwartetes Verhalten. SMB Ausführungszeit Temp. BR Anfragezeit Temp. BR Ausführungszeit - - von der Authenticator App für: %1$s gefolgt von der PIN - Zusätzliche obligatorische PIN am Token-Ende - Zusätzliche Ziffern, die auswendig gelernt und am Ende jedes generierten Einmal-Passworts angehängt werden sollten. - Konfiguration des Authentifikators - Zu prüfender Code: - OTP + PIN - Der Verifizierungscode besteht aus 6 Ziffern, die von Authenticator App (auch OTP genannt) angezeigt werden, gefolgt von 3 oder mehr Ziffern der obligatorischen PIN. - Authentifikators zurücksetzen - Authentifikatorschlüssel zurücksetzen - Willst Du wirklich den Authentifikatorschlüssel zurücksetzen? Dies wird alle momentan genutzten Authentifikatoren ungültig machen und Du musst sie neu einrichten. - Neuer Authentifizierungsschlüssel generiert! Bitte verwende den aktualisierten QR-Code für die Bereitstellung von Authentifikatoren. - OTP-Secret exportieren - Willst Du wirklich das OTP Secret in die Zwischenablage kopieren?\n\nDas ist nur erforderlich, wenn Deine Authentifizierungs-App Probleme mit dem Scannen des QR-Codes hat. Du kannst es auch manuell eingeben oder einen Hardware-OTP-Token mit einer bestimmten App verwenden. - OTP Secret (im Base32 Format) exportiert und in die Zwischenablage kopiert. Setze es von dort in Deine Authentifizierungs-App ein. - 1. Authentifikator installieren - 3. Teste das Einmal-Passwort - Authentifikators zurücksetzen - Installiere auf jedem Follower-Phone eine Authenticator-App, die RFC 6238 TOTP-Token unterstützt. Beliebte kostenlose Apps sind:\n Authy\n Google Authenticator\n LastPass Authenticator\n FreeOTP Authenticator Predictions (Vorhersagen) Behandlungen Steigung der Abweichung @@ -838,21 +711,9 @@ Unerwartetes Verhalten. Filter Profil kann nicht erstellt werden. Profil ist ungültig. Don\'t kill my app? - SMS senden, wenn Pumpe nicht erreichbar - Hinweis Pumpe nicht erreichbar Alarmiere mich, wenn es Zeit zum Essen ist. - Alarm in %1$d Min. - Bolus-Berater - Deine BZ-Werte sind hoch. Statt jetzt zu essen solltest Du abwarten, bis die Werte gesunken sind. Willst du jetzt einen Korrekturbolus abgeben und erinnert werden, wenn es Zeit zum Essen ist? In diesem Fall werden die Kohlenhydrate nicht übernommen und Du musst nach der Erinnerung den Bolus-Rechner erneut verwenden. - Bolus-Berater aktivieren - Option zur Erinnerung an späteres Essen (z.B. bei hohen BZ-Werten) im Bolus-Rechner (\"Spritz-Ess-Abstand\") Zeit zum Essen!\nStarte den Bolus-Rechner und gib die KH ein. - Zeit zum Essen - Bolus-Erinnerung Bolus-Erinnerung aktivieren - Erinnerung an späteren Bolus mit dem Assistenten verwenden - (\"Post-Bolus\") - Zeit für den nächsten Bolus!\nFühre den Bolus-Assistenten aus, um die Berechnung erneut durchzuführen. Hochladen von Crash-Protokollen deaktiviert! Diagramm Diagrammmenü @@ -889,8 +750,6 @@ Unerwartetes Verhalten.
    Ereignisse (Kanülen-, Ampullen-, Batteriewechsel etc.) akzeptieren, die in NS oder NSClient eingegeben wurden Historische CGM Daten ergänzen CGM Daten von NS akzeptieren - Zeitüberschreitung beim Warten auf das Ende der vorherigen Kommunikation mit der Pumpe - In der Warteschlange befindet sich ein weiterer Bolus. Bitte später erneut versuchen. Kalkulation wird gerade durchgeführt Fehlender Profilname Fehler in IC-Werten @@ -935,7 +794,6 @@ Unerwartetes Verhalten.
    Insulin Blutzucker veraltet - Erinnerung einstellen Neues Profil hinzufügen aktuelles Profil klonen (kopieren) aktuelles Profil löschen @@ -994,7 +852,6 @@ Unerwartetes Verhalten. Zeige Loop an %1$d ausgewählt Sortieren - Dialog abgebrochen Sehr niedrig Niedrig Hoch @@ -1012,7 +869,6 @@ Unerwartetes Verhalten. Login Alle entfernen Start zurücksetzen - QR Code für einmaliges Passwort einrichten Einstellungen öffnen setze Alarm für KH Timer Alle @@ -1029,6 +885,5 @@ Unerwartetes Verhalten. Blockiert durch Ladeoptionen Blockiert durch Verbindungsoptionen (keine Uhr verbunden) - Fehler beim Anfordern der Erlaubnis Empfindlichkeit und BZ anpassen diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index 5a98fb7105..8215365801 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -11,7 +11,6 @@ Επαναφορά Βάσεων Δεδομένων Θέλετε πραγματικά να επαναφέρετε την βάση δεδομένων; Έξοδος - Αυτή η συσκευή δεν φαίνεται να υποστηρίζει τη λίστα κατάτμησης βελτιστοποίησης μπαταρίας - ενδέχεται να αντιμετωπίσετε προβλήματα απόδοσης. Ορισμένα πλήκτρα για γρήγορη πρόσβαση σε κοινά χαρακτηριστικά Χρησιμοποιείται για ρύθμιση ενεργών συνδέσεων Πρόγραμμα εκμάθησης @@ -38,7 +37,6 @@ Ινσουλίνη: Υδατάνθρακες: IOB: - IOB: Συνολική IOB: Συνολική δραστηριότητα IOB: Διάρκεια: @@ -46,9 +44,7 @@ Ins: IOB: Συνολική IOB: - BG TT - Υδατάνθρακες Διόρθωση Έναρξη τώρα ΕΙΚΟΝΙΚΗ ΑΝΤΛΙΑ @@ -64,7 +60,6 @@ Μη διαθέσιμα δεδομένα γλυκόζης Αίτημα Διαφορά - Διαφορά: Διαμόρφωση Επισκόπηση Θεραπείες @@ -88,9 +83,6 @@ Αποδοχή νέου Προσ Ρυθμού: Θεραπεία Υπολογιστής - Εφαρμόστηκαν Περιορισμοί! - Bolus: - Βασικός Ρυθμός: Αλλάξτε αυτό που εισάγατε! Πηγή BG Λειτουργία APS @@ -100,12 +92,9 @@ Νέα πρόταση διαθέσιμη Μη υποστηριζόμενη έκδοση Nightscout Βασική ΙΟΒ - Ενεργός Περιορισμός Bolus - Ενεργός περιορισμός Υδατανθράκων Άλλο Μετρητής Αισθητήρας - Διάρκεια Τύπος Γλυκόζης Προσ Ρυθμός Εκτεταμμένο Bolus @@ -124,33 +113,6 @@ ΔΕΝ ΠΡΕΠΕΙ ΝΑ ΧΡΗΣΙΜΟΠΟΙΗΘΕΙ ΓΙΑ ΝΑ ΚΑΝΕΤΕ ΙΑΤΡΙΚΗ ΑΠΟΦΑΣΗ. ΔΕΝ ΥΠΑΡΧΕΙ ΕΓΓΥΗΣΗ ΓΙΑ ΤΟ ΠΡΟΓΡΑΜΜΑ, ΣΤΟ ΒΑΘΜΟ ΠΟΥ ΕΠΙΤΡΕΠΕΤΑΙ ΑΠΟ ΤΟ ΕΦΑΡΜΟΣΤΕΟ ΔΙΚΑΙΟ. ΕΚΤΟΣ ΟΠΟΙΑΣΔΗΠΟΤΕ ΔΙΑΒΑΘΜΙΣΜΕΝΗ ΚΑΤΑ ΤΗΝ ΕΓΓΡΑΦΗ ΤΩΝ ΚΑΤΟΧΟΙ ΠΝΕΥΜΑΤΙΚΩΝ ΔΙΚΑΙΩΜΑΤΩΝ ΚΑΙ/Ή ΑΛΛΑ ΜΕΡΗ ΠΑΡΕΧΟΝΤΑΙ ΤΟ ΠΡΟΓΡΑΜΜΑ \"ΩΣ ΕΧΕΙ\" ΧΩΡΙΣ ΕΓΓΥΗΣΗ ΟΠΟΙΟΥΔΗΠΟΤΕ ΕΙΔΟΥΣ, ΕΞΑΙΡΟΥΜΕΝΕΣ Ή ΣΙΩΠΗΡΕΣ, ΣΥΜΠΕΡΙΛΑΜΒΑΝΟΜΕΝΩΝ, ΕΝΔΕΙΚΤΙΚΑ, ΤΩΝ ΣΙΩΠΗΡΩΝ ΕΓΓΥΗΣΕΩΝ ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ΚΑΙ ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ ΣΥΓΚΕΚΡΙΜΕΝΟ ΣΚΟΠΟ. Ο ΟΛΟΚΛΗΡΩΜΕΝΟΣ ΚΙΝΔΥΝΟΣ ΟΣΟΝ ΑΦΟΡΑ ΤΗΝ ΠΟΙΟΤΗΤΑ ΚΑΙ ΤΗΝ ΑΠΟΔΟΣΗ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΕΙΝΑΙ ΔΙΚΟ ΣΑΣ. ΕΑΝ ΤΟ ΠΡΟΓΡΑΜΜΑ ΔΕΝ ΕΙΝΑΙ ΕΛΑΤΤΩΜΑΤΙΚΟ, ΠΡΕΠΕΙ ΝΑ ΕΞΕΤΑΣΤΕ ΤΟ ΚΟΣΤΟΣ ΟΛΩΝ ΤΩΝ ΑΠΑΡΑΙΤΗΤΩΝ ΣΥΝΤΗΡΗΣΕΩΝ, ΕΠΙΣΚΕΥΩΝ Ή ΔΙΟΡΘΩΣΕΩΝ. ΚΑΤΑΛΑΒΑ ΚΑΙ ΣΥΜΦΩΝΩ Ξαναφορτώστε το προφίλ - SMS Επικοινωνία - Επιτρεπτά τηλεφωνικά νούμερα - +XXXXXXXXXX;+YYYYYYYYYY - Για έγχυση bolus %1$.2fU στείλτε με κωδικό %2$s - Για αποστολή καλιμπραρίσματος %1$.2f στείλτε με κωδικό %2$s - Αποτυχία Bolus - Άδεια για απομακρυσμένες εντολές μέσω SMS - Το κύκλωμα απενεργοποιήθηκε - Το κύκλωμα ενεργοποιήθηκε - Κύκλωμα ενεργοποιημένο - Δεν επιτρέπεται απομακρυσμένη εντολή - Απομακρυσμένο bolus μη διαθέσιμο. Δοκιμάστε ξανά αργότερα. - Για αλλαγή προφίλ σε %1$s %2$d%% στείλτε κωδικό %3$s - Για έναρξη βασικού %1$d%% για %2$d λεπτά στείλτε κωδικό %3$s - Για αναστολή κυκλκώματος για %1$d λεπτών στείλτε με κωδικό %2$s - Προσωρινός Ρυθμός %1$.2fU/h για %2$d λεπτά ξεκίνησε επιτυχώς - Εκτεταμένο bolus %1$.2fU για %2$d λεπτά ξεκίνησε επιτυχώς - Προσωρινός Ρυθμός %1$d%% για %2$d λεπτά ξεκίνησε επιτυχώς - Εκκίνηση Προσωρινού Ρυθμού απέτυχε - Έναρξη εκτεταμένου bolus απέτυχε - Για κλείσιμο Προσωρινού Ρυθμού στείλτε κωδικό %1$s - Για κλείσιμο Εκτεταμένου bolus στείλτε κωδικό %1$s - Ο Προσωρινός Ρυθμός ακυρώθηκε - Εκτεταμένο bolus ακυρώθηκε - Ακύρωση Προσωρινού Ρυθμού απέτυχε - Η ακύρωση του Εκτεταμένου bolus απέτυχε - Άγνωστη εντολή ή λάθος απάντηση Γρήγορος Οδηγός Ρυθμίσεις Γρήγορου Οδηγού Κείμενο στο πλήκτρο: @@ -174,13 +136,9 @@ Wear Ξαναστείλτε όλα τα Δεδομένα Ρυθμίσεις στο Wear - Τιμή βασικού κάτω από το ελάχιστο. Δεν έχει ρυθμιστεί το προφίλ! - BG: - Τελευταία BG: MM640g Συνεχής Ειδοποίηση Παλιά Δεδομένα - πριν από %1$d λεπτά OpenAPS AMA Πεδίο %1$d Στοιχεία.\nΤρέχουσα τιμή: Δεδομένα Autosens @@ -197,7 +155,6 @@ ΘΕΡΑΠ ΣΤΟΧΟΙ WEAR - SMS Συντομογραφίες ενοτήτων Χρησιμοποιείτε πάντα τη βραχυπρόθεσμη μέση διαφορά αντί της απλής διαφοράς Προφίλ @@ -209,10 +166,6 @@ Προεπιλεγμένη τιμή: 2\nΗ αναβολή Bolus ενεργοποιείται αφού κάνετε ένα γευματικό bolus, έτσι το κύκλωμα δεν θα εξουδετερώσει με χαμηλό προσωρινό μόλις έχετε φάει. Το παράδειγμα εδώ και η προεπιλογή είναι 2: έτσι μια τρίωρη DIA σημαίνει ότι το bolus αναβολής θα είναι σταδιακά πάνω από 1,5 ώρα (3DIA/2). Προεπιλεγμένη τιμή: 3.0 (AMA) ή 8.0 (SMB). Αυτό είναι μια ρύθμιση για την επίπτωση της προεπιλεγμένης απορρόφησης υδατανθράκων ανά 5 λεπτά. Η προεπιλογή είναι μια αναμενόμενη 3mg/dl/5min. Αυτό επηρεάζει το πόσο γρήγορα το COB ελλατώνεται, και πόση απορρόφηση υδατανθράκων θα υποθέτει για τον υπολογισμό της μελλοντικής πρόβλεψης BG, όταν το BG πέφτει περισσότερο από το αναμενόμενο ή δεν αυξάνεται όσο το αναμενόμενο. Προσοχή!\nΣυνήθως δεν χρειάζεται να αλλάξετε αυτές τις τιμές. Κάντε κλικ ΕΔΩ, ΔΙΑΒΑΣΤΕ τις πληροφορίες και σιγουρευτείτε ότι τις καταλαβαίνετε πριν τις αλλάξετε. - Μη έγκυρος αριθμός τηλεφώνου για SMS - Καλιμπράρισμα - xDrip+ μη εγκατεστημένο - Η αντλία είναι σε παύση Εκτελείτε Ρυθμίσεις Εικονικής αντλίας Φόρτωση κατάστασης στο NS @@ -243,8 +196,6 @@ Ενήλικας Αντίσταση ινσουλίνης ενηλίκων Glimp - Κύκλωμα σε αναστολή - Αναστολή (%1$d m) Κύκλωμα σε αναστολή για 1h Κύκλωμα σε αναστολή για 2h Κύκλωμα σε αναστολή για 3h @@ -256,9 +207,6 @@ Αποσύνδεση αντλίας για 3h Επαναφορά Επανασύνδεση αντλίας - Λάθος διάρκεια - Κύκλωμα σε αναστολή - Επαναφορά κυκλώματος COB Superbolus Η εφαρμογή καταγραφής ξεκινά από το NS @@ -273,7 +221,6 @@ Όριο προειδοποίησης χαμηλής αμπούλας [U] Όριο προειδοποίησης πολύ χαμηλής αμπούλας [U] Σχετικά με - Απουσία δικαιωμάτων SMS Λείπει η άδεια κατάστασης τηλεφώνου xds Δείξε BGI @@ -329,14 +276,11 @@ Έλεγχος από ρολόι Ρυθμίστε Στόχους-Προσ Ρυθμού και βάλτε Θεραπείες από το ρολόι. Γεύμα - g ]]> kj Ενέργεια Πρωτεΐνες Λίπος - Η εντολή εκτελείται τώρα - Χαμένες μετρήσεις BG Χρησιμοποιήστε ειδοποιήσεις συστήματος για ειδοποιήσεις και συναγερμούς Τοπικές Ειδοποιήσεις Προειδοποίηση αν δεν ληφθούν δεδομένα μετρήσεων BG @@ -396,9 +340,6 @@ Να επιτρέπεται η αυτόματη αποστολή αναφορών σφάλματος και χαρακτηριστικά χρήσης δεδομένων στους προγραμματιστές μέσω του fabric.io. service. Ενημερώστε την εφαρμογή G5 στην υποστηριζόμενη έκδοση Η εφαρμογή Dexcom δεν είναι εγκατεστημένη. - Εκκίνηση δραστηριότητας TT - Εκκίνηση Τρώω σύντομα ΤΤ - TT Μην κάνετε bolus, μόνο να καταγράφετε Κατηγορία Υποκατηγορία @@ -409,8 +350,6 @@ Ενεργοί Υδατάνθρακες Ενεργή Ινσουλίνη Βασικοί - Δεν έχει επιλεγεί καμία ενέργεια, δεν υπάρχει τίποτα να κάνει - Εκκίνηση TT Υπογλυκαιμίας Εκτελείται έκδοση Dev. Το κλειστό κύκλωμα είναι απενεργοποιημένο. Μηχανική λειτουργία ενεργοποιημένη Η αλλαγή προφίλ λείπει. Αλλάξτε το προφίλ ή πατήστε \"Ενεργοποίηση Προφίλ\" στο Τοπικό Προφίλ. @@ -429,7 +368,6 @@ Περιορίζεται η IOB σε %1$.1f U λόγω %2$s μέγιστη τιμή στις Επιλογές σταθερό όριο - Η ανάγνωση κατάστασης απέτυχε Καταγράψτε την αλλαγή της τοποθεσίας αντλίας Καταγράψτε την αλλαγή της τοποθεσίας καθετήρα Το SMB πάντα και μετά το γεύμα απενεργοποιείται επειδή η ενεργή πηγή BG δεν υποστηρίζει προηγμένο φιλτράρισμα @@ -478,9 +416,7 @@ Προσοχή: Τα νέα προφίλ ινσουλίνης απαιτούν DIA τουλάχιστον 5 ωρών. Η DIA 5-6 ώρες στα νέα προφίλ είναι ισοδύναμα με DIA των 3 ωρών στα παλιά προφίλ ινσουλινών. Επιλέξτε έναν από τους διαθέσιμους αλγόριθμους. Ταξινομούνται από το παλαιότερο στον νεότερο. Ένας νεότερος είναι συνήθως καλύτερος και πιο επιθετικός. Επομένως, αν είστε καινούριος στο κλειστό κύκλωμα, θα πρέπει πρώτα να επιλέξετε μόνο το AMA και όχι το τελευταίο. Μην ξεχάσετε να διαβάσετε το εγχειρίδιο του OpenAPS και να κάνετε τις ρυθμίσεις προτού αρχίσετε να το χρησιμοποιείτε. Ξεκινήστε τον πρώτο στόχο - Άδεια Ζητείστε άδεια - Αίτημα Άνοιγμα μενού πλοήγησης Κλείσιμο μενού πλοήγησης Επιλογές προσθήκης @@ -509,7 +445,6 @@ Ρυθμίσεις Αρχείου Καταγραφής Επαναφορά προεπιλογών Δυσλειτουργία NSClient. Εξετάστε την επανεκκίνηση του NS και του NSClient. - Χρονική μετατόπιση Προτιμώμενη λειτουργία APS Σύνολο Υπολογ @@ -537,10 +472,6 @@ Αποστολή BG βαθμονομήσεων περιορισμός εσωτερικής μνήμης Ελευθερώστε τουλάχιστον %1$d MB από εσωτερική μνήμη! Κύκλωμα απενεργοποιήθηκε! - Λάθος μορφή αρχείου - Λάθος κωδικός. Η εντολή ακυρώθηκε. - Δεν έχει ρυθμιστεί - Δημιουργήθηκε αλλαγή προφίλ Έλεγχος Έκδοσης παλιά έκδοση πολύ παλιά έκδοση @@ -550,13 +481,10 @@ Ο Υπολογισμός Bolus κάνει υπολογισμούς αλλά μόνο αυτό το μέρος της υπολογίσημης ινσουλίνης χορηγείται. Χρήσιμο με τον αλγόριθμο SMB. Αναβολή Αυξείστε την μέγιστη βασική τιμή, επειδή η ρύθμιση είναι χαμηλότερη από τη μέγιστη βασική στο προφίλ σας - Μη έγκυρο μήνυμα %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min - diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 7ca6808107..868dc35105 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -13,7 +13,6 @@ Restablecer las bases de datos ¿Realmente quiere restablecer las bases de datos? Salir - Este dispositivo no parece soportar la optimización de la batería por los ajustes - pueden ocurrir problemas de funcionamiento. Algunos botones para acceder rápidamente a funciones comunes Utilizado para configurar complementos activos Programa de aprendizaje @@ -42,11 +41,9 @@ Guarda todos los tratamientos que se realizaron Supervisar y controlar AAPS usando un reloj WearOS Mostrar información sobre tu lazo en tu esfera xDrip+ - Control remoto de AAPS usando comandos SMS. Insulina: Carbohidratos: IOB: - IOB: IOB total: Actividad total IOB: Dur: @@ -54,9 +51,7 @@ Ins: IOB: IOB Total: - BG OT - Carbohidratos Corrección Bolo IOB Ejecutar ahora @@ -73,7 +68,6 @@ No hay disponibles datos de glucosa Solicitud Delta - Delta: Tabla de configuraciones Inicio Tratamientos @@ -97,13 +91,9 @@ Seguridad El complemento está deshabilitado Violación de restricciones - El bolo reportó un error. Comprueba manualmente la cantidad real de insulina entregada Aceptar nueva basal temporal: Tratamiento Calculadora - Restricción aplicada! - Bolo: - Dosis Basal: ¡Cambiar datos! Origen de Glucosa ¿Desde dónde debería obtener AAPS los datos? @@ -117,13 +107,10 @@ Sugerencia de carbohidratos Versión de Nightscout no soportada Basal IOB - Restricción aplicada en bolo - Restricción aplicada en carbohidratos Otro Medidor Sensor Tiempo de absorción - Duración Perfil Tipo de glucosa Basal temporal @@ -163,60 +150,6 @@ LO ENTIENDO Y ACEPTO Guardar Recargar Perfil - Comunicador SMS - Números de teléfono permitidos - XXXXXXXXXX +; + YYYYYYYYYY - Para entregar bolo %1$.2fU responder con código %2$s - Para entregar bolo %1$.2fU responder con código %2$s - Para establecer un basal temporal %1$s responder con el código %2$s - Para cancelar la basal temporal, responder con el código %1$s - Para inhabilitar la respuesta de servicio remoto de SMS, responder con el código %1$s.\n\nTenga en cuenta que solamente será capaz de reactivarlo directamente desde el móvil con la AAPS maestro. - Servicio remoto de SMS detenido. Para reactivarlo, utilice AAPS en el movil maestro. - Para enviar calibración %1$.2f responder con código %2$s - Bolo fallido - Número mínimo de minutos que deben transcurrir entre un bolo remoto y el siguiente - Cuántos minutos deben transcurrir, al menos, entre un bolo y el siguiente - Por su seguridad, para editar esta preferencia es necesario añadir al menos 2 números de teléfono. - Entregando %1$.2f U - Bolo %1$.2fU entregado correctamente - Bolo de comida %1$.2f U entregado correctamente - Objetivo %1$s para %2$d minutos - Objetivo %1$s para %2$d minutos establecido correctamente - Objetivo temporal cancelado correctamente - Permitir comandos remotos vía SMS - El lazo se ha desactivado - El lazo se ha activado - Lazo activo - Para conectar la bomba, responder con el código %1$s - Error al conectar a la bomba - Para desconectar la bomba durante %1$dminutos, responde con el código %2$s - Bomba desconectada - Bomba reconectada - Comando remoto no permitido - El bolo remoto no está disponible. Inténtalo de nuevo más tarde. - Para iniciar una basal de %1$.2fU/h durante %2$d min, responder con el código %3$s - Para cambiar el perfil a %1$s %2$d%% responder con el código %3$s - Para iniciar un bolo extendido de %1$.2fU durante %2$d minutos, responder con el código %3$s - Para introducir %1$dg en %2$s, responder con el código %3$s - Para iniciar una basal de %1$d%% durante %2$d min, responder con el código %3$s - Para suspender el lazo durante %1$d minutos, responde con el código %2$s - Para reanudar el lazo, responde con el código %1$s - Para activar el lazo, responder con el código %1$s - Para desactivar el lazo, responder con el código %1$s - Basal temporal %1$.2fU/h durante %2$d minutos iniciada correctamente - Bolo extendido de %1$.2fU durante %2$d minutos se inició correctamente - Carbohidratos %1$d g ingresados correctamente - Error al introducir %1$dg de carbohidratos - Basal temporal de %1$d%% durante %2$d minutos iniciada correctamente - Error al iniciar la basal temporal - Error al iniciar el bolo extendido - Para cancelar la basal temporal, responder con el código %1$s - Para parar el bolo extendido, responder con el código %1$s - Basal temporal cancelada - Bolo extendido cancelado - Error al cancelar la basal temporal - Error al cancelar el bolo extendido - Comando desconocido o respuesta incorrecta Asistente Asistente de configuración Botón Texto: @@ -247,13 +180,9 @@ Reenviar todos los datos Abrir ajustes en el reloj Tasa Basal - Valor basal por debajo del mínimo. Perfil no establecido. - Glucosa: - Última Glucosa: MM640g Notificaciones en curso DATOS CADUCADOS - hace %1$d min Perfil OpenAPS AMA Matriz de %1$d elementos.\nValor actual: @@ -273,7 +202,6 @@ TRAT OBJ RELOJ - SMS Nombres cortos en pestañas Usar siempre el delta medio corto, en lugar del delta simple Útil cuando los datos de fuentes sin filtrar como los de xDrip+ son inestables @@ -287,13 +215,6 @@ Valor predeterminado: 2\nLa característica \"Bolus snooze\" (bolo de repetición) se activa después de suministrar un bolo de comida. Esto permite que durante el periodo de tiempo resultante de dividir el valor de DIA por este ajuste, AAPS no establezca basales temporales demasiado bajas. Por ejemplo, con el valor predeterminado 2 y un valor de DIA establecido en 5 horas, la duración del bolo de repetición resultante sería de 2,5 horas (5/2=2,5h), periodo en el cuál, las basales temporales no serán demasiado bajas. Valores predeterminados: 3.0 (AMA) y 8.0 (SMB)\nEsta configuración establece cómo se absorben los carbohidratos cada 5 minutos. Por defecto se espera que se absorban 3mg/dl cada 5 minutos. Esto afecta a la rapidez con la que los carbohidratos (COB) decaen, y cómo se calcula la predicción de la absorción de carbohidratos futuros, cuando la glucosa está cayendo más de lo esperado, o no aumenta tanto como se esperaba ¡ATENCIÓN!\nLos valores que se muestran a continuación, normalmente no suelen ser necesario modificarlos. Por favor, PINCHA AQUÍ y lee todo el contenido. Asegúrate de que lo has entendido completamente antes de modificar alguno de estos valores. - Número de teléfono incorrecto para SMS - Calibración - xDrip+ no instalado - Calibración mandada a xDrip+ - Calibración enviada. La recepción debe estar habilitada en xDrip+. - xDrip+ no está recibiendo calibraciones - Bomba parada Ejecutando Ajustes de bomba virtual Subir estado a Nightscout @@ -329,11 +250,7 @@ Por favor, selecciona el tipo de paciente para establecer los límites de seguridad Nombre del paciente Proporcione el nombre de paciente o el apodo para diferenciar entre varias configuraciones - Usuario Glimp - %1$s necesita añadir la optimización de la batería a la lista blanca, para obtener un rendimiento adecuado - Lazo suspendido - Desactivado (%1$d m) Suspender lazo durante 1 hora Suspender lazo durante 2 horas Suspender lazo durante 3 horas @@ -352,9 +269,6 @@ 10 horas Reanudar Vuelva a conectar la bomba - Duración incorrecta - Lazo suspendido - Lazo reanudado Tendencia 15min COB Superbolo @@ -389,7 +303,6 @@ ABS DEVSLOPE Acerca de - Falta permiso SMS Falta permiso de estado del teléfono Estado de xDrip+ (reloj) Línea de estado de xDrip+ (reloj) @@ -462,14 +375,11 @@ Control desde el reloj Establece objetivos temporales (OT) y añade tratamientos desde el reloj Comida - g ]]> kJ En Pr Grasa - Orden se esta efectuando en este momento - Faltan lecturas de glucosa Usa las notificaciones del sistema para las alarmas y las notificaciones Aumentar gradualmente el volumen de las alarmas y de las notificaciones Alarmas locales @@ -547,9 +457,6 @@ Permite que los informes de errores automáticos y los datos de uso de las funciones, se envíen a los desarrolladores mediante el servicio fabric.io Actualiza tu aplicación de Dexcom a una versión compatible La aplicación Dexcom no está instalada. - Iniciar OT Actividad - Iniciar OT Comiendo Pronto - OT No administrar bolo, sólo anotarlo Categoría Subcategoría @@ -562,8 +469,6 @@ Carbohidratos activos COB Insulina activa Basales - No se ha seleccionado ninguna opción, por lo que no se realizará ningún cambio - Iniciar OT Hipo Ejecutando la versión dev. Lazo cerrado no disponible. Modo de ingeniería activado Falta Cambio de Perfil. Haga un Cambio de Perfil o presione \"Activar perfil\" en PerfilLocal. @@ -582,7 +487,6 @@ Limitando IOB a %1$.1f U debido a %2$s valor máximo en preferencias límite estricto - Error al leer estado Anotar el cambio de sitio de la bomba Anotar cambio del cartucho de insulina SMB siempre y tras carbohidratos deshabilitados porque la fuente activa de glucosa no admite filtro avanzado @@ -640,12 +544,7 @@ Por favor, a continuación configure su RileyLink. Después de seleccionar un RileyLink, será posible continuar la configuración una vez que el estado de RileyLink esté en \"Conectado\". Esto podría tardar un minuto.\n Nota: Puede continuar con la configuración una vez que la bomba se haya configurado.\n Comienza tu primer objetivo - Permiso Pedir permiso - La aplicación necesita permisos del sistema para poder mostrarse sobre otras aplicaciones, para las notificaciones - La aplicación necesita permiso de ubicación para poder buscar dispositivos Bluetooth y redes WiFi - La aplicación necesita permiso de almacenamiento para poder almacenar archivos de registro y valores de exportación - Solicitar Abrir navegación Cerrar navegación Preferencias del complemento @@ -691,8 +590,6 @@ Ajustes de registros Restablecer valores predeterminados NSClient fallando. Considera reiniciar NS y NSClient. - Retardo - Recordar ejecutar el bolo más tarde Modo preferido de APS Total Cálculo @@ -723,11 +620,6 @@ Cambio al horario de verano hace menos de 3 horas - Lazo cerrado deshabilitado restricción de almacenamiento interno Libera al menos %1$d MB de almacenamiento interno. ¡Loop desactivado! - Formato incorrecto - La duración de TBR debe ser un múltiplo de %1$d minutos y mayor a 0. - Código incorrecto. Comando cancelado. - Sin configurar - Cambio de perfil creado Verificador de versión versión antigua versión muy antigua @@ -744,12 +636,10 @@ El asistente de bolos realiza el cálculo, pero solo se entrega esta parte de la insulina calculada. Útil con el algoritmo SMB. Silenciar Aumentar el valor basal máximo porque el ajuste es inferior a tu base máxima en el perfil - El cuerpo del mensaje es inválido %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Nombre del perfil: Seleccionado: Unidades @@ -803,27 +693,6 @@ Tiempo de ejecución de SMB Tiempo requerido para basal temporal Tiempo de ejecución para basal temporal - - desde la aplicación de autenticación para: %1$s seguido de PIN - PIN obligatorio adicional al final del token - Los dígitos adicionales se deben memorizar y pegar al final de cada una de las contraseñas generadas por One Time Password - Configuración de autentificación - Código para comprobar: - OTP + PIN - El código de verificación consta de 6 dígitos mostrados por la aplicación Authenticator (conocido como OTP) seguido de 3 o más dígitos del PIN obligatorio. - Restablecer autentificadores - Restablecer clave de autentificación - ¿Está seguro de que desea restablecer la clave del autenticador? Los autenticadores configurados actualmente no seran válidos, y tendrá que volver a configurarlos. - ¡Se ha generado una clave de autenticador nueva! Utilice QRCode actualizado para suministrar autenticadores. - Exportando OTP secreto - ¿Estás seguro que deseas copiar el secreto OTP al portapapeles?\n\nSólo lo necesitas si tu aplicación de autentificación tiene problemas para escanear el código QR, quieres introducirlo manualmente o quieres configurar el token de hardware OTP usando una aplicación dedicada. - OTP secreto (en formato Base32) exportado y copiado en portapapeles. Pegalo en el autenticador o grabador hardware OTP! - 1. Instalar autenticador - 2. Escanea el código para configurar los códigos AAPS OTP - 3. Probar la contraseña de Uso único - Restablecer autentificadores - En cada teléfono seguidor, instale la aplicación Authenticator que admita tokens RFC 6238 TOTP. Las aplicaciones gratuitas populares son:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator - Al reiniciar el autenticador, haces que todos los autenticadores previos no sean válidos. ¡Necesitarás configurarlos de nuevo! Predicciones Tratamientos Pendiente de desviación @@ -854,21 +723,9 @@ Filtro No se puede crear el perfil. El perfil es inválido. ¿No matar mi aplicación? - Enviar SMS si se activa un evento de bomba inaccesible - Reportar bomba inalcanzable Ejecutar alarma cuando es hora de comer - Ejecutar alarma en %1$d min - Asistente de bolo - Tienes la glucosa alta. En lugar de comer ahora, se recomienda esperar a tener un mejor valor de glucosa. ¿Quieres poner un bolo de corrección ahora y recibir un aviso cuando sea un buen momento para comer? En este caso no se registrarán los carbohidratos y deberás utilizar el asistente de bolos después de recibir la notificación - Habilitar asistente de bolo - Utiliza un recordatorio para empezar a comer más tarde, en lugar del resultado del asistente durante una glucemia alta (\"pre-bolo\") ¡Hora de comer!\nEjecutar el asistente de bolo y calcular de nuevo. - Hora de comer - Recordatorio de bolo Habilitar recordatorio de bolo - Usa recordatorio de bolo más tarde con el asistente - (\"post-bolus\") - ¡Hora de comer!\nEjecutar el asistente de bolo y calcular de nuevo. ¡Carga de registros de errores desactivada! Gráfico Menú gráfico @@ -905,8 +762,6 @@ Aceptar registros de terapia (cánula, insulina, cambios de batería, etc.) añadidos mediante Nightscout o NSClient Recibir/Rellenar datos del MCG Aceptar valores MCG desde Nightscout - Tiempo de espera agotado mientras finalizaba la comunicación anterior con la bomba - Hay otro bolo en cola. Inténtalo de nuevo más tarde. Cálculo en curso Falta el nombre de perfil Error en valores IC @@ -951,7 +806,6 @@ insulina glucosa en sangre desactualizado - establecer recordatorio añadir nuevo perfil clonar el perfil actual borrar el perfil actual @@ -1010,7 +864,6 @@ Mostrar lazo %1$d selecionado Ordenar - Diálogo cancelado Muy bajo Bajo Alto @@ -1029,7 +882,6 @@ Inicio de sesión Eliminar todos Restablecer inicio - Código QR para la configuración de la contraseña de un sólo uso Abrir la configuración Establecer alarma de carbohidratos Todo @@ -1046,7 +898,6 @@ Bloqueado por opciones de carga Bloqueado por opciones de conectividad (Ningún reloj conectado) - Error al solicitar permisos Ajustar sensibilidad y glucosa Limpiar base de dados ¿Desea limpiar la base de datos?\nSe eliminarán los cambios registrados y los datos históricos con más de 3 meses de antiguedad. diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 7f12aeff28..757c97b58d 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -13,7 +13,6 @@ Réinitialiser les Bases de Données Voulez-vous vraiment réinitialiser les bases de données ? Quitter - Ce périphérique ne semble pas permettre l\'optimisation de la batterie par une liste blanche - vous pourriez rencontrer des problèmes de performance. Quelques boutons pour accéder rapidement aux fonctions communes Utilisé pour configurer les plugins actifs Programme d’apprentissage @@ -42,11 +41,9 @@ Enregistre tous les traitements qui ont été effectués Surveillez et contrôlez AAPS en utilisant votre montre WearOS. Afficher les informations de votre Boucle sur votre écran de montre xDrip+. - Commander à distance AAPS en utilisant les commandes SMS. Insuline: Glucides : IA: - IA: IA Totale: Activité IA Totale: Dur: @@ -54,9 +51,7 @@ Ins: IA: IA Totale : - Gly TT - Glucides Corr. IA Bolus Exécuter maintenant @@ -73,7 +68,6 @@ Pas de données glycémiques disponibles Requête Delta - Delta: Configuration Aperçu Traitements @@ -97,13 +91,9 @@ Sécurité Plugin désactivé Violation des restrictions - Erreur lors du Bolus. Vérifiez manuellement la quantité réellement injectée Accepter nouveau basal temporaire : Traitement Assistant - Restriction appliquée ! - Bolus: - Basal: Changez vos entrées ! Source des glycémies Quelle source de données doit être utilisée par AAPS ? @@ -117,13 +107,10 @@ Suggestion de glucides Version incompatible de Nightscout IA Basal - Restriction du Bolus appliquée - Restriction des Glucides appliquée Autre Lecteur Capteur Décalage horaire - Durée Profil Source de Glycémie Basal Temporaire @@ -164,60 +151,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S JE COMPRENDS ET J\'ACCEPTE LES CONDITIONS DU CONTRAT Enregistrer Actualiser le profil - Communicateur SMS - Numéros de tél autorisés - +XXXXXXXXXX;+YYYYYYYYYY - Pour injecter le bolus de %1$.2f U, renvoyez le code %2$s - Pour injecter le bolus repas de %1$.2f U, renvoyez le code %2$s - Pour définir la cible temp %1$s, renvoyez le code %2$s - Pour annuler la cible temp, renvoyez le code %1$s - Pour désactiver les commandes à distance SMS, renvoyez le code %1$s.\n\nGardez à l\'esprit que vous ne pourrez le réactiver que directement à partir de l\'application AAPS du smartphone maître. - Service de commande à distance SMS arrêté. Pour le réactiver, utilisez AAPS sur le smartphone maître. - Pour envoyer la calibration %1$.2f, renvoyez le code %2$s - Échec du Bolus - Nombre minimum de minutes qu\'il doit y avoir entre un bolus distant et le suivant - Combien de minutes doit-il y avoir, au minimum, entre un bolus et le suivant - Pour votre sécurité, pour modifier cette préférence vous devez ajouter au moins 2 numéros de téléphone. - %1$.2f U vont être injectées - Bolus de %1$.2f U délivré avec succès - Bolus repas de %1$.2f U délivré avec succès - Cible %1$s pendant %2$d minutes - Cible %1$s pendant %2$d minutes définie avec succès - Cible Temp annulée avec succès - Autoriser les commandes à distance par SMS - La Boucle a été désactivée - La Boucle a été activée - La Boucle est activée - Pour connecter la pompe, renvoyez le code %1$s - Echec de la connexion pompe - Pour déconnecter la pompe pendant %1$d min, renvoyez le code %2$s - Pompe déconnectée - Pompe reconnectée - La commande à distance n\'est pas autorisée - Bolus à distance non disponible. Réessayez plus tard. - Pour démarrer la basal de %1$.2f U/h pendant %2$d min, renvoyez le code %3$s - Pour changer le profil vers %1$s %2$d%%, renvoyez le code %3$s - Pour démarrer le bolus étendu de %1$.2f U/h pendant %2$d min, renvoyez le code %3$s - Pour entrer %1$dg à %2$s, renvoyez le code %3$s - Pour démarrer la Basal %1$d%% pendant %2$d min, renvoyez le code %3$s - Pour suspendre la boucle pendant %1$d min, renvoyez le code %2$s - Pour reprendre la boucle, renvoyez le code %1$s - Pour activer la boucle, renvoyez le code %1$s - Pour désactiver la boucle, renvoyez le code %1$s - Démarrage réussi pour %1$.2fU/h de basal temp pour %2$d min - Le Bolus étendu %1$.2fU pendant %2$d min a commencé avec succès - %1$d g de glucides entrés avec succès - L\'entrée de %1$dg de glucides a échoué - Démarrage réussi pour %1$d%% de Basal temporaire pour %2$d min - Le démarrage du basal temporaire a échoué - Le départ du Bolus étendu a échoué - Pour arrêter la basal temp, renvoyez le code %1$s - Pour arrêter le bolus étendu, renvoyez le code %1$s - Basal temporaire annulé - Bolus étendu annulé - Echec de l\'annulation du basal temporaire - Échec de l\'annulation du Bolus étendu - Commande inconnue ou mauvaise réponse Assistant Rapide Assistant Rapide Texte du bouton : @@ -248,13 +181,9 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Renvoyer toutes les données Afficher les Paramètres sur la Montre Débit de Basal - Le débit Basal est inférieur au minimum autorisé. Profil non accepté ! - G: - Dernière G: Medtronic 640g Notification en cours DONNÉES ANCIENNES - il y a %1$d min Profil OpenAPS AMA Tableau de %1$d éléments.\nValeur Actuelle : @@ -274,7 +203,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S TRAIT OBJ WEAR - SMS Raccourcir les titres des onglets Utiliser delta basé sur moyenne courte Utile lorsque les données provenant de sources non filtrées comme xDrip+ deviennent incohérentes. @@ -288,13 +216,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Valeur par défaut : 2\nBolus snooze est activé apres votre bolus de repas, la boucle ne réagira pas avec des valeurs basses temporaire quand vous venez juste de manger. L’exemple ici et la valeur par défaut est 2 ; donc avec une Durée d\'Action (DIA) de 3 heures signifie que snooze bolus sera graduellement éliminé après 1,5 heures (3DIA/2). Valeur par défaut : 3.0 (AMA) ou 8.0 (SMB). Il s’agit d’un paramètre décrivant l’absorption des glucides par 5 minutes. La valeur par défaut est de 3mg/dl/5min. Cela influe sur la vitesse calculée de disparition des Glucides Actifs (GA), et comment sera estimée la consommation des glucides pour calculer les valeurs futures de glycémies, lorsque la glycémie chute plus que prévu ou n\'augmente pas autant que calculé. Attention !\nNormalement vous n\'avez pas à changer les valeurs mentionnées ci-dessous. SVP CLIQUEZ ICI et LISEZ bien le texte. Assurez-vous de bien le COMPRENDRE avant de changer n’importe laquelle de ces valeurs. - Num tél du SMS est invalide - Étalonnage - xDrip+ n\'est pas installé - Étalonnage envoyé à xDrip+ - Étalonnage envoyé. La réception doit être activée dans xDrip+. - xDrip+ ne reçoit pas les étalonnages - Pompe arrêtée Exécution en cours Paramètres pompe virtuelle Remontée des informations vers NS @@ -330,11 +251,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Veuillez sélectionner le type de patient pour définir les limites de sécurité Nom du patient Veuillez indiquer un nom ou pseudo du patient pour différencier plusieurs configurations - Patient Glimp - %1$s a besoin d\'être sur la liste blanche de l\'optimisation de la batterie pour des performances correctes - La Boucle est suspendue - Suspendu (%1$d m) Suspendre la Boucle pour 1h Suspendre la Boucle pour 2h Suspendre la Boucle pour 3h @@ -353,9 +270,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S 10 heures Reprendre Rebrancher la pompe - Durée incorrecte - Boucle suspendue - Boucle relancée Delta 15 min GA Superbolus @@ -390,7 +304,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S ABS PENTEDEV À propos - Autorisation SMS manquante Autorisation du téléphone manquante état Xdrip+ (montre) Barre d\'état pour xDrip+ (Montre) @@ -463,14 +376,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Commandes depuis la montre Définir les Cibles Temp et entrer les Traitements depuis la montre Aliments - g ]]> kJ En Protéines Gras (Lipides) - Commande exécutée à l\'instant - Valeurs de glycémie manquantes Utiliser les notifications système pour les alertes et notifications Augmentation progressive du volume pour les alertes et les notifications Alertes locales @@ -548,9 +458,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Autoriser l\'envoi automatique des rapports d\'erreur et des données d\'utilisation aux développeurs via le service fabric.io SVP actualisez votre app Dexcom vers une version compatible L\'application Dexcom n\'est pas installée. - Début Activités - Début Repas Imminent - Traitement Ne pas administrer de bolus, enregistrer uniquement Catégorie Sous-catégorie @@ -563,8 +470,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Glucides actifs Insuline Active Basals - Aucune action sélectionnée, rien ne se passera - Début Traitement Hypo Version Dev. La Boucle Fermée est désactivée. Mode ingénierie actif ProfileSwitch manquant. S’il vous plaît faire un changement de profil ou appuyez sur « Activer le profil » dans le LocalProfile. @@ -583,7 +488,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Limiter l’IA %1$.1f U en raison de la %2$s valeur Max dans les préférences limite fixée - La lecture du statut a échoué Enregistrer changement de site de cathéter Enreg. changement de réservoir SMB toujours et post-ingestion de glucides désactivé car la source de glycémies actuelle ne supporte pas de filtrage avancé @@ -641,12 +545,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Veuillez configurer votre RileyLink ci-dessous. Après avoir sélectionné un RileyLink, il sera possible de continuer l\'installation une fois que le statut de RileyLink sera « Connecté ». Cela peut prendre une minute.\n Remarque : Vous pouvez continuer l\'installation une fois la pompe configurée.\n Démarrez votre premier objectif - Autorisation Demande d\'autorisation - L\'application a besoin de l\'autorisation d\'accès à la fenêtre système pour les notifications - L\'application a besoin de l\'autorisation de localisation pour l\'analyse BT et l\'identification WiFi - L\'application a besoin d\'une autorisation de stockage pour pouvoir stocker les fichiers journaux et les paramètres d\'exportation - Demande Ouvrir navigation Fermer navigation Préférences du plugin @@ -692,8 +591,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Paramètres journal Réinitialiser les valeurs par défaut Dysfonctionnement NSClient. Redémarrez NS et NSClient. - Décalage horaire - Rappel du bolus plus tard Mode APS préféré Total Calc @@ -724,11 +621,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Changement d\'heure dans moins de 3 heures - Boucle fermée désactivée stockage interne limité Boucle désactivée ! Libérez au moins %1$d Mo du stockage interne ! - Format incorrect - La durée du DBT doit être un multiple de %1$d minutes et supérieure à 0. - Code incorrect. Commande annulée. - Non configuré - Changement de profil effectué Vérificateur de version ancienne version très ancienne version @@ -745,12 +637,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S L\'assistant bolus effectue le calcul mais seulement ce pourcentage de l\'insuline calculée est délivré. Utile avec l\'algorithme SMB. Masquer Augmentation de la valeur du débit Basal max parce que ce paramètre est inférieur au débit Basal max de votre profil - Message invalide %1$s SI: %2$.1f %1$.0fg G/I: %2$.1f %1$.1fg G/I: %2$.1f %1$d%% - min Nom du profil : Sélectionné : Unités @@ -804,27 +694,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Heure d\'exécution SMB Heure de demande basal temp Heure d\'exécution basal temp - - depuis l\'application Authenticator pour : %1$s suivie du code PIN - Code PIN obligatoire à la fin de l\'OTP - Chiffres supplémentaires qui doivent être mémorisés et collés à la fin de chaque OTP généré - Configuration de l\'Authentificateur - Code à vérifier : - OTP + PIN - Le code de vérification est composé de 6 chiffres affichés par l\'application Authenticator (appelée OTP) suivi du code PIN obligatoire constitué de 3 chiffres ou plus. - Réinitialiser les authentificateurs - Réinitialiser la clé de l\'Authentificateur - Voulez-vous réinitialiser la clé de l\'Authenticateur ? Cela rendra tous authentificateurs configurés invalides, et vous devrez les configurer à nouveau. - Nouvelle clé de l\'Authenticateur générée ! Veuillez utiliser le QRCode mis à jour pour les authentificateurs. - Exportation de l\'OTP secret - Êtes-vous sûr de vouloir copier l\'OTP secret dans le presse-papiers ?\n\nVous pouvez en avoir besoin uniquement si votre application d\'authentification a des problèmes pour scanner le QRCode, si vous voulez le saisir manuellement ou si vous voulez configurer un jeton OTP matériel en utilisant une application dédiée. - OTP secret (au format Base32) exporté et copié dans le presse-papiers. Collez-le dans l\'authentificateur ou le graveur OTP matériel ! - 1. Installation l\'Authentificateur - 2. Scannez le code pour configurer les codes OTP AAPS - 3. Test Mot-de-Passe-Unique (OTP) - Réinitialiser les authentificateurs - Sur chaque téléphone suiveur, installez une appli. Authentificateur qui prend en charge les jetons RFC 6238 TOTP. Les applications libres populaires sont:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator - En réinitialisant l\'Authentificateur, vous invalidez tous les authentificateurs déjà initialisés. Vous devrez les reconfigurer ! Prédictions Traitements Pente de déviations @@ -855,20 +724,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Filtrer Impossible de créer le profil. Le profil est invalide. Garder l\'appli en arrière plan ? - Envoyer un SMS si l\'événement Pompe hors de portée est déclenché - Signaler Pompe hors de portée Alerter quand il est temps de manger - Alerter dans %1$d min - Assistant bolus - Vous avez une glycémie élevée. Au lieu de manger maintenant, il est recommandé d\'attendre une meilleure glycémie. Voulez-vous faire un bolus de correction maintenant et avoir une alerte quand il sera temps de manger ? Dans ce cas, aucun glucide ne sera enregistré et vous devrez utiliser l\'assistant à nouveau lorsque nous vous le rappelons. - Activer l\'assistant bolus - Utiliser un rappel pour commencer le repas à la place du résultat de l\'assistant quand la glycémie est élevée (\"pré-bolus\") Il est temps de manger !\nExécutez l\'assistant Bolus et refaites le calcul. - Il est temps de manger - Rappel bolus Activer le rappel bolus Utiliser un rappel pour faire le bolus plus tard avec l\'Assistant (\"post-bolus\") - Il est temps de faire le bolus !\nExécutez l\'Assistant et faites de nouveau le calcul. Téléchargement logs crashs désactivé! Graph Menu graphique @@ -905,8 +764,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Accepter les événements de thérapie (canule, insuline, changement de batterie, etc.) entrés via NS ou NSClient Recevoir/remplir les anciennes données MGC Accepter les données MGC de NS - Délai d\'attente pour finir la communication précédente avec la pompe - Un autre bolus est en file d\'attente. Réessayez plus tard. Calcul en cours Nom de profil manquant Erreur dans les valeurs de G/I @@ -951,7 +808,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S insuline glycémie obsolète - définir un rappel ajouter un nouveau profil dupliquer le profil actuel supprimer le profil actuel @@ -1010,7 +866,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Afficher les entrées boucle %1$d sélectionnée(s) Trier - Boîte de dialogue annulée Très bas Bas Haut @@ -1029,7 +884,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Connexion Supprimer tout Réinitialiser le démarrage - Code QR pour configurer un mot de passe à usage unique ouvrir les paramètres définir l\'alarme du minuteur de glucides Tous @@ -1046,7 +900,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Bloqué par les options de recharge Bloqué par les options de connectivité (Pas de montre connectée) - Erreur lors de la demande des autorisations Ajuster la sensibilité et la glycémie Nettoyer la base de données Voulez-vous nettoyer la base de données ?\nCela supprimera les modifications suivies et les données historiques de plus de 3 mois. diff --git a/app/src/main/res/values-ga-rIE/strings.xml b/app/src/main/res/values-ga-rIE/strings.xml index b73615f8f0..4b593cc694 100644 --- a/app/src/main/res/values-ga-rIE/strings.xml +++ b/app/src/main/res/values-ga-rIE/strings.xml @@ -3,7 +3,6 @@ - diff --git a/app/src/main/res/values-hr-rHR/strings.xml b/app/src/main/res/values-hr-rHR/strings.xml index b73615f8f0..4b593cc694 100644 --- a/app/src/main/res/values-hr-rHR/strings.xml +++ b/app/src/main/res/values-hr-rHR/strings.xml @@ -3,7 +3,6 @@ - diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index e824f271f6..06c79d53f8 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -4,7 +4,6 @@ WiFi SSID - diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 373ae94d51..8ad394a177 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -13,7 +13,6 @@ Resetta database Vuoi davvero resettare i database? Esci - Questo dispositivo non sembra supportare la whitelist dell\'ottimizzazione batteria: potrebbero verificarsi problemi di prestazioni. Alcuni tasti per accedere rapidamente alle funzioni comuni Usato per configurare i plugin attivi Programma di apprendimento @@ -42,11 +41,9 @@ Salva tutti i trattamenti che sono stati fatti Monitora e controlla AAPS usando il tuo smartwatch WearOS. Mostra le informazioni del loop sulla watchface di xDrip+. - Controlla AAPS in remoto usando i comandi SMS. Insulina: CHO: IOB: - IOB: IOB totale: Attività IOB totale: Dur: @@ -54,9 +51,7 @@ Ins: IOB: IOB totale: - BG TT - CHO Corr IOB da bolo Esegui ora @@ -73,7 +68,6 @@ Dati glicemia non disponibili Richiesta Delta - Delta: Configuratore strutturale Panoramica Trattamenti @@ -97,13 +91,9 @@ Sicurezza Il plugin è disabilitato Violazione dei vincoli - Segnalato errore sul bolo. Controlla manualmente la reale quantità erogata Accetta nuova basale temporanea: Trattamento Calcolatore - Vincolo applicato! - Bolo: - Basale: Cambia il tuo input! Origine BG Da dove AAPS dovrebbe ottenere i suoi dati? @@ -117,13 +107,10 @@ Suggerimento CHO Versione non supportata di Nightscout IOB da basale - Vincolo bolo applicato - Vincolo CHO applicato Altro Glucometro Sensore Offset CHO - Durata Profilo Tipo glicemia Basale temporanea @@ -163,60 +150,6 @@ COMPRENDO E ACCETTO Salva Ricarica profilo - Comunicazioni SMS - Numeri di telefono consentiti - +XXXXXXXXXX;+YYYYYYYYYY - Per erogare il bolo di %1$.2fU rispondi col codice %2$s - Per erogare il bolo pasto di %1$.2fU rispondi col codice %2$s - Per impostare il Temp-Target %1$s rispondi con il codice %2$s - Per cancellare il Temp-Target rispondi col codice %1$s - Per disabilitare il servizio di controllo remoto tramite SMS rispondi col codice %1$s.\n\nRicorda che potrai riattivarlo solo in maniera diretta dallo smartphone master in cui è installato AAPS. - Servizio di controllo remoto tramite SMS stoppato. Per riattivarlo, usa lo smartphone master in cui è installato AAPS. - Per inviare la calibrazione %1$.2f rispondi col codice %2$s - Bolo fallito - Numero minimo di minuti che devono trascorrere tra un bolo remoto e il successivo - Quanti minuti devono trascorrere, almeno, tra un bolo e il successivo - Per la tua sicurezza, per modificare questa preferenza hai bisogno di aggiungere almeno 2 numeri di telefono. - Sto per erogare %1$.2fU - Bolo di %1$.2f U erogato con successo - Bolo pasto di %1$.2f U erogato con successo - Target %1$s per %2$d minuti - Target %1$s per %2$d minuti impostato con successo - Temp-Target cancellato con successo - Consenti comandi remoti tramite SMS - Il loop è stato disabilitato - Il loop è stato abilitato - Il loop è abilitato - Per connettere il micro rispondi col codice %1$s - Connessione al micro fallita - Per disconnettere il micro per %1$d minuti rispondi col codice %2$s - Micro disconnesso - Micro riconnesso - Il comando da remoto non è permesso - Bolo remoto non disponibile. Riprova più tardi. - Per avviare la basale %1$.2f U/h per %2$d min rispondi col codice %3$s - Per passare al profilo %1$s %2$d%% rispondi col codice %3$s - Per avviare il bolo esteso %1$.2f U/h per %2$d min rispondi col codice %3$s - Per inserire %1$dg a %2$s rispondi col codice %3$s - Per avviare la basale %1$d%% per %2$d min rispondi col codice %3$s - Per sospendere il loop per %1$d minuti rispondi col codice %2$s - Per riprendere il loop rispondi col codice %1$s - Per abilitare il loop rispondi col codice %1$s - Per disabilitare il loop rispondi col codice %1$s - Basale temporanea %1$.2fU/h per %2$d min avviata con successo - Bolo esteso %1$.2fU/h per %2$d min avviato con successo - CHO %1$d g inseriti con successo - Inserimento di %1$dg di CHO fallito - Basale temporanea %1$d%% per %2$d min avviata con successo - Avvio basale temporanea fallito - Avvio bolo esteso fallito - Per stoppare la basale temporanea rispondi col codice %1$s - Per stoppare il bolo esteso rispondi col codice %1$s - Basale temporanea cancellata - Bolo esteso cancellato - Basale temporanea: cancellazione fallita - Bolo esteso: cancellazione fallita - Comando sconosciuto o risposta errata Calcolatore rapido Impostazioni Calcolatore rapido Testo: @@ -247,13 +180,9 @@ Invia di nuovo tutti i dati Apri impostazioni sullo smartwatch Velocità basale - Valore basale inferiore al minimo. Profilo non impostato! - BG: - Ultimo BG: MM640g Notifica persistente DATI VECCHI - %1$dmin fa Profilo OpenAPS AMA Matrice di %1$d elementi.\nValore attuale: @@ -273,7 +202,6 @@ TRATT OBT SMWA - SMS Accorcia titoli schede Usa sempre il delta medio ridotto Utile quando i dati provenienti da sorgenti non filtrate come xDrip+ diventano \"rumorosi\" (instabili). @@ -287,13 +215,6 @@ [Valore predefinito: 2]\nBolus snooze è attivato dopo un bolo pasto per fare in modo che il loop non imposti basali temporanee basse quando hai appena mangiato. AndroidAPS non imposterà velocità basali troppo basse nel periodo corrispondente a DIA diviso il parametro bolus snooze - divisore DIA. Con DIA di 3 ore \"bolus snooze\" durerà 1.5 ore (3/2). [Valore predefinito: 3.0 (AMA) o 8.0 (SMB)]. Questa è un\'impostazione per l\'impatto di assorbimento predefinito dei carboidrati in 5 minuti. L\'impostazione predefinita è una previsione di 3mg/dl/5min. Ha effetto sulla velocità di decadimento dei COB (carboidrati attivi) e su quanto il loro assorbimento incide nella previsione dell’andamento glicemico, quando la glicemia sta scendendo più del previsto o non sta salendo quanto previsto. Attenzione!\nNormalmente non dovresti modificare questi valori. FAI CLICK QUI e leggi il testo e assicurati di AVERLO CAPITO prima di cambiare uno di questi valori. - Numero di telefono SMS non valido - Calibrazione - xDrip+ non installato - Calibrazione inviata a xDrip+ - Calibrazione inviata. La ricezione deve essere abilitata in xDrip+. - xDrip+ non sta ricevendo calibrazioni - Micro sospeso Esecuzione Impostazioni micro virtuale Carica stato in NS @@ -329,11 +250,7 @@ Seleziona il tipo di paziente per configurare i limiti di sicurezza Nome paziente Fornisci il nome del paziente o il nickname per distinguere questa configurazione tra altre - Utente Glimp - %1$s necessita della whitelist per l\'ottimizzazione della batteria per avere prestazioni adeguate - Loop sospeso - Sospeso (%1$d m) Sospendi loop per 1h Sospendi loop per 2h Sospendi loop per 3h @@ -352,9 +269,6 @@ 10 ore Riprendi Riconnetti micro - Durata errata - Loop sospeso - Loop ripreso Trend di 15min COB Superbolo @@ -389,7 +303,6 @@ ASS PENDEV Informazioni su - Autorizzazione SMS mancante Autorizzazione stato telefono mancante Stato xDrip+ (smartwatch) Statusline xDrip+ (smartwatch) @@ -462,14 +375,11 @@ Controlli da smartwatch Imposta Temp-Target e inserisci trattamenti dallo smartwatch. Cibo - g ]]> kJ Enr Prt Grs - Il comando sarà eseguito ora - Letture BG mancanti Usa le notifiche di sistema per gli avvisi Aumenta gradualmente il volume per avvisi e notifiche Avvisi locali @@ -547,9 +457,6 @@ Consenti la segnalazione automatica degli errori e l\'invio dei dati d\'uso delle funzioni dell\'app agli sviluppatori tramite il servizio fabric.io. Aggiorna la tua app Dexcom a una versione supportata App Dexcom non installata. - Avvia TT Attività fisica - Avvia TT Pasto a breve - TT No bolo, solo record Categoria Sottocategoria @@ -562,8 +469,6 @@ CHO attivi Insulina attiva Basali - Nessuna azione selezionata, non succederà nulla - Avvia TT Ipoglicemia Versione sviluppatore in esecuzione. Loop chiuso disabilitato. Engineering mode abilitata Nessun cambio profilo. Effettua un cambio profilo o premi \"Attiva profilo\" nella sezione Profilo locale. @@ -582,7 +487,6 @@ Limitazione IOB a %1$.1f U a causa di: %2$s valore max nelle preferenze limite fisso - Lettura stato fallita Registra cambio posizione cannula Registra cambio cartuccia insulina Le funzioni \"SMB sempre\" e \"SMB dopo i CHO\" sono disabilitate perché l\'attuale sorgente delle glicemie non supporta il filtraggio avanzato @@ -640,12 +544,7 @@ Configura il RileyLink di seguito. Dopo aver selezionato un RileyLink, sarà possibile continuare la configurazione una volta che lo stato del RileyLink sarà \"Connesso\". Questo potrebbe richiedere un minuto.\n Nota: Puoi continuare la configurazione una volta che il micro è stato configurato.\n Avvia il tuo primo obiettivo - Autorizzazione Chiedi l\'autorizzazione - L\'applicazione richiede l\'autorizzazione \"finestra di sistema\" per le notifiche - L\'applicazione richiede l\'accesso alla posizione per la scansione bluetooth e l\'identificazione WiFi - L\'applicazione richiede l\'accesso alla memoria per memorizzare i file di log ed esportare le impostazioni - Richiesta Apri navigazione Chiudi navigazione Preferenze plugin @@ -691,8 +590,6 @@ Impostazioni Log Ripristina valori predefiniti Malfunzionamento NSClient. Considera il riavvio di NS e NSClient. - Offset - Ricorda di fare il bolo Modalità APS preferita Totale Calc @@ -723,11 +620,6 @@ Cambio all\'ora legale/solare avvenuto meno di 3 ore fa - Loop chiuso disabilitato vincolo di archiviazione interna Libera almeno %1$d MB dalla memoria interna! Loop disabilitato! - Formato errato - La durata del TBR deve essere un multiplo di %1$d minuti e maggiore di 0. - Codice errato. Comando cancellato. - Non configurato - Cambio profilo creato Controllo versione versione datata versione molto datata @@ -744,12 +636,10 @@ Il calcolatore esegue il calcolo, ma solo questa parte dell\'insulina calcolata è erogata. Utile con algoritmo SMB. Posticipa Aumento del valore max basale perché l\'impostazione è inferiore alla tua basale massima nel profilo - Corpo del messaggio non valido %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Nome profilo: Selezionato: Unità @@ -803,27 +693,6 @@ Esecuzione SMB (momento) Richiesta basale temporanea (momento) Esecuzione basale temporanea (momento) - - da app autenticatore: %1$s seguito da PIN - PIN obbligatorio aggiuntivo a fine token - Cifre aggiuntive che devono essere memorizzate e incollate alla fine di ogni OTP generata - Configurazione autenticatore - Codice controllo: - OTP + PIN - Il codice di verifica è composto da 6 cifre visualizzate dall\'app autenticatore (note come OTP) seguite da 3 o più cifre del PIN obbligatorio. - Resetta autenticatori - Resetta chiave autenticatore - Sei sicuro di resettare la chiave autenticatore? Renderà non validi tutti gli autenticatori attualmente configurati e sarà necessario configurarli nuovamente. - La nuova chiave autenticatore è stata generata! Usa il QRCode aggiornato per fornire gli autenticatori. - Esportazione OTP secret - Sei sicuro di voler copiare l\'OTP secret negli appunti?\n\nPotresti averne bisogno solo se la tua app autenticatore ha problemi con la scansione del QRCode, vuoi inserirlo manualmente o vuoi configurare un token OTP hardware usando un\'app dedicata. - OTP secret (in formato Base32) esportato e copiato negli appunti. Incollalo nell\'autenticatore o nel configuratore hardware di OTP! - 1. Installa l\'autenticatore - 2. Scansione il codice per configurare i codici OTP di AAPS - 3. Testa OTP - Resetta autenticatori - Su ogni telefono follower installa una app autenticatore che supporta i token RFC 6238 TOTP. App gratuite popolari sono:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator - Resettando l\'autenticatore rendi non validi tutti gli autenticatori già forniti. Dovrai configurarli di nuovo! Predizioni Trattamenti Pendenza deviazione @@ -854,21 +723,9 @@ Filtro Impossibile creare il profilo. Il profilo non è valido. Non terminare l\'app? - Invia SMS se si verifica l\'evento \"micro irraggiungibile\" - Segnala micro irraggiungibile Esegui allarme quando è tempo di mangiare - Esegui allarme in %1$d min - Consiglio bolo - Hai una glicemia alta. Invece di mangiare ora, si consiglia di attendere una glicemia migliore. Vuoi fare adesso un bolo di correzione ed essere ricordato quando è il momento di mangiare? In questo caso non verranno registrati carboidrati e dovrai usare di nuovo il calcolatore quando ti verrà mostrato il promemoria. - Abilita consiglio bolo - Usa un promemoria per iniziare a mangiare invece del risultato del calcolatore durante la glicemia alta (\"pre-bolo\") Tempo di mangiare!\nEsegui il calcolatore e fai di nuovi i calcoli. - Tempo di mangiare - Promemoria bolo Abilita promemoria bolo - Usa promemoria bolo con calcolatore - (\"post-bolo\") - Tempo di fare un bolo!\nEsegui il calcolatore e fai di nuovi i calcoli. Caricamento log dei crash disabilitato! Grafico Menu grafico @@ -905,8 +762,6 @@ Accetta eventi terapia (cambio cannula, insulina, batteria, ecc.) inseriti tramite NS o NSClient Ricevi/riempi dati CGM Accetta dati CGM da NS - Timeout nell\'attesa della fine della precedente comunicazione col micro. - C\'è un altro bolo in coda. Riprova più tardi. Calcolo in corso Nome profilo mancante Errore nei valori IC @@ -951,7 +806,6 @@ insulina glicemia obsoleto - imposta promemoria aggiungi nuovo profilo clona profilo corrente elimina profilo corrente @@ -1010,7 +864,6 @@ Mostra loop %1$d selezionati Ordina - Finestra di dialogo cancellata Molto basso Basso Alto @@ -1029,7 +882,6 @@ Login Rimuovi tutto Avvio reset - Codice QR per configurare OTP apri impostazioni imposta allarme timer CHO Tutto @@ -1046,7 +898,6 @@ Bloccato dalle opzioni di ricarica Bloccato dalle opzioni di connettività (Nessuno smartwatch connesso) - Errore nel richiedere le autorizzazioni Regola sensibilità e BG Pulizia database Vuoi pulire il database?\nIl processo rimuoverà i cambiamenti tracciati e i dati dello storico più vecchi di 3 mesi. diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index 1c27e4e33c..37b74837a2 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -13,7 +13,6 @@ איפוס מסדי נתונים אתם בטוחים שאתם רוצים לאפס את מסדי הנתונים? יציאה - נראה שמכשיר זה אינו תומך ברשימת היתרים למיטוב הסוללה - ייתכן שתיתקל בבעיות ביצועים. לחצנים לגישה מהירה לפונקציות שימושיות משמש לקביעת תצורה של תוספים פעילים תוכנית הלימוד @@ -44,7 +43,6 @@ אינסולין: פחמימות: אינסולין פעיל: - אינסולין פעיל: אינסולין פעיל כולל: פעילות אינסולין פעיל כוללת: משך: @@ -52,9 +50,7 @@ אינסולין: IOB: IBO כולל: - ערכי סוכר בדם TT - פחמימות תיקון בולוס פעיל בצע @@ -71,7 +67,6 @@ אין ערכי סוכר זמינים בקשה דלתא - דלתא: בונה התצורה סקירה כללית טיפולים @@ -92,13 +87,9 @@ בטיחות התוסף אינו זמין הפרת מגבלות - דווחה שגיאה בבולוס. נא לבדוק את הכמות שהוזרקה באופן ידני אשר בזאלי זמני חדש: טיפול מחשבון - מגבלה הוחלה! - בולוס: - אינסולין בזאלי: שנה קלט! מקור ערכי הסוכר xDrip+ @@ -111,13 +102,10 @@ המלצת פחמימות גרסה לא נתמכת של Nightscout בזאלי פעיל - בולוס מעבר למגבלה - פחמימות מעבר למגבלה אחר מד חיישן זמן פחמימות - משך פרופיל סוג גלוקוז בזאלי זמני @@ -157,60 +145,6 @@ אני מבין\\ה ומסכים\\ה שמירה טעינה מחדש של הפרופיל - תקשורת SMS - מספרי טלפון מורשים - +XXXXXXXXXX;+YYYYYYYYYY - לאישור מתן בולוס %1$.2f יחידות יש להשיב עם הקוד %2$s - למתן %1$.2f יחידות בולוס ארוחה יש להשיב עם הקוד %2$s - להגדרת המטרה הזמנית %1$s יש להשיב עם הקוד %2$s - לביטול המטרה הזמנית יש להשיב עם הקוד %1$s - לביטול שירות השליטה מרחוק באמצעות SMS השיבו עם הקוד %1$s. \n\nהשירות ניתן להפעלה מחדש ממכשיר ה-AAPS הראשי בלבד. - שירות השליטה מרחוק באמצעות SMS מופסק. על מנת להפעילו, השתמשו ב-AAPS במכשיר הראשי. - כדי לשלוח ערך כיול %1$.2f יש להשיב עם הקוד %2$s - הבולוס נכשל - מספר המינימלי (בדקות) שחייב לחלוף בין בולוס מרוחק אחד למשנהו - מספר הדקות המינימלי שצריכות לחלוף, בין בולוס אחד למשנהו - למען בטחונכם, על מנת לערוך את העדפה זו, עליכם להוסיף לפחות שני מספרי טלפון. - עומד להזריק %1$.2f יח\' - בולוס %1$.2f יחידות ניתן בהצלחה - בולוס עבור ארוחה %1$.2fU ניתן בהצלחה - ערך מטרה %1$s למשך %2$d דקות - יעד %1$s עבור %2$d דקות הוגדר בהצלחה - יעד זמני בוטל בהצלחה - אפשר שליטה מרחוק באמצעות SMS - הלולאה הושבתה - הלולאה הופעלה - לולאה פעילה - לחיבור המשאבה יש להשיב עם הקוד %1$s - החיבור אל המשאבה נכשל - לניתוק המשאבה למשך %1$d דקות השיבו עם הקוד %2$s - המשאבה מנותקת - המשאבה חוברה מחדש - פקודה מרוחקת אינה מותרת - בולוס מרחוק אינו זמין. נסו שוב מאוחר יותר. - להפעלת בזאלי %1$.2f יח\' לשעה למשך %2$d דקות יש להשיב עם הקוד %3$s - להחלפת פרופיל ל- %1$s %2$d %% הקש את הקוד %3$s - למתן בולוס ממושך %1$.2f יח\' למשך %2$d דקות יש להשיב עם הקוד %3$s - למתן %1$d גר\' ב-%2$s יש להשיב עם הקוד %3$s - להפעלת בזאלי %1$d%% למשך %2$d דקות הקש קוד %3$s - להשהיית הלולאה למשך %1$d דקות יש להשיב עם הקוד %2$s - להפעלת הלולאה מחדש יש להשיב עם הקוד %1$s - כדי לאפשר הלולאה יש להשיב עם הקוד %1$s - להשבתת הלולאה יש להשיב עם הקוד %1$s - בזאלי זמני %1$.2f יחידות\\שעה למשך %2$d דקות הופעל בהצלחה - בולוס ממושך %1$.2f יחידות למשך %2$d דקות הופעל בהצלחה - %1$d גר\' פחמימות נקלטו בהצלחה - קליטת %1$d גר\' פחמימות נכשלה - בזאלי זמני %1$d%% למשך %2$d דקות הופעל בהצלחה - הפעלת בזאלי זמני נכשלה - הפעלת בולוס ממושך נכשלה - להפסקת בזאלי זמני הקש קוד %1$s - להפסקת בולוס ממושך יש להשיב עם הקוד %1$s - בזאלי זמני בוטל - בולוס ממושך בוטל - ביטול בזאלי זמני ניכשל - ביטול בולוס ממושך נכשל - פקודה לא מוכרת או תגובה שגויה אשף מהיר הגדרות אשף מהיר טקסט הלחצן: @@ -241,13 +175,9 @@ שלח מחדש את כל הנתונים פתיחת הגדרות Wear מינון בזאלי - ערך הבסיס מתחת למינימום. פרופיל אינו מוגדר! - ערכי סוכר בדם: - ערכי סוכר אחרונים: Minimed 640G התראה מתמשכת נתונים ישנים - לפני %1$d דקות פרופיל OpenAPS AMA מערך של %1$d אלמנטים. \n ערך נוכחי: @@ -267,7 +197,6 @@ TREAT OBJ WEAR - SMS קצר את כותרות הלשוניות התבסס על הפרש ממוצע קצר במקום הפרש פשוט\\רגיל לשימוש כאשר נתונים ממקור לא מפוקח כמו xDrip אינם יציבים. @@ -281,13 +210,6 @@ ערך ברירת מחדל: 2\n מעכב בולוס מופעל אחרי שאתם מזריקים בולוס ארוחה, כך שהלולאה לא תפצה ע\"י בזאלי זמני נמוך אחרי הארוחה. הדוגמה כאן וברירת המחדל היא 2; כך שהגדרה של משך פעילות אינסולין של 3 שעות משמעה שהעיכוב יחלוף בהדרגה בתוך 1.5 שעות (3 ש\' לחלק ל-2). ערך ברירת מחדל: 3.0 (AMA) או 8.0 (SMB). זוהי הגדרת ברירת מחדל להשפעת פחמימות על הסוכר בדם ב-5 דקות. ברירת המחדל היא 3mg/dL/5min. פעולה זו משפיעה על קצב הדעיכה של פחמ\' פעילות, ועל הנחת קצב ספיגת הפחמ\' בחישוב רמות סוכר עתידיות כשהן בירידה מהירה מהצפוי או עליה איטית מהצפוי. שימו לב!\nבדרך כלל אינכם צריכים לשנות את הערכים שלהלן. נא ללחוץ כאן, לקרוא את הטקסט ולוודא שאתם מבינים אותו לפני שתשנו ערכים אלה. - מספר טלפון ל-SMS אינו תקין - כיול - xDrip+ אינו מותקן - כיול נשלח ל-xDrip+ - הכיול נשלח. יש לאשר את קבלת כיולים ב-xDrip+. - xDrip אינו מקבל כיולים - משאבה מושהית מבצע הגדרות משאבה וירטואלית טוען מצב ל-Nightscout @@ -323,10 +245,7 @@ נא לבחור את גיל המטופל\\ת להתאמת מגבלות בטיחות שם המטופל\\ת נא לציין את שם המטופל\\ת או כינוי, להבחנה בין מספר הגדרות - משתמש Glimp - לולאה מושהית - מושהה (%1$d דק\') השהה לולאה לשעה אחת השהה לולאה ל-2 ש\' השהה לולאה ל-3 ש\' @@ -345,9 +264,6 @@ 10 שעות חידוש חיבור משאבה מחדש - משך שגוי - לולאה מושהית - לולאה חודשה מגמת 15 דקות פחמ\' פעילות סופר בולוס @@ -382,7 +298,6 @@ אבס\' שיפוע אודות - הרשאות SMS חסרות הרשאת סטטוס הטלפון חסרה מצב xDrip (שעון) שורת מצב xDrip (שעון) @@ -454,14 +369,11 @@ שליטה מהשעון הגדירו ערכי מטרה זמניים וציינו טיפולים מהשעון. מזון - גר\' ]]> kJ אנרגיה חלבון שומן - הפקודה מבוצעת כעת - לא התקבלו קריאות סוכר שימוש בהודעות מערכת עבור התראות ודיווחים הגבר את עוצמת הקול בהדרגה להתראות ולהודעות התראות מקומיות @@ -539,9 +451,6 @@ אפשר דיווח אוטומטי על קריסה ושליחת נתוני השימוש למפתחים דרך שירות fabric.io. עדכנו את יישום ה-Dexcom שלכם לגרסה נתמכת אפליקציית Dexcom אינה מותקנת. - התחל פעילות TT - התחל TT אוכלים בקרוב - TT רישום בולוס ללא הזרקה קטגוריה תת קטגוריה @@ -554,8 +463,6 @@ פחמימות פעילות אניסולין פעיל בזאלי - לא נבחרה פעולה, דבר לא יתבצע. - הפעלת היפו TT זוהי גרסת פיתוח. לולאה סגורה אינה מורשת. מצב הנדסה מופעל שינוי פרופיל חסר. אנא החליפו פרופיל או לחצו על \"הפעל פרופיל\" בפרופיל המקומי. @@ -574,7 +481,6 @@ הגבלת IOB ל-%1$.1f יח\' בגלל %2$s ערך מקסימלי בהעדפות מגבלה קשיחה - קריאת סטטוס נכשלה רשום החלפת אתר עירוי רשום החלפת מכל אינסולין SMB תמידי ו-SMB לאחר פחמימות מושבתים כיוון שמקור ערכי הסוכר הפעיל אינו תומך בסינון נתונים מתקדם @@ -631,12 +537,7 @@ הגדירו את תצורת הריילילינק מטה. לאחר שתבחרו באפשרות ריילילינק, ניתן יהיה להמשיך בהתקנה אחרי שסטטוס הריילילינק יהיה \"מחובר\". פעולה זו עשויה להימשך דקה.\n הערה: ניתן יהיה להמשיך בהתקנה לאחר חיבור ההמשאבה.\n התחלת המשימה הראשונה שלכם - הרשאה מבקש הרשאה - האפליקציה צריכה הרשאת מערכת של חלונות לצורך התראות - דרושה הרשאת מיקום עבור סריקת בלוטות\' וזיהוי WiFi - דרושה הרשאת אחסון כדי שתוכלו לאחסן קובצי יומן והגדרות יצוא. - בקשה פתח ניווט סגור ניווט העדפות תוסף @@ -680,8 +581,6 @@ הגדרות יומן רישום אפס לברירת המחדל תקלה ב-NSClient. שקלו להפעיל את Nightscout ו-NSClient מחדש. - היסט זמן - תזכורת להזרקת בולוס אח\"כ מצב APS מועדף סה\"כ חישוב @@ -711,11 +610,6 @@ חל מעבר לשעון קיץ לפני פחות מ-3 שעות - לולאה סגורה מושבתת אילוץ אחסון פנימי יש לפנות לפחות %1$d מ\"ב מנפח האחסון של מכשירכם! הלולאה מושבתת! - פורמט שגוי - משך הבזאלי הזמני חייב להיות כפולה של %1$d דקות ויותר מ-0. - קוד שגוי. הפקודה בוטלה. - לא מוגדר - נוצרה החלפת פרופיל בודק גרסה גרסה ישנה גרסה ישנה מאוד @@ -732,12 +626,10 @@ אשף הבולוס מבצע חישוב אך רק חלק זה של האינסולין המחושב מוזרק. שימושי בשימוש עם אלגוריתם SMB. נודניק מגדיל את ערך מקסימום הבזאלי מפני שהוא נמוך מערכו המרבי בפרופיל - גוף ההודעה אינו חוקי %1$s פקטור הרגישות: %2$.1f %1$.0f גר\' יחס פחמ\': %2$.1f %1$.1f גר\' יחס פחמ\':%2$.1f %1$d%% - דק\' שם הפרופיל: נבחר: יחידות @@ -790,25 +682,6 @@ זמן ביצוע SMB זמן בקשת בזאלי זמני זמן הפעלת בזאלי זמני - - מיישום מאמת עבור: %1$s ואחריו PIN - תוספת PIN חובה בסוף האסימון - ספרות נוספות שיש לשנן ולהדביק בסוף כל אחת מהסיסמאות החד פעמיות - הגדרת מאמת - קוד לבדיקה: - OTP + PIN - קוד האימות מורכב מ-6 ספרות המוצגות על ידי יישום מאמת (הידוע בתור OTP) ואחריו 3 או יותר ספרות של PIN הכרחי. - איפוס מאמתים - איפוס מפתח אימות - האם אתם בטוחים שברצונכם לאפס את מפתח האימות? איפוס יהפוך את כל המאמתים המוגדרים כעת לבלתי תקפים, ותצטרכו להגדיר אותם מחדש. - מפתח אימות חדש הופק! נא להשתמש בקוד QR מעודכן כדי לאפשר אימות. - יצוא סוד OTP - אתם בטוחים שברצונכם להעתיק את סוד ה-OTP ללוח ההעתקה?\n\nייתכן שתצטרכו לעשות זאת רק אם יישום האימות נתקל בבעיות בסריקת קוד QR, או שברצונכם להכניס אותו ידנית או להגדיר אסימון OTP של חומרה באמצעות יישום ייעודי. - סוד OTP (בפורמט Base32) יוצא והועתק אל לוח ההעתקה. הדביקו אותו לתוך תוכנת האימות או בחומרת צריבת OTP! - 1. התקנת מאמת - 3. ניסוי סיסמה חד-פעמית - איפוס מאמתים - בכל אחד מהטלפונים העוקבים, התקינו יישום מאמת התומך באסימוני RFC 6238 TOTP. יישומים פופולריים בחינם הם:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator חיזוי טיפולים שיפוע הסטייה @@ -839,21 +712,9 @@ סינון לא ניתן ליצור פרופיל מקומי. הפרופיל אינו חוקי. איך לא להשבית את האפליקציה שלי? - שולח SMS אם מופעל אירוע \"המשאבה אינה נגישה\" - דווח שהמשאבה אינה נגישה הפעל התראה כשצריכים לאכול - הפעל התראה בעוד %1$d דקות - יועץ הבולוסים - יש לכם היפרגליקמיה. במקום לאכול עכשיו מומלץ לחכות לרמת סוכר נמוכה יותר. האם תרצו לעשות בולוס תיקון עכשיו ולאחר מכן תופעל תזכורת לאכול? במקרה זה, לא יירשמו פחמימות ויהיה עליכם להשתמש באשף מחדש כאשר תגשו לאכול. - אפשר את יועץ הבולוסים - מציג תזכורת לאכול אחר כך במקום להזריק את המינון שהומלץ ע\"י האשף בעת היפרגליקמיה (\"בולוס מקדים\") זמן לאכול!\nהפעילו את אשף הבולוסים וחשבו בולוס חדש. - זמן לאכול - תזכורת בולוס אפשר את תזכורת בולוס - השתמש בתזכורת כדי להזריק בולוס מאוחר יותר במחשבון - (\"פוסט-בולוס\") - זמן להזריק בולוס!\nהשתמשו במחשבון וחשבו מחדש. העלאת רשומות קריסה מושבתת! גרף תפריט הגרף @@ -890,8 +751,6 @@ קבלת אירועי טיפול (צינורית, אינסולין, החלפת סוללה) שצוינו באמצעות נייטסקאוט או NSClient קבלת\\טעינת נתוני סנסור קבלת נתוני סנסור מנייטסקאוט - בהמתנה עד לסיום תקשורת קודמת עם המשאבה - ישנו בולוס נוסף בתור. נסו שוב מאוחר יותר. מבצע חישוב חסר שם לפרופיל שגיאה בערכי יחס הפחמימות @@ -936,7 +795,6 @@ אינסולין ערכי סוכר בדם לא עדכני - קביעת תזכורת הוסף פרופיל חדש שכפל את הפרופיל הנוכחי מחק את הפרופיל הנוכחי @@ -993,7 +851,6 @@ הצג לולאה %1$d נבחרו מיין - דו-שיח בוטל נמוך מאוד נמוך גבוה @@ -1011,7 +868,6 @@ התחברות הסר הכל אתחל התחלה - ברקוד QR ליצירת סיסמה חד פעמית פתח הגדרות הגדרת אזעקה טיימר פחמימות הכול @@ -1028,6 +884,5 @@ חסום ע\"י הגדרות טעינה חסום ע\"י הגדרות חיבור (השעון לא מחובר) - שגיאה בעת בקשת הרשאות כיוונון הרגישות והסוכר בדם diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index f39e3672d4..ead8b36546 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -12,7 +12,6 @@ 데이터베이스 초기화 데이터 베이스를 정말 초기화하시겠습니까? 종료 - 이 장치는 배터리 최적화 화이트리스트를 지원하지 않습니다 - 성능 문제가 발생할 수 있습니다. 일반 기능을 빠르게 실행시킬 버튼 활성화된 플러그인을 구성하는 데 사용됩니다. 프로그램 배우기 @@ -42,7 +41,6 @@ 인슐린: 탄수화물: IOB: - IOB: IOB 총량: 활동 IOB 총량: 기간: @@ -50,9 +48,7 @@ 인슐린: IOB: IOB 총량: - 혈당 임시목표 - 탄수화물 교정 지금 실행 가상 펌프 @@ -68,7 +64,6 @@ 혈당 데이터 없음 요청 증분 - Delta: 구성 관리자 관리 @@ -92,9 +87,6 @@ 새 임시Basal 적용: 관리 계산기 - 제한 적용! - Bolus: - Basal: 입력값을 변경하세요! 혈당 출처 xDrip+ @@ -107,12 +99,9 @@ 탄수화물 제안 지원하지 않는 Nightscout 버전입니다 Basal IOB - Bolus 제한이 적용되었습니다 - 탄수화물 제한이 적용되었습니다 기타 측정기 센서 - 기간 혈당 종류 임시Basal 확장 Bolus @@ -151,60 +140,6 @@ 모두 이해하였고 동의합니다. 저장 프로파일 새로고침 - SMS 통신기 - 허가된 전화번호 - +XXXXXXXXXX;+YYYYYYYYYY - Bolus %1$.2fU 을 주입하려면 %2$s 를 입력하고 답장하세요 - MEAL Bolus %1$.2f을 주입하려면 %2$s를 입력하고 답장하세요 - 임시목표 %1$s를 설정하려면 %2$s를 입력하고 답장하세요 - 임시목표를 취소하려면 %1$s를 입력하고 답장하세요 - SMS 원격 기능을 비활성화려면 %1$s를 입력하고 답장하세요.\n\nAAPS 마스터폰을 통해서만 다시 활성화할 수 있습니다. - SMS 원격 기능이 중지되었습니다. 다시 활성화하려면 AAPS 마스터폰을 이용하세요. - 보정값 %1$.2f을 전송하려면 %2$s 를 입력하고 답장하세요 - Bolus failed - 원격 Bolus를 주입한 후 얼마간의 시간이 흐른 후에야 다음 원격 Bolus주입이 가능합니다 - 원격 Bolus를 주입한 후 몇분이 지나야 다음 원격 Bolus 주입이 가능하게 합니까 - 안전을 위하여 이 설정을 수정하기 위해 최소 2개의 폰 번호를 추가해야합니다. - %1$.2f U이 주입됩니다. - Bolus %1$.2f U이 성공적으로 주입되었습니다. - 식사 Bolus %1$.2f U 이 성공적으로 주입되었습니다. - %2$d 분 동안 목표 %1$s - %2$d 분 동안 목표 %1$s 설정이 완료되었습니다 - 임시 목표 취소가 완료되었습니다 - SMS 원격 명령 사용하기 - Loop가 중지되었습니다. - Loop가 실행되었습니다. - Loop가 실행중입니다. - 코드 %1$s을(를) 사용하여 펌프에 연결하기 - 펌프에 연결하지 못했습니다. - %1$d분 동안 펌프 연결을 끊으려면 코드 %2$s를 입력하세요. - 펌프가 연결되지 않았습니다. - 펌프가 다시 연결되었습니다. - 원격 명령이 허가되지 않았습니다 - 원격 주입이 불가능합니다. 나중에 다시 시도해주세요. - %2$d분동안 basal %1$.2fU/h 주입하려면 %3$s을(를) 입력하세요. - 프로파일 %1$s %2$d%%로 변경하려면 %3$s 를 입력하고 답장하세요 - %2$d분동안 확장bolus %1$.2fU 주입하려면 %3$s을(를) 입력하세요. - %2$s에 %1$dg을 입력하려면 %3$s를 입력하고 답장하세요 - %2$d 분 동안 Basal %1$d%% 주입하려면 %3$s을 입력하고 답장하세요 - %1$d분동안 Loop 일시중지하려면 %2$s 를 입력하고 답장하세요 - 코드 %1$s을(를) 사용하여 loop의 작동 다시 시작하기 - 코드 %1$s을(를) 사용하여 loop의 작동 활성화하기 - 코드 %1$s을(를) 사용하여 loop의 작동 비활성화하기 - Temp Basal %1$.2fU/h for %2$d min started successfully - Extended bolus %1$.2fU for %2$d min started successfully - 탄수화물 %1$dg 입력이 완료되었습니다. - 탄수화물 %1$dg 입력이 실패하였습니다 - Temp basal %1$d%% for %2$d min started successfully - Temp Basal start failed - Extended bolus start failed - 임시Basal을 중지하려면 %1$s 를 입력하고 답장하세요 - 확장 Bolus를 중지하려면 %1$s 를 입력하고 답장하세요 - Temp Basal canceled - Extended bolus canceled - Canceling Temp Basal failed - Canceling extended bolus failed - 알려지지 않은 명령이거나 잘못된 답장입니다 빠른마법사 빠른마법사 설정 버튼명: @@ -234,13 +169,9 @@ 워치 모든 데이터 다시 보내기 워치에서 설정 열기 - Basal값이 최소값 이하입니다. 프로파일이 설정되지 않습니다! - BG: - Last BG: 미니메드640g 연속 알림 오래된 데이터 - %dmin ago OpenAPS AMA %1$d 요소의 배열.\n실제 값: Autosens 정보 @@ -258,7 +189,6 @@ TREAT OBJ WEAR - SMS 탭 이름 단축 단순증분값 대신 단기평균증분값을 항상 사용합니다. xDrip+처럼 필터링되지 않은 혈당 출처에서 받은 데이터의 노이즈가 심할 경우 유용함. @@ -272,13 +202,6 @@ 기본값: 2\n식사주입 후 Bolus snooze가 수행되게 되고, 따라서 식사주입 직후엔 loop가 low temp에 대응하지 않게 됩니다. 기본값이 2일때 예제는 다음과 같습니다; DIA가 3시간일 경우 bolus snooz는 점차적으로 1.5시간에 걸쳐 단계적으로 사라지게 됩니다.(3DIA/2). 기본값: 3.0 (AMA) 또는 8.0 (SMB). 5분당 탄수화물이 얼만큼 흡수되었는지에 대한 기본값 설정입니다. 기본값은 3mg/dl / 5분 입니다. 이는 혈당이 예상보다 빨리 떨어지거나 혹은 예상보다 오르지 않을때, COB가 얼마나 빨리 사라지게 되는지에 영향을 주게 되고, 추정된 탄수화물 흡수량이 미래 혈당 예측 계산시에도 영향을 주게 됩니다. 주의!\n보통의 경우 아래의 값을 변경하면 안됩니다. 이 값들을 변경하기 전에 반드시 이곳을 클릭하고 글을 정독해서 확실하게 이해를 하여야 합니다. - SMS폰번호가 유효하지 않습니다 - 보정 - xDrip+가 설치되지 않았습니다 - 보정이 xDrip으로 전송되었습니다+ - 보정 전송됨. xDrip에서 수신이 되도록 설정되어 있어야 합니다+. - xDrip+에서 보정값을 받지 못합니다. - 펌프 일시중지됨 실행중 가상펌프 설정 NS에 상태 업로드하기 @@ -314,10 +237,7 @@ 안전 제한 설정을 위해 환자 유형을 선택하십시오. 환자 이름 다양한 설정들을 구별하기 위하여 환자 이름 또는 별명을 입력합니다. - 사용자 Glimp - Loop 일시중지 - 일시중지중 (%d분) 1시간동안 Loop 일시중지 2시간동안 Loop 일시중지 3시간동안 Loop 일시중지 @@ -336,9 +256,6 @@ 10시간 재실행 펌프 재연결 - 기간이 잘못되었습니다. - Loop가 일시중지 되었습니다. - Loop가 재실행 되었습니다. COB Superbolus 앱시작을 NS에 기록하기 @@ -372,7 +289,6 @@ ABS DEVSLOPE 버전정보 - SMS 권한 누락 전화 상태 권한이 허가되지 않았습니다 xDrip+ 상태 (워치) xDrip+ 상태표시라인 (워치) @@ -440,14 +356,11 @@ 워치로 제어하기 임시목표와 관리입력을 워치로 설정합니다. 음식 - g ]]> kJ En 단백질 지방 - 명령을 지금 실행합니다. - 혈당 읽기가 누락되었습니다. 경고와 알림시 시스템 알림 사용하기 알람과 알림의 소리를 점차적으로 증가시킴 자체 경고 기능 @@ -521,9 +434,6 @@ fabric.io 서비스를 통해 개발자에게 앱 오류 및 특정 데이터를 자동 전송합니다. Dexcom앱을 지원가능한 버전으로 업데이트하세요. Dexcom 앱이 설치되지 않았습니다. - 활동 임시목표 시작 - 식사직전 임시목표 시작 - TT 실제 Bolus 주입않고, 기록만 하기 분류 하위 분류 @@ -536,8 +446,6 @@ 체내탄수화물양(COB) 체내인슐린양(IOB) Basal - 선택한 실행이 없습니다. 아무런 실행이 되지 않습니다. - 저혈당 임시목표 시작 개발자버전을 실행중입니다. Closed Loop는 비활성화 됩니다. 전문가 모드 사용 프로파일변경 누락. 로컬 프로파일에서 프로파일 변경을 하거나 \"프로파일 활성화하기\"를 누르세요. @@ -556,7 +464,6 @@ %2$s로 인해 IOB가 %1$.1f U으로 제한됩니다. 설정에서의 최대값 하드한계 - 상태를 읽지 못했습니다. 펌프 위치 변경 기록 인슐린 카트리지 변경 기록 선택한 혈당 출처가 고급 필터링을 지원하지 않기 때문에 SMB가 항상 비활성화됩니다. @@ -607,12 +514,7 @@ 하단의 RileyLink를 설정하십시오. RileyLink를 선택한 뒤, RileyLink 상태가 \"연결됨\"이 되고 나면 설정을 계속 할 수 있습니다. 이 작업은 금방 진행됩니다.\n 참고: 펌프가 한 번 연동되면 계속 설정할 수 있습니다.\n 첫번째 목표를 시작하세요. - 권한 권한 요청하기 - 알림에 대한 시스템 창 권한이 필요합니다 - 어플은 BT scan과 WiFi 식별을 위해 \"위치 허용\"이 요구됩니다. - 어플은 로그 파일 저장과 설정 내보내기를 위해 \"저장공간 허용\"이 요구됩니다. - 요청 메뉴 열기 메뉴 닫기 플러그인 설정 @@ -646,7 +548,6 @@ 로그 설정 기본값으로 초기화 NSClient가 정상적으로 작동하지 않습니다. Nightscout와 NSClient를 재시작 해보세요. - 시간 이동 선호하는 APS 모드 합계 Calc @@ -676,11 +577,6 @@ 썸머타임 변경이 3시간 미만입니다 - Closed Loop 비활성됨 내부 저장 용량 제한 내부 저장 공간을 최소 %1$d MB 이상 비우세요! Loop가 비활성화되었습니다! - 잘못된 형식 - TBR 기간은 %1$d분의 배수가 되어야 하고 0보다 커야 함. - 잘못된 코드입니다. 명령이 취소됩니다. - 설정되지 않음 - 프로파일 변경 생성됨 버전 검사기 오래된 버전 아주 오래된 버전 @@ -693,12 +589,10 @@ Bolus 마법사는 계산을 수행하지만 계산된 인슐린의 이 부분만 주입됩니다. SMB 알고리즘에 유용합니다. 스누즈 설정이 프로파일에서의 최대 Basal보다 낮은 이유로 최대 Basal을 올립니다 - 잘못된 메시지 내용 %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - 프로파일명: 선택: 단위 @@ -743,25 +637,6 @@ SMB 실행시간 임시 Basal 요청시간 임시 Basal 실행시간 - - 인증 어플에서: %1$s 뒤에 PIN - 암호 끝에 더해지는 자동형성 PIN - 부가적인 숫자를 생성되는 일회성 비밀번호 끝에 더하고 기억해야 함. - 인증 설정 - 확인용 code: - OTP + PIN - 유효한 코드는 인증 어플에서 보여지는 6개의 숫자 (OTP) 뒤에 자동형성 PIN의 3개 또는 그 이상의 숫자가 이어져야 함. - 인증 초기화 - 인증 암호 초기화 - 인증 암호를 초기화하는 것이 확실합니까? 현재 설정된 인증 암호를 모두 무효화 시키며, 이들을 모두 다시 설정해야 합니다. - 새로운 인증 암호가 생성되었습니다! 준비된 인증 어플에서 업데이트된 QRCode를 사용하십시오. - OTP 비밀번호 내보내기 - OTP 비밀번호의 클립보드 복사를 원하는 것이 확실합니까?\n\n 이는 인증 어플이 QRCode를 스캐닝하는데 문제가 있을 때, 비밀번호 수동 입력을 원할 때, 또는 공용 어플 사용 시에 하드웨어 OTP 암호 설정을 원할 때에만 필요합니다. - OTP 비밀번호 (Base32 포맷)가 클립보드에 내보내져서 복사되었습니다. 인증 어플 또는 하드웨어 OTP burner에 붙여넣기 하십시오! - 1. 인증어플 설치하기 - 3. 일회성 비밀번호 테스트 - 인증 초기화 - 각각의 팔로워 폰에 RFC 6238 TOTP 암호를 사용하는 인증 어플을 설치합니다. 대중적인 무료 어플은 다음과 같습니다:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator. 예측 편차 기울기 인증 실패 @@ -790,16 +665,8 @@ RileyLink 상태: 필터 앱이 종료되지 않도록 합니다? - 허용되지 않는 펌프 이벤트가 발생하면 SMS를 보내기 - 허용되지 않는 펌프 기록 식사 시간이 되면 알람을 울리기 - %1$d분 뒤 알람 울림 - Bolus advisor - 현재 혈당이 높습니다. 지금 식사를 하기 보다 적절한 혈당이 되도록 기다리는 것을 추천합니다. 교정 bolus를 지금 주입하고 식사할 시간이 되면 알려드릴까요? 이 경우 탄수화물은 기록되지 않으며, 알림을 받으면 wizard를 다시 사용해야 합니다. - Bolus advisor 활성화 - 혈당이 높을 때 wizard 결과 대신 reminder를 사용하여 나중에 식사하기 (pre-bolus) 식사할 시간입니다! \nBolus wizard를 켜고 다시 계산하십시오. - 식사할 시간 충돌 로그 업로드가 작동하지 않습니다. 그래프 차트 메뉴 @@ -830,8 +697,6 @@ NS 또는 NSClient에서 입력한 처치 이벤트 (캐뉼라, 인슐린, 배터리 교체 등) 수락하기 CGM 데이터 받기/다시 채우기 NS로부터 CGM 데이터 수락하기 - 직전의 펌프 통신 종료를 기다리는 동안 타임 아웃 - 대기열에 또다른 bolus가 있습니다. 이후에 다시 시도하세요. 계산 진행 중 diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index 9845e822fe..3387e4b49a 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -12,7 +12,6 @@ Iš naujo nustatyti duomenų bazę Ar tikrai norite iš naujo nustatyti duomenų bazę? Išeiti - Šis įrenginys nepalaiko baterijos optimizavimo išimčių - galite patirti veikimo nesklandumų. Mygtukai greitesniam pagrindinių funkcijų paleidimui Naudojama aktyvių įskiepių konfigūravimui Mokymosi programa @@ -42,7 +41,6 @@ Insulinas: AV: AIO: - AIO: Visas AIO: Bendro AIO aktyvumas: Trukmė: @@ -50,9 +48,7 @@ Ins: AIO: Visas AIO: - KG LT - AV Korekcija Bolusų AIO Paleisti dabar @@ -69,7 +65,6 @@ Nėra gliukozės duomenų Užklausa Pokytis - Pokytis: Konfigūracija Apžvalga Terapija @@ -90,13 +85,9 @@ Saugumas Įskiepis išjungtas Apribojimų pažeidimas - Boluso suleidimo klaida. Rankiniu būdu patikrinkite faktiškai suleistą kiekį Patvirtinti naują laikiną bazę: Terapija Skaičiuotuvas - Taikomas ribojimas! - Bolusas: - Valandinė bazė: Pakeiskite įvestus duomenis! Glikemijos šaltinis xDrip+ @@ -109,13 +100,10 @@ Angliavandenių pasiūlymas Nepalaikoma Nightscout versija Bazės AIO - Pritaikytas boluso apribojimas - Pritaikytas AV apribojimas Kiti Matuoklis Sensorius AV laikas - Trukmė Profilis Gliukozės tipas Laikina bazė @@ -155,60 +143,6 @@ SUPRATAU IR SUTINKU Išsaugoti Atnaujinti profilį - SMS komunikatorius - Leidžiami telefono numeriai - +370XXXXXXXX; +370YYYYYYYY - Norėdami suleisti %1$.2fvv bolusą, atsakykite kodu %2$s - Norėdami suleisti %1$.2fvv bolusą, atsakykite su kodu %2$s - Norėdami nustatyti laikiną tikslą %1$s, atsakykite su kodu %2$s - Norėdami atšaukti laikiną tikslą, atsakykite su kodu %1$s - Norėdami išjungti SMS nuotolinį valdymą, atsakykite kodu %1$s.\n\n Turėkite omenyje, kad jūs funkciją galėsite atnaujinti tiesiai tik iš AAPS pagrindinio telefono. - SMS nuotolinio valdymo funkcija sustojo. Norėdami ją atnaujinti, naudokite AAPS pagrindinį išmanųjį telefoną. - Norėdami nusiųsti kalibraciją %1$.2f, atsakykite kodu %2$s - Bolusas nesuleistas - Minimalus minučių skaičius, kuris turi praeiti nuo vieno boluso, suleisto nuotoliniu būdu iki kito - Kiek mažiausiai minučių turi praeiti tarp vieno ir kito boluso - Jūsų saugumui, norėdami redaguoti šį pasirinkimą, jums reikia pridėti ne mažiau kaip 2 telefono numerius. - Bus suleista %1$.2f vv - %1$.2f vv bolusas sėkmingai suleistas - Bolusas %1$.2f vv sėkmingai suleistas - Tikslas %1$s %2$d min. - Tikslas %1$s %2$d min. nustatytas sėkmingai - Laikinas tikslas atšauktas sėkmingai - Leisti nuotolines komandas SMS žinutėmis - Ciklas buvo išjungtas - Ciklas buvo įjungtas - Ciklas įjungtas - Pompos prijungimui atsakykite su kodu %1$s - Nepavyko prisijungti prie pompos - Norėdami atjungti pompą %1$d min., atsakykite kodu %2$s - Pompa atjungta - Pompa prijungta - Nuotolinis valdymas negalimas - Nuotolinis bolusas negalimas. Bandykite vėliau. - Norėdami aktyvuoti %1$.2f vv/val bazę, kurios trukmė %2$d min, atsakykite kodu %3$s - Norėdami perjungti profilį %1$s %2$d%%, atsakykite kodu %3$s - Norint pradėti ištęstinį bolusą %1$.2f vv %2$d min., atsakykite kodu %3$s - Įvedimui %1$dg %2$s atsakykite kodu %3$s - Norėdami aktyvuoti %1$d%% bazę %2$d min., atsakykite kodu %3$s - Norėdami sustabdyti Ciklą %1$d min., atsakykite kodu %2$s - Ciklo atnaujinimui atsakykite su kodu %1$s - Ciklo įjungimui atsakykite su kodu %1$s - Ciklo išjungimui atsakykite su kodu %1$s - %1$.2f vv/val laikina bazė, kurios trukmė %2$d min., aktyvuota sėkmingai - %1$.2f vv ištęstas bolusas, kurio trukmė %2$d min., aktyvuotas sėkmingai - %1$d g angliavandenių įrašyti sėkmingai - Įvesti %1$dg angliavandenių nepavyko - %1$d%% laikina bazė, kurios trukmė %2$d min., aktyvuota sėkmingai - Laikina bazė neaktyvuota - Ištęstinis bolusas nepradėtas - Norėdami sustabdyti laikiną bazę, atsakykite kodu %1$s - Norėdami sustabdyti ištęstinį bolusą, atsakykite kodu %1$s - Laikina bazė atšaukta - Ištęstinis bolusas atšauktas - Laikinos bazės atšaukti nepavyko - Nepavyko atšaukti ištęstinio boluso - Nežinoma komanda arba neteisingas atsakymas Greitasis patarėjas Greitojo patarėjo nustatymai Mygtuko tekstas: @@ -238,13 +172,9 @@ Išmanieji laikrodžiai Pakartotinai siųsti visus duomenis Atidaryti išmaniojo laikrodžio nustatymus - Valandinės bazės vertė mažesnė už minimalią. Profilis nenustatytas! - KG: - Paskutinė KG: MM640g Nuolatinis pranešimas SENI DUOMENYS - prieš %1$dmin Profilis OpenAPS AMA %1$d elementų masyvas. \naktuali vertė: @@ -263,7 +193,6 @@ ĮRAŠ TIKSL WEAR - SMS Naudoti sutrumpintus skirtukų pavadinimus Visada naudoti trumpo laikotarpio vidutinį pokyti vietoj paprasto pokyčio Naudinga, kai duomenys, gaunami iš nefiltruoto šaltinio, tokio kaip xDrip+, tampa nestabilūs. @@ -277,13 +206,6 @@ Numatytoji reikšmė: 2\nBoluso snaudimas aktyvuojamas iškart po to, kai susileidžiate bolusą maistui. Ši funkcija neleidžia sistemai nustatyti mažų LBD iškart po valgio. Pvz.: jei IVT yra 3 val, tai boluso snaudimas pamažu deaktyvuojamas per 1,5 val (3 val. / 2). Numatytoji reikšmė: 3.0 (AMA) arba 8.0 (SMB). Tai parametras, nurodantis angliavandenių poveikį kraujo gliukozei kas 5 minutes nuo jų suvartojimo. Numatytoji reikšmė yra 3 mg/dl per 5min. Šis skaičius turi įtakos apskaičiavimams, kaip greitai mažės AAO, kokia bus kraujo gliukozės kitimo prognozė, ypač kai ji krenta daugiau nei tikėtasi, arba nedidėja tiek, kiek tikėtasi. Dėmesio!\nPaprastai neturėtumėte keisti šių, žemiau esančių, reikšmių. Prašome PASPAUSTI ČIA ir PERSKAITYKITE tekstą ir įsitikinkite, kad SUPRANTATE prieš keisdami bet kurią iš šių verčių. - Neteisingas SMS telefono numeris - Kalibravimas - xDrip+ neįdiegta - Kalibracija nusiųsta į xDrip+ - Kalibracija išsiųsta. xDrip+ programoje turi būti įgalintas gavimas. - xDrip+ negauna kalibracijų - Pompa sustabdyta Vykdoma Virtualios pompos nustatymai Perduoti būsenos duomenis į NS @@ -319,10 +241,7 @@ Pasirinkite paciento tipą saugumo riboms nustatyti Paciento vardas Pateikite paciento vardą arba slapyvardį, kad galima būtų atskirti tarp skirtingų konfigūracijų. - Vartotojas Glimp - Ciklas sustabdytas - Sustabdyta (%1$d m) Sustabdyti ciklą 1 val Sustabdyti ciklą 2 val Sustabdyti ciklą 3 val @@ -341,9 +260,6 @@ 10 val. Atnaujinti Prijungti pompą - Neteisinga trukmė - Ciklas sustabdytas - Ciklas atnaujintas 15 min tendencija AAO Superbolus @@ -378,7 +294,6 @@ ABS DEVSLOPE Apie - Trūksta leidimo SMS Trūksta telefono būsenos leidimo xDrip+ statusas (laikrodyje) xDrip+ būsenos juosta (laikrodyje) @@ -446,14 +361,11 @@ Laikrodžio valdikliai Nustatyti Laikinus Tikslus ir įvesti terapinius įrašus iš laikrodžio. Maistas - g ]]> kJ Energ. vertė Balt. Rieb - Komanda vykdoma - Negauti KG duomenys Naudoti sistemos perspėjimus aliarmams ir įspėjimams Palaipsniui didinkite įspėjimų ir pranešimų garso lygį Lokalūs perspėjimai @@ -530,9 +442,6 @@ Leisti automatinį pranešimų apie programos trikdžius ir funkcijų naudojimo duomenų siuntimą kūrėjams, naudojant fabric.io servisą. Atnaujinkite savo Dexcom programėlės versiją Dexcom app neįdiegta. - Pradėti Aktyvumo LT - Pradėti Netrukus valgysiu LT - LT Boluso nesuleisti, tik įrašyti Kategorija Subkategorija @@ -545,8 +454,6 @@ Aktyvūs angliavandeniai Aktyvus insulinas organizme Bazė - Veiksmas nepasirinktas, nieko neįvyks - Pradėti \"Hipo\" LT Naudojama neužbaigta versija. Uždaras ciklas neaktyvus. Inžinerinis režimas įjungtas Neatliktas profilio keitimas. Prašome atlikti profilio keitimą arba paspausti \"Aktyvuoti profilį\" Vietinio profilio (VP) skiltyje. @@ -565,7 +472,6 @@ Ribojamas AIO iki %1$.1f V dėl %2$s Maksimali reikšmė nustatymuose Nekeičiama riba - Būsenos nuskaityti nepavyko Įrašas apie infuzijos rinkinio keitimą Įrašas apie rezervuaro keitimą Funkcijos \"SMB visada\" ir \"SMB po angliavandenių\" išjungtos, nes kraujo gliukozės duomenų šaltinis neturi reikalingo filtravimo @@ -617,12 +523,7 @@ Sukonfigūruokite RileyLink žemiau. Pasirinkę RileyLink, galėsite tęsti diegimą, kai tik RileyLink būsena bus „Prisijungta“. Tai gali užtrukti minutę.\n Pastaba: Sąranką galite tęsti, kai tik inicijuojama pompa.\n Pradėti jūsų pirmąjį tikslą - Leidimas Prašyti leidimo - Norint gauti pranešimus, programai reikalingas sisteminio lango leidimas - Programai reikia vietos nustatymo leidimo, kad būtų galima naudoti Bluetooth ir WiFi - Aplikacijai reikia leidimo prieigai prie saugyklos, kad galėtų išsaugoti žurnalo įrašus ir eksportavimo nustatymus - Užklausa Atidaryti meniu Uždaryti meniu Įskiepių nustatymai @@ -658,8 +559,6 @@ Įrašų nustatymai Atkurti numatytuosius NSClient sutrikimas. Reikėtų paleisti iš naujo NS ir NSClient. - Laiko poslinkis - Priminti apie bolusą vėliau Pageidaujamas DKS režimas Viso Skaič. @@ -689,11 +588,6 @@ Laiko persukimas įvyks po mažiau nei 3 val - Uždaras ciklas deaktyvuotas vidinės saugyklos apribojimas Atlaisvinkite ne mažiau kaip %1$d MB iš vidinės atminties! Ciklas išjungtas! - Neteisingas formatas - Laikinos bazės trukmė turi būti kartotinė %1$d minučių ir didesnė nei 0. - Neteisingas kodas. Komanda atšaukta. - Nesukonfigūruota - Profilio perjungimas sukurtas Versijos tikrintuvas sena versija labai sena versija @@ -710,12 +604,10 @@ Boluso skaičiuoklė atlieka skaičiavimus, tačiau tik dalis apskaičiuoto insulino yra suleidžiama. Naudinga kartu su SMB algoritmu. Snausti Didinama maksimali valandinės bazės reikšmė, nes nustatytoji reikšmė yra mažesnė nei profilio maksimali val. bazės reikšmė - Neteisingas pranešimas %1$s JIF: %2$.1f %1$.0fg IA: %2$.1f %1$.1fg IA: %2$.1f %1$d%% - min. Profilio pavadinimas: Parinkta: Vienetai @@ -761,25 +653,6 @@ SMB įvykdymo laikas Laikinos bazės užklausos laikas Laikinos bazės įvykdymo laikas - - iš Authenticator programėlės: %1$s, po to - PIN - Papildomas privalomas PIN kodas žymeklio gale - Papildomi skaitmenys, kuriuos reikia atsiminti ir pridėti kiekvieno sugeneruoto slaptažodžio pabaigoje - Autentifikavimo sąrankos nustatymas - Kodas patikrinimui: - OTP + PIN - Patvirtinimo kodą sudaro 6 skaitmenys, kuriuos rodo Authenticator programa (dar vadinama OTP), po 3 ar daugiau privalomo PIN skaitmenų. - Atstatyti tapatybės nustatymą - Atstatyti autentifikatoriaus kodą - Ar tikrai norite iš naujo nustatyti autentifikatoriaus raktą? Dėl to visi šiuo metu konfigūruojami autentifikatoriai negalios, ir jums reikės juos nustatyti dar kartą. - Sukurtas naujas autentifikavimo raktas! Autentifikatoriams pateikti naudokite atnaujintą QR kodą. - Eksportuojamas OTP kodas - Ar tikrai norite nukopijuoti OTP slaptažodį į mainų sritį?\n\nTai gali būti reikalinga tik tuo atveju, jei jūsų programai kyla problemų identifikuojant nuskaitant QR kodą. Arba norite jį įvesti rankiniu būdu ar sukonfigūruoti įrangos OTP prieigos raktą naudodami specialią programą. - OTP kodas (Base32 formatas) eksportuotas ir nukopijuotas į mainų sritį. Įklijuokite jį į autentifikatorių arba OTP programą! - 1. Įdiegti Authenticator - 3. Patikrinti vienkartinį slaptažodį - Atstatyti tapatybės nustatymą - Kiekviename telefone, palaikančiame RFC 6238 TOTP prieigos raktus, įdiekite autentifikavimo programą. Populiariausios nemokamos programos yra:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Prognozė Nukrypimo koeficientas Autorizacija nepavyko @@ -809,20 +682,9 @@ Filtruoti Nepavyksta sukurti profilio. Profilis neteisingas. Don\'t kill my app? - Siųsti SMS, jei aptinkamas įrašas apie nepasiekiamą pompą - Pranešti apie nepasiekiamą pompą Pranešti apie laiką valgyti - Pranešti po %1$d min - Boluso patarėjas - Jūsų glikemija yra aukšta. Užuot valgę dabar, turėtumėte palaukti, kol sumažės glikemija. Ar norite dabar susileisti korekcinį bolusą ir nustatyti priminimą, kada ateis laikas valgyti? Tokiu atveju angliavandeniai nebus įrašyti, o po priminimo turėsite vėl naudoti boluso skaičiuoklę. - Įgalinti boluso patarėją - Galimybė priminti jums valgyti vėliau (pvz., esant aukštai glikemijai) boliuso vedlyje („po susileidimo palaukti ir valgyti vėliau“) Laikas valgyti!\nĮjunkite Boluso patarėją ir atlikite skaičiavimą dar kartą. - Laikas valgyti - Priminimas apie bolusą Įgalinti priminimą apie bolusą - Naudoti priminimus apie bolusą su skaičiuotuvu („post-bolusas“) - Laikas bolusui!\nĮjunkite Skaičiuotuvą ir pakartokite skaičiavimus. Sutrikimų žurnalo įrašų įkėlimas išjungtas! Grafikas Grafiko meniu @@ -857,8 +719,6 @@ Priimti terapijos įvykius (kaniulės, insulino, baterijos keitimą ir pan.), įvestus per NS arba NSClient Gauti/užpildyti atgaline data NGJ duomenis Priimti NGJ duomenis iš NS - Baigėsi laikas kol buvo laukiama, kada baigsis ankstesnis susijungimas su pompa - Kitas bolusas laukia eilėje. Bandykite dar kartą vėliau. Skaičiuojama Profilio pavadinimas nėra įrašytas Insulino ir AV santykio (I:A) reikšmės klaida diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index cd676a86be..cc0757af53 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -13,7 +13,6 @@ Reset database Wil je echt de database wissen? Afsluiten - Dit apparaat lijkt geen ondersteuning te bieden voor whitelisten voor batterijoptimalisatie - u kunt prestatieproblemen ervaren. Een aantal knoppen voor snelle toegang tot algemene functies Gebruikt om actieve plugins te configureren Leerprogramma @@ -44,7 +43,6 @@ Insuline: Koolhydraten: IOB: - IOB: Totale IOB: Totale IOB activiteit: Tijdsduur: @@ -52,9 +50,7 @@ Ins: IOB: Totale IOB: - BG TT - Koolhydraten Correctie Bolus IOB Nu uitvoeren @@ -71,7 +67,6 @@ Geen BG gegevens beschikbaar Voorstel Verschil - Verschil: Configurator Overzicht Behandelingen @@ -92,13 +87,9 @@ Veiligheid Plugin is gedeactiveerd In strijd met beperkingen - Bolus fout geconstateerd. Controleer de daadwerkelijk toegediende hoeveelheid Accepteer nieuw tijdelijk basaal: Bolus Bolus wizard - Beperking toegepast! - Bolus: - Basaal: Wijzig het ingegevene! BG bron xDrip+ @@ -111,13 +102,10 @@ Koolhydraten Voorstel Niet ondersteunde versie van Nightscout Basaal IOB - Bolus limiet ingesteld - KH limiet ingesteld Andere Meter Sensor KH tijdsduur - Tijdsduur Profiel Glucose type Tijdelijk basaal @@ -157,60 +145,6 @@ Begrepen en goedgekeurd Opslaan Herlaad profiel - SMS Commando\'s - Geautoriseerde telefoon nummers - +XXXXXXXXXX;+YYYYYYYYYY - Om een bolus van %1$.2fE te geven antwoord met de code %2$s - Om een maaltijd bolus van %1$.2fE te geven antwoord met de code %2$s - Om tijdelijk streefdoel %1$s in te stellen antwoord met code %2$s - Om tijdelijk streefdoel te annuleren antwoord met code %1$s - Om de SMS Remote Service uit te zetten, antwoord met code %1$s. \n\nDenk er aan dat je deze alleen weer aan kunt zetten op de AAPS master smartphone. - De controle via SMS is uitgezet. Gebruik AAPS op de master smartphone om deze weer te aan te zetten. - Om calibratie %1$.2f te verzenden antwoord met de code %2$s - Bolus mislukt - Minimum aantal minuten dat moet verstrijken tussen de ene bolus op afstand en de volgende - Hoeveel minuten er ten minste moeten verstrijken tussen de ene bolus en de volgende - Voor de veiligheid moet je ten minste 2 telefoonnummers toevoegen om deze instelling te kunnen bijwerken. - %1$.2f E toedienen - Bolus van %1$.2f E succesvol toegediend - Maaltijdbolus van %1$.2f E succesvol toegediend - Streefdoel %1$s gedurende %2$d minuten - Streefdoel %1$s gedurende %2$d minuten succesvol ingesteld - Tijdelijk streefdoel is geannuleerd - Sta SMS commando\'s toe - Loop was uitgeschakeld - Loop was ingeschakeld - Loop is ingeschakeld - Om verbinding te maken met pomp antwoord met code %1$s - Verbinding maken met pomp is mislukt - Om de pomp te ontkoppelen gedurende %1$d minuten antwoord met code %2$s - Pomp verbinding verbroken - Pomp opnieuw verbonden - Commando\'s op afstand zijn niet toegestaan - Bolus op afstand niet beschikbaar. Probeer het later opnieuw. - Om een basaal van %1$.2f E/uur gedurende %2$d min te starten, antwoord met code %3$s - Om naar profiel %1$s %2$d%% te wisselen antwoord met code %3$s - Om een vertraagde bolus van %1$.2f E gedurende %2$d min te starten, antwoord met code %3$s - Om %1$dg in te voeren om %2$s antwoord met code %3$s - Om een basaal van %1$d%% gedurende %2$d min te starten antwoord met code %3$s - Om de loop te onderbreken gedurende %1$d minuten antwoord met de code %2$s - Om loop te hervatten antwoord met code %1$s - Om loop in te schakelen antwoord met code %1$s - Om loop uit te schakelen antwoord met code %1$s - Tijdelijk basaal %1$.2fE/uur voor %2$d minuten succesvol gestart - Vertraagde bolus %1$.2fE voor %2$d minuten succesvol gestart - Koolhydraten %1$d g succesvol ingevoerd - Invoeren van %1$dg koolhydraten is mislukt - Tijdelijk basaal van %1$d%% voor %2$d minuten succesvol gestart - Start tijdelijk basaal mislukt - Starten vertraagde bolus is mislukt - Om het tijdelijke basaal te stoppen antwoord met de code %1$s - Om de vertraagde bolus te stoppen antwoord met de code %1$s - Tijdelijk basaal afgebroken - Vertraagde bolus is geannuleerd - Afbreken van tijdelijk basaal mislukt - Annuleren van vertraagde bolus is mislukt - Onbekende opdracht of verkeerd antwoord Vaste maaltijd Vaste maaltijd instellingen Naam: @@ -241,13 +175,9 @@ Update Wear gegevens Open instellingen op Wear Basaalstand - Basaalwaarde onder minimum. Profiel niet ingesteld! - BG: - Laatste BG: MM640g Permanent bericht Oude gegevens - %1$dmin geleden Profiel OpenAPS AMA Array van %1$d elementen. \nActuele waarde: @@ -267,7 +197,6 @@ BEHAND DOEL WEAR - SMS Afgekorte tab titels Gebruik altijd korte gemiddeld verschil ipv gewone verschil Nuttig wanneer gegevens van niet gefilterde bronnen zoals xDrip+ veel ruis heeft. @@ -281,13 +210,6 @@ Standaard waarde: 2\nBolus snooze is actief nadat je een maaltijd bolus toegediend hebt, zodat de loop geen tegenvoorstel met een verlaagd tijdelijk basaal doet nadat je gegeten hebt. Het voorbeeld hier van van standaard 2; dus een 3 u DIA betekent dat de bolus snooze gemiddeld 1.5u actief is (3DIA/2). Standaardwaarde: 3,0 (AMA) of 8,0 (SMB). Dit is een instelling voor de standaard koolhydraten absorptie-impact per 5 minuten. De standaard is een verwachte 3mg / dl / 5min. Dit is van invloed op hoe snel COB zijn opgenomen en hoeveel koolhydraten absorptie wordt verwacht, bij het voorspellen van toekomstige BG, wanneer BG meer dan verwacht daalt of niet zoveel stijgt als verwacht. Opgelet!\n Onderstaande waardes moeten normaal gezien niet worden aangepast. KLIK HIER en LEES de tekst zodat je alles volledig BEGRIJPT voordat je een waarde wijzigt. - Foutief SMS telefoon nummer - Kalibratie - xDrip+ niet geïnstalleerd - Kalibratie verzonden naar xDrip+ - Kalibratie verzonden. xDrip+ moet zo zijn ingesteld dat hij het ontvangen van kalibraties toestaat. - xDrip+ ontvangt geen kalibraties - Pomp onderbreken Uitvoeren Virtuele pomp instellingen Upload status naar NS @@ -323,10 +245,7 @@ Selecteer het type patiënt om de veiligheidslimieten in te stellen Naam patiënt Geef de naam of roepnaam van de patiënt op om onderscheid te maken tussen meerdere setups - Gebruiker Glimp - Loop pauzeren - Gepauzeerd (%1$d m) Onderbreek loop voor 1u Onderbreek loop voor 2u Onderbreek loop voor 3u @@ -345,9 +264,6 @@ 10 uur Hervatten Opnieuw verbinden met pomp - Verkeerde tijdsduur - Loop onderbroken - Loop hervat 15min trend COB Superbolus @@ -382,7 +298,6 @@ ABS DEVSLOPE Over - Geen SMS bevoegdheid Machtiging ontbreekt voor telefoon gebruik xDrip+ Status (horloge) xDrip+ Statuslijn (horloge) @@ -454,14 +369,11 @@ Bedieningen via horloge Stel tijdelijke doelen en bolussen in vanop je horloge. Voeding - g ]]> kJ En Prot Vet - Opdracht is nu uitgevoerd - Geen BG metingen Gebruik systeem notificaties voor waarschuwingen en notificaties Volume van notificaties en meldingen geleidelijk verhogen Lokaal gegenereerde waarschuwingen @@ -539,9 +451,6 @@ Sta automatische crashrapporten en verder gebruik van data toe zodat deze naar de ontwikkelaars via fabric.io kan verzonden worden. Gelieve Dexcom app naar ondersteunde versie te updaten Dexcom app is niet geïnstalleerd. - Start inspanning TT - Start binnenkort eten TT - TT Geen bolus toedienen enkel in behandelingen zetten Categorie Subcategorie @@ -554,8 +463,6 @@ Opgenomen Koolhydraten Opgenomen Insuline Basalen - Geen actie geselecteerd, er zal niets uitgevoerd worden - Start Hypo TT Dev versie actief. Closed loop gedeactiveerd Engineering modus is geactiveerd Profiel wissel ontbreekt. Doe aub een profiel wissel of duw op Activeer Profiel in het Lokale profiel. @@ -574,7 +481,6 @@ IOB gelimiteerd tot %1$.1f E doordat %2$s Maximum waarde in instellingen max limiet (SC) - Lezen van status mislukt Markeer een infuuswissel in NS Markeer een insuline ampul wissel in NS SMB altijd gedeactiveerd doordat de gekozen BG bron geen optimale filtering toepast @@ -631,12 +537,7 @@ Configureer uw RileyLink hieronder. Na het selecteren van een RileyLink, kun je doorgaan zodra de RileyLink status \"Verbonden\" is. Dit kan even duren.\n Opmerking: Je kunt doorgaan zodra de pomp is ingesteld.\n Start je eerste Doel - Toestemming Vragen om toestemming - Toepassing vereist systeemvenstermachtiging voor meldingen - App heeft locatie toestemming nodig voor Bluetooth scan en WiFi identificatie - Applicatie heeft toestemming nodig om log bestanden op te slaan en instellingen te exporteren - Verzoek Open navigatie Sluit navigatie Plugin instellingen @@ -678,8 +579,6 @@ Log instellingen Terug naar standaardinstellingen NSClient werkt niet goed. Overweg een herstart van NS en NSClient. - Tijdverschuiving - Herinner later te bolussen Voorkeur APS-modus Totaal Calc @@ -709,11 +608,6 @@ Omschakeling zomer/wintertijd minder dan 3 uur geleden - Gesloten Lus modus gedeactiveerd interne opslag bijna vol Maak minstens %1$d MB vrij in interne opslag! Loop is uitgeschakeld! - Verkeerde invoer - Tijdelijk basaal duur moet een veelvoud van %1$d minuten en groter dan 0 zijn. - Verkeerde code. Opdracht geannuleerd. - Niet ingesteld - Profiel wissel aangemaakt Versie Checker oude versie zeer oude versie @@ -730,12 +624,10 @@ Bolus wizard voert de berekening uit maar alleen dit deel van berekende insuline wordt geleverd. Handig in combinatie met het SMB algoritme. Sluimeren Verhogen van de maximale basaal waarde omdat de instelling lager is dan het maximum in het profiel - Ongeldige inhoud van het bericht %1$s ISF: %2$.1f %1$.0fg KH-ratio: %2$.1f %1$.1fg KH-ratio: %2$.1f %1$d%% - min Profielnaam: Geselecteerd: Eenheden @@ -788,25 +680,6 @@ SMB uitvoeringstijd Tijdelijk basaal aanvraag tijd Tijdelijke basaal uitvoering tijd - - van de Authenticator-app voor: %1$s gevolgd door PIN - Extra verplichte PIN aan einde van token - Extra cijfers die je moet onthouden, en aan het eind van elk gegenereerd eenmalig wachtwoord moet toevoegen. - Authentificatie instellingen - Te controleren code: - OTP + PIN - De verificatiecode bestaat uit 6 cijfers die worden afgebeeld door de Authenticator-app (bekend als OTP), gevolgd door 3 of meer cijfers van de verplichte PIN-code. - Reset Authentificatie - Reset Authentificatie-sleutel - Weet je zeker dat je de Autentificatie-sleutel wilt resetten? Met deze actie maak je alle Authentificatie instellingen van verbonden telefoons ongeldig, en je zult ze opnieuw moeten instellen. - Er is een nieuwe Authentificatie-sleutel gegenereerd! Gebruik de nieuwe QR-Code voor het instellen van geautoriseerde telefoons. - OTP-secret wordt geëxporteerd - Weet je zeker dat je het OTP-secret naar het klembord wilt kopiëren?\n\nJe hebt dit alleen nodig als je Authenticator-app problemen heeft met het scannen van QR-codes, als je het handmatig wilt invullen of als je een hardware OTP-token met een speciale app wilt configureren. - OTP-secret (in Base32-formaat) is geëxporteerd en gekopieerd naar het klembord. Plak het in de Authenticator-app of de app van de hardware OTP-token! - 1. Installeer Authenticator app - 3. Test eenmalig wachtwoord (One Time Password) - Reset Authentificatie - Installeer de Authenticator-app op elke volger telefoon die RFC 6238 TOTP tokens ondersteunt. Populaire gratis apps zijn:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Voorspellingen Behandelingen Richtingscoëfficiënt afwijking @@ -837,21 +710,9 @@ Filter Kan profiel niet aanmaken. Profiel is ongeldig. Don\'t kill my app? - Stuur SMS wanneer de pomp onbereikbaar is - Melding pomp onbereikbaar Start alarm wanneer het tijd is om te eten - Start alarm over %1$d min - Bolusadviseur - Je hebt een hoge bloedglucose. In plaats van te eten, is het nu aan te raden om te wachten op een betere bloedglucose. Wil je nu een correctiebolus uitvoeren en je herinneren wanneer het tijd is om te eten? In dit geval worden er geen koolhydraten opgenomen en moet je de wizard opnieuw gebruiken wanneer we je eraan herinneren. - Bolusadviseur inschakelen - Gebruik bij een hoge bloedglucose niet het resultaat van de wizard, maar een herinnering om later met eten te beginnen (\"pre-bolus\") Tijd om te eten!\nVoer de boluswizard opnieuw uit. - Tijd om te eten - Bolus herinnering Bolus herinnering inschakelen - Gebruik herinnering om later te bolussen met de wizard - (\"post-bolus\") - Tijd om te bolussen!\nVoer de boluswizard uit en maak de berekening opnieuw. Upload van crashrapporten is uitgeschakeld! Grafiek Grafiek menu @@ -888,8 +749,6 @@ Accepteer behandelingen (cannule, insuline, batterijwissel etc) ingevoerd via NS of NSClient Ontvang / backfill CGM gegevens Accepteer CGM data van NS - Time-out tijdens het wachten op het voltooien van de vorige pomp communicatie - Er staat een andere bolus in de wachtrij. Probeer het later opnieuw. Berekening wordt uitgevoerd Profielnaam ontbreekt Fout in IC waarden @@ -934,7 +793,6 @@ insuline bloed glucose verouderd - herinnering instellen nieuw profiel toevoegen huidig profiel dupliceren huidig profiel verwijderen @@ -993,7 +851,6 @@ Toon loop %1$d geselecteerd Sorteren - Dialoog geannuleerd Zeer laag Laag Hoog @@ -1011,7 +868,6 @@ Aanmelden Alles verwijderen Start reset - QR Code voor het instellen van een eenmalig wachtwoord instellingen openen koolhydraten timer alarm instellen Alle diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml index bc8bc16995..521d66d07e 100644 --- a/app/src/main/res/values-no-rNO/strings.xml +++ b/app/src/main/res/values-no-rNO/strings.xml @@ -13,7 +13,6 @@ Nullstill databasene Vil du virkelig nullstille databasene? Avslutt - Det ser ikke ut som mobilen støtter registrering av apper som unntas fra batterioptimalisering - du kan oppleve ytelsesproblemer. Knapper for rask tilgang til ofte brukte funksjoner Brukes for innstilling av aktive plugins Opplæringsprogram @@ -44,7 +43,6 @@ Insulin: Karbo: IOB: - IOB: Total IOB: Total IOB aktivitet: Varighet: @@ -52,9 +50,7 @@ Ins: IOB: Total IOB: - BS TT - Karbo Korr Bolus IOB Utfør nå @@ -71,7 +67,6 @@ Ingen BS-data tilgjengelig Forespørsel Delta - Delta: Konfigurasjonsverktøy Oversikt Behandlinger @@ -92,13 +87,9 @@ Sikkerhet Plugin er deaktivert Brudd på begrensninger - Det er registrert en feil med bolus-leveransen. Sjekk manuelt om den er levert og hvor mye Aksepter ny temp basal: Behandling Kalkulator - Begrensning benyttet! - Bolus: - Basal: Endre dine inndata! BS-kilde xDrip+ @@ -111,13 +102,10 @@ Karbo forslag Versjonen av Nightscout støttes ikke Basal IOB - Bolus-begrensning utført - Karbohydrat-begrensning utført Annet Meter Sensor Karbo-tid - Varighet Profil Glukosetype Temp basal @@ -157,60 +145,6 @@ JEG FORSTÅR OG GODTAR Lagre Les inn profil på nytt - SMS-tjeneste - Godkjente mobilnumre - +XXXXXXXXXX;+YYYYYYYYYY - For å levere bolus på %1$.2fE, svar med kode %2$s - For å levere måltidsbolus på %1$.2fE, svar med kode %2$s - For å sette Temp Target på %1$s, svar med kode %2$s - For å avbryte Temp Target, svar med kode %1$s - For å deaktivere fjernstyring via SMS-meldinger, svar med kode %1$s.\n\nHusk at du vil kunne reaktivere den igjen kun fra AAPS hovedtelefon. - Fjernstyring via SMS-meldinger er stanset. For å reaktivere, bruk AAPS på hovedtelefonen. - For å sende kalibrering %1$.2f, svar med kode %2$s - Bolus mislyktes - Minimum antall minutter som må forløpe mellom en fjernstyrt bolus og den neste - Minimum antall minutter mellom en fjernstyrt bolus og neste - For din egen sikkerhet, må du legge til minst 2 telefonnumre for å endre denne innstillingen. - Skal levere %1$.2f E - Bolus på %1$.2f E er levert - Måltidsbolus på %1$.2f E er levert - Temp target på %1$s er satt i %2$d minutter - Temp target på %1$s i %2$d minutter ble lagret - Temp Target ble fjernet - Tillat fjernstyring via SMS-meldinger - Loop har blitt deaktivert - Loop har blitt aktivert - Loop er aktivert - For å koble til pumpen, svar med kode %1$s - Tilkobling til pumpen mislyktes - For å koble fra pumpen i %1$d minutter, svar med koden %2$s - Pumpe frakoblet - Pumpen tilkoblet igjen - Fjernstyringskommando er ikke tillatt - Fjernstyringsbolus er ikke tilgjengelig. Prøv igjen senere. - For å starte basal %1$.2f E/t i %2$d minutter, svar med kode %3$s - For å bytte profil til %1$s %2$d%%, svar med kode %3$s - For å starte forlenget bolus %1$.2f E i %2$d minutter, svar med kode %3$s - For å angi %1$dg kl. %2$s, svar med kode %3$s - For å starte basal %1$d%% i %2$d minutter, svar med kode %3$s - For å pause loop i %1$d minutter, svar med kode %2$s - For å gjenoppta loop, svar med kode %1$s - For å aktivere loop, svar med kode %1$s - For å deaktivere loop, svar med kode %1$s - Vellykket start av temp basal %1$.2fE/t i %2$d minutter - Vellykket start av forlenget bolus %1$.2fE i %2$d minutter - Vellykket registrering av %1$dg KH - Registrering av %1$dg karbohydrater mislyktes - Vellykket start av temp basal %1$d%% i %2$d minutter - Mislykket start av temp basal - Mislykket start av forlenget bolus - For å avbryte Temp basal, svar med kode %1$s - For å stoppe forlenget bolus, svar med kode %1$s - Temp basal avbrutt - Forlenget bolus avbrutt - Mislykket kansellering av Temp basal - Mislykket kansellering av forlenget bolus - Ukjent kommando eller feil svar Hurtigveiviser Innstillinger for hurtigveiviser Knappetekst: @@ -241,13 +175,9 @@ Send alle data på nytt Åpne Innstillinger på klokken Basalrate - Basalverdi under minimum. Profilen settes ikke! - BS: - Siste BS: MM640G Pågående varslinger GAMLE DATA - %1$d min siden Profil OpenAPS AMA Liste med %1$d elementer.\nFaktisk verdi: @@ -267,7 +197,6 @@ BEH MÅL WEAR - SMS Korte navn i menyfaner Bruk alltid kort gjennomsnittsverdi delta i stedet for enkel delta Nyttig når data fra ufiltrerte kilder som xDrip+ registrerer mye støy. @@ -281,13 +210,6 @@ Standard verdi: 2\nBolus-snooze er aktivt etter at du har gitt en måltidsbolus slik at loop ikke skal forsøke å sette lav-temp når du nettopp har spist. I dette eksempelet brukes standardverdi på 2, så med en 3 timers DIA vil bolus-snoozebegrensning gradvis forsvinne etter 1.5 timer (3DIA / 2). Bolus-snooze brukes ikke hvis SMB er aktivert. Standardverdi er: 3.0 (AMA) eller 8.0 (SMB). Dette er grunninnstillingen for KH-opptak per 5 minutt. Den påvirker hvor raskt COB skal reduseres, og benyttes i beregning av fremtidig BS-kurve når BS enten synker eller øker mer enn forventet. Standardverdi er 3mg/dl/5 min. Advarsel!\nNormalt vil du ikke trenge å endre verdiene under. Vennligst TRYKK HER og LES teksten for å være sikker på at du FORSTÅR konsekvensene før du gjør endringer. - Ugyldig mobilnummer for SMS - Kalibrering - xDrip+ ikke installert - Kalibrering er sendt til xDrip+ - Kalibrering sendt. Mottak må være aktivert i xDrip+. - xDrip+ tar ikke imot kalibreringer - Pumpen er pauset Utfører Innstillinger for virtuell pumpe Last opp status til Nightscout @@ -323,10 +245,7 @@ Velg pasienttype for oppsett av sikkerhetsgrenser Pasientnavn Angi pasientnavn eller kallenavn for å kunne skille mellom flere oppsett - Bruker Glimp - Loop pauset - Pauset (%1$d m) Pause loop i 1t Pause loop i 2t Pause loop i 3t @@ -345,9 +264,6 @@ 10 timer Gjenoppta Koble til pumpen - Feil varighet - Loop er pauset - Loop gjenopptatt 15 min trend COB Superbolus @@ -382,7 +298,6 @@ ABS DEVSLOPE Om - Mangler SMS-tillatelse Appen mangler tilgang til telefonstatus xDrip+ Status (klokke) xDrip+ Statuslinje (klokke) @@ -454,14 +369,11 @@ Kontroller fra klokke Sett temp målverdi og angi behandlinger fra klokken. Mat - g ]]> kJ En Pr Fett - Kommandoen utføres akkurat nå - Mangler BS-målinger Bruk systemvarslinger for alarmer og varslinger Øk volumet gradvis for alarmer og varsler Lokale varsler @@ -539,9 +451,6 @@ Tillat automatisk rapportering av appkrasher og bruksdata til utviklerne via fabrioc.io tjenesten. Vennligst oppdater din Dexcom app til en versjon som støttes Dexcom appen er ikke installert. - Start Trening TT - Start Spise snart TT - TT Ikke gi bolus, bare loggfør Kategori Underkategori @@ -554,8 +463,6 @@ Aktive KH (COB) Aktivt insulin (IOB) Basaler - Ingen handling valgt. Ingenting endres - Start Hypo TT Du kjører dev-versjonen. Lukket loop ikke aktivert. Engineering Mode aktivert Profilbytte mangler. Utfør et profilbytte og trykk på \"Aktiver profil\" i din lokale profil. @@ -574,7 +481,6 @@ Begrenser IOB til %1$.1f E på grunn av %2$s maks verdi i innstillingene hard begrensning - Feil i lesing av status Logg bytte av slangesett Logg bytte av insulinampull SMB Alltid På og SMB Etter Karbohydrater er deaktivert fordi BS kilden ikke støtter avansert filtrering @@ -631,12 +537,7 @@ Vennligst konfigurer din RileyLink under. Etter å ha valgt en RileyLink, vil det være mulig å fortsette konfigureringen når RileyLink statusen er \"Tilkoblet\". Dette kan ta et minutt.\n Merk: Du kan fortsette oppsettet når pumpen er satt opp.\n Start første læringsmål - Tillatelse Spør om tillatelse - App trenger tillatelse til å bruke Varslinger for å vise meldinger - App trenger tilgang til Posisjon for å søke etter Bluetooth og Wifi enheter - App trenger tilgang til Lagring for lagre logg filer og eksportere innstillinger - Forespørsel Åpne meny Lukk meny Plugin innstillinger @@ -681,8 +582,6 @@ Logginnstillinger Gjenopprett standardinnstillinger NSClient feil. Vurder omstart av NS og NSClient. - Tidsforskyvning - Påminnelse til å gi bolus senere Foretrukket APS modus Total Kalkyle @@ -712,11 +611,6 @@ Sommer/vintertid inntreffer innen 3t - lukket loop er midlertidig deaktivert intern lagringsbegrensning Frigjør minst %1$d MB fra internminnet! Loop deaktivert! - Feil format - Temp basal varighet må oppgis i antall %1$d minutter og større enn 0. - Feil kode. Kommandoen avbrutt. - Ikke konfigurert - Profilbytte opprettet Versjonskontroll gammel versjon veldig gammel versjon @@ -733,12 +627,10 @@ Bolus veiviser utfører beregninger, men bare denne del av beregnet insulin leveres. Nyttig ved bruk av SMB algoritmen. Utsett Øker maks basaldose fordi innstillingen er lavere enn din maks basal i profilen - Ugyldig innhold i meldingen %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Profilnavn: Valgt: Enheter @@ -791,25 +683,6 @@ SMB utført Temp basal endring forespurt Temp basal utført - - fra Authenticator appen for: %1$s etterfulgt av PIN - PIN kode som legges til på slutten av token - Ytterligere sifre som MÅ memoreres og legges til på slutten av hvert generert engangspassord - Oppsett for 2 faktor autentisering - Kode som skal kontrolleres: - OTP + PIN - Bekreftelseskoden består av 6 sifre som vises av Authenticator appen (kjent som OTP) etterfulgt av 3 eller flere siffer for obligatorisk PIN-kode. - Tilbakestill Authenticators - Tilbakestill Authenticator nøkkel - Er du sikker på at du vil tilbakestille Authenticator nøkkel? Dette vil gjøre alle lagrede Authenticators ugyldige, og du må sette dem opp på nytt igjen. - Ny Authenticator nøkkel ble generert! Vennligst bruk oppdatert QR kode til å aktivere autentiserere. - Eksporterer OTP hemmelig kode - Er du sikker på at du vil kopiere OTP hemmelig kode til utklippstavlen?\n\nDu trenger bare det hvis din Authenticator app har problemer med skanning av QRCode og du ønsker å legge den inn manuelt, eller du ønsker å konfigurere maskinvare OTP-kode ved hjelp av dedikert app. - OTP hemmelig kode (i base32-format) er eksportert og kopiert til utklippstavlen. Lim den inn i Authenticator app eller hardware OTP system! - 1. Installer Authenticator - 3. Test engangspassord - Tilbakestill Authenticators - I hver følger telefon installerer du en Authenticator-app som støtter RFC 6238 TOTP token. Populære gratis apper er:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Prognoser Behandlinger Avvikskurve @@ -840,21 +713,9 @@ Filter Klarte ikke å opprette profil. Profilen er ikke gyldig. Avslutte app? - Send SMS hvis det ikke oppnås kontakt med pumpa - Rapporter når kontakt med pumpe ikke oppnås Aktiver alarm når det er på tide å spise - Aktiver alarm om %1$d min - Bolusguide - Du har høyt blodsukker. I stedet for å spise nå er det bedre å utsette det til du har et lavere blodsukker. Ønsker du å sette en korrigerings bolus nå og få en påminnelse om når den er på tide å spise? I dette tilfellet vil ingen karbohydrater registreres nå, og du må bruke måltids veiviseren igjen når vi gir deg en påminnelse. - Aktiver boluskalkulator - Bruk en påminnelse om å spise senere enn kalkulator resultatet fra wizard ved høyt blodsukker (\"pre-bolus\") Nå må du spise!\Bruk bolus veiviseren og beregn på nytt. - Nå må du spise - Bolus påminnelse Aktiver bolus påminnelse - Bruk påminnelse for å sette bolus dosen senere med veiviseren - («post bolus») - Tid for bolus!\nStart bolus-veiviser og gjør beregning på nytt. Opplast av krasj logger er deaktivert! Graf Diagram meny @@ -891,8 +752,6 @@ Godta behandlingshendelser (kanyle, insulin, batteribytte osv.) som er lagt inn gjennom NS eller NSClient Motta/tilbakefyll CGM data Aksepter CGM data fra NS - Tidsavbrudd fordi vi ventet på avslutning av forrige pumpekommunikasjon - Det ligger en annen bolus i køen. Prøv igjen senere. Beregning pågår Mangler profilnavn Feil i IK faktoren @@ -937,7 +796,6 @@ insulin blodsukker utdatert - angi påminnelse legg til ny profil kopier gjeldende profil slett gjeldende profil @@ -996,7 +854,6 @@ Vis loop %1$d valgt Sorter - Dialog avbrutt Veldig lavt Lavt Høyt @@ -1014,7 +871,6 @@ Logg inn Fjern alt Tilbakestill til oppstart - QR-kode for oppsett av engangspassord åpne innstillinger angi karbo nedtellings alarm Alle @@ -1031,6 +887,5 @@ Blokkert på grunn av ladealternativer Blokkert på grunn av tilkoblingsalternativer (Ingen klokke tilkoblet) - Feil under spørring etter tillatelser Juster sensitivitet og BS diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 7db90e36d4..0b774299e2 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -12,7 +12,6 @@ Zresetuj bazy danych Na pewno chcesz zresetować bazy danych? Wyjście - To urządzenie nie obsługuje białej listy optymalizacji baterii - mogą wystąpić problemy z wydajnością. Niektóre przyciski umożliwiające szybki dostęp do typowych funkcji Konfiguracja aktywnych modułów systemu Program do nauki @@ -42,7 +41,6 @@ Insulina: Węglow.: IOB: - IOB: Całkowita IOB: Aktywna IOB: Czas: @@ -50,9 +48,7 @@ Ins: IOB: Całkowita IOB: - BG TT - Węglow Poprawka IOB z bolusów Uruchom teraz @@ -69,7 +65,6 @@ Brak danych o glukozie Żądanie Delta - Delta: Konfiguracja Przegląd Terapia @@ -90,13 +85,9 @@ Zabezpieczenia Wtyczka jest wyłączona Naruszenie ograniczeń - Błąd podczas podawania bolusa. Sprawdź ręcznie rzeczywiście dostarczoną ilość Akceptuj nową bazę tymczasową: Terapia Kalkulator - Ograniczenie nałożone! - Bolus: - Baza: Zmień wprowadzone dane! Źródło BG xDrip+ @@ -109,13 +100,10 @@ Sugestia węglowodanów Niewspierana wersja Nightscout IOB z bazy - Ograniczenia bolusa wprowadzone - Ograniczenie stosowania węglowodanów Inne Glukometr Sensor Czas węglow. - Czas trwania Profil Typ glukozy BazaTymczasowa @@ -155,60 +143,6 @@ ROZUMIEM I WYRAŻAM ZGODĘ ZACHOWAJ Załaduj profil ponownie - Komunikator SMS - Dozwolone numery telefonów - +XXXXXXXXXX;+YYYYYYYYYY - Aby dostarczyć bolus %1$.2fU wprowadź kod %2$s - Aby podać do posiłku bolus %1$.2fU odeślij %2$s - Aby ustawić cel tymczasowy %1$s odeślij w SMS kod %2$s - Aby anulować cel docelowy odeślij w SMS kod %1$s - Aby wyłączyć zdalne sterowanie SMS-ami odeślij kod %1$s.\n\nPamiętaj że możesz to ponownie włączyć tylko bezpośrednio w aplikacji AAPS na głównym telefonie. - Zatrzymano zdalne sterowanie SMS-ami. Aby ponownie włączyć użyj aplikacji AAPS na głównym telefonie. - Aby wysłać kalibrację %1$.2f wprowadź kod %2$s - Bolus nieudany - Minimalna liczba minut która musi upłynąć pomiędzy jednym a drugim zdalnie podawanym bolusem - Ile co najmniej minut musi upłynąć pomiędzy jednym a drugim bolusem - Dla twojego bezpieczeństwa, aby zmienić to ustawienie musisz dodać co najmniej 2 numery telefonów. - Zamierzam podać %1$.2f U - Bolus %1$.2f U podany prawidłowo - Pomyślnie podano %1$.2f U bolusa posiłkowego - Cel %1$s na %2$d minut - Pomyślnie ustawiono cel %1$s na %2$d minuty - Pomyślnie anulowano cel tymczasowy - Zezwalaj na komendy zdalne via SMS - Pętla (Loop) została wyłączona - Pętla (Loop) została włączona - Pętla (Loop) jest włączona - Aby podłączyć pompę odpowiedz kodem %1$s - Połączenie z pompą nie powiodło się - Aby odłączyć pompę na %1$d minut odpowiedz kodem %2$s - Pompa odłączona - Pompa ponownie podłączona - Zdalne komendy nie są dozwolone - Bolus zdalny niedostępny. Spróbuj ponownie później. - Aby rozpocząć bazę %1$.2f U/h przez %2$d min. odpowiedz kodem %3$s - Aby przełączyć profil na %1$s %2$d%% odpowiedz kodem %3$s - Aby rozpocząć bolus przedłużony %1$.2f U przez %2$d min. odpowiedz kodem %3$s - Aby wprowadzić %1$dg o %2$s odeślij w SMS kod %3$s - Aby rozpocząć bolus przedłużony %1$d%% przez %2$d min. odpowiedz kodem %3$s - Aby wstrzymać pętle na %1$d minut odpowiedz kodem %2$s - Aby wznowić pętlę odpowiedz kodem %1$s - Aby włączyć pętlę odpowiedz kodem %1$s - Aby wyłączyć pętlę odpowiedz kodem %1$s - Tymczasowa baza %1$.2fU/h przez %2$d min rozpoczęta - Bolus przedłużony %1$.2fU na %2$d min. rozpoczęty pomyślnie - Pomyślnie wprowadzono %1$d g węglowodanów - Próba wprowadzenia %1$dg węglowodanów nie powiodła się - Tymczasowa baza %1$d%% przez %2$d min. pomyślnie rozpoczęta - Rozpoczęcie tymczasowej bazy nie powiodło się - Nie powiodło się podanie bolusa przedłużonego - Aby zatrzymać bazę tymczasową wprowadź kod %1$s - Aby zatrzymać bolus przedłużony wprowadź kod %1$s - Baza tymczasowa anulowana - Przedłużony bolus anulowano - Anulowanie tymczasowej bazy nie powiodło się - Anulowanie bolusa przedłużonego nie powiodło się - Nieznane polecenie lub błędna odpowiedź Bolus zdefiniowany Ustaw szybkie bolusy Tekst przycisku: @@ -239,13 +173,9 @@ Prześlij ponownie wszystkie dane Otwórz ustawienia dla Wear Dawka bazowa - Wartość bazy poniżej minimum. Nie ustawiono profilu! - BG: - Ostatnia BG: MM640g Nadchodzące powiadomienia NIEAKTUALNE DANE - %1$dmin temu Profil OpenAPS AMA Lista %1$d elementów.\n Bieżąca wartość: @@ -264,7 +194,6 @@ TREAT OBJ WEAR - SMS Skrócone tytuły kart Zawsze używaj krótkiej średniej delty zamiast prostej delta Użyteczne, jeżeli dane z niefiltrowanego źródła jak xDrip+ mają rozrzut / szumy. @@ -278,13 +207,6 @@ Wartość domyślna: 2\nBolus snooze jest uruchamiany po wykonaniu bolusa posiłkowego, tak by pętla nie przeciwdziałała niskim wartościom tymczasowym zaraz po posiłku. Jako przykład: wartość domyślna ustawiona jest 2; więc 3 godzinne DIA oznacza, że bolus snooze będzie stopniowo wycofany po 1.5 godziny (3DIA/2). Wartość domyślna: 3.0 (AMA) lub 8.0 (SMB). To jest ustawienie domyślnego wpływu wchłaniania węglowodanów w czasie 5 min. Wartością domyślną jest spodziewane 3mg/dl/5min. Ma to wpływ na szybkość zaniku COB, oraz jak duże wchłanianie węglowodanów będzie przyjęte do obliczeń przyszłych przewidywanych wartości BG, jeżeli BG obniża się bardziej niż w założono, lub nie wzrasta tak szybko jak się spodziewano. UWAGA!\nZwykle nie trzeba zmieniać tych wartości. Proszę NACIŚNIJ TUTAJ i PRZECZYTAJ tekst i upewnij się, że ROZUMIESZ go przed zmianą którejś z tych wartości. - Nieprawidłowy numer telefonu SMS - Kalibracja - xDrip+ nie zainstalowany - Kalibracja przesłana do xDrip+ - Kalibracja wysłana. Odbiór musi być włączony w xDrip+. - xDrip+ nie odbiera kalibracji - Pompa wstrzymana Wykonywanie Ustawienia pompy wirtualnej Przesyłaj status do NS @@ -320,10 +242,7 @@ Wybierz typ pacjenta, aby ustawić limity bezpieczeństwa Nazwa pacjenta Proszę podać nazwę pacjenta lub pseudonim w celu rozróżnienia pomiędzy różnymi konfiguracjami - Użytkownik Glimp - Pętla wstrzymana - Wstrzymana (%1$d m) Wstrzymaj pętlę na 1h Wstrzymaj pętlę na 2h Wstrzymaj pętlę na 3h @@ -342,9 +261,6 @@ 10 godzin Wznów Połącz ponownie pompę - Zły czas trwania - Pętla wstrzymana - Pętla wznowiona Trend 15 minutowy COB Superbolus @@ -379,7 +295,6 @@ ABS KRZOD O programie - Brak uprawnień SMS Brak uprawnień do wykrywania stanu telefonu Status xDrip+ (zegarek) Linia Statusu xDrip+ (zegarek) @@ -447,14 +362,11 @@ Sterowanie z zegarka Ustawiaj wartości docelowe i wprowadzaj leczenie z zegarka. Posiłek - g ]]> kJ En Bi - Polecenie jest teraz wykonywane - Pominięte odczyty BG Użyj powiadomień systemowych dla alertów i powiadomień Stopniowo zwiększaj głośność ostrzeżeń i powiadomień Alarmy lokalne @@ -531,9 +443,6 @@ Zezwalaj na automatyczne zgłaszanie awarii i danych o użytkowaniu aplikacji do deweloperów za pośrednictwem usługi fabric.io. Proszę uaktualnij swoją Apkę Dexcom do wersji wspieranej Apka Dexcom nie jest zainstalowana. - Rozpocznij TT Ćwiczenia - Rozpocznij TT WkrótcePosiłek - TT Nie podawaj bolusa, tylko zapisz rekord Kategoria Podkategoria @@ -546,8 +455,6 @@ COB (Aktywne Węglow.) IOB (Aktywna Insulina) Dawki Bazowe - Nie wybrano żadnej akcji, zdarzenie nie będzie wprowadzone - Rozpocznij TT Hipo Uruchomiona jest wersja dev. Zamknięta pętla jest wyłączona. Tryb Inżynierski włączony Brakuje ZmianyProfilu. Proszę wykonać ZmianęProfilu lub nacisnąć \"Aktywuj Profil\" w ProfiluLokalnym @@ -566,7 +473,6 @@ Ograniczam IOB do %1$.1f U z uwagi na %2$s maks. wartość w ustawieniach twarde ograniczenie - Odczyt statusu nie powiódł się Zapisz zmianę wkłucia Zapisz zmianę zasobnika insuliny SMB zawsze i po węglow. wyłączone z uwagi na brak źródła BG z zaawansowanym filtrowaniem @@ -618,12 +524,7 @@ Proszę skonfigurować RileyLink poniżej. Po wybraniu RileyLink, możliwe będzie kontynuowanie konfiguracji, gdy status RileyLink będzie \"Połączony\". To może zająć minutę.\n Uwaga: Możesz kontynuować konfigurację po skonfigurowaniu pompy.\n Rozpocznij swoje pierwsze Zadanie - Uprawnienia Zapytaj o uprawnienia - Aplikacja wymaga uprawnienia systemowego okna dla powiadomień - Aplikacja wymaga dostępu do lokalizacji dla zarządzania bluetoothem i identyfikacją Wi-Fi - Aplikacja wymaga zgody na zapis do pamięci, aby móc przechować pliki logów i eksportować ustawienia - Żądanie Otwórz menu Zamknij menu Konfiguracja wtyczki @@ -660,8 +561,6 @@ Ustawienia logów Przywróć ustawienia domyślne Usterka NSClient. Spróbuj zrestartować NS i NSClient. - Przesunięcie czasu - Przypomnij o bolusie Preferowany tryb APS Razem Kalk @@ -691,11 +590,6 @@ Zmiana czasu nastąpiła mniej niż 3 godziny temu - Zamknięta pętla wyłączona limit wielkości pamięci wewnętrznej Zwolnij co najmniej %1$d MB z pamięci wewnętrznej! Pętla zatrzymana! - Błędny format - Czas trwania TBR musi być wielokrotnością %1$d minut i większy niż 0. - Zły kod. Polecenie anulowano. - Nie skonfigurowano - Zmiana profilu wykonana Kontroler wersji stara wersja bardzo stara wersja @@ -712,12 +606,10 @@ Kreator bolusa wykonuje obliczenia, ale tylko ta część obliczonej dawki insuliny jest dostarczana. Pomocne z algorytmem SMB. Wycisz Zwiększanie maksymalnej wartości bazowej ponieważ ustawienia są poniżej maxymalnej wartości bazy w profilu - Błędny tekst wiadomości %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Nazwa profilu: Wybrany: Jednostki @@ -765,25 +657,6 @@ Czas wykonywania SMB Żądany czas bazy tymczasowej Czas wykonywania bazy tymczasowej - - z aplikacji Authenticator dla: %1$s, z doklejonym PIN-em - Dodatkowy obowiązkowy PIN na końcu tokenu - Dodatkowe cyfry, które powinny być zapamiętywane i przyklejone na końcu każdego wygenerowanego hasła jednorazowego - Ustawienia uwierzytelnienia - Kod do sprawdzenia: - OTP + PIN - Kod weryfikacyjny składa się z 6 cyfr wyświetlanych przez aplikację uwierzytelniającą (tzw. OTP) po których następują co najmniej 3 cyfry obowiązkowego PIN-u. - Resetuj uwierzytelnianie - Resetuj klucz uwierzytelniania - Czy na pewno zresetować klucz uwierzytelniający? Spowoduje to, że wszystkie aktualnie skonfigurowane uwierzytelniania będą niepoprawne i konieczne będzie ponowne ich skonfigurowanie. - Nowy klucz uwierzytelniający został wygenerowany! Proszę użyć zaktualizowanego kodu QRCode do potwierdzenia uwierzytelniania. - Eksportowanie sekretu OTP - Czy na pewno chcesz skopiować klucz tajny OTP do schowka?\n\nMożesz tego potrzebować jeśli Twoja aplikacja uwierzytelniająca (authenticator) ma problemy ze skanowaniem kodu QR, chcesz wprowadzić klucz ręcznie lub chcesz skonfigurować sprzętowy token OTP za pomocą dedykowanej aplikacji. - Klucz tajny OTP (w formacie Base32) został wyeksportowany i skopiowany do schowka. Wklej go przy ręcznym dodawaniu konta w aplikacji authenticator lub użyj w aplikacji konfigurującej tokeny sprzętowe! - 1. Zainstaluj uwierzytelnianie - 3. Sprawdź hasło jednorazowe - Resetuj uwierzytelnianie - Na każdym telefonie śledzącym zainstalować aplikację uwierzytelniania obsługującą tokeny TOTP RFC 6238 Popularne darmowe aplikacje:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Prognozy poziomu Zabiegi Krzywa odchylenie @@ -814,20 +687,9 @@ Filtr Nie można utworzyć profilu. Profil jest nieprawidłowy. Nie zabij mojej aplikacji? - Wyślij SMS, jeśli wyzwolone jest zdarzenie pompy nieosiągalnej - Zgłoś nieosiągalną pompę Uruchom alarm kiedy będzie czas na jedzenie - Uruchom alarm za %1$d min - Doradca bolusa - Masz wysoki poziom. Zamiast jeść teraz, zaleca się poczekać na wyrównanie poziomu cukru. Czy chcesz teraz wykonać korekcyjny bolus i otrzymać przypomnienie, kiedy nadejdzie czas na posiłek? W tym przypadku żadne węglowodany nie zostaną zarejestrowane i należy ponownie użyć kreatora, gdy zostanie otrzymane przypomnienie. - Włącz doradcę bolusa - Użyj przypomnienia, aby rozpocząć jedzenie później podczas wysokiej glikemii (\"pre-bolus\") Czas jeść!\nUruchom kreatora bolusa i zrób obliczenia ponownie. - Czas na jedzenie - Przypomnienie bolusa Włącz przypomnienie bolusa - Użyj przypomnienia o potrzebie obliczenia i podania bolusa kalkulatorem (\"opóźniony bolus\") - Czas na bolus!\nUruchom Kalkulator bolusa aby ponownie wykonać obliczenia. Przesyłanie dzienników awarii jest wyłączone! Wykres Menu wykresu @@ -862,8 +724,6 @@ Akceptuj zdarzenia związane z leczeniem (kaniula, insulina, zmiana baterii itp.) wprowadzone przez NS lub NSClient Odbieraj/uzupełnij dane CGM Akceptuj dane CGM z NS - Przekroczono limit czasu oczekiwania na zakończenie poprzedniej komunikacji z pompą - W kolejce oczekuje inny bolus. Spróbuj ponownie później. Trwa obliczanie Brak nazwy profilu Błąd w przelicznikach IC diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 2d607714f2..2bb0f07745 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -12,7 +12,6 @@ Redefinir banco de dados Você realmente quer redefinir os bancos de dados? Sair - Este dispositivo não parece suportar a optimização de bateria na lista de permissões - pode ter problemas de desempenho. Alguns botões para acessar rapidamente a funções comuns Usado para configurar os plugins ativos Programa de aprendizagem @@ -43,7 +42,6 @@ Insulina: Carboidratos: IOB: - IOB: IOB Total: Atividade Total IOB: Dur: @@ -51,9 +49,7 @@ Ins: IOB: IOB Total: - BG TT - Carbos Corr I.A de Bolus Executar agora @@ -70,7 +66,6 @@ Sem dados de glicose disponíveis Solicitar Delta - Delta: Configurador Visão geral Tratamentos @@ -91,13 +86,9 @@ Seguro Plugin está desativado Violação das restrições - O Bolus relatou um erro. Verifique a quantidade administrada manualmente Aceitar nova basal temporária: Tratamento Calculadora - Restrição aplicada! - Bolus: - Basal: Altere sua entrada! Fonte de BG xDrip+ @@ -110,13 +101,10 @@ Sugestão de Carbs Versão não suportada do Nightscout IOB Basal - Restrição de bólus aplicada - Restrições de carbs aplicada Outro Medidor Sensor Hora do carboidrato - Duração Perfil Tipo de glicose Basal Temporária @@ -156,60 +144,6 @@ EU ENTENDO E CONCORDO Salvar Recarregar perfil - Comunicador SMS - Números de telefone permitidos - +XXXXXXXXXX;+YYYYYYYYYY - Para dar bolus %1$.2fU responder com código %2$s - Para dar bólus %1$.2fU responder com código %2$s - Para definir o Alvo Tempo %1$s responda com o código %2$s - Para cancelar Alvo Temp responda com o código %1$s - Para desativar o Serviço Remoto SMS de responda com o código %1$s.\n\nTenha em mente que será capaz de o reativar diretamente apenas a partir do celular principal do AAPS. - SMS Serviço Remoto interrompido. Para reativá-lo, use o AAPS no telemóvel mestre. - Para enviar calibração %1$.2f responder com código %2$s - Bolus falhou - Número mínimo de minutos que deve decorrer entre um bólus remoto e o próximo - Quantos minutos deve decorrer, pelo menos, entre um bólus e o próximo - Para sua segurança, para editar esta preferência você precisa adicionar pelo menos 2 números de telefone. - Iniciando aplicação de %1$.2f U - Bolus %1$.2f U aplicado com sucesso - Bolus da refeição %1$.2f U aplicado com sucesso - Alvo %1$s para %2$d minutos - Alvo %1$s para %2$d minutos definido com sucesso - Alvo Temp cancelado com êxito - Permitir comandos remotos via SMS - Loop foi desativado - Loop foi ativado - Loop ativado - Para conectar à bomba responda com o código %1$s - Conexão com a bomba falhou - Para desconectar a bomba por %1$d minutos responda com código %2$s - Bomba desconectada - Bomba reconectada - O comando remoto não é permitido - O bolus remoto não está disponível. Tente novamente mais tarde. - Para começar o basal %1$.2fU/h durante%2$d min responda com o código %3$s - Para mudar o perfil para %1$s %2$d%% responda com o código %3$s - Para começar o bólus estendido %1$.2fU/h para %2$d min responda com o código %3$s - Para inserir %1$dg em %2$s responda com código %3$s - Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s - Para suspender o loop por %1$d minutos resposta com código %2$s - Para retomar o loop responda com o código %1$s - Para ativar o loop responda com o código %1$s - Para desativar o loop responda com o código %1$s - Basal temporária %1$.2fU/h para %2$d min iniciada com êxito - Bólus estendido %1$.2fU/h para %2$d min iniciado com êxito - Carboidratos %1$d g inseridos com sucesso - Introdução de %1$dg de hidratos falhou - Basal temporária %1$d%% U/h durante%2$d min iniciada com êxito - Falha ao iniciar basal temp - Falha ao iniciar o bolus estendido - Para parar a basal temporária responda com o código %1$s - Para parar o bólus temporário responda com o código %1$s - basal temporária cancelada - Bólus estendido cancelado - Cancelamento do basal temporário falhou - Falhou o cancelamento do bolus extendido - Comando desconhecido ou resposta errada Assistente Rápido Definições do Assistente Rápido Texto do botão: @@ -239,13 +173,9 @@ Reenviar Todos os Dados Abrir Definições em Wear Valor da Basal - Valor da basal abaixo do mínimo. Perfil não definido! - BG: - Último BG: MM640g Notificação em curso DADOS ANTIGOS - %1$dmin atrás Perfil OpenAPS AMA Array de %1$d elementos.\nValor atual: @@ -265,7 +195,6 @@ TRATA OBJ WEAR - SMS Abreviar títulos dos separadores Usar sempre delta médio curto em vez de delta simples Útil quando há ruído nos dados das fontes sem filtro como o xDrip. @@ -279,13 +208,6 @@ Valor padrão: 2\nBolus Snooze (pausa após bolus) é executado depois de realizar um bolus por refeição Desta maneira o algoritmo não irá contrariar com temporárias baixas logo depois da refeição. O valor padrão é 2; Então uma duração de ação da insulina (DIA) de 5h significa que o Bolus Snooze irá ser gradualmente reduzido ao longo de 2,5 horas = 5/2 = DIA/Valor padrão. Valor padrão: 3.0 para assitência avançada de refeições (AAR) ou 8.0 para super micro bolus (SMB). Esta é a configuração padrão para o calculo de quanto varia a cada 5 min a glicemia (BG) devido à absorção de carboidratos. O padrão é 3mg/dl/5min. Isso afeta a rapidez com que decaem os carboidratos ativos (CA) e quanta absorção de carboidrato será considerada no cálculo da previsão de glicemia futura, tornando possível notar que glicemia está baixando mais do que o esperado ou não subindo como esperado. Atenção!\n Normalmente não é necessário modificar os valores abaixo. Por favor PRESSIONE AQUI e LEIA o texto para garantir que ENTENDE as consequências antes de alterar qualquer um destes valores. - Número de telefone inválido para comunicação por SMS - Calibração - xDrip+ não está instalado - Calibração enviada para o xDrip+ - Calibração enviada. O recebimento deve estar ativado no xDrip+. - xDrip+ não está recebendo calibrações - Bomba suspensa Executando Definições da bomba virtual Enviar estado para NS @@ -321,10 +243,7 @@ Selecione o tipo de paciente para configurar os limites de segurança Nome do Paciente Por favor, forneça nome do paciente ou apelido para diferenciar entre várias configurações - Usuário Glimp - Loop suspenso - Suspenso (%1$d m) Suspender loop por 1h Suspender loop por 2h Suspender loop por 3h @@ -343,9 +262,6 @@ 10 horas Continuar Reconectar Bomba - Duração errada - Loop suspenso - Loop retomado Tendência 15 min CA Superbolus @@ -372,7 +288,6 @@ Aviso de limite crítico de nível de reservatório [U] ACT Sobre - Falta de permissão SMS Falta permissão do estado do telefone xds Mostrar IG (Impacto na Glicemia) @@ -431,14 +346,11 @@ Controles do Relógio Definir Alvo-Temp and inserir Tratamentos do relógio. Alimentos - g ]]> kJ En Pr Gor - Comando será executado agora - Leituras Glic. perdidas Usar as notificações do sistema para alertas e notificações Alertas local Alerta caso nenhuma glicemia seja recebida @@ -505,9 +417,6 @@ Permitir que seja enviado automaticamente à equipa de desenvolvimento o report de crashes e das funções utilizadas, utilizando o serviço fabric.io. Por favor atualize as sua aplicação Dexcom para uma versão suportada App Dexcom não está instalada. - Iniciar atividade TT - Iniciar Comer em breve TT - TT Sem bólus, registar apenas Categoria Subcategoria @@ -518,8 +427,6 @@ Carboidratos a bordo Insulina a bordo Basais - Nenhuma acção seleccionada, nada irá acontecer - Começar TT Hipo A correr a versão dev. O Loop fechado está desabilitado. Modo engenheiro activado TrocaPerfil em falta. Por favor faça uma troca de perfil ou pressione \"Ativar Perfil\" em PerfilLocal. @@ -538,7 +445,6 @@ A limitar IOB para %1$.1f U porque %2$s valor máx nas preferências limite rígido - Erro na leitura de estado Registar mudança de sítio Registar mudança cartucho SMB sempre e depois dos hidratos desactivado por fonte da Glicemia activa não suportar filtro avançado @@ -587,10 +493,7 @@ Lembre-se: novos perfis de insulina requerem diâmetro de pelo menos 5h. DIA 5–6h no novo perfil é igual ao diâmetro 3h nos antigos perfis de insulina. Seleccione um dos algoritmos disponíveis. Eles são classificados do mais antigo para o mais recente. Algoritmo mais recente é geralmente mais forte e mais agressivo. Assim, se você é novo looper, poderá provavelmente começar com AMA e não com a versão mais recente. Não se esqueça de ler a documentação de OpenAPS e configurá-lo antes de usar. Iniciar primeiro objetivo - Permissão Pedir permissão - Aplicação precisa de permissão de janela do sistema para notificações - Pedido Abrir a navegação Fechar a navegação Preferências plugin @@ -625,7 +528,6 @@ Definições de registo Repor definições por defeito Erro de funcionamento do NSCliente. Pondere reiniciar o NS e NSCliente. - Fuso horário Modo APS preferido Total Calc @@ -655,10 +557,6 @@ Horário de Verão a menos de 3 horas - Closed Loop desligado restrição de armazenamento interno Liberte pelo menos %1$d MB do armazenamento interno! Loop desativado! - Formato incorrecto - Código errado. Comando cancelado. - Não configurado - Troca de perfil criada Verificador de Versão versão antiga versão muito antiga @@ -675,11 +573,9 @@ Assistente de bólus executa o cálculo, mas apenas esta parte da insulina calculada é entregue. Útil com o algoritmo SMB. Silenciar Aumentar o valor máximo de basal porque a configuração é inferior à sua basal máxima no perfil - Corpo da mensagem inválido %1$s FSI: %2$.1f %1$.0fg IC: %2$.1f %1$d%% - min Nome do Perfil: Seleccionado: Unidades @@ -727,25 +623,6 @@ Hora de execução do SMB Hora de solicitação Basal Temp Hora de execução Basal Temp - - do aplicativo Autenticador para: %1$s seguido por PIN - PIN adicional obrigatório no fim do token - Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Password-Única que seja gerada - Configuração do Autenticador - Código para verificar: - CÓDIGO + PIN - O código de verificação consiste em 6 dígitos exibidos pelo app Autenticador (conhecido como OTP) seguido por 3 ou mais dígitos do PIN obrigatório. - Repor Autenticadores - Repor Chave Autenticador - Tem certeza de redefinir chave Authenticador? Ele tornará todos os Authenticators configurados atualmente como inválidos, e precisará de os configurar novamente. - Nova Chave do Autenticador foi gerada! Por favor, use o QRCode atualizado para os autenticadores. - Exportando senha OTP - Tem certeza de que deseja copiar a senha OTP para a área de transferência?\n\nGeralmente, isso somente é necessário se o aplicativo autenticador apresenta problemas para escanear o QRCode, se você quer inserir a senha manualmente ou se você deseja configurar um token físico (hardware) de OTP usando um aplicativo dedicado. - Senha OTP (no formato Base32) exportada e copiada para a área de transferência. Cole-a em um aplicativo autenticador ou gravador de dispositivo OTP físico! - 1. Instalar Autenticador - 3. Teste Uma-Password-Única - Repor Autenticadores - Instalar uma app Autenticador que suporte Tokens RFC 6238 TOTP em cada telefone seguidor. Populares aplicativos gratuitos são:\n • Authy\n • o Google Authenticator\n • LastPass Autenticador\n • FreeOTP Autenticador Previsões Tratamentos Desvio de inclinação @@ -776,20 +653,9 @@ Filtros Não foi possível criar o perfil. Perfil inválido. Não encerre meu aplicativo? - Enviar SMS se um evento de bomba inacessível for identificado - Reportar bomba inacessível Disparar alarme quando for a hora de comer - Disparar alarme em %1$d min - Assistente de bolus - Sua glicemia está alta. Em vez de comer agora, é recomendado esperar por uma glicemia melhor. Quer fazer um bolus de correção agora e ser lembrado de quando for hora de comer? Neste caso, nenhum carboidrato será registrado e você deverá usar o assistente novamente quando lembrarmos você. - Ativar o assistente de bolus Hora de comer!\nAbra o assistente de bolus e faça o cálculo novamente. - Hora de comer - Lembrete de bolus Ativar lembrete de bolus - Usar lembrete para adiar o bolus com o assistente - (\"pós-bolus\") - Hora do bolus!\nAbra o assistente de bolus e faça o cálculo novamente. Purgar/Preencher Perfis, bolus, carboidratos, basais temporários são enviados para NS Receber taxa basal temporária (TBT) e bolus estendido (e-bolus ou BE) @@ -829,7 +695,6 @@ insulina glicemia desatualizado - definir lembrete adicionar novo perfil clonar perfil atual excluir perfil atual @@ -863,7 +728,6 @@ Nenhum registro disponível Exibir loop Ordenar - Janela cancelada Abaixo Dentro da meta Acima @@ -871,7 +735,6 @@ Ocultar registros do loop Configurar opacidade Status do loop - Código QR para configuração de senha de uso único abrir configurações definir alarme temporizador de carboidrato Todos diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 1490f8b74e..5fad731f79 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -12,7 +12,6 @@ Reiniciar Base de Dados Quer realmente reiniciar a base de dados? Sair - Este dispositivo parece não suportar a otimização de bateria na lista de permissões - pode ter problemas de desempenho. Alguns botões para aceder rapidamente a funções comuns Usado para configurar os plugins ativos Programa de aprendizagem @@ -42,7 +41,6 @@ Insulina: Hidratos: IA: - IA: IA Total: Atividade Total da IA: Dur: @@ -50,9 +48,7 @@ Ins: IA: Total da IA: - GLIC AT - Hidratos Corr Bólus - IA Executar agora @@ -69,7 +65,6 @@ Sem dados de glucose disponíveis Pedido Delta - Delta: Configurador Visão Geral Tratamentos @@ -90,13 +85,9 @@ Segurança Plugin está desativado Violação das restrições - Ocorreu um erro de bólus. Verifique manualmente a quantidade administrada Aceitar nova basal temporária: Tratamento Calculadora - Restrição aplicada! - Bólus: - Basal: Altere o seu input! Fonte da Glicose xDrip+ @@ -109,13 +100,10 @@ Sugestão de Hidratos Versão sem suporte do Nightscout Basal IA - Restrição de bólus aplicada - Restrição de hidratos de carbono aplicada Outro Medidor Sensor Hora dos Hidratos - Duração Perfil Tipo de Glicose Basal Temporária @@ -155,60 +143,6 @@ EU ENTENDO E CONCORDO Guardar Recarregar perfil - Comunicador SMS - Número de telefones permitidos - +XXXXXXXXXX;+YYYYYYYYYY - Para administrar bólus %1$.2fU responder com código %2$s - Para administrar bólus %1$.2fU responder com código %2$s - Para definir o Alvo Temporário %1$s responda com o código %2$s - Para cancelar Alvo Temporário responda com o código %1$s - Para desactivar o Serviço Remoto SMS de responda com o código %1$s.\n\nTenha em mente que será capaz de o reactivar directamente apenas a partir do telemóvel mestre do AAPS. - SMS Serviço Remoto interrompido. Para reactivá-lo, use o AAPS no telemóvel mestre. - Para enviar calibração %1$.2f responder com código %2$s - Bólus falhado - Número mínimo de minutos que deve decorrer entre um bólus remoto e o próximo - Quantos minutos deve decorrer, pelo menos, entre um bólus e o próximo - Para sua segurança, para editar esta preferência precisa adicionar pelo menos 2 números de telefone. - A ser administrado %1$.2f U - Bólus %1$.2f U administrado com sucesso - Bólus de Refeição %1$.2f U administrado com sucesso - Alvo %1$s para %2$d minutos - Alvo %1$s para %2$d minutos definido com sucesso - Alvo Temporário cancelado com êxito - Permitir comandos remotos via SMS - Loop foi desactivado - Loop foi activado - Loop activado - Para ligar a bomba responda com o código %1$s - Ligação à bomba falhou - Para remover a bomba por %1$d minutos responda com o código %2$s - Bomba removida - Bomba ligada novamente - O comando remoto não é permitido - O bólus remoto não está disponível. Tente novamente mais tarde. - Para iniciar basal %1$.2f U/h por %2$d min responda com o código %3$s - Para mudar o perfil para %1$s %2$d%% responda com o código %3$s - Para iniciar bólus prolongado %1$.2f U por %2$d min responda com o código %3$s - Para inserir %1$dg em %2$s responda com código %3$s - Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s - Para suspender o loop por %1$d minutos resposta com código %2$s - Para retomar o loop responda com o código %1$s - Para activar o loop responda com o código %1$s - Para desativar o loop responda com o código %1$s - Basal temporária %1$.2fU/h para %2$d min iniciada com êxito - Bólus prolongado %1$.2fU/h para %2$d min iniciado com êxito - Hidratos %1$d g inseridos com sucesso - Introdução de %1$dg de hidratos falhou - Basal temporária %1$d%% U/h durante%2$d min iniciada com êxito - Início basal temporária falhou - Falha ao iniciar o bólus prolongado - Para parar a basal temporária responda com o código %1$s - Para parar o bólus prolongado responda com o código %1$s - Basal temporária cancelada - Bólus prolongado cancelado - Não foi possível cancelar a basal temporária - Falhou a cancelar bólus prolongado - Comando desconhecido ou resposta errada Assistente Rápido Definições do Assistente Rápido Texto do botão: @@ -238,13 +172,9 @@ Wear Reenviar Todos os Dados Abrir Definições no Relógio - Valor da basal abaixo do mínimo. Perfil não definido! - Glicose: - Ultima Gli: MM640g Notificação em curso DADOS ANTIGOS - %1$dmin atrás Perfil OpenAPS AMA Array de %1$d elementos.\nValor actual: @@ -263,7 +193,6 @@ TRATA OBJ WEAR - SMS Abreviar títulos dos separadores Utilizar sempre delta médio curto em vez de delta simples Útil quando há ruído nos dados de fontes sem filtro como xDrip+. @@ -277,13 +206,6 @@ Valor padrão: 2\nBólus Snooze (pausa após bólus) é executado depois de realizar um bólus por refeição Desta maneira o algoritmo não irá contrariar com temporárias baixas logo depois da refeição. O valor padrão é 2; Então uma duração de ação da insulina (DIA) de 5h significa que o Bólus Snooze irá ser gradualmente reduzido ao longo de 2,5 horas = 5/2 = DIA/Valor padrão. Valor padrão: 3.0 para deteção avançada de refeições (AMA) ou 8.0 para super micro bólus (SMB). Esta é a configuração padrão para o cálculo de quanto varia a cada 5 min a glicose no sangue (GLIC) devido à absorção de hidratos de carbono. O padrão é 3mg/ dl / 5min. Isso afeta a rapidez com que decaem as calorias no corpo (HCA), e quantos hidratos de carbono terão de ser considerados no cálculo da previsão de GLIC, quando é que a GLIC está baixando mais do que espectável ou não subindo como espectável. Atenção!\n Normalmente não é necessário modificar os valores abaixo. Por favor PRESSIONE AQUI e LEIA o texto para garantir que ENTENDE as consequenciais antes de alterar algum destes valores. - Número de telefone de SMS inválido - Calibração - xDrip+ não está instalado - Calibração enviada para xDrip+ - Calibração enviada. Receção tem de estar ativada na xDrip+. - O xDrip+ não está a receber as calibrações - Bomba suspensa A Executar Definições da bomba virtual Enviar estado para NS @@ -319,10 +241,7 @@ Por favor seleccione o tipo de paciente para configurar limites de segurança Nome do Paciente Por favor, forneça o nome do paciente ou alcunha para diferenciar entre várias configurações - Utilizador Glimp - Loop suspenso - Suspendido (%1$d m) Suspender loop por 1h Suspender loop por 2h Suspender loop por 3h @@ -341,9 +260,6 @@ 10 horas Retomar Re-ligar a Bomba - Duração errada - Loop suspenso - Loop retomado Tendência 15 min HCA Superbólus @@ -378,7 +294,6 @@ ABS DESVINCLI Acerca - Falta de permissão SMS Falta permissão do estado do telefone Estado xDrip+ (relógio) Linha Estado xDrip+ (relógio) @@ -446,14 +361,11 @@ Controles do Relógio Definir Alvo-Temp and inserir Tratamentos do relógio. Alimentos - g ]]> kJ En Pr Gor - Comando será executado agora - Leituras Glicose perdidas Utilizar as notificações do sistema para alertas e notificações Aumentar gradualmente o volume de alertas e notificações Alertas locais @@ -530,9 +442,6 @@ Permitir que seja enviado automaticamente à equipa de desenvolvimento o report de crashes e das funções utilizadas, utilizando o serviço fabric.io. Por favor atualize as sua aplicação Dexcom para uma versão suportada App Dexcom não está instalada. - Iniciar AT de atividade - Iniciar AT de Comer em breve - AT Sem bólus, registar apenas Categoria Subcategoria @@ -545,8 +454,6 @@ Hidratos de Carbono Ativos (HCA) Insulina ativa Basais - Nenhuma ação seleccionada, nada irá acontecer - Iniciar AT de Hipo A correr a versão dev. O Loop fechado está desativado. Modo engenheiro activado Troca de Perfil em falta. Por favor faça uma troca de perfil ou pressione \"Activar Perfil\" em Perfil Local. @@ -565,7 +472,6 @@ A limitar IA para %1$.1f U porque %2$s valor máx nas preferências limite rígido - Erro na leitura de estado Registar mudança local bomba Registar mudança de reservatório SMB sempre e depois dos hidratos desactivado por fonte da Glicose activa não suportar filtro avançado @@ -617,12 +523,7 @@ Por favor, configure o seu RileyLink abaixo. Depois de seleccionar um RileyLink, será possível continuar a configuração quando o estado do RileyLink estiver \"Conectado\". Isso pode levar um minuto.\n Nota: Pode continuar a configuração assim que a bomba for configurada.\n Iniciar primeiro objectivo - Permissão Pedir permissão - Aplicação precisa de permissão de janela do sistema para notificações - Aplicação necessita de permissão de localização para pesquisa Bluetooth e identificação Wi-Fi - A aplicação precisa da permissão de armazenamento para poder armazenar ficheiros de registo e exportar definições - Pedido Abrir a navegação Fechar a navegação Preferências plugin @@ -658,8 +559,6 @@ Definições de registo Repor definições por defeito Erro de funcionamento do ClienteNS. Pondere reiniciar o NS e ClienteNS. - Fuso horário - Lembrete para bólus mais tarde Modo APS preferido Total Calc @@ -689,11 +588,6 @@ Horário de Verão a menos de 3 horas - Loop Fechado desativado restrição de armazenamento interno Liberte pelo menos %1$d MB do armazenamento interno! Loop desativado! - Formato incorrecto - A duração do DBT deve ser de um múltiplo de %1$d minutos e maior que 0. - Código errado. Comando cancelado. - Não configurado - Troca de perfil criada Verificador de Versão versão antiga versão muito antiga @@ -710,12 +604,10 @@ Assistente de bólus executa o cálculo, mas apenas esta parte da insulina calculada é administada. Útil com o algoritmo SMB. Silenciar Aumentar o valor máximo de basal porque a configuração é inferior à sua basal máxima no perfil - Corpo da mensagem inválido %1$s FSI: %2$.1f %1$.0fg IHC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Nome do Perfil: Seleccionado: Unidades @@ -761,25 +653,6 @@ Hora de execução do SMB Hora de solicitação da DBT Hora de execução da DBT - - da app Authenticator para: %1$s seguido pelo PIN - PIN obrigatório adicional no token final - Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Senha-Única que seja gerada - Configuração do Autenticador - Código para verificar: - OTP + PIN - O código de verificação consiste em 6 dígitos exibidos pela app Authenticator (conhecido como OTP) seguido de 3 ou mais dígitos de PIN obrigatório. - Repor Autenticadores - Repor Chave Autenticador - Tem certeza de redefinir chave Authenticador? Ele tornará todos os Authenticators configurados actualmente como inválidos, e precisará de os configurar novamente. - Nova Chave do Autenticador foi gerada! Por favor, use o QRCode actualizado para os autenticadores. - A exportar segredo da OTP - Tem a certeza de que deseja copiar o segredo da OTP para a área de transferêencia?\n\nSó pode precisar se a app do seu autenticador tiver problemas para digitalizar QRCode, deseja digitá-lo manualmente ou deseja configurar o token OTP de hardware usando app dedicada. - Segredo da OTP (em formato Base32) exportado e copiado na áreas de transferênca. Cole-o no autenticador ou no hardware OTP burner! - 1. Instalar Autenticador - 3. Testar Uma-Senha-Única (OTP) - Repor Autenticadores - Instalar uma app Autenticador que suporte Tokens RFC 6238 TOTP em cada telefone seguidor. Populares aplicativos gratuitos são:\n • Authy\n • o Google Authenticator\n • LastPass Autenticador\n • FreeOTP Autenticador Previsões Desvio de inclinação Falha na autorização @@ -809,21 +682,9 @@ Filtro Não é possível criar o perfil. O perfil é inválido. Não encerre minha app? - Enviar SMS se evento de bomba inacessível for acionado - Reportar bomba inacessível Executar alarme quando for tempo de comer - Executar alarme em %1$d min - Guia de Bólus - Tem glicemia alta. Em vez de comer agora é recomendado esperar por uma melhor glicemia. Quer fazer um bólus de correção agora e lembrá-lo quando for hora de comer? Neste caso nenhum hidrato será registado e deve utilizar o assistente novamente quando for lembrado. - Activar Guia de Bólus - Use lembrete para começar a comer mais tarde em vez di resultado do assistente durante a glicemia alta (\"pré-bolus\") Hora de comer!\nExecutar assistente de Bólus e fazer cálculo novamente. - Hora de comer - Lembrete de bólus Ativar lembrete de bólus - Usar lembrete para bólus mais tarde com o assistente - (\"pós-bólus\") - Hora de fazer o bólus!\nExecute o assistente de bólus e faça o cálculo novamente. Envio de registos de erro desativado! Gráfico Menu do Gráfico @@ -858,8 +719,6 @@ Aceitar tratamentos (catéter, insulina, mudança de bateria etc) inseridos através do NS ou NSCliente Receber/preencher dados do MCG Aceitar dados do MCG provenientes do NS - Tempo limite de espera para conclusão da comunicação com a bomba - Existe outro bólus em espera. Tente novamente mais tarde. Cálculo em curso Nome do perfil ausente Erro nos valores de IHC diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index 4f9363be6a..f841aac185 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -12,7 +12,6 @@ Resetează bazele de date Sigur resetați bazele de date? Ieșire - Acest dispozitiv nu permite folosirea excluderii din lista de optimizare a bateriei - se poate să întâmpinați probleme de performanță. Butoane pentru accesarea celor mai comune facilităţi Folosit pentru configurarea facilităţilor active Program de învăţare @@ -42,7 +41,6 @@ Insulină: Carbohidrați: IOB: - IOB: IOB total: Activitate total IOB: Durată: @@ -50,9 +48,7 @@ Ins: IOB: IOB totală: - Gl TT - Carbohidrați Corecție IOB bolus Execută @@ -69,7 +65,6 @@ Nu există date despre glicemie Solicitare Diferență - Diferență: Configurator Privire de ansamblu Tratamente @@ -90,13 +85,9 @@ Siguranță Modul inactiv Încălcare a unei limite - Bolus a raportat o eroare. Verifică manual cantitatea livrată Acceptă noua bazală temporară: Tratament Calculator - Limitare aplicată! - Bolus: - Bazală: Schimbați ceea ce ați introdus! Sursă glicemie xDrip+ @@ -109,13 +100,10 @@ Sugestie carbohidrați Versiune incompatibilă de Nightscout IOB bazală - Constrângere de bolus aplicată - Constrângere de carbohidrați aplicată Altul Glucometru Senzor Ora carbohidrați - Durată Profil Tip glicemie Bazală temporară @@ -155,60 +143,6 @@ ÎNȚELEG ȘI SUNT DE ACORD Salvează Reîncarcă profilul - Comunicator SMS - Numere de telefon permise - + XXXXXXXXXX; + YYYYYYYYYY - Pentru a livra un bolus de %1$.2fU răspundeți cu codul %2$s - Pentru a livra un bolus de %1$.2fU raspundeți cu: %2$s - Pentru a seta tinta temporara %1$s raspundeti cu: %2$s - Pentru a anula tinta temporara raspundeți cu: %1$s - Pentru a dezactiva serviciul SMS la distanta raspundeti cu: %1$s.\n\nRetineti ca o sa il puteti reactiva doar direct de pe smartphone-ul master AAPS. - Serviciul SMS la distanta s-a oprit. Pentru a il reactiva, utilizati AAPS de pe smartphone-ul master. - Pentru a trimite calibrarea cu %1$.2f răspundeți cu codul %2$s - Bolusare eșuată - Numarul minim de minute care trebuie sa treaca intre un bolus la distanta si urmatorul - Cate minute trebuie sa treaca, cel puţin, intre un bolus si următorul - Pentru siguranta dumneavoastra, pentru a edita aceasta preferinta trebuie sa adaugati cel putin 2 numere de telefon. - Se vor livra %1$.2fU - Bolusul de %1$.2fU a fost livrat cu succes - Bolusul de masa de %1$.2fU a fost livrat cu succes - Țintă %1$s pentru %2$d minute - Tinta %1$s pentru %2$d minute este setata cu succes - Tinta temporara anulata cu succes - Permite comenzi de la distanță, prin SMS - Bucla a fost dezactivată - Bucla a fost activată - Bucla este activată - Pentru a conecta pompa raspundeti cu codul %1$s - Conectarea cu pompa a esuat - Pentru a deconecta pompa timp de %1$d minute, răspundeți cu: %2$s - Pompă deconectată - Pompă reconectată - Comanda de la distanță nu este permisă - Bolus de la distanță nu este disponibil. Încearcă din nou mai târziu. - Pentru a iniția bazala de %1$.2fU/h pentru %2$d min trimiteți codul %3$s - Pentru a schimba profilul în %1$s %2$d%% trimiteți codul %3$s - Pentru a iniția bolusul extins de %1$.2fU/h pentru %2$d min trimiteți codul %3$s - Pentru a introduce %1$dg la %2$s, raspundeti cu: %3$s - Pentru a iniția bazala de %1$d%% pentru %2$d min trimiteți codul %3$s - Pentru suspendarea buclei pentru %1$d minute trimiteți codul %2$s - Pentru a reactiva bucla inchisa, raspundeti cu %1$s - Pentru a activa bucla inchisa, raspundeti cu %1$s - Pentru a dezactiva bucla inchisa, raspundeti cu %1$s - Bazala temporară %1$.2fU/h pentru %2$d minute a fost trimisă cu succes - Bolusul extins de %1$.2fU pentru %2$d min a fost inițiat - %1$dg carbohidrați introduși cu succes - Introducerea a %1$dg de carbohidrati a esuat - Bazala temporară %1$d%% pentru %2$d minute a fost stabilită cu succes - Trimiterea bazalei temporare a eșuat - Pornirea bolusului extins a eșuat - Pentru oprirea bazalei temporare, răspundeți cu codul %1$s - Pentru oprirea bolusului extins, răspundeți cu codul %1$s - Bazala temporară a fost anulată - Bolus extins anulat - Renunțarea la bazala temporară a eșuat - Anularea bolusului extins a eșuat - Comandă necunoscută sau răspuns greșit AsistentRapid Setări AsistentRapid Text buton: @@ -238,13 +172,9 @@ Ceas Retrimite toate datele Deschide setările pe Wear - Valoarea bazalei este sub minimul permis. Profilul nu este setat! - Glicemie: - Ultima glicemie: MM640g Notificare activă DATE VECHI - acum %1$dmin Profil OpenAPS AMA Matrice de %1$d elemente.\nValoarea curentă: @@ -263,7 +193,6 @@ TRAT OBI CEAS - SMS Scurtează titlurile secțiunilor Folosește întotdeauna media scurtă a diferenței în locul diferenței simple Folositor când datele de la surse nefiltrate precum xDrip+ devin \'\'zgomotoase\". @@ -277,13 +206,6 @@ Valoare implicită: 2\nAmânarea bolusului este aplicată după ce ați făcut un bolus de masă, astfel încât bucla să nu reacționeze cu ținte bazale temporare scăzute atunci când tocmai ați mâncat. Exemplul de față și valoarea implicită sunt 2; astfel o durată de acțiune a insulinei (DIA) de 3 ore duce la o eliminare treptată a întârzierii setării bazalelor temporare după 1.5 ore (3DIA/2). Valoarea implicită: 3.0 (AMA) sau 8.0 (SMB). Aceasta este o setare pentru impactul implicit al carbohidraţilor pe 5 minute. Valoarea implicită este 3mg/dl la 5min. Aceasta influenţează rapiditatea cu care se scade COB şi modul în care se ia în calcul absorbţia carbohidraţilor în calcularea valorilor estimate ale glicemiei, atunci când glicemia este în scădere mai mare decât se aştepta sau nu creşte atât de repede pe cât se aştepta. Atenție!\nÎn mod normal nu este nevoie să modificați valorile de mai jos. Vă rog să APĂSAȚI AICI și să CITIȚI textul și să vă asigurați că l-ați ÎNȚELES înainte de a schimba valorile. - Număr de telefon SMS invalid - Calibrare - xDrip+ nu este instalat. - Calibrare trimisă către xDrip+ - Calibrare trimisă. Recepționarea trebuie să fie activată și în xDrip+. - xDrip+ nu recepționează calibrări - Livrare de insulină suspendată Se execută Setări pompă virtuală Trimitere status către NS @@ -319,10 +241,7 @@ Te rog confirmă tipul de pacient pentru a stabilii limitele de siguranță Numele pacientului Vă rugăm să furnizați numele sau porecla pacientului pentru a diferenția între configurări - Utilizator Glimp - Buclă suspendată - Suspendat (%1$d min) Suspendă bucla pentru 1h Suspendă bucla pentru 2h Suspendă bucla pentru 3h @@ -341,9 +260,6 @@ 10 ore Restabilește Reconectaţi pompa - Durată greșită - Buclă suspendată - Buclă restabilită Tendință 15min COB Superbolus @@ -378,7 +294,6 @@ ABS DEVSLOPE Despre - Lipsesc permisiunile de SMS Nu este acordată permisiunea de citire a stării telefonului Stare xDrip+ (ceas) Linie de stare xDrip+ (ceas) @@ -446,14 +361,11 @@ Controlare din ceas Setare Ținte-Temporare și se introduc Tratamente din ceas. Mâncare - g ]]> kJ En Pr Grăsime - Se execută comanda chiar acum - Lipsesc date glicemie Se folosesc notificările sistemului pentru alerte și notificări Creşterea treptată a volumului pentru alerte şi notificări Alerte locale @@ -530,9 +442,6 @@ Permite trimiterea de rapoarte automate de eroare și de date despre folosire către dezvoltatori prin serviciul fabric.io. Actualizați aplicația Dexcom la o versiune acceptată Aplicația Dexcom nu este instalată. - Start TT activitate - Start TT mănânc-în-curând - TT Nu bolusa, doar înregistrează Categorie Subcategorie @@ -545,8 +454,6 @@ Carbohidrați activi Insulină activă Bazale - Nicio acțiune selectată, nu se va întâmpla nimic - Start TT hipo Se folosește versiunea dev. Bucla închisă este dezactivată. Mod inginer activat Lipsă SchimbareProfil. Efectuați o schimbare de profil sau apăsați \"Activare profil\" în ProfilulLocal. @@ -565,7 +472,6 @@ Se limitează IOB la %1$.1f U datorită %2$s valoare maximă în preferințe limită fizică - Citire eșuată a stării Înregistrare schimbare a locului pompei Înregistrare schimbare rezervor insulină SMB dezactivat întotdeauna și după carbohidrați, deoarece sursa glicemiei nu suportă filtrare avansată @@ -617,12 +523,7 @@ Vă rugăm configuraţi RileyLink mai jos. După selectarea unui RileyLink, va fi posibil să continuaţi setarea odată ce starea RieyLink este \"Connected\". Acest lucru ar putea dura un minut.\n Notă: Puteți continua configurarea imediat ce pompa a fost inițializată.\n Începeți primul obiectiv - Permisiune Solicitați permisiunea - Aplicația are nevoie de permisiune la fereastra sistemului pentru a afișa notificări - Aplicația are nevoie sa acceseze locația pentru scanare Bluetooth și identificare WiFi - Aplicația are nevoie de permisiunea de a accesa unitatea de stocare pentru a scrie fișierele registru și pentru a exporta setările - Cerință Afișare navigație Închidere navigație Preferințe plugin @@ -658,8 +559,6 @@ Setări loguri Resetare la setările implicite Funcționare incorectă a NSClient. Aveți în vedere un restart al NS și al NSClient. - Decalaj - Amintește-mi sa fac bolus mai târziu Modul APS preferat Total Calc @@ -689,11 +588,6 @@ Schimbare oră vară/iarnă în mai puțin de 3 ore - buclă închisă dezactivată restricție de stocare internă Eliberați cel puțin %1$d MB din spațiunl de stocare al telefonlui! Buclă dezactivată! - Format greșit - Durata RBT trebuie să fie un multiplu de %1$d minute și mai mare de 0. - Cod greșit. Comandă anulată. - Nu este configurat - Schimbare de profil creată Verificator versiune versiune veche versiune foarte veche @@ -710,12 +604,10 @@ Wizard bolus face un calcul, dar numai o parte din insulina calculată este și livrată. Este mai eficient când se folosește cu algoritmul SMB. Amână Se mărește valoarea bazalei maxime deoarece setarea este mai joasă decât bazala maximă din profil - Conținutul mesajului nu este valid %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Nume profil: Selectat: Unități @@ -761,25 +653,6 @@ Timp de execuţie SMB Timp solicitare bazală temporară Timpul de execuție al bazalei temporare - - de la aplicația Authenticator pentru: %1$s urmat de PIN - PIN obligatoriu suplimentar la sfârșitul token-ului - Cifre suplimentare care ar trebui să fie memorate și adăugate la sfârșitul fiecărei parole unice generate - Setare Authenticator - Cod de verificat: - OTP + cod PIN - Codul de verificare constă din 6 cifre afişate de către aplicaţia Authentificator (cunoscută ca OTP), urmat de 3 sau mai multe cifre de PIN obligatoriu. - Resetați Authenticatori - Resetați cheia pentru Authenticator - Sunteți sigur că vreți sa resetați cheia pentru Authenticator? Acest lucru va invalida toți Authenticatorii configurați și va trebui să ii setați din nou. - S-a generat o nouă cheie pentru Authenticator! Vă rugăm să utilizați QRCode actualizat pentru a configura autentificatori. - Se exporta secretul OTP - Sunteţi sigur că doriţi să copiaţi secretul OTP în clipboard?\n\nS-ar putea să aveţi nevoie doar dacă aplicaţia dumneavoastră de autentificare are probleme de scanare a QRCode, doriţi să o introduceţi manual sau doriţi să configuraţi token-ul hardware OTP folosind aplicaţia dedicată. - Secret OTP (în formatul Base32) exportat şi copiat în clipboard. Lipiţi-l în autentificator sau in hardware OTP burner! - 1. Instalați Authenticator - 3. Testați o parolă unică - Resetați Authenticatori - Pe fiecare telefon urmăritor instalați o aplicație de tip Authenticator care suporta tokens RFC 6238 TOTP. Asemenea aplicații gratuite populare sunt:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Predicții Panta deviaţiei Autorizarea a eșuat @@ -809,21 +682,9 @@ Filtru Nu se poate crea profilul. Profilul este invalid. Nu-mi opri aplicația? - Trimite SMS dacă este generata o alarma de eroare conexiune pompa - Raportează pompa inaccesibilă Rulează alarma când este timpul să mănânci - Rulează alarma în %1$d min - Consilier bolus - Glicemia ta e mare. In loc sa mănânci acum, este recomandat sa mai aștepți un pic. Vrei sa faci un bolus de corecție acum si sa setezi o alarma pentru a manca mai târziu? In acest caz, nu vor fi înregistrați carbohidrați si va trebui sa folosești calculatorul de bolus din nou când îți vom reaminti. - Activare consilier bolus - Folosește o alarma de reamintire pentru a începe sa mănânci mai târziu în loc de alerta de la calculatorul de bolus din timpul hiperglicemiei (\"pre-bolus\") Timpul sa mănânci!\nRuleaza Calculatorul de Bolus pentru a face calculele din nou. - Timpul sa mănânci - Memento bolus Activează memento bolus - Folosește memento pentru a bolusa mai târziu cu asistentul - (\"post-bolus\") - Timpul sa faci bolus!\nRuleaza Calculatorul de Bolus pentru a face calculele din nou. Încărcarea jurnalelor de erori este dezactivata! Grafic Meniu diagramă @@ -858,8 +719,6 @@ Acceptaţi evenimentele de tratament (canulă, insulină, modificarea bateriei etc.) introduse prin NS sau NSClient Primire/completare date CGM Acceptați datele CGM din NS - Timp expirat cat ce se aștepta terminarea comunicării anterioare a pompei - Există un alt bolus în coada de așteptare. Încercați din nou mai târziu. Calcul în desfășurare Lipsește numele profilului Eroare in valorile IC diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 0535c1f5ec..dfef107f45 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -13,7 +13,6 @@ обнулить базы Вы действительно хотите обнулить базы данных? Выход - Это устройство не поддерживает меню оптимизации батареи - могут быть проблемы с производительностью. Кнопки быстрого доступа к некоторым распространенным настройкам Применяется для настройки активных плагинов Обучающая программа @@ -42,11 +41,9 @@ Сохраняет все выполненные назначения Мониторить и контролировать AAPS при помощи часов WearOS. Показать информацию о работе алгоритма ИПЖ на экране смарт-часов xDrip+. - Дистанционное управление AAPS при помощи команд SMS. инсулин: углеводы: IOB: активн инс - IOB: активный инсулин Общий IOB: Общая активность IOB: длит: @@ -54,9 +51,7 @@ инсулин: IOB: активный инсулин общий IOB - гликемия TT - углеводы коррекция болюс IOB выполнить сейчас @@ -73,7 +68,6 @@ данные гликемии недоступны запрос изменение - дельта: Конфигуратор Начало Терапия @@ -97,13 +91,9 @@ безопасность модуль не активен ограничение нарушено - Возможна ошибка в подаче болюса. Проверьте реальное количество поданного инсулина принять новый врем базал: болюс калькулятор - применено ограничение! - болюс: - базал: измените введенные данные источник СК Откуда должен получать данные AAPS? @@ -117,13 +107,10 @@ Предложены углеводы Неподдерживаемая версия Nightscout базал IOB - применено ограничение болюса - применено ограничение углеводов другое глюкометр сенсор Подождать до еды - Длительность действия профиль тип глюкозы ВремБазал @@ -163,60 +150,6 @@ я понимаю и принимаю Сохранить обновить профиль - SMS коммуникатор - разрешенные телефонные номера - + XXXXXXXXXX; + YYYYYYYYYY - Чтобы подать болюс %1$.2fU ответьте кодом %2$s - Чтобы подать болюс %1$.2fU ответьте кодом %2$s - Чтобы установить временную цель %1$s ответьте кодом %2$s - Чтобы отменить временную цель ответьте кодом %1$s - Чтобы отключить службу удаленных SMS-сообщений ответьте кодом %1$s.\n\n Имейте в виду, что вы сможете вновь активировать ее только с основного телефона AAPS. - Удаленная служба SMS остановлена. Для ее реактивации используйте AAPS на главном смартфоне. - чтобы отправить калибровку %1$.2f ответьте кодом %2$s - Подача болюса не состоялась - Минимальное количество минут между одним удаленным болюсом и следующим - Минимум минут, должных пройти между одним болюсом и следующим - В целях безопасности, для изменения этого параметра необходимо добавить не менее 2 телефонных номеров. - Будет подано %1$.2fU ед. инс - Болюс %1$.2fед. подан успешно - Болюс на еду %1$.2f ед. подан успешно - Цель %1$s на %2$d минут - Цель %1$s на %2$d минут установлена успешно - Временная цель успешно отменена - разрешить команды через смс - зцикл был деактивирован - зцикл был активирован - зцикл работает - Чтобы подсоединить помпу ответьте кодом %1$s - Ошибка подключения к помпе - Для разъединения с помпой на %1$d мин ответьте кодом %2$s - Помпа отключена - Связь с помпой возобновлена - удаленная команда не разрешена - Удаленный болюс недоступен, повторите попытку позже. - Для начала подачи базала %1$.2f ед./ч на %2$d мин. ответьте кодом %3$s - Для переключения профиля на %1$s %2$d%% ответьте кодом %3$s - Для начала подачи пролонгированного болюса %1$.2fед. на %2$d мин. ответьте кодом %3$s - Чтобы ввести %1$d г в %2$s ответьте кодом %3$s - Для начала подачи базала %1$d%% на %2$d мин. ответьте кодом %3$s - для приостановки цикла на %1$d мин ответьте кодом %2$s - Чтобы возобновить цикл ответьте кодом %1$s - Чтобы включить цикл ответьте кодом %1$s - Чтобы отключить цикл ответьте кодом %1$s - врем базал %1$.2fU/h на %2$d мин начат успешно - Пролонгированный болюс %1$.2fед. на %2$d мин. начат успешно - Углеводы %1$d г введены успешно - Не удалось ввести %1$d г углеводов - Врем. базал %1$d%% на %2$d мин. начат успешно - неуспех старта врем базала - Не удалось начать подачу пролонгированного болюса - Для прекращения подачи врем. базала ответьте кодом %1$s - Для прекращения подачи пролонгированного болюса ответьте кодом %1$s - врем базал отменен - Пролонгированный болюс отменен - отмена врем базала не состоялась - Сбой отмены пролонгированного болюса - Неизвестная команда или неверный ответ БыстрыйБолюс БыстрыйБолюс настройки текст на кнопке @@ -247,13 +180,9 @@ повторить отправку всех данных Открыть настройки на Wear Базальная скорость - значение базала ниже минимума. профиль не создан! - гликемия: - прошлый СК: MM640g текущие уведомления старые данные - %1$d мин. назад Профиль Помощник болюса OpenAPS AMA Массив %1$d элементов. \nActual актуальная величина: @@ -273,7 +202,6 @@ НАЗНАЧ ЦЕЛИ WEAR - SMS сокращенные имена табул всегда используйте укороченное среднее приращение вместо простого Полезно когда данные из нефильтрованных источников вроде xDrip+ начинают \"шуметь\". @@ -287,13 +215,6 @@ значение по умолчанию :2 bolus snoose активируется после введения болюса на еду чтобы цикл не взаимодействовал с временными низкими СК сразу после еды. так, трехчасовой DIA при величине 2 означает постыпенное затихание bolus snooze после 1.5 часов (3DIA/2) Значение по умолчанию: 3.0 (AMA) или 8.0 (SMB). Эта настройка на усвоение углеводов за 5 мин. По умолчанию ожидается 3мг/дл/5мин. Влияет на скорость учета поглощения углеводов COB и усвоения в расчетах прогнозируемой гликемии, когда СК падает быстрее или не растет так как ожидается. Внимание! Обычно нет необходимости изменять приведенные ниже величины. Нажмите ЗДЕСЬ, ПРОЧТИТЕ и убедитесь что вы ПОНИМАЕТЕ изложенное прежде чем менять какую-либо из этих величин - неверный номер телефона для смс - калибровка - xdrip+ не установлен - Калибровка отправлена на xDrip+ - Калибровка отправлена. В xDrip+ должен быть включена возможность приема. - xDrip + не получает калибровки - Работа помпы остановлена выполнение настройки вирт помпы статус передачи данных в NS @@ -329,11 +250,7 @@ Пожалуйста, выберите тип пациента для установки лимитов безопасности Имя пациента Укажите имя или псевдоним пациента, чтобы распознавать разные настройки - Пользователь Glimp - %1$s необходимо включить в белый список оптимизации батареи для корректной работы - ЗЦ остановлен - Остановлен на(%1$d m) приостановить цикл на 1 час приостановить цикл на 2 часа приостановить цикл на 3 часа @@ -352,9 +269,6 @@ 10 часов возобновить Возобновить соединение с помпой - неверное значение длительности - ЗЦ остановлен - ЗЦикл возобновлен 15 мин тренд активн углеводы суперболюс @@ -389,7 +303,6 @@ НАДО ЛИНОТКЛН о приложении - отсутствует смс подтверждение Отсутствует разрешение телефона Cтрока состояния xDrip (часы) Cтрока состояния xDrip (часы) @@ -462,14 +375,11 @@ Контроль с часов Ставить временные цели и вводить назначения с часов. Еда - грамм ]]> кДж Энергия Белки Жиры - Команда выполняется - Пропущенные данные СК Использовать системные уведомления для предупреждений и уведомлений Постепенно увеличивать громкость оповещений и уведомлений Локальные оповещения @@ -547,9 +457,6 @@ Разрешить отправлять сообщения о неполадках и данные об использовании опций разработчикам при помощи сервиса fabric.io. Пожалуйста, обновите приложение Dexcom до поддерживаемой версии Приложение Dexcom не установлено - Включить временную цель TT Нагрузка - Включить временную цель TT Ожидаемый прием пищи - Временная цель (TT) Не подавать болюс, только внести запись Категория Подкатегория @@ -562,8 +469,6 @@ Активные углеводы COB Активный инсулин IOB Базал - Действие не выбрано, ничего не произойдет - Начать временную цель ТТ Гипо Работает версия разработчика. Замкнутый цикл отключен. Режим отладки включен Профиль не переключен. Пожалуйста переключите профиль или нажмите \"активировать профиль\" в LocalProfile. @@ -582,7 +487,6 @@ Ограничение активного инсулина IOB до %1$.1f ед. из-за %2$s максимальное значение в настройках жесткий предел - Статус чтения: неудача Запись о замене места помпы Запись о замене картриджа инсулина Опция супер микро болюс всегда и после углеводов отключена т. к. активный источник данных СК не поддерживает комплексное фильтрование @@ -640,12 +544,7 @@ Сконфигурируйте RileyLink. После выбора RileyLink можно будет продолжить установку если состояние RileyLink \"Соединено\". Это может занять минуту.\n Примечание: После инициализации помпы можно продолжить настройку\n Начните первую Цель - Права доступа Запросить права доступа - Приложению требуется разрешение системного окна для уведомлений - Приложению требуется разрешение на доступ к местоположению для сканирования BT и идентификации WiFi - Приложение требует разрешения на доступ к записи в память, чтобы хранить файлы журналов и настройки экспорта - Запрос Показать панель навигации Cкрыть панель навигации Настройки расширений @@ -691,8 +590,6 @@ Настройки журнала Восстановить значения по умолчанию Некорректная работа NSClient. Возможно следует перезапустить NS и NSClient. - Смещение по времени - Напомнить о болюсе позже Предпочитаемый режим APS Итого Кальк @@ -723,11 +620,6 @@ Изменение сезонного времени произошло меньше 3 часов назад-Закрытый цикл выключен ограничение по объему карты памяти Освободите по крайней мере %1$d MB из внутренней памяти! Цикл остановлен! - Неверный формат - Длительность временного базала TBR должна быть кратной %1$d минутам и больше 0. - Неверный код. Команда отменена. - Не сконфигурировано - Переключатель профиля создан Проверка версии старая версия очень старая версия @@ -744,12 +636,10 @@ Мастер болюса выполняет расчет, но подана только эта часть рекомендуемого инсулина. Полезно с алгоритмом SMB. Отложить Повышаю максимальное значение базы т. к. оно меньше, чем максимальное значение в профиле - Недопустимое тело сообщения %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - мин Название профиля: Выбрано: Единицы @@ -803,27 +693,6 @@ Время выполнения микроболюса SMB Время запроса временной базальной скорости Время выполнения временной базальной скорости - - из приложения Authenticator для %1$s и дополните пином в конце - Дополнительный обязательный пин-код в конце маркера - Дополнительные цифры, которые должны быть запомнены и добавлены в конце каждого сгенерированного одноразового пароля - Настройка аутентификации - Код для проверки: - OTP + ПИН-код - Проверочный код состоит из 6 цифр, отображаемых приложением Authenticator (известным как OTP), за которым следует 3 или более цифр обязательного PIN-кода. - Сбросить аутентификаторы - Сбросить ключ идентификации - Вы действительно хотите сбросить ключ аутентификации? Все сконфигурированные в настоящее время ключи станут недопустимы, и придется их настроить заново. - Создан новый ключ аутентификации! Для идентификации используйте обновленный QRCode. - Экспорт секретного кода OTP - Вы действительно хотите скопировать пароль OTP в буфер обмена?\n\nЭто может потребоваться только в том случае, если у вашего приложения идентификации проблемы при сканировании QR кода, вы хотите ввести его вручную или настроить аппаратный маркер OTP с помощью специального приложения. - Секретный одноразовый код OTP (в формате Base32) экспортирован и скопирован в буфер обмена. Вставьте его в систему идентификации или аппаратный маркер OTP! - 1. Установить Аутентификатор - 2. Сканируйте код для настройки OTP кодов AAPS - 3. Одноразовый Пароль - Сбросить аутентификаторы - В каждом отслеживающем телефоне установите приложение Authenticator, поддерживающее маркеры TOTP RFC 6238. Популярные бесплатные приложения: \n Authy\n Google Authenticator\n LastPass Authenticator\n FreeOTP Authenticator - После сброса аутентификатора вы делаете все созданные идентификаторы недействительными. Вам нужно будет снова создать их! Прогнозирование Терапия Линия отклонения @@ -854,20 +723,9 @@ Фильтр Не удается создать локальный профиль. Настройки профиля неправильны. Не закрывать приложение? - Отправить SMS, если инициируется запись о недоступности помпы - Сообщить о недоступности помпы Напомнить о еде - Напомнить через %1$d мин - Помощник болюса - У вас высокая глюкоза крови. Лучше подождать, чем есть сейчас. Хотите сделать болюс на коррекцию и установить напоминание, когда будет пора есть? В этом случае углеводы не будут записаны и после напоминания надо будет снова воспользоваться помощником. - Вкл помощник болюса - Используйте напоминание для того, чтобы начать есть позже, вместо того, чтобы воспользоваться помощником болюса на высоких значениях ГК (\"пре-болюс\") Пора есть!\nЗапустите помощник болюса снова для подсчета. - Пора есть - Напоминание о болюсе Включить напоминание о болюсе - Применить напоминание о болюсе с помощью мастера (постболюс) - Пора дать болюс!\nЗапустите помощник болюса и повторите расчет. Загрузка журналов сбоя на сервер отключена! График Меню графика @@ -904,8 +762,6 @@ Принимать события терапии (катетер, инсулин, изменение батареи и т. д.) через NS или NSClient Получать/заполнять данные мониторинга CGM Принимать данные мониторинга CGM из NS - Таймаут во время ожидания окончания предыдущего соединения с помпой - В очереди есть еще один болюс. Повторите попытку позже. Идет подсчет Отсутствует название профиля Ошибка в значении углеводного коэффициента IC @@ -950,7 +806,6 @@ инсулин уровень глюкозы в крови (ГК) устаревшие данные - установить напоминание добавить новый профиль клонировать текущий профиль удалить текущий профиль @@ -1009,7 +864,6 @@ Показать цикл %1$d выбрано Сортировать - Диалог отменен Очень низкий Низкий Высокий @@ -1028,7 +882,6 @@ Логин Удалить всё Перезапустить старт - QR код для введения временного пароля открыть настройки задать оповещение таймера углеводов Все @@ -1045,7 +898,6 @@ Заблокировано опциями зарядки Заблокировано настройками подключения (Часы не подключены) - Ошибка при запросе разрешения Настроить чувствительность относительно ГК Очистка базы данных Вы хотите очистить базу данных?\nЭто удалит отслеживаемые изменения и данные старше 3 месяцев. diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index f3566915e0..c0ac5ec301 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -13,7 +13,6 @@ Vymaž databázu Naozaj chcete vymazať databázu? Ukončiť - Toto zariadenie zrejme neumožňuje vypnúť optimalizáciu batérie - môže dochádzať k problémom s výkonom. Niektoré tlačidlá na rýchly prístup do spoločných funkcií Používané na konfiguráciu aktívnych pluginov Výukový program @@ -42,11 +41,9 @@ Ukladá všetky ošetrenia do databázy Zobrazovanie stavu a riadenie AndroidAPS z hodiniek s WearOS. Zobraz informácie o uzavretom okruhu na xDrip+ watchface. - Ovládanie AndroidAPS na diaľku použitím SMS príkazov. Inzulín: Sacharidy: IOB: - IOB: Celkový IOB: Celková aktivita IOB: Trv: @@ -54,9 +51,7 @@ Inz: IOB: Celkový IOB: - Glykémia TT - Sacharidy Korekcia Bolusový IOB Spustiť teraz @@ -73,7 +68,6 @@ Nedostupné dáta o glykémiách Požiadavka Rozdiel - Rozdiel: Konfigurácia Prehľad Ošetrenia @@ -97,13 +91,9 @@ Bezpečnosť Modul je deaktivovaný Mimo povolený rozsah - Bolus zaznamenal chybu. Overte prosím manuálne reálne podané množstvo Povoliť nový dočasný bazál: Bolus Kalkulačka - Aplikované obmedzenie! - Bolus: - Bazál: Zmeňte zadanie! Zdroj glykémie Odkiaľ má AndroidAPS získavať glykémie? @@ -117,13 +107,10 @@ Návrh sacharidov Nepodporovaná verzia Nighscoutu Bazálny IOB - Aplikované obmedzenie bolusu - Aplikované obmedzenie sacharidov Iné Glukomer Senzor Čas jedla - Trvanie Profil Zadanie glykémie Dočasný bazál @@ -163,60 +150,6 @@ ROZUMIEM A POTVRDZUJEM Uložiť Obnoviť profil - SMS komunikátor - Povolené telefónne čísla - +421XXXXXXXXX;+421YYYYYYYYY - Pre podanie bolusu %1$.2fJI odpovedz SMS kódom %2$s - Pre podanie bolusu k jedlu %1$.2fJI odpovedz SMS kódom %2$s - Pre nastavenie dočasného cieľa %1$s odpovedz SMS kódom %2$s - Pre zrušenie dočasného bazálu odpovedzte SMS s kódom %1$s - Pre vypnutie služby SMS komunikátora odpovedz SMS kódom %1$s.\n\n\Majte na pamäti, že opätovná reaktivácia je možná len priamo na AAPS master telefóne. - SMS komunikátor zastavený. Na jeho reaktiváciu, použite AAPS na master telefóne. - Pre odoslanie kalibrácie %1$.2f odpovedz SMS kódom %2$s - Chyba pri aplikovaní bolusu - Minimálny počet minút, ktorý musí uplynúť medzi jedným vzdialeným bolusom a tým nasledujúcim - Aspoň koľko minút musí uplynúť, medzi jedným vzdialeným bolusom a tým nasledujúcim - Pre vašu bezpečnosť, musíte pridať aspoň 2 telefónne čísla, aby ste zmenili toto prednastavenie. - Podávanie %1$.2f J inzulínu - Bolus %1$.2f JI podaný úspešne - Bolus na jedlo %1$.2f JI podaný úspešne - Cieľ %1$s na %2$d minút - Cieľ %1$s na %2$d minút bol úspešne nastavený - Dočasný cieľ úspešne zrušený - Povoliť príkazy na diaľku cez SMS - Uzavretý okruh bol deaktivovaný - Uzavretý okruh bol aktivovaný - Uzavretý okruh je aktivovaný - Ak chcete pripojiť pumpu, odpovedzte pomocou SMS s kódom %1$s - Pripojenie k pumpe zlyhalo - Ak chcete odpojiť pumpu na %1$d minút, odpovedzte pomocou SMS s kódom %2$s - Pumpa odpojená - Pumpa bola znovu pripojená - Príkazy na diaľku nie sú povolené - Diaľkovo ovládaný bolus nie je momentálne povolený. Skúste to neskôr. - Pre spustenie bazálu %1$.2f JI/h na %2$d min odpovedzte SMS s kódom %3$s - Pre prepnutie profilu na %1$s %2$d%% odpovedzte SMS s kódom %3$s - Pre spustenie predĺženého bolusu %1$.2f JI na %2$d min odpovedzte SMS s kódom %3$s - Pre zadanie %1$dg na %2$s odpovedz SMS kódom %3$s - Pre spustenie bazálu %1$d%% na %2$d min odpovedzte SMS s kódom %3$s - Pre pozastavenie uzavretého okruhu na %1$d minút odpovedaj SMS s kódom %2$s - Pre obnovenie uzavretého okruhu, odpovedzte SMS s kódom %1$s - Pre povolenie uzavretého okruhu, odpovedzte SMS s kódom %1$s - Pre zakázanie uzavretého okruhu, odpovedzte SMS s kódom %1$s - Dočasný bazál %1$.2fJI/h spustený na %2$d minút - Predĺžený bolus %1$.2fJI na %2$d min úspešne spustený - Sacharidy %1$d g zadané úspešne - Zadanie %1$dg sacharidov sa nepodarilo - Dočasný bazál %1$d%% na %2$d minút úspešne spustený - Spustenie dočasného bazálu zlyhalo - Spustenie predĺženého bolusu zlyhalo - Na zastavenie dočasného bazálu odpovedzte SMS s kódom %1$s - Na zastavenie predĺženého bolusu odpovedzte SMS s kódom %1$s - Dočasný bazál zrušený - Predĺžený bolus zastavený - Zrušenie dočasného bazálu zlyhalo - Zastavenie predĺženého bolusu zlyhalo - Neznámy príkaz alebo chybná odpoveď Rýchly bolus Nastavenie rýchleho bolusu Text na tlačidle: @@ -247,13 +180,9 @@ Všetky dáta poslať znova Otvoriť nastavenia na hodinkách Bazál - Hodnota bazálu pod povoleným minimom. Profil nenastavený! - Glykémia: - Posledná glykémia: MM640g Priebežné notifikácie ZASTARALÉ DÁTA - pred %1$d min Profil OpenAPS AMA Pole %1$d prvkov.\nAktuálna hodnota: @@ -273,7 +202,6 @@ OŠET CIEĽ WEAR - SMS Krátke názvy modulov Vždy používať krátkodobý priemerný rozdiel glykémií, namiesto rozdielu posledných dvoch hodnôt Zmysluplné, pokiaľ dáta z xDrip+ obsahujú veľký šum. @@ -287,13 +215,6 @@ Štandardná hodnota: 2\nToto nastavenie hovorí, po akú časť z hodnoty DIA uzavretý okruh po boluse čaká a nereaguje na zmeny glykémií (tu 3DIA/2 = 1,5h). Štandardná hodnota: 3.0 (AMA), alebo 8.0 (SMB) mg/dl/5min. Táto hodnota definuje minimálnu časť vstrebaných sacharidov za každých 5min. Táto hodnota ovplyvňuje výpočet COB. Pozor!\nZa normálnych okolností tieto hodnoty nemusíte meniť. Kliknete TU, PREČÍTAJTE si informácie a UISTITE sa, že im rozumiete skôr, ako ich začnete meniť. - Chybné telefónne číslo - Kalibrácia - xDrip+ nie je nainštalovaný - Kalibrácia odoslaná do xDrip+ - Kalibrácia odoslaná. Príjem kalibrácií musí byť povolený v xDrip+. - xDrip+ neprijíma kalibrácie - Pumpa pozastavená Vykonávam Nastavenie virtuálnej pumpy Nahrať stav do NS @@ -329,11 +250,7 @@ Prosím vyberte typ pacienta pre nastavenie bezpečnostných limitov Meno pacienta Zadajte meno pacienta, alebo prezývku pre rozlíšenie medzi viacerými nastaveniami - Používateľ Glimp - %1$s potrebuje vypnúť optimalizáciu batérie pre optimálny výkon - Uzavretý okruh pozastavený - Pozastavený (%1$d min) Pozastaviť uzavretý okruh na 1 h Pozastaviť uzavretý okruh na 2 h Pozastaviť uzavretý okruh na 3 h @@ -352,9 +269,6 @@ 10 hodiny Pokračovať Znovu pripojiť pumpu - Nesprávna doba trvania - Uzavretý okruh pozastavený - Uzavretý okruh obnovený 15min trend COB Superbolus @@ -389,7 +303,6 @@ ABS DEVSLOPE O aplikácii - Chýbajúce povolenie SMS príkazov Chýba oprávnenia pre zisťovanie stavu telefónu Stav z xDrip+ (hodinky) Stavový riadok xDrip+ (hodinky) @@ -462,14 +375,11 @@ Ovládanie z hodiniek Nastavovanie dočasných cieľov a vkladanie ošetrení hodinkami. Jedlo - g ]]> kJ En Pr Tuk - Príkaz sa práve vykonáva - Chýbajúce hodnoty glykémie Používať systémové notifikácie pre výstrahy a oznámenia Postupne zvyšovať hlasitosť upozornení a oznámení Lokálne výstrahy @@ -547,9 +457,6 @@ Automatické odosielanie chýb aplikácie a štatistiky používania vývojárom pomocou služby fabric.io. Prosím aktualizuj tvoju Dexcom aplikáciu na podporovanú verziu Dexcom aplikácia nie je nainštalovaná. - Spustiť Dočasný cieľ Aktivita - Spustiť Dočasný cieľ Blížiace sa jedlo - DC Nepodať bolus, iba zaznamenať Kategória Podkategória @@ -562,8 +469,6 @@ Aktívne sacharidy Aktívny inzulín Bazály - Žiadna akcia nevybraná, nič sa neudeje - Spustiť doč. cieľ Hypo Bežiaca vývojárska verzia. Uzavretý okruh je zakázaný. Vývojársky mód povolený Prepnutie profilu chýba. Vykonajte prepnutie profilu, alebo ho aktivujte na záložke lokálneho profilu. @@ -582,7 +487,6 @@ IOB obmedzený na %1$.1f JI: %2$s maximálna hodnota v nastaveniach pevný limit - Načítanie stavu zlyhalo Zaznamenať výmenu setu Zaznamenať výmenu inzulínu \"SMB vždy\" a \"po jedle\" zakázané pretože zdroj glykémie nepodporuje rozšírené filtrovánie @@ -640,12 +544,7 @@ Prosím nakonfigurujte svoj RileyLink nižšie. Po výbere RileyLinku bude možné pokračovať v nastavení, akonáhle je stav RileyLinku \"Pripojené\". Táto akcia môže chvíľku trvať.\n Poznámka: Po nastavení pumpy môžete pokračovať v nastavení.\n Spusťte prvý cieľ - Povolenie Vyžiadať si povolenie - Aplikácia vyžaduje pre oznámenia systémové oprávnenie - Aplikácia vyžaduje oprávnenie polohy, pre vyhľadávanie BT a identifikáciu WiFi - Aby bolo možné nahrávať logy a exportovať nastavenia, je nutné pre aplikáciu povoliť oprávnenie prístupu k úložisku - Požiadavka Otvoriť Menu Zavrieť Menu Nastavenie modulu @@ -691,8 +590,6 @@ Nastavenie logovania Obnoviť predvolené Chyba NSClienta. Zvážte reštart NS a NSClienta. - Časový posun - Upozorniť na bolus neskôr Preferovaný režim APS Spolu Kalk @@ -723,11 +620,6 @@ Zmena letného času za menej ako 3 hodiny - Uzavretý okruh pozastavený obmedzenie interného úložiska Uvoľnite aspoň %1$d MB z interného úložiska! Uzavretý okruh zakázaný! - Chybný formát - Trvanie dočasného bazálu musí byť násobkom %1$d minút a musí byť väčšie ako 0. - Nesprávný kód. Príkaz zrušený. - Nie je nakonfigurované - Prepnutie profilu vytvorené Kontrola verzie stará verzia veľmi stará verzia @@ -744,12 +636,10 @@ Bolusová kalkulačka urobí výpočet, ale iba táto časť vypočítaného inzulínu je podaná. Pomáha pri SMB algoritme. Stíšiť Zvýšenie maximálnej hodnoty bazálu, pretože nastavenie je nižšie, než je vaša maximálna hodnota bazálu v profile - Neplatný obsah správy %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Názov profilu: Vybrané: Jednotky @@ -803,27 +693,6 @@ Čas aplikácie SMB Čas požiadavky dočasného bazálu Čas spustenia dočasného bazálu - - z aplikácie Authenticator pre: %1$s nasledované kódom PIN - Ďalší povinný kód PIN na konci tokenu - Ďalšie číslice, ktoré by mali byť zapamätané a pridané na koniec každého vygenerovaného jednorázového hesla - Nastavenie autentifikátora - Kód pre kontrolu: - OTP + PIN - Overovací kód sa skladá zo 6 číslic zobrazených aplikáciou Authenticator (známej ako OTP) nasledované 3, alebo viacerými číslicami povinného kódu PIN. - Resetovať autentifikátory - Resetovať autentifikačný kľúč - Ste si istý, že chcete obnoviť autentifikačný kľúč? Vyresetujete tým všetky aktuálne nakonfigurované autentikátory a budete ich musieť znovu nastaviť. - Bol vygenerovaný nový autentifikačný kľúč! Prosím, použite aktualizovaný QR kód pre nastavenie autentifikátorov. - Export OTP tajného kľúča - Ste si istý, že chcete skopírovať tajný OTP kľúč do schránky?\n\nPravdepodobne to budete potrebovať iba v prípade, keď bude mať vaša overovacia aplikácia problém so skenováním QR kódu, chcete ho zadať ručne, alebo chcete nakonfigurovať hardwarový OTP token pomocou špeciálnej aplikácie. - Tajné OTP heslo (vo formáte Base32) bolo vyexportované a skopírované do schránky. Vložte ho do autentikátora, alebo programátora OTP hardwaru! - 1. Nainštalujte Autentifikátor - 2. Naskenujte kód pre nastavenie AndroidAPS OTP kódov - 3. Odtestujte jednorázové heslo - Resetovať autentifikátory - Na každom sledovacom telefóne nainštalujte Autentifikátor, ktorý podporuje tokeny TOTP RFC 6238. Najobľúbenejšie bezplatné aplikácie sú:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator - Resetovaním autentifikátora budú všetky už poskytnuté autentifikátory neplatné. Budete ich musieť znovu nastaviť! Predikcie Ošetrenia Odchýlka sklonu @@ -854,21 +723,11 @@ Filter Nie je možné vytvoriť lokálny profil. Profil je neplatný. Nepotláčať moju aplikáciu? - Odoslať SMS, pokiaľ pumpa nie je dostupná - Nahlásiť nedostupnú pumpu Spustiť výstrahu, keď je čas na jedlo - Spustiť výstrahu za %1$d min - Bolusový poradca - Máte vysokú glykémiu. Namiesto jedla doporučujeme počkať na lepšiu glykémiu a pripomenúť, keď bude čas na jedlo. Prajete si poslať korekčný bolus a pripomenúť, keď bude čas na jedlo? V tomto prípade nebudú zapísané žiadne sacharidy, a neskôr musíte opäť spustiť kalkulačku, akonáhle vám to pripomenieme. - Povoliť bolusového poradcu - Pri vysokej glykémii spustiť pripomienku namiesto výsledku z kalkulačky, aby ste začali jesť neskôr (tzv. \"prebolus\") Čas na jedlo!\nSpustite Bolusovú kalkulačku a urobte výpočet znova. - Čas na jedlo - Pripomenutie bolusu Zapnúť pripomínanie bolusu Použite pripomenutie pre neskorší bolus s kalkulačkou (\"oneskorený bolus\") - Čas na bolus!\nSpustite Bolusovú kalkulačku a urobte výpočet znova. Odosielanie protokolov o zlyhaní je zakázané! Graf Grafové menu @@ -905,8 +764,6 @@ Prijať liečebné udalosti (výmena setu, inzulínu, batérie atď.) zadané prostredníctvom NS, alebo NSClienta Prijímať/doplňovať glykémie Prijať CGM dáta z NS - Vypršal časový limit pri čakaní na dokončenie predchádzajúcej komunikácie s pumpou - Vo fronte je ďalší bolus. Skúste to znovu neskôr. Prebieha výpočet Chýba názov profilu Chyba v hodnotách inz./sach. prevodu @@ -951,7 +808,6 @@ inzulín glykémia zastaralé - nastaviť pripomienku pridať nový profil klonovať aktuálny profil zmazať aktuálny profil @@ -1010,7 +866,6 @@ Zobraziť uzavretý okruh Vybrané: %1$d Zoradiť - Dialóg zrušený Veľmi nízka Nízka Vysoká @@ -1029,7 +884,6 @@ Prihlásenie Odstrániť všetko Resetovať štart - QR kód pre nastavenie jednorázového hesla otvoriť nastavenia nastaviť upozornenie na sacharidy Všetko @@ -1046,7 +900,6 @@ Zablokované možnosti nabíjania Zablokované možnosti pripojenia (Žiadne hodinky nie sú pripojené) - Chyba pri žiadosti o oprávnenie Upraviť citlivosť a glykémiu Vyčistenie databázy Chcete vyčistiť databázu?\nOdstráni sledované zmeny a historické dáta staršie ako 3 mesiace. diff --git a/app/src/main/res/values-sr-rCS/strings.xml b/app/src/main/res/values-sr-rCS/strings.xml index b73615f8f0..4b593cc694 100644 --- a/app/src/main/res/values-sr-rCS/strings.xml +++ b/app/src/main/res/values-sr-rCS/strings.xml @@ -3,7 +3,6 @@ - diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index db64001d80..32e2d82b44 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -12,7 +12,6 @@ Återställ databaserna Vill du verkligen återställa databaserna? Avsluta - Denna enhet verkar inte ha stöd för vitlistning från batterioptimering. Du eventuellt råka ut för problem pga detta. Knappar för att snabbt komma åt vanliga funktioner Används för att konfigurera de aktiva insticksprogrammen Inlärningsprogram @@ -44,7 +43,6 @@ Eversense-appen. Insulin: KH: IOB: - IOB: IOB fr bolus: Insulinaktivitet (5m): Dur: @@ -52,9 +50,7 @@ Eversense-appen. Ins: IOB: IOB fr basal: - BG TT - Kolhydrater Korrektion Bolus IOB Utför nu @@ -71,7 +67,6 @@ Eversense-appen. Ingen BG-data tillänglig Beräknat behov Delta - Delta: Konfigurationsverktyg Översikt Behandlingar @@ -92,13 +87,9 @@ Eversense-appen. Säkerhet Insticksprogram inaktiverat Begränsning nådd - Ett fel rapporterades under bolus. Vänligen kontrollera pumpen manuellt Acceptera ny temp basal: Behandling Kalkylator - Begränsning nådd - Bolus: - Basal: Ändra inmatning BG-källa xDrip+ @@ -111,13 +102,10 @@ Eversense-appen. KH-förslag Versionen av Nightscout stöds inte IOB från basal - Bolusspärr aktiverad - Kolhydratsspärr aktiverad Annat Mätare Sensor KH-tid - Duration Profil Glukostyp Temp basal @@ -157,60 +145,6 @@ Eversense-appen. JAG FÖRSTÅR OCH GODKÄNNER Spara Ladda om profil - SMS-tjänst - Godkända telefonnummer - +4670XXXXXXX; +4670YYYYYYY - För att ge bolus %1$.2f enheter, svara med kod %2$s - För att ge bolus %1$.2f enheter, svara med kod: %2$s - För att sätta ett temporärt mål på %1$s svara med kod %2$s - För att avbryta temporärt mål, svara med kod: %1$s - För att inaktivera fjärrkommandon via SMS, svara med kod: %1$s \n\nTänk på att måste ha tillgång till huvudtelefonen för att kunna återaktivera. - Fjärrkommandon via SMS stoppas. För att återaktivera detta, använd Konfigurationsverktyget på huvudtelefonen. - För att skicka kalibrering %1$.2f, svara med kod %2$s - Bolus misslyckades - Minsta antal minuter som måste förflyta mellan en fjärrbolus och nästa - Minsta antal minuter mellan fjärrbolus - För att redigera den här inställningen måste du, för din säkerhet, lägga till minst 2 telefonnummer. - Kommer att leverera %1$.2f enheter - Bolus %1$.2f enheter levererat - Bolus på %1$.2f enheter levererat - Temporärt mål på %1$s är satt i %2$d minuter - Temporärt mål på %1$s är satt i %2$d minuter - Temporärt mål avbrutet - Tillåt fjärrstyrning via SMS - Loop inaktiverad. - Loop aktiverad - Loop är aktiverad - För att ansluta pumpen, svara med kod %1$s - Anslutning till pump misslyckades - För att koppla från pumpen i %1$d minuter, svara med kod %2$s - Pump frånkopplad - Pump återansluten - Otillåtet fjärrkommando - Fjärrbolus inte tillgängligt. Försök igen senare. - För att starta temp basal %1$.2f enheter/tim i %2$d min, svara med kod %3$s - För att byta till profil %1$s %2$d%% svara med kod %3$s - För att starta förlängd bolus med %1$.2f enheter över %2$d min, svara med kod %3$s - Om du vill ange %1$dg kl. %2$s, svara med kod %3$s - För att starta temp basal %1$d%% i %2$d min, svara med kod %3$s - För att pausa loop i %1$d minuter, svara med kod %2$s - För att återuppta loopen, svara med kod %1$s - För att aktivera loopen, svara med kod %1$s - För att inaktivera loopen, svara med kod %1$s - Temp basal %1$.2f enheter/tim i %2$d min startad - Förlängd bolus %1$.2f enheter över %2$d min har startats - %1$dg kolhydrater registrerat - Misslyckades med att registrera %1$dg kolhydrater - Temp basal %1$d%% enheter/tim i %2$d min startad - Fel vid start av temp basal - Lyckades inte starta förlängd bolus - För att stoppa temp basal, svara med kod %1$s - För att stoppa förlängd bolus, svara med kod %1$s - Temp basal avbruten - Förlängd bolus avbruten - Misslyckades med att avbryta temp basal - Avbryter förlängd bolus - Okänt kommando eller fel svar Snabbsteg Inställningar för snabbsteg Knapptext: @@ -241,13 +175,9 @@ Eversense-appen. Uppdatera klockans data Öppna inställningar på klockan Basaldos - Basal understiger miniminivå. Profilen sattes inte. - BG: - Senaste BG: Minimed 640G Konstant avisering i telefonen Aktuellt BG saknas! - %1$d min sedan Profil OpenAPS AMA En serie med %1$d tal.\nVärde: @@ -267,7 +197,6 @@ Eversense-appen. Beh Mål Wear - SMS Förkorta namnen på flikarna Använd alltid kort medeldelta istället för enkel delta Användbart när ofiltrerade källor ger brusiga värden. @@ -281,13 +210,6 @@ Eversense-appen. Standardvärde: 2 Bolus snooze är aktivt efter att du givit en måltidsbolus, detta för att inte loop ska lågtempa när du just ätit. I detta exempel och grundvärde är 2; innebär att DIA på 3 tim kommer bolus snooze kommer att fasas ut under 1,5 tim (3DIA/2). Standardvärde: 3.0 (AMA) eller 8.0 (SMB). Detta är grundinställning för KH-absorption per 5 min. Detta styr hur snabbt COB minskar, dvs hur snabbt programmet kalkylerar att KH tagits upp, och påverkar BG framöver när BG faller mer än väntat, eller inte stiger som väntat. Viktigt!\nNormalt behöver du inte ändra dessa värden. Vg KLICKA HÄR och LÄS texten och försäkra dig om att du FÖRSTÅTT innan du ändrar dessa värden. - Ogiltigt telefonnummer för SMS - Kalibrering - xDrip+ inte installerat - Kalibrering skickad till xDrip+ - Kalibrering skickad. Observera att xDrip+ måste vara inställd att ta emot kalibreringar. - xDrip+ tar inte emot kalibreringar - Pump pausad Utför Inställningar för Virtuell pump Ladda upp status till Nightscout @@ -323,10 +245,7 @@ Eversense-appen. Välj en patienttyp för att ställa in säkerhetsgränser Patientens namn Vänligen ange patientens namn eller smeknamn för att kunna skilja mellan flera uppsättningar av inställningar - Ditt namn Glimp - Loop pausad - Pausad (%1$d min) Pausa loop i 1 timme Pausa loop i 2 timmar Pausa loop i 3 timmar @@ -345,9 +264,6 @@ Eversense-appen. 10 tim Återuppta Återanslut Pump - Fel duration - Loop pausad - Loop återupptagen 15 min trend COB Superbolus @@ -382,7 +298,6 @@ Eversense-appen. Abs Devslope Om - Saknar behörighet att skicka SMS Behörighet saknas xDrip+ Status (klocka) xDrip+ Statusrad (klocka) @@ -450,14 +365,11 @@ Eversense-appen. Kontrollera från klockan Sätt temp målvärde och ange behandlingar från klockan. Matdatabas - g ]]> kJ En Pr Fett - Kommando körs just nu - BG-värden saknas Systemaviseringar för larm & info Öka volymen gradvis för larm och aviseringar Lokala larm @@ -535,9 +447,6 @@ Eversense-appen. Tillåt automatisk rapportering av appkrascher och användningsinformation till utvecklarna via fabric.io-tjänsten. Vänligen uppdatera din Dexcom-app till en supportad version Dexcom-appen är inte installerad. - Starta \"Träning\" - Starta \"Äta snart\" - TT Ge ingen bolus, logga bara Kategori Underkategori @@ -550,8 +459,6 @@ Eversense-appen. Aktiva KH (COB) Aktivt insulin (IOB) Basaler - Ingen åtgärd vald. Inget ändras. - Starta \"Hypo\" Du kör nu dev-versionen. Closed Loop inaktiverat. Engineering Mode aktiverat Profilbyte saknas. Vänligen gör ett profilbyte eller tryck Aktivera profil under Lokal Profil. @@ -570,7 +477,6 @@ Eversense-appen. Begränsar IOB till %1$.1f pga %2$s maxvärde i Inställningar hård begränsning - Statuskontroll misslyckad Logga byte av kanyl Logga byte av insulinreservoar SMB Alltid På och SMB Efter Kolhydrater är inaktiverat pga att den aktiva BG-källan inte stöder avancerad filtrering @@ -622,12 +528,7 @@ Eversense-appen. Konfigurera din Riley Link nedan. När du har valt en Riley Link kan du fortsätta installationen när status är \"Ansluten\". Det här kan ta en minut.\n Du kan fortsätta installationen först när pumpen har konfigurerats.\n Påbörja ditt första mål - Behörighet Be om behörighet - Applikationen behöver förhöjd behörighet för aviseringar - Appen behöver platsåtkomst för bluetooth- och WiFi-identifiering - Applikationen behöver lagringsbehörighet för att kunna lagra loggfiler och exportinställningar - Begäran Öppna menyn Stäng menyn Inställningar för insticksprogram @@ -663,8 +564,6 @@ Eversense-appen. Loggningsinställningar Återställ standardinställningar Fel på NSClient. Överväg att starta om NSClient och Nightscout-webbplatsen. - KH-tid - Påminn om bolus senare Föredraget APS-läge Total Kalkyl @@ -694,11 +593,6 @@ Eversense-appen. Sommar/vintertid ändrades för mindre än 3 timmar sedan. Closed Loop avstängt intern lagringsbegränsning Frigör minst %1$d MB från internminnet. Loop inaktiverad! - Felaktigt format - Durationen måste vara större än 0 och en multipel av %1$d minuter. - Fel kod. Kommandot avbrutet. - Inte konfigurerad - Skapade ett profilbyte Versionskontroll gammal version väldigt gammal version @@ -715,12 +609,10 @@ Eversense-appen. Bolusguiden utför beräkningar, men endast denna del av beräknat insulin levereras. Användbar med SMB-algoritm. Snooze Ökar maximalt basaldos eftersom inställningen är lägre än din maximala basal i profilen - Ogiltigt innehåll i meddelande %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - min Profilnamn: Valt: Enheter @@ -768,25 +660,6 @@ Eversense-appen. SMB utförd Basalförändring begärd Basalförändring utförd - - från autentiseringsapp för: %1$s följt av PIN-kod - PIN-kod som läggs till på slutet - Ytterligare siffror som ska memoreras och läggas till i slutet av varje genererat engångslösenord - Konfiguration av tvåfaktorsautentisering - Kod att kontrollera: - OTP + PIN-kod - Verifieringskoden består av sex siffror som visas av autentiseringsappen (känd som OTP) följt av 3 eller fler siffror som är en valbar PIN-kod. - Återställ autentiserare - Återställ autentiseringsnyckel - Är du säker på att återställa autentiseringsnyckeln? Det gör alla konfigurerade autentiseringsappar ogiltiga och du kommer behöva ställa in dem igen. - Ny autentiseringsnyckel genererades! Använd uppdaterad QR-kod till att aktivera autentiserare. - Exporterar OTP-hemlighet - Är du säker på att du vill kopiera OTP-hemligheten till Urklipp?\n\nDu behöver bara göra detta om din autentiseringsapp har problem QR-koder så du vill ange den manuellt eller om du vill konfigurera OTP-token med hjälp av en dedikerad app. - OTP-hemligheten exporteras och kopieras till klippbordet i Base32-format. Klistra in den i autentiseringsfunktionen eller OTP-brännaren! - 1. Installera autentiseringsapp - 3. Testa engångslösenord - Återställ autentiserare - På varje följartelefon behöver man installera en autentiseringsapp som stöder RFC 6238 TOTP tokens. Populära gratisappar är:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator BG-prognos Avvikelsekurva Behörighetskontroll misslyckades @@ -816,21 +689,9 @@ Eversense-appen. Filter Kan inte att skapa profilen. Profilen är felaktig. Döda inte min app? - Skicka SMS om pumpen inte kan nås - Rapportera om pump inte kan nås Larma när det är dags att äta - Larma om %1$d min - Bolusguide - Ditt blodsocker är högt. Istället för att äta är det rekommenderat att vänta tills det sjunker. Vill du göra en korrektionsbolus nu och påminna dig när det är dags att äta? I det här fallet kommer inga kolhydrater att registreras nu, utan du måste ange måltiden på nytt i kalkylatorn. - Aktivera bolusguiden - Få en påminnelse om att börja äta senare (istället för kalkylatorns resultat) om du ligger högt i BG Dags att äta!\nKör bolusguiden igen för ny beräkning. - Dags att äta - Boluspåminnelse Aktivera boluspåminnelse - Använd påminnelse för att ge bolus senare - (\"post-bolus\") - Dags för bolus!\nKör Bolusguiden och gör beräkningar igen. Uppladdning av kraschloggar inaktiverad! Graf Diagrammeny @@ -865,8 +726,6 @@ Eversense-appen. Acceptera händelser (kanyl-, insulin-, batteribyte etc) som angetts via NS eller NSClient Ladda ner CGM-data Acceptera CGM-data från NS - Föregående pumpkommunikation har inte bekräftats/avslutats i tid - Det finns en annan bolus i kö. Försök igen senare. Beräkning pågår Profilnamn saknas Fel i KH-kvoter @@ -910,7 +769,6 @@ Eversense-appen. insulin blodglukos föråldrad - ställ in påminnelse lägg till ny profil klona nuvarande profil ta bort aktuell profil diff --git a/app/src/main/res/values-tr-rTR/exam.xml b/app/src/main/res/values-tr-rTR/exam.xml index a5e76221ba..3ccc466580 100644 --- a/app/src/main/res/values-tr-rTR/exam.xml +++ b/app/src/main/res/values-tr-rTR/exam.xml @@ -5,10 +5,12 @@ Profilinizde İES değerini ayarlamalısınız. İzin verilen minimum değer 5 saattir. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html?#insulin + AAPS\'den önce pompanızda kullandığınız İES değerinin doğru olduğundan eminseniz, döngüye başladığınızda bunu değiştirmenize gerek yoktur. İES için uygun değeri kendiniz belirlemelisiniz. Hipo Geçici-Hedef Hipo geçici hedef belirlemenin birincil nedeni nedir? Yanlış bazal oranı ayarlarından kaynaklanan hipoları düzeltmek için. + Hipo tedavisinde kullanılan hızlı etkili karbonhidratların neden olduğu kan şekeri artışında, AAPS\'in aşırı düzeltme yapmasını önlemek. Egzersizin bir sonucu olarak tetiklenen hipoyu düzeltmek için. Halihazırda %0 geçici bazal oran çalışıyorsa, kan şekerinin düşmesini önlemek için. https://androidaps.readthedocs.io/en/latest/EN/Usage/temptarget.html @@ -16,10 +18,15 @@ Konu: Çevrimdışı profiller NS Profili kullanılabilir ancak yapılandırılamaz. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#profile + AAPS\'de Pompa bağlantısını kesme nedenleri Pompa bağlantısı kesilirken ne yapılmalı? Pompanın fiziksel olarak bağlantısı kesilirse insülin iletilmeyeceğinden bu gereksizdir. + AAPS\'nin, pompa fiziksel olarak bağlı değilken iletilmeyen insülini hesaba katmasını önler. Pompa bağlı kalırsa insülin iletimini durdurmaz. + AAPS\'yi açık döngü moduna gönderir. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#other-settings + AAPS Ayarları + AAPS Ayarları Ayarlarınızı yedeklemek için en sağlıklı yöntemler nelerdir? Ayarlarınızı not etmeniz şartıyla ayarları dışa aktarmanıza gerek yoktur. Bir görevi tamamlamayı bitirdikten sonra ayarlarınızı dışa aktarın. @@ -33,6 +40,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#what-emergency-equipment-is-recommended-to-take-with-me Gürültülü CGM Okumaları CGM (dexcom, miaomaio vs.) verileri gürültülü ise ne yapılmalı? + Hiçbir şey yapmayın - AAPS bununla ilgilenecektir. Olası aşırı veya düşük dozdan kaçınmak için kapalı döngüyü devre dışı bırakın. Sürekli gürültülü veya hatalı sensörleri değiştirin. CGM uygulamanızın sorunsuz veriler sağladığını doğrulayın. @@ -63,6 +71,7 @@ Bir kez ayarlanıp onaylandıktan sonra bu değerler zaman içinde değişmemelidir. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#androidaps-settings Önkoşullar + AAPS\'yi kurmak ve kullanmak için gerekenler nelerdir? Doğrulanmış profil bilgileri (Basal, IC, ISF, DIA). Android Studio\'nun kurulu ve yapılandırılmış olduğu bir bilgisayar. Desteklenen bir telefon. @@ -77,17 +86,25 @@ Akıllı saat. Desteklenen bir CGM. Önkoşullar + AAPS\'yi kurmak ve kullanmak için gerekenler nelerdir? Profil oluşturmak için doğrulanmış bilgiler (ISF, I:C oranı, bazal oranlar, DIA vb.). Uyumlu bir Android cihaz (ör. cep telefonu, Android saat veya tablet). + AAPS\'in kapalı döngüde çalışması için internet bağlantısı gerekir. Telefonda/cihazda kan şekeri değerlerini almak için desteklenen bir CGM ve uygulama. https://androidaps.readthedocs.io/en/latest/EN/Module/module.html + AAPS\'i güncelleme Tüm doğru cevapları kontrol edin. Git\'in bilgisayarınızda kurulu ve yapılandırılmış olması gerekir. + AAPS\'nin güncellenmiş sürümleri yayınlandığında, önceki sürümler belirli bir süre sonra uzaktan sınırlandırılabilir. Anahtar deponuzun konumunu kaydetmeli ve not etmeli ve önceki yüklemenizde olduğu gibi güncellemeler için aynı imzalama anahtarını kullanmalısınız. Sistem iyi çalışıyorsa asla güncelleme yapmayın. Apk oluşturmakta zorluk çekiyorsanız, bir arkadaşınız tarafından oluşturulmuş bir apk yükleyebilirsiniz. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch Sorun giderme + AAPS ile ilgili nereden yardım alabilirsiniz? + AAPS Kullanıcıları Facebook grubundan tavsiye isteyebilirsiniz. + AAPS belgelerini okumalısınız (ve yeniden okumalısınız). + AAPS Discord\'da tavsiye isteyebilir ve teknik sorunları veya hataları bildirebilirsiniz. Diyabet kliniğinize/endokrinoloğunuza sormalısınız. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting https://www.facebook.com/groups/AndroidAPSUsers/ @@ -101,6 +118,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#insulin Duyarlılık Eklentileri Tüm doğru cevapları kontrol edin. + Duyarlılık eklentileri, AAPS\'nin insülin duyarlılığındaki geçici veya kısa süreli değişiklikleri (örneğin hormonal değişiklikler veya infüzyon bölgesinde emilim sorunları) ayarlamasına olanak tanır. Duyarlılık eklentileri, kullanıcıya profili düzenlemek için kullanılabilecek bazal oranlar, I:C oranları ve ISF için önerilen değişiklikleri sağlar. Bir kanül değişikliğinin kaydedilmesi, Otoduyarlılık oranını %100\'e sıfırlayacaktır. Eklenti seçeneklerinden bazıları, kullanıcı tarafından ayarlanabilen yapılandırılabilir zaman aralıklarına sahiptir. @@ -110,11 +128,14 @@ Yanlış bir karbonhidrat girişi yaptıysanız ne yapmalısınız? Tedavilerdeki yanlış girişi siler ve doğru karbonhidrat değerini girerim. İnfüzyon seti başlatma menüsünü kullanarak insülin gönderme. + Hiçbir şey yapmayın – AAPS uygun ayarlamaları yapacaktır. Genel Bakış\'ta İnsülin (bolus) düğmesini kullanarak insülin gönderme. İnsülin gönderme/giriş hataları Tıkanma, başarısız bir kanül veya duştan sonra pompayı tekrar takmayı unutma v.s. nedeniyle, pompa geçmişinin önerdiğinden daha az insülin aldıysanız ne yapmalısınız? Pompa geçmişinden çıkarmak için insülin verilerini Nightscout Bakım Portalından silin. + AAPS ve pompa geçmişindeki değerleri karşılaştırın (pompa bunu destekliyorsa). Şırınga/kalem veya başlatma kullanarak hesaplanan \"eksik\" insülininizi bolus olarak karşılayın. + Hiçbir şey yapmayın ve AAPS\'in ortaya çıkabilecek yüksek kan şekeri seviyesini düzeltmesine müsade edin. Aktif Karbonhidrat (AKRB) İDF değerinin değiştirilmesi AKRB (Aktif karbonhidrat) hesaplamasını nasıl etkiler? Artan İDF, karbonhidratların daha uzun süre emilmesini sağlayacaktır @@ -136,20 +157,28 @@ Karbonhidrat girişi ve boluslar Tüketilen karbonhidratları tahmin etmek ve kaydetmek için sadece gram kullanılmalıdır. Tüketilen karbonhidratlar uygun bir değişim sistemi kullanılarak kaydedilebilir (örn. DAFNE \"CHO\" değişimleri veya Avrupa \"Ekmek Birimleri\"). + AAPS, karbonhidrat \"çözünmesini\" tahmin etmek ve AKRB\'ı hesaplamak için dinamik bir model kullanır. Kan şekeri seviyeleri kabul edilebilir değerlerin dışındaysa (çok düşük veya çok yüksek), karbonhidrat veya insülin düzeltmeleri için öneriler sağlamak için bolus hesaplayıcı kullanılabilir. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-to-carb-ratio-ic-g-u yayma-karbonhidratlar Y-karbonhidratları (yayma karbonhidratlar) ne için kullanabilirsiniz? Gelecekte karbonhidratları planlamak için, muhtemelen bir aralığa dağıtılır (bir aralıkta insülin dağıtan yayma bolusa benzer). + AAPS\'den gizlemek istediğiniz \'ücretsiz\' egzersiz karbonhidratlarını kaydetmek için. + y-karbonhidratlar (gelecekte dağıtılacak) AAPS\'nin yüksek yağ/proteinli öğünlerle uğraşmasına yardımcı olabilir. Düşük kan şekerini tedavi etmede kullandığınız kurtarma karbonhidratlarını kaydetmek için. https://androidaps.readthedocs.io/en/latest/EN/Usage/Extended-Carbs.html Uzaktan İzleme + AAPS\'i (örneğin çocuğunuz için) uzaktan nasıl izleyebilirsiniz? + AAPSClient uygulaması, Nightscout uygulaması ve Nightscout web sayfasının tümü, AAPS\'i uzaktan takip etmenize olanak tanır. Diğer uygulamalar (ör. Dexcom takip, xDrip) bazı parametreleri (ör. kan şekeri/sensör değerleri) uzaktan takip etmenize izin verir, ancak farklı algoritma kullanımı, hatalı AİNS veya AKRB değerlerine sebep olabilir. + AAPS\'yi uzaktan takip etmek için her iki cihazın da internet erişimine sahip olması gerekir (ör. Wi-Fi veya mobil/hücresel ağ verileri aracılığıyla). + Uzak takipçi olarak kullanılan AAPSClient, AAPS\'i hem izleyecek hem de tam kontrol sağlayacaktır. https://androidaps.readthedocs.io/en/latest/EN/Children/Children.html İnsülin Duyarlılık Faktörü (İDF) ISF değerlerini yükseltmek, belirli bir karbonhidrat miktarını karşılamak için daha fazla insülin verilmesine yol açacaktır. ISF değerinin düşürülmesi, hedeflenen kan şekerinin üzerinde bir düzeltme için daha fazla insülin verilmesine yol açar. Kan şekeri seviyeleri hedefin altında olduğunda ISF\'yi yükseltmenin veya düşürmenin insülin iletimi üzerinde hiçbir etkisi yoktur. + İDF, AAPS Tercihlerinize girilmelidir. Profilinizdeki ISF değerini değiştirmeniz değişikliği uygulamak için yeterlidir. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html @@ -176,6 +205,7 @@ Hedef kan şekeri değişmeyecektir. ISF %20 daha yüksek olacaktır. Profil Değiştirme + Normalden 2 saat önce kalkarsanız, zaman değişikliğini AAPS\'e nasıl bildirmelisiniz? 2 saatlik bir zaman kayması ile bir profil değişikliği başlatın -2saatlik bir zaman kayması ile bir profil değişikliği başlatın Yakında yemek geçici hedefi belirleyin. @@ -183,6 +213,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html?highlight=profile%20switch#timeshift Profillerdeki değişiklikler Profillerde bazal oranlar, ISF, I:C oranları vb. ayarlanmalıdır. + Nightscout Profilinizdeki değişiklikleri etkinleştirmek, AAPS kurulu telefonunuzun internete bağlı olmasını gerektirir. Değerleri değiştirmek için profi düzenlemek, yapılan değişiklikleri yürürlüğe koymak için yeterlidir. Değişen koşullara (ör. hormonal değişiklikler, vardiyalı çalışma, hafta içi/hafta sonu yaşam tarzı) uyum sağlamak için birden fazla profil ayarlanabilir ve seçilebilir. https://androidaps.readthedocs.io/en/latest/EN/Module/module.html#good-individual-dosage-algorithm-for-your-diabetes-therapy @@ -192,4 +223,6 @@ Google Facebook Diğer ilaçlarla etkileşim. Lütfen aşağıdaki beyanı okuyun ve ardından kabul etmek için kutuyu işaretleyin. + AAPS, kan şekerini yükseltmek için bazal oranları düşürür veya insülin iletimini askıya alır. SGLT2 inhibitörleri (gliflozinler) sınıfındaki ilaçlar kan şekerindeki artışları önleyebilir ve bu nedenle DKA\'ya (Diyabetik ketoasidoz) yol açan tehlikeli bir insülin eksikliğine yol açabilir. +\nYaygın marka isimleri şunlardır: Invokana®, Forxiga®, Jardiance®, Steglatro®, Suglat®, Apleway®, Deberza®, Synjardy®, Vokanamet®, Xigduo®.\n\nAAPS kullanırken bu tür ilaçları almayacağıma veya bu tür ilaçları kullanmadan önce döngüyü devre dışı bırakacağıma söz veriyorum. diff --git a/app/src/main/res/values-tr-rTR/objectives.xml b/app/src/main/res/values-tr-rTR/objectives.xml index 5777afbe3a..553656415c 100644 --- a/app/src/main/res/values-tr-rTR/objectives.xml +++ b/app/src/main/res/values-tr-rTR/objectives.xml @@ -25,6 +25,8 @@ Pompa durumu NS\'ta mevcut Manuel eylemler Başarıldı: %1$s + AAPS\'yi nasıl kontrol edeceğinizi öğrenin + AAPS\'de farklı eylemler gerçekleştirin Profili 10 dakika boyunca %90 olarak ayarla (Ana sayfada profil adına uzun basın) Duşu simüle edin. 1 saat boyunca pompanın bağlantısını kesin (Açık Döngü işaretine Uzun Basın) ... ve aynı şekilde tekrar bağlanın diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index e0650e303e..65e6de6ca0 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -13,7 +13,7 @@ Veritabanlarını sıfırla Veritabanlarını gerçekten sıfırlamak istiyor musunuz? Çıkış - Bu cihaz, program için pil optimizasyonunu desteklemiyor gibi görünüyor - performans sorunları yaşayabilirsiniz. + Ortak özelliklere hızlıca erişmek için bazı düğmeler Aktif eklentileri yapılandırmak için kullanılır Eğitim programı Nightscout\'ta tanımlanan gıda ön ayarlarını gösterir @@ -39,11 +39,11 @@ Nightscout\'tan KŞ verilerini yükler XDrip+\'ten KŞ değerlerini alır. Yapılan tüm tedavileri kaydeder + WearOS saatinizi kullanarak AAPS\'yi izleyin ve kontrol edin. Döngü\'yle ilgili bilgileri xDrip+ saat arayüzünde gösterin. İnsülin: Karbonhidrat: AİNS: - AİNS: Toplam AİNS: Toplam AİNS etkinliği: Süre: @@ -51,9 +51,7 @@ İns: AİNS: Toplam AİNS: - GH - Karbonhidrat Düzeltme Bolus AİNS Şimdi Çalıştır @@ -70,13 +68,14 @@ Glikoz verisi yok İstek Delta - Delta: Konfigürasyon ayarları Genel Bakış Tedaviler Sanal pompa Pompa + Hangi pompa ile AAPS kullanmak istersiniz? Profil + AAPS Hangi profili kullanmalı? APS (YPS) Hangi APS algoritması terapi ayarlamalarını yapsın? Genel @@ -84,6 +83,7 @@ Hangi kısıtlamaları uygula? Kısıtlamalar Döngü + AAPS\'nin döngü entegrasyonunu etkinleştirmek için bunu kullanın. APS İşlenmiş kısıtlamalardan sonra Pompa tarafından ayarlanan geçici bazal @@ -91,15 +91,12 @@ Güvenlik Eklenti devre dışı Kısıtlamalar ihlali - Bolus bir hata bildirdi. Gerçek teslim edilen miktarı manuel olarak kontrol edin Yeni geçici bazal oranını kabul et: Tedavi Hesap makinesi - Sınırlaması uygulanır! - Bolus: - Bazal: Girişinizi değiştirin! KŞ kaynağı + AAPS verilerini nereden alsın? xDrip+ APS modu Kapalı Döngü @@ -110,13 +107,10 @@ Karbonhidrat Önerisi Nightscout\'un desteklenmeyen sürümü Bazal AİNS - Bolus kısıtlaması uygulandı - Karbonhidrat kısıtlaması uygulandı Diğer GlkMetre Sensör Karb. zamanı - Süre Profil Glikoz türü Geçici Bazal @@ -156,62 +150,9 @@ ANLADIM VE KABUL EDİYORUM Kaydet Profili yeniden yükle - SMS Kominikatör - İzinli telefon numaraları - +XXXXXXXXXX;+YYYYYYYYYY - %1$.2fÜ Bolus gönderilecek, kod ile cevap ver %2$s - %1$.2fU Yemek bolusu göndermek için %2$s koduyla yanıt verin - Geçici Hedefi %1$s yapmak için %2$s koduyla yanıt verin - Geçici Hedefi iptal etmek için %1$s koduyla yanıt verin - SMS Uzak Hizmet desteğini devre dışı bırakmak için %1$s koduyla yanıt verin.\n\nBu hizmeti yalnızca AAPS yüklü ana telefondan yeniden etkinleştirebileceğinizi unutmayın. - SMS Uzak Hizmeti durduruldu. Yeniden etkinleştirmek için ana telefondaki APPS\'i kullanın. - Kalibrasyon için %1$.2f gönderilecek, kod ile cevap ver %2$s - Bolus başarısız oldu - Bir sms bolusu ile bir sonraki bolus arasında geçmesi gereken minimum dakika sayısı - Bir sms bolus gönderimi ile bir sonraki bolus arasında en az kaç dakika geçsin? - Güvenliğiniz için en az 2 telefon numarası eklemeniz gerekir. - %1$.2f U gönderilecek - %1$.2f U Bolus başarıyla gönderildi - %1$.2f U Yemek Bolusu başarıyla gönderildi - Hedef %2$d dakika boyunca %1$s - Hedef %2$d dakika boyunca %1$s olarak başarıyla ayarlandı - Geçici Hedef başarıyla iptal edildi - SMS ile uzaktan komutlara izin ver - Döngü devre dışı bırakıldı - Döngü etkinleştirildi - Döngü etkin - Pompaya bağlanmak için %1$s koduyla yanıt verin - Pompa bağlantısı başarısız - Pompanın bağlantısını %1$d dakika boyunca kesmek için %2$s koduyla yanıtlayın - Pompa bağlantısı kesildi - Pompa yeniden bağlandı - Uzaktan komuta izin verilmez - Uzaktan bolus gönderilemiyor. Daha sonra tekrar deneyin. - %2$d dk boyunca bazalı %1$.2f Ü/sa yapmak için %3$s koduyla yanıtlayın - Profili %1$s %2$d%% olarak değiştirmek için %3$s koduyla yanıtlayın - %2$d dakika boyunca %1$.2f U yayma bolus başlatmak için %3$s koduyla yanıtlayın - %2$s\'de %1$dg girmek için %3$s koduyla yanıtlayın - %2$d dk boyunca bazal %1$d%% başlatmak için %3$s koduyla yanıtlayın - Döngüyü %1$d dakika askıya almak için %2$s koduyla yanıtlayın - Döngüye devam etmek için %1$s koduyla yanıtlayın - Döngüyü etkinleştirmek için %1$s koduyla yanıtlayın - Döngüyü iptal etmek için %1$s koduyla yanıtlayın - Geçici bazal %1$.2fÜ/s %2$d dakika için başarıyla başlatıldı - %1$.2fU yayma bolus %2$d dakika boyunca başarıyla başlatıldı - %1$d g karbonhidrat başarıyla sisteme girildi - %1$d g karbonhidrat girilemedi - %2$d dakikalık geçici bazal %1$d%% başarıyla başlatıldı - Geçici bazal başlatma başarısız oldu - Yayma bolus başlatma başarısız oldu - Geçici bazalı durdurmak için %1$s kodunu gir - Yayma bolusu durdurmak için %1$s koduyla yanıtlayın - Geçici bazal iptal edildi - Yayma bolus iptal edildi - Geçici bazal iptal edilemedi - Yayma bolus iptal edilemedi - Bilinmeyen komut veya yanlış cevap Hızlı Asistan Hızlı asistan ayarları + Buton Metni: Karbonhidrat: Geçerli: Ekle @@ -239,13 +180,9 @@ Tüm verileri yeniden gönderin Ayarları Wear\'da açın Bazal oranı - Bazal değer minimumun altında. Profil ayarlanmadı! - KŞ: - Son KŞ: MM640g Sürekli Bildirim ESKİ VERİ - %1$ddak önce Profil OpenAPS AMA %1$d öğelerin dizisi.\nGerçek değer: @@ -265,7 +202,6 @@ TEDAVİ GRV WEAR - SMS Kısa sekme başlıkları Her zaman basit delta yerine kısa ortalama delta kullan xDrip+ gibi filtrelenmemiş kaynaklardan gelen veriler gürültülü olduğunda kullanışlıdır. @@ -280,13 +216,6 @@ Varsayılan değer: 3.0 (AMA) Gelişmiş Yemek Asistanı veya 8.0 (SMB) Super Micro Bolus. Bu 5 dakika başına varsayılan karbonhidrat emilimi için bir ayardır. Standart değer AMA için 3mg/dl/5dk aynı şekilde SMB 8mg/dl/5dk dir. Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden daha fazla düştüğü veya beklenildiği kadar yükselmediği zamanlarda gelecekte yapılacak tahminlerde KŞ\'nin hesaplanmasında ne kadar karbonhidrat emilimi gerçekleşeceğini öngörür. Dikkat!\nNormalde aşağıdaki bu değerleri değiştirmek zorunda değilsiniz. Lütfen burayı TIKLAYIN ve metni OKUYUN ve bu değerlerden herhangi birini değiştirmeden önce ANLADIĞINIZDAN emin olun. - Geçersiz SMS telefon numarası - Kalibrasyon - xDrip+ uygulaması yüklenmemiş - Kalibrasyon xDrip+ a gönderildi - Kalibrasyon gönderildi. Alma xDrip+\'ta etkinleştirilmelidir. - xDrip+ kalibrasyonları almıyor - Pompa durduldu Yürütülüyor Sanal pompa ayarları Nightscout\'a durum aktar @@ -322,10 +251,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Güvenlik limitlerini ayarlamak için lütfen hasta tipini seçin Hasta Adı Lütfen çoklu kurulumlar arasında ayrım yapmak için hasta adı veya takma ad belirleyin - Kullanıcı Glimp - Döngü duraklatıldı - (%1$d dk) Duraklatıldı Döngüyü 1saat duraklat Döngüyü 2saat duraklat Döngüyü 3saat duraklat @@ -344,9 +270,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d 10 Saat Devam et Pompayı tekrar bağla - Yanlış süre - Döngü duraklatıldı - Döngü devam ettirildi 15 dk eğilim AKRB Süperbolus @@ -381,7 +304,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d ABS EĞİMSAPMA Hakkında - SMS izni eksik Telefon durumu izni eksik xDrip+ Durumu (saat) xDrip+ Durum Çizgisi (saat) @@ -421,6 +343,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Ağırlıklı ortalama duyarlılık Tüm profiller yüklenmedi! Değerler kaydedilmedi! + Diğer uygulamalara (xDrip+ gibi) yayınları etkinleştirin. Yüklü birden fazla APPS veya AAPSClient örneğiniz varsa etkinleştirmeyin! Yerel yayınları etkinleştirin. OpenAPS SMB Dinamik İDF @@ -453,14 +376,11 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Saat tarafından kontrol Tedavileri ve Geçici hedefleri saat tarafından girin. Yiyecek - gr ]]> kJ En Pr Yağ - Komut şu anda çalıştırıldı - Kaçırılan KŞ Okumaları Uyarılar ve bildirimler için sistem bildirimlerini kullan Uyarılar ve bildirimler için ses seviyesini kademeli olarak artırın Yerel uyarılar @@ -516,6 +436,8 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Butonlar xDrip+\'a bir kalibrasyon gönderir veya BYODA kalibrasyon iletişim kutusunu açar xDrip+ veya BYODA\'yı açar, geri dönme düğmesi AAPS\'ye döndürür + Butona basıldığında eklenecek karbonhidrat sayısı + Butona basıldığında eklenecek insülin miktarı CGM uygulaması başlatılamadı. Yüklendiğinden emin olun. CGM 5dk yoksay @@ -536,9 +458,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Geliştiricilere, fabric.io hizmeti aracılığıyla otomatik kilitlenme raporlaması ve özellik kullanım verilerinin gönderilmesine izin verir. Lütfen Dexcom uygulamanızı desteklenen sürüme güncelleyin Dexcom uygulaması yüklü değil. - Egzersiz Başlat GH - Yakında Öğün GH - TT Bolusu sadece kayıt altına al Kategori Alt kategori @@ -551,8 +470,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Aktif Karbonhidrat Aktif İnsülin Bazallar - Seçili eylem yok, hiçbir şey olmayacak - Hipo GH başlat Geliştirici sürümü çalışıyor. Kapalı Döngü devre dışı. Geliştirici modu etkinleştirildi Profil geçişi yok. Lütfen Profil Değiştirme ile bir profil geçişi yapın veya Yerel Profil\'de \"Profili Etkinleştir\" düğmesine basın. @@ -571,7 +488,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d %2$s\'den dolayı AİNS %1$.1f Ü ile sınırlandırılıyor tercihlerde maksimum değer sert sınır - Durumu okumak başarısız oldu İnfüzyon seti değişimini kaydet Rezervuar değişimini kaydet Aktif KŞ kaynağı gelişmiş filtrelemeyi desteklemediği için SMB (Super Micro Bolus) her zaman ve karbonhidratlardan sonra devre dışı bırakıldı @@ -620,6 +536,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Kurulum sihirbazına hoş geldiniz. Kurulum işleminde size rehberlik edecektir\n Durum oku Kurulum sihirbazını atla + AAPS\'ın bazal değişiklikleri önerme/yapmasını sağlamak için aşağıdaki düğmeye basın Duyarlılık eklentisi, duyarlılık tespiti ve AKRB hesaplaması için kullanılır. Daha fazla bilgi için ziyaret edin: https://androidaps.readthedocs.io/en/latest/Configuration/Sensitivity-detection-and-COB.html NSClient, Nightscout\'a bağlantıyı sağlar. Şimdi bu kısmı atlayabilirsiniz, ancak ayarlamadan görevleri geçemezsiniz. @@ -628,12 +545,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Lütfen aşağıda RileyLink\'inizi yapılandırın. Bir RileyLink seçtikten sonra, RileyLink durumu \"Bağlandı\" olduğunda kuruluma devam etmek mümkün olacaktır. Bu bir dakika sürebilir.\n Not: Pompa kurulduktan sonra kuruluma devam edebilirsiniz.\n İlk görevinize başlayın - Yetki İzin için sorunuz - Uygulama, bildirimler için sistem iznine ihtiyaç duyuyor - Uygulamanın BT taraması ve WiFi tanımlaması için konum iznine ihtiyacı var - Uygulamanın, günlük dosyalarını saklayabilmesi ve ayarları dışa aktarabilmesi için depolama iznine ihtiyacı var - İstek Navigasyonu aç Navigasyonu kapat Eklenti tercihleri @@ -661,6 +573,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Öğeleri kaldır Öğeleri sırala Saklanan ayarlar bulundu + Dikkat: Eğer bir donanım pompasını etkinleştirir ve bağlarsanız, AAPS, bazal ayarları profilden pompaya aktaracaktır ve pompada kayıtlı mevcut bazal oranlarının üzerine yazacaktır. AAPS\'de doğru ayarların olduğundan emin olun. Emin değilseniz veya pompanızdaki bazal ayarların üzerine yazmak istemiyorsanız, iptal tuşuna basın ve daha sonra tekrar deneyin. Tedavi verileri eksik Bakım ayarları E-Posta alıcısı @@ -678,8 +591,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Günlük ayarları Varsayılanlara sıfırla NSClient arızası. NS ve NSClient yeniden başlatmayı düşünün. - Saat farkı - Bolusu daha sonra hatırlat Tercih edilen APS modu Toplam Hesap @@ -688,6 +599,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Açık Döngü, yalnızca değişiklik % cinsinden bu değerden büyükse yeni değişiklik isteğini açar. Varsayılan değer %20\'dir == ∑ %1$s Ü Sensör değişimlerini NS\'a kaydet + Sensör başlangıcında otomatik olarak NS\'de \"Sensör Değişimi\" olayı oluştur Tomato (MiaoMiao) Tomato Tidepool oturum açma kullanıcı adınız, normalde e-posta adresiniz @@ -709,11 +621,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Yaz Saati Uygulaması 3 saatten daha kısa bir süre önce değişti - Kapalı döngü devre dışı dahili depolama birimi Dahili depolama biriminden en az %1$d MB yer kaldı! Döngü devre dışı! - Yanlış Format - Geçici Bazal Oranı süresi %1$d dakikanın katı ve 0\'dan büyük olmalıdır. - Hatalı kod. Komut iptal edildi. - Yapılandırılmadı - Profil değiştirme yapıldı Sürüm Kontrolcüsü eski sürüm çok eski sürüm @@ -730,12 +637,10 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Bolus sihirbazı hesaplamayı gerçekleştirir ancak hesaplanan insülinin yalnızca bu kısmı iletilir. SMB algoritması ile kullanışlıdır. Ertele Profilinizdeki maksimum bazal değeriniz düşük olduğu için maksimum bazal değeri artırma - Geçersiz mesaj %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg Kİ: %2$.1f %1$d%% - dk. Profil adı: Seçildi: Birim @@ -760,6 +665,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Kimlik: Sunum En yaygın profil: + Not: Yalnızca bu ekranda görünen veriler anonim olarak yüklenecektir. Bu AAPS kurulumunda kimlik atanır. Ana profiliniz değişirse verileri tekrar gönderebilir, ancak sonuçların zaman içinde görünür olması için en az bir hafta çalışmasına izin verebilirsiniz. Yardımın takdire değer. Geçersiz yaş girişi Geçersiz ağırlık girişi Geçersiz % giriş @@ -788,25 +694,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d SMB (Super Micro Bolus) uygulama süresi Geçici bazal zamanı Geçici bazal uygulama süresi - - authenticator uygulamasından %1$s için PIN girin - İlave zorunlu şifre (PIN) - Oluşturulan Her Tek Kullanımlık Şifrenin sonunda ezberlenmesi ve yapıştırılması gereken ek şifre - Kimlik doğrulayıcı (OTP-Authenticator) kurulumu - Kontrol edilecek kod: - OTP + PIN - Doğrulama kodu, Authenticator uygulaması (OTP olarak bilinir) tarafından görüntülenen 6 haneden ve ardından 3 veya daha fazla zorunlu PIN hanesinden oluşur. - Kimlik Doğrulayıcıları (OTP) Sıfırla - Kimlik Doğrulayıcı Anahtarını Sıfırla - Kimlik Doğrulayıcı (Authenticator) anahtarını sıfırlamak istediğinizden emin misiniz? Şu anda yapılandırılmış tüm Kimlik Doğrulayıcıları geçersiz kılar ve bunları yeniden ayarlamanız gerekir. - Yeni Kimlik Doğrulayıcı (Authenticator) Anahtarı oluşturuldu! Kimlik doğrulayıcıları için lütfen güncellenmiş QRCode\'u kullanın. - OTP dışa aktarma - OTP secret panoya kopyalamak istediğinizden emin misiniz?\n\nYalnızca kimlik doğrulama uygulamanızın QRCode\'u tarama sorunları varsa, bunu elle girmek veya uygulamayı kullanarak OTP donanımı yapılandırmak istiyorsanız buna ihtiyacınız olabilir. - OTP secret (Base32 formatında) dışa aktarıldı ve panoya kopyalandı. Doğrulayıcıya veya OTP donanım yazıcısına yapıştırın! - 1. Doğrulayıcıyı (Authenticator) yükleyin - 3. Tek Kullanımlık Parolayı (OTP) Test Edin - Doğrulayıcıları (Authenticators) Sıfırla - Her takipçi telefonunda, RFC 6238 TOTP belirteçlerini destekleyen Kimlik Doğrulayıcı uygulamasını yükleyin. Popüler ücretsiz uygulamalar şunlardır:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Tahminler Tedaviler Sapma eğimi @@ -819,6 +706,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d NS ayarları kopyalansın mı (varsa)? Orjinal görünüm Düşük çözünürlüklü görünüm + Butonlar her zaman ekranın altında görüntülenir Büyük ekran Görünüm Profilleri karşılaştırın @@ -836,21 +724,11 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Filtre Profil oluşturulamıyor. Profil geçersiz. Uygulamamı devre dışı bırakma? - Pompa ulaşılamazsa SMS gönder - Pompaya ulaşılamadığını bildir Yemek zamanı alarmı çalıştır - Alarmı %1$d dakika içinde çalıştır - Bolus danışmanı - Yüksek glisemiksiniz. Şimdi yemek yemek yerine daha iyi glisemi beklemeniz önerilir. Şimdi bir düzeltme bolusu yapmak ve yemek zamanı geldiğinde size hatırlatmak ister misiniz? Bu durumda karbonhidrat kaydı yapılmaz ve size hatırlattığımızda sihirbazı tekrar kullanmanız gerekir. - Bolus danışmanını etkinleştir - Yüksek glisemi sırasında sihirbaz sonucu yerine daha sonra yemeye başlamak için hatırlatıcı kullanın (\"pre-bolus\") Yemek zamanı!\nBolus sihirbazını çalıştırın ve yeniden hesaplama yapın. - Yemek zamanı - Bolus hatırlatıcısı Bolus hatırlatıcıyı etkinleştir Sihirbazla daha sonra bolus için hatırlatıcı kullanın (\"bolus sonrası\") - Bolus zamanı!\nBolus sihirbazını çalıştırın ve yeniden hesaplama yapın. Çökme günlükleri yükleme devre dışı bırakıldı! Grafik Grafik menüsü @@ -887,8 +765,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d NS veya NSClient aracılığıyla girilen tedavi olaylarını (kanül, insülin, pil değişimi vb.) kabul edin SGİ (CGM) verilerini alma/doldurma NS\'tan SGİ (CGM) verilerini kabul edin - Önceki pompa iletişiminin bitmesini beklerken zaman aşımı - Sırada başka bir bolus var. Daha sonra tekrar deneyin. Hesaplanıyor Profil adı eksik IC değerinde hata @@ -933,7 +809,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d insülin kan şekeri güncel değil - hatırlatıcıyı kur yeni profil ekle mevcut profili klonla mevcut profil sil @@ -992,7 +867,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Döngüyü göster %1$d seçildi Sırala - İletişim kutusu iptal edildi Çok düşük Düşük Yüksek @@ -1002,6 +876,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Üstünde Döngü kayıtlarını göster Döngü kayıtlarını gizle + AAPS widget Şeffaflığı yapılandır Döngü durumu Grafik ölçeği @@ -1010,7 +885,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Giriş Tümünü kaldır Başlatmayı sıfırla - Tek kullanımlık şifre kurulumu için QR Kodu ayarları aç karbonhidrat zamanlayıcı alarmı kur Tümü @@ -1027,6 +901,8 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Şarj seçenekleri tarafından engellendi Bağlantı seçenekleri tarafından engellendi (Saat Bağlı Değil) - İzin istenirken hata Duyarlılığı ve KŞ\'ni ayarlayın + Veritabanı temizleme + Veritabanını temizlemek istiyor musunuz?\nİzlenen değişiklikleri ve 3 aydan eski geçmiş verileri kaldıracak. + Temizlenen girişler diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f7842dace8..56c25533c7 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -12,7 +12,6 @@ 重置数据库 你真的想重置数据库吗? 退出 - 此设备似乎不支持电池优化白名单 - 您可能会遇到性能问题。 一些快速访问常用功能的按钮 用于配置活动插件 学习计划 @@ -43,7 +42,6 @@ 胰岛素: 碳水化合物: IOB活性胰岛素: - IOB活性胰岛素: 总 IOB: 总IOB activity(活动): Dur: @@ -51,9 +49,7 @@ Ins: IOB活性胰岛素: 总 IOB: - 血糖 临时目标 - 碳水化合物 矫正值 大剂量活性胰岛素IOB 现在运行 @@ -70,7 +66,6 @@ 没有可用的血糖数据 请求 增量 - 增量: 配置生成器 首页概览 治疗 @@ -91,13 +86,9 @@ 安全性 插件已禁用 违反约束条件 - 大剂量输注报告了一个错误。请手动检查真实输注量 接受新的临时基础率 治疗 计算器 - 应用约束! - 大剂量: - 基础率: 更改您的输入! 血糖来源 xDrip+ @@ -110,13 +101,10 @@ 碳水建议 不支持的 Nightscout 版本 基础 IOB - 大剂量约束条件应用了 - 碳水化合物约束条件应用了 其他 血糖仪 传感器 碳水时间 - 持续时间 配置文件 血糖类型 临时基础 @@ -156,60 +144,6 @@ 我理解并同意 保存 重新加载配置文件 - SMS短信通讯器 - 允许的手机号码 - +XXXXXXXXXX;+YYYYYYYYYY - 要输注大剂量胰岛素%1$.2fU 回复如下代码 %2$s - 要输注餐前大剂量 %1$.2fU ,请回复验证码 %2$s - 要设置临时目标 %1$s,请回复验证码 %2$s - 要取消临时目标,请回复验证码 %1$s - 要禁用短信遥控服务,请回复验证码%1$s.\n\n请记住,你只能在AAPS闭环手机上重新激活此功能。 - 短信遥控服务已禁用。要重新激活它,请使用AAPS闭环手机。 - 要发送校准值 %1$.2f 回复如下代码 %2$s - 大剂量输注失败 - 一次远程遥控输注命令与下一次命令之间必须经过的最小分钟数 - 两次短信遥控胰岛素输注的时间间隔 - 为了您的安全,您需要添加至少两个电话号码。 - 将要输注 %1$.2f U - 成功输注大剂量%1$.2fU - 成功输注餐时大剂量%1$.2fU - 目标 %1$s 执行 %2$d 分钟 - 目标 %1$s 执行 %2$d 分钟设置成功 - 临时目标已成功取消 - 通过SMS短信允许远程命令 - 闭环已经被禁用 - 闭环已经被启用 - 闭环被启用 - 连接泵,请回复验证码:%1$s - 连接泵失败 - 断开泵%1$d分钟,请回复验证码:%2$s - 泵已断开 - 泵已重新连接 - 远程命令没有被允许 - 远程大剂量不可用。请稍后再试。 - 执行基础率%1$.2fU/h持续时间%2$d分钟,请回复验证码:%3$s - 要切换配置文件到 %1$s %2$d%% 请回复代码 %3$s - 要开始扩展大剂量 %1$.2fU/h 持续时间%2$d 分钟,请回复验证码:%3$s - 要在 %2$s 输入 %1$d 克,请回复验证码 %3$s - 要开始基础率 %1$d%% 持续时间%2$d 分钟,请回复如下代码 %3$s - 要暂停闭环 %1$d 分钟请回复如下代码 %2$s - 恢复闭环,请回复验证码:%1$s - 启用闭环,请回复验证码:%1$s - 禁用闭环,请回复验证码:%1$s - 临时基础率 %1$.2fU/h 持续 %2$d 分钟启用成功了 - 扩展大剂量 %1$.2fU/h 持续时间 %2$d 分钟已经启用成功了 - 碳水%1$d克输入成功 - 输入 %1$d 克碳水化合物失败 - 临时基础率 %1$d%% 持续时间 %2$d 分钟 启用成功了 - 开始临时基础率失败了 - 开始扩展大剂量失败了 - 要停止临时基础率,请回复如下代码 %1$s - 要停止扩展大剂量,请回复如下代码 %1$s - 临时基础率取消了 - 扩展大剂量已经取消了 - 取消临时基础率失败 - 取消扩展大剂量失败 - 未知的命令或者错误的回复 快速向导 快速向导设置 按钮文本: @@ -240,13 +174,9 @@ 重新发送所有数据 在手表上打开设置 基础率 - 基础率值低于泵支持的最小值。配置文件没有设定 - 血糖: - 上次血糖: 美敦力640g 持续的的通知 旧数据 - %1$d分钟前 配置文件 OpenAPS AMA %1$d 元素的数组. \n 实际值: @@ -266,7 +196,6 @@ 治疗 目标 手表 - 手机SMS 标题名称缩写 总是使用短时间的平均增量代替简单增量 当血糖数据未经过滤时,如xDrip+数据嘈杂,此功能非常有用。 @@ -280,13 +209,6 @@ 默认值: 2 \n大剂量snooze是在输注餐时大剂量后开始生效的, 所以在你刚吃完饭的时候, 闭环不会因为你输注了大剂量而减少或停基础。这里的例子和缺省是 2; 因此, 3 小时的DIA(胰岛素持续作用时间) 意味着大剂量snooze将逐步在1. 5小时 (3 DIA/2) 后失效。 默认值: 3.0 (AMA) 或者 8.0 (SMB)。这是默认的每5分钟碳水化合物吸收量。默认值为3毫克/dl/5 分钟。 当血糖的下降超过预期时, 或者不像预期的上升的那么多时,这个值就影响了活性碳水化合物的衰减速度, 以及在计算预测未来血糖时假设的碳水化合物吸收量, 注意! \n 正常地您不必在下面更改这些值。请点击这里, 阅读说明, 并确保您了解它之前不要更改任何这些值。 - 无效的SMS手机号码 - 校准 - 没有安装xDrip+ - 校准发送到 xDrip+ - 校准已发送。必须在 xDrip+ 中启用接收功能。 - xDrip+未接收校准 - 泵暂停了 正在执行 虚拟泵设置 将状态上传到 NS @@ -322,10 +244,7 @@ 请选择患者类型,以设置安全限制 患者名称 请提供患者姓名或昵称来区分多个设置 - 用户 Glimp - 闭环暂停了 - 暂停了 (%1$d m) 暂停闭环一个小时 暂停闭环2个小时 暂停闭环3个小时 @@ -344,9 +263,6 @@ 10 小时 恢复 重新连接泵 - 错误的持续时间 - 闭环暂停了 - 闭环恢复了 15分钟 趋势 碳水 超级大剂量Superbolus @@ -381,7 +297,6 @@ ABS DEVSLOPE 关于 - 缺少 SMS 短信权限 缺少手机状态权限 xDrip+状态 (手表) xDrip+状态线 (手表) @@ -451,14 +366,11 @@ 从手表上控制 设置临时目标并从手表中进行治疗操作。 食物 - ]]> kJ En 蛋白质 脂肪 - 现在命令被执行了 - 血糖读数丢失 对警报和通知使用系统通知音 逐渐增加警报和通知的音量 本地警报 @@ -536,9 +448,6 @@ 允许通过fabric.io服务将自动崩溃报告和功能使用数据发送给开发人员。 请将您的 dexcom app 更新为支持的版本 未安装德康app。 - 开始运动临时目标 - 开始很快吃饭TT(临时目标) - TT(临时目标) 不打大剂量,只记录 类别 子类别 @@ -551,8 +460,6 @@ 活性碳水化合物 活性胰岛素 基础率 - 没有选择任何行动,不会做出任何改变 - 开始低的临时目标 正在运行开发版本,闭环被禁用了 已启用工程模式 配置文件切换缺失。请做一次配置文件切换或者在本地配置文件里按“激活配置文件” @@ -571,7 +478,6 @@ 由于 %2$s, 将 IOB(活性胰岛素) 限制为 %1$.1f U 在参数选项里的最大值 硬限制 - 读取状态失败了 记录泵管路更换 记录胰岛素储药器变化 SMB always and after carbs disabled 因为实时的血糖来源不支持高级筛选 @@ -623,12 +529,7 @@ 在下面配置你的RileyLink 。选择RileLink后,一旦RileLink状态为“已连接”,就可以继续安装。这可能需要一分钟。\n 注意:胰岛素泵设置完成后,您可以继续安装。\n 开始你的第一个目标 - 权限 请求权限 - 应用程序需要悬浮窗权限用于发送通知。 - 应用程序需要定位权限,才能进行蓝牙扫描及WIFI识别。 - 应用程序需要文件存储权限,才能存储日志文件及导出设置。 - 请求 打开导航栏 关闭导航栏 插件选项 @@ -668,8 +569,6 @@ 日志设置 重置为默认值 NSClient故障。 考虑Nightscout和NSClient重启。 - 时区偏移 - 稍后提醒输注大剂量 首选的APS模式 总计 计算 @@ -699,11 +598,6 @@ 夏令时变更在三小时内-已禁用闭环 内部储存空间不足 至少 剩余%1$d MB 内部存储!闭环已禁用! - 格式错误 - TBR(临时基础率) 的持续时间必须是 %1$d 分钟的倍数,且大于0。 - 错误的代码。命令取消 - 未配置 - 配置文件切换已创建 版本检查器 旧版本 非常旧版本 @@ -720,12 +614,10 @@ 大剂量向导执行计算,但只有这部分计算结果的胰岛素被输注。适用于SMB算法。 稍后再响 增加最大基础率,因为设置参数低于你配置文件中的最大基础率 - 无效消息 %1$s ISF: %2$.1f %1$.0fg IC: %2$.1f %1$.1fg IC: %2$.1f %1$d%% - 分钟 个人配置名称: 已选择: 单位 @@ -774,25 +666,6 @@ SMB持续时长 临时基础率请求时间 临时基础率持续时长 - - 从验证码生成器应用获取%1$s的随机码,并附加PIN码 - 验证码末尾强制附加的PIN码 - 在每次生成的一次性随机密码末尾,需要记住并强制附加的数字。 - 验证码生成器设置 - 验证码检查: - OTP随机 + PIN固定 - 验证码包含6位数字,由验证器应用程序生成(称为OTP),然后再包含3位或3位以上的必填数字PIN码。 - 重置身份验证器 - 重置身份验证器的密钥 - 你确定要重置验证器密钥吗?它将导致以前配置的OTP随机验证码无效,您需要重新设置它们(在遥控手机的OTP应用上)。 - 生成了新的身份验证器密钥!请使用更新的二维码设置验证器。 - 导出OTP密钥 - 你确定要将OTP密钥复制到剪贴板?\n\n只有在验证器应用扫描二维码出现问题时,你才需要这么做。可能你想手动输入二维码,或者使用专用的应用程序配置硬件OTP令牌。 - 将OTP密钥 (Base32 格式) 导出并复制到剪贴板。粘贴它到身份验证器或硬件OTP中! - 1. 安装身份验证器app - 3. 测试一次性验证码 - 重置身份验证器 - 在其他遥控手机上安装支持RFC 6238 TOTP令牌协议的应用程序。常用的免费应用有:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator 预测 治疗 斜度偏差 @@ -823,21 +696,9 @@ 筛选 无法创建配置文件。配置文件无效。 不要杀死我的应用程序? - 如果触发泵连接丢失事件,则发送短信通知。 - 泵连接丢失报告 在应当吃饭时提醒 - 在 %1$d 分钟内运行提醒 - 大剂量向导 - 你现在血糖值高,请等待血糖值改善后再吃饭。你是否需要输注胰岛素进行纠正并提醒你吃饭?在这种情况下,不会记录碳水,当我们提醒你吃饭时,您必须再次使用大剂量向导。 - 启用大剂量向导 - 在高血糖期间(\"预测大剂量\"),使用延迟吃饭的提醒功能,来替代大剂量向导结果 吃饭时间到了!\n请运行大剂量向导,然后进行计算。 - 吃饭时间 - 大剂量提醒 启用大剂量提醒 - 使用大剂量向导稍后推注的提醒功能 - (“稍后注射大剂量”) - 输注胰岛素时间到了!\n请运行大剂量向导,然后再次进行计算。 已禁用崩溃日志上传! 绘图 图表菜单 @@ -874,8 +735,6 @@ 允许通过NS或NS客户端接收(导管更换、胰岛素更换、电池更换等) 护理事件 接收/回填CGM数据 接受来自NS 的 CGM 数据 - 等待上一次胰岛素泵通信完成时超时 - 队列中在执行另一个大剂量命令,请稍后再试。 正在进行计算 缺少配置文件名称 IC数值错误 @@ -920,7 +779,6 @@ 胰岛素 血糖 已过期 - 设置提醒 添加新配置文件 克隆当前配置文件 删除当前配置文件 @@ -978,7 +836,6 @@ 显示闭环 已选中 %1$d 排序 - 对话框已取消 非常低 @@ -995,7 +852,6 @@ 配置文件 2 登录 删除全部 - 用于安装一次性随机验证码的二维码 打开设置 设置碳水计时器提醒 全部 diff --git a/automation/src/main/res/values-sr-rCS/strings.xml b/automation/src/main/res/values-sr-rCS/strings.xml index 3ea04e700d..3eb8ae6bdb 100644 --- a/automation/src/main/res/values-sr-rCS/strings.xml +++ b/automation/src/main/res/values-sr-rCS/strings.xml @@ -1,2 +1,4 @@ - + + Delta + diff --git a/core/src/main/res/values-af-rZA/strings.xml b/core/src/main/res/values-af-rZA/strings.xml index 0b6a6abc84..f828a1c46f 100644 --- a/core/src/main/res/values-af-rZA/strings.xml +++ b/core/src/main/res/values-af-rZA/strings.xml @@ -28,6 +28,10 @@ Tyd WiFi SSID Voeg nuwe by + g + Pomp opgeskort + Nie gekonfigureer nie + Lus opgeskort @@ -64,4 +68,5 @@ Basale + diff --git a/core/src/main/res/values-bg-rBG/strings.xml b/core/src/main/res/values-bg-rBG/strings.xml index e3a587a2b2..dd52bfa91b 100644 --- a/core/src/main/res/values-bg-rBG/strings.xml +++ b/core/src/main/res/values-bg-rBG/strings.xml @@ -105,6 +105,12 @@ Изтрий Добави нов Данните идват от различна помпа. Сменете драйвера на помпата и за да възстановите състоянието на помпата. + Сларма след %1$d мин + Грешка в болуса. Сам провери истинската стойност на доставения инсулин + гр. + Помпата е спряна + Не е конфигуриран + Loop изключен Ограничаване на макс. базална стойност до %1$.2f Е/ч поради %2$s лимит на помпата @@ -283,6 +289,7 @@ Базал Апликацията изисква разрешение за bluetooth + %1$d дeн %1$d дни diff --git a/core/src/main/res/values-ca-rES/strings.xml b/core/src/main/res/values-ca-rES/strings.xml index 6cd9b7b34c..17ab329f03 100644 --- a/core/src/main/res/values-ca-rES/strings.xml +++ b/core/src/main/res/values-ca-rES/strings.xml @@ -4,6 +4,12 @@ Desar ]]> + Executar alarma en %1$d min + Error en el bolus. Comprova manualment la quantitat real subministrada + g + Bomba aturada + No configurat + Llaç aturat @@ -71,4 +77,5 @@ Basal L\'aplicació necessita el permís del bluethoot + diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml index 35a3b91303..f05af9e3ed 100644 --- a/core/src/main/res/values-cs-rCZ/strings.xml +++ b/core/src/main/res/values-cs-rCZ/strings.xml @@ -114,6 +114,16 @@ Přidat nový Přidat novou nad Data přicházejí z jiné pumpy. Změňte ovladač pro obnovení stavu pumpy. + Gly + Kalibrace + Spustit alarm za %1$d min + Podání bolusu skončilo chybou. Ručně zkontrolujte, kolik inzulinu se skutečně vydalo. + Připomenutí bolusu + Trvání + g + Pumpa pozastavena + Není nakonfigurováno + Smyčka pozastavena Max bazál omezen na %1$.2f U/h: %2$s limit pumpy @@ -491,6 +501,8 @@ Chyba při posledním spuštění Autotune Byla zjištěna jiná běžící úloha Autotune, spuštění zrušeno Aplikace potřebuje oprávnění bluetooth + + Chybějící povolení SMS %1$d den %1$d dnů diff --git a/core/src/main/res/values-da-rDK/strings.xml b/core/src/main/res/values-da-rDK/strings.xml index d01717ed15..2004e3100f 100644 --- a/core/src/main/res/values-da-rDK/strings.xml +++ b/core/src/main/res/values-da-rDK/strings.xml @@ -110,6 +110,12 @@ Tilføj ny Tilføj ny ovenfor Data kommer fra en anden pumpe. Skift pumpedriver for at nulstille pumpetilstand. + Kør alarm om %1$d min + Bolus fejl. Undersøg manuelt hvor meget insulin der er givet + g + Pumpe er afbrudt + Ikke konfigureret + Loop suspenderet Begrænser max IOB til %1$.2f E/t på grund af %2$s pumpe grænse @@ -479,6 +485,7 @@ Fejl under sidste Autotune kørsel Autotune kører allerede, annulleret Applikationen kræver tilladelse til bluetooth + %1$d dag %1$d dage diff --git a/core/src/main/res/values-de-rDE/strings.xml b/core/src/main/res/values-de-rDE/strings.xml index 0b9e839894..96782066ed 100644 --- a/core/src/main/res/values-de-rDE/strings.xml +++ b/core/src/main/res/values-de-rDE/strings.xml @@ -110,6 +110,12 @@ Weiteren hinzufügen Neu oben hinzufügen Daten kommen von einer anderen Pumpe. Wechsle den Pumpentreiber. + Alarm in %1$d Min. + Fehlermeldung Bolusabgabe. Prüfe manuell die tatsächlich abgegebene Menge. + g + Pumpe pausiert + Nicht konfiguriert + Loop pausiert Begrenzung der max. Basalrate auf %1$.2f IE/h wegen %2$s Limit der Pumpe @@ -479,6 +485,7 @@ Fehler beim letzten Autotune Lauf Ein weiterer Lauf von Autotune wurde erkannt, Lauf abgebrochen App benötigt Bluetooth-Berechtigung + %1$d Tag %1$d Tage diff --git a/core/src/main/res/values-el-rGR/strings.xml b/core/src/main/res/values-el-rGR/strings.xml index 68de2b7014..50fb103f7b 100644 --- a/core/src/main/res/values-el-rGR/strings.xml +++ b/core/src/main/res/values-el-rGR/strings.xml @@ -27,6 +27,11 @@ Χρόνος WiFi SSID Προσθήκη νέου + Το Bolus ανέφερε ένα σφάλμα. Ελέγξτε χειροκίνητα την ποσότητα που έχει πραγματικά χορηγηθεί + g + Η αντλία είναι σε παύση + Δεν έχει ρυθμιστεί + Κύκλωμα σε αναστολή @@ -64,4 +69,5 @@ Βασικός Ρυθμός + diff --git a/core/src/main/res/values-es-rES/strings.xml b/core/src/main/res/values-es-rES/strings.xml index 4b3eff1dc8..d94ea1b0e1 100644 --- a/core/src/main/res/values-es-rES/strings.xml +++ b/core/src/main/res/values-es-rES/strings.xml @@ -114,6 +114,12 @@ Añadir nuevo Añadir nuevo arriba Los datos proceden de una bomba diferente. Cambia el controlador de la bomba para resetear su estado. + Ejecutar alarma en %1$d min + El bolo reportó un error. Comprueba manualmente la cantidad real de insulina entregada + g + Bomba parada + Sin configurar + Lazo suspendido Limitando max basal rate a %1$.2f U/h debido a %2$s límite de la bomba @@ -491,6 +497,7 @@ Error durante la última ejecución de Autotune Se ha detectado otra ejecución de Autotune, ejecución cancelada La aplicación necesita permiso de bluetooth + %1$d día %1$d días diff --git a/core/src/main/res/values-fr-rFR/strings.xml b/core/src/main/res/values-fr-rFR/strings.xml index 8dee18fc29..71d2f8cb87 100644 --- a/core/src/main/res/values-fr-rFR/strings.xml +++ b/core/src/main/res/values-fr-rFR/strings.xml @@ -114,6 +114,16 @@ Ajouter Ajouter le nouveau au-dessus Les données proviennent de différentes pompes. Changer le pilote de la pompe pour réinitialiser l\'état de la pompe. + Gly + Étalonnage + Alerter dans %1$d min + Erreur lors du Bolus. Vérifiez manuellement la quantité réellement injectée + Rappel bolus + Durée + g + Pompe arrêtée + Non configuré + La Boucle est suspendue Limiter le débit de basal max à %1$.2f U/h à cause de %2$s Limite de la pompe @@ -491,6 +501,7 @@ Erreur lors de la dernière exécution d\'Autotune Une autre exécution d\'Autotune est détectée, l\'exécution est annulée L\'application a besoin de l\'autorisation Bluetooth + %1$d jour %1$d jours diff --git a/core/src/main/res/values-ga-rIE/strings.xml b/core/src/main/res/values-ga-rIE/strings.xml index 6f676893c7..6cd1cac1b3 100644 --- a/core/src/main/res/values-ga-rIE/strings.xml +++ b/core/src/main/res/values-ga-rIE/strings.xml @@ -2,6 +2,9 @@ + g + Caidéil ar fionraí + Lúb ar fionraí @@ -26,4 +29,5 @@ + diff --git a/core/src/main/res/values-hr-rHR/strings.xml b/core/src/main/res/values-hr-rHR/strings.xml index 57579e20e0..e2412b4093 100644 --- a/core/src/main/res/values-hr-rHR/strings.xml +++ b/core/src/main/res/values-hr-rHR/strings.xml @@ -28,4 +28,5 @@ + diff --git a/core/src/main/res/values-hu-rHU/strings.xml b/core/src/main/res/values-hu-rHU/strings.xml index 8d7d288e7b..09276d5a58 100644 --- a/core/src/main/res/values-hu-rHU/strings.xml +++ b/core/src/main/res/values-hu-rHU/strings.xml @@ -3,6 +3,7 @@ Pumpa idő frissítve + Nincs beállítva @@ -28,4 +29,5 @@ Bázis + diff --git a/core/src/main/res/values-it-rIT/strings.xml b/core/src/main/res/values-it-rIT/strings.xml index 78e496de8f..20d1c0777f 100644 --- a/core/src/main/res/values-it-rIT/strings.xml +++ b/core/src/main/res/values-it-rIT/strings.xml @@ -114,6 +114,12 @@ Aggiungi nuovo Aggiungi nuovo sopra I dati arrivano da un micro differente. Cambia il driver del micro per resettarne lo stato. + Esegui allarme in %1$d min + Segnalato errore sul bolo. Controlla manualmente la reale quantità erogata + g + Micro sospeso + Non configurato + Loop sospeso Limitazione max velocità basale a %1$.2f U/h a causa di: %2$s limite micro @@ -491,6 +497,7 @@ Errore durante l\'ultima esecuzione di Autotune È stata rilevata un\'altra esecuzione di Autotune, esecuzione annullata L\'applicazione richiede l\'autorizzazione bluetooth + %1$d giorno %1$d giorni diff --git a/core/src/main/res/values-iw-rIL/strings.xml b/core/src/main/res/values-iw-rIL/strings.xml index eb8baf30c5..80b376b1e7 100644 --- a/core/src/main/res/values-iw-rIL/strings.xml +++ b/core/src/main/res/values-iw-rIL/strings.xml @@ -110,6 +110,12 @@ הוסף חדש הוסף חדש למעלה הנתונים מגיעים ממשאבה אחרת. בחרו מחדש את סוג המשאבה כדי לאפס את מצב המשאבה. + הפעל התראה בעוד %1$d דקות + דווחה שגיאה בבולוס. נא לבדוק את הכמות שהוזרקה באופן ידני + גר\' + משאבה מושהית + לא מוגדר + לולאה מושהית מגביל את הקצב הבזאלי המרבי ל-%1$.2f יח\' לשעה בגלל %2$s מגבלת משאבה @@ -479,6 +485,7 @@ שגיאה במהלך הכיוונון האוטומטי האחרון נמצאה הפעלה נוספת של הכוונון האוטומטי ברקע, ההפעלה מבוטלת האפליקציה צריכה הרשאה לבלוטות\' + %1$d יום %1$d ימים diff --git a/core/src/main/res/values-ko-rKR/strings.xml b/core/src/main/res/values-ko-rKR/strings.xml index 79a2f596ad..38bfd65137 100644 --- a/core/src/main/res/values-ko-rKR/strings.xml +++ b/core/src/main/res/values-ko-rKR/strings.xml @@ -104,6 +104,11 @@ 삭제 새로 추가 다른 펌프에서 전송된 데이터. 펌프 상태 재설정을 위해 펌프 드라이버를 바꾸세요. + %1$d분 뒤 알람 울림 + g + 펌프 일시중지됨 + 설정되지 않음 + Loop 일시중지 %2$s로 인해 최대 Basal양이 %1$.2f U/h으로 제한됩니다. 펌프 제한 @@ -373,6 +378,7 @@ Basal + %1$d 일 diff --git a/core/src/main/res/values-lt-rLT/strings.xml b/core/src/main/res/values-lt-rLT/strings.xml index 36a397b561..a610a2a44d 100644 --- a/core/src/main/res/values-lt-rLT/strings.xml +++ b/core/src/main/res/values-lt-rLT/strings.xml @@ -105,6 +105,12 @@ Pašalinti Pridėti naują Duomenys gaunami iš kitos pompos. Pakeiskite pompos valdiklį. + Pranešti po %1$d min + Boluso suleidimo klaida. Rankiniu būdu patikrinkite faktiškai suleistą kiekį + g + Pompa sustabdyta + Nesukonfigūruota + Ciklas sustabdytas Ribojamas maksimalus bazės dydis%1$.2f vv/val dėl %2$s pompos limitas @@ -415,6 +421,7 @@ Valandinė bazė Programai reikalinga Bluetooth prieigos teisė + %1$d d. %1$d d. diff --git a/core/src/main/res/values-nl-rNL/strings.xml b/core/src/main/res/values-nl-rNL/strings.xml index 5ea2197ce0..9c760cb12d 100644 --- a/core/src/main/res/values-nl-rNL/strings.xml +++ b/core/src/main/res/values-nl-rNL/strings.xml @@ -110,6 +110,12 @@ Voeg nieuw toe Voeg nieuw hierboven toe Data komt van een andere pomp. Wijzig de pomp driver om de pomp status te resetten. + Start alarm over %1$d min + Bolus fout geconstateerd. Controleer de daadwerkelijk toegediende hoeveelheid + g + Pomp onderbreken + Niet ingesteld + Loop pauzeren Beperken van basaal tot max %1$.2f E/uur wegens de %2$s Pomp limiet @@ -477,6 +483,7 @@ Profiel %1$s terugzetten met invoerprofiel? Profiel ongeldig Fout tijdens laatste Autotune uitvoeren + %1$d dag %1$d dagen diff --git a/core/src/main/res/values-no-rNO/strings.xml b/core/src/main/res/values-no-rNO/strings.xml index 4211dfcdef..d94d6c6004 100644 --- a/core/src/main/res/values-no-rNO/strings.xml +++ b/core/src/main/res/values-no-rNO/strings.xml @@ -114,6 +114,12 @@ Legg til ny Legg til ny over Data kommer fra forskjellige pumper. Bytt pumpevalg for å nullstille pumpens tilstand. + Aktiver alarm om %1$d min + Det er registrert en feil med bolus-leveransen. Sjekk manuelt om den er levert og hvor mye + g + Pumpen er pauset + Ikke konfigurert + Loop pauset Begrenser maks basal dose til %1$.2f E/t på grunn av %2$s pumpebegrensning @@ -490,6 +496,7 @@ Feil oppdaget under siste Autotune kjøring Autotune kjører allerede. Kjøring avbrutt Appen trenger bluetooth tillatelse + %1$d dag %1$d dager diff --git a/core/src/main/res/values-pl-rPL/strings.xml b/core/src/main/res/values-pl-rPL/strings.xml index d9f6d5ab55..332e9d92b0 100644 --- a/core/src/main/res/values-pl-rPL/strings.xml +++ b/core/src/main/res/values-pl-rPL/strings.xml @@ -105,6 +105,12 @@ Usuń Dodaj nowy Dane pochodzą z innej pompy. Zmień sterownik pompy, aby zresetować stan pompy. + Uruchom alarm za %1$d min + Błąd podczas podawania bolusa. Sprawdź ręcznie rzeczywiście dostarczoną ilość + g + Pompa wstrzymana + Nie skonfigurowano + Pętla wstrzymana Ograniczam maks. dawkę bazową do %1$.2f U/h z uwagi na %2$s ograniczenie pompy @@ -417,6 +423,7 @@ Sortuj Aplikacja wymaga uprawnienia Bluetooth + %1$d dzień %1$d dni diff --git a/core/src/main/res/values-pt-rBR/strings.xml b/core/src/main/res/values-pt-rBR/strings.xml index d9bad0685a..ec7b0d7914 100644 --- a/core/src/main/res/values-pt-rBR/strings.xml +++ b/core/src/main/res/values-pt-rBR/strings.xml @@ -81,6 +81,12 @@ Hora do Evento Notas Adicionar novo + Disparar alarme em %1$d min + O Bolus relatou um erro. Verifique a quantidade administrada manualmente + g + Bomba suspensa + Não configurado + Loop suspenso A basal max está limitada a %1$.2f U/h por %2$s limite da bomba @@ -225,6 +231,7 @@ Número padrão de dias de dados a serem processados por Autotune (até 30) Erro nos dados de entrada, tente executar novamente autotune ou reduza o número de dias O aplicativo precisa de permissão bluetooth + %1$d dia %1$d dias diff --git a/core/src/main/res/values-pt-rPT/strings.xml b/core/src/main/res/values-pt-rPT/strings.xml index 35a289dea6..abdca40792 100644 --- a/core/src/main/res/values-pt-rPT/strings.xml +++ b/core/src/main/res/values-pt-rPT/strings.xml @@ -103,6 +103,12 @@ Notas Remover Adicionar novo + Executar alarme em %1$d min + Ocorreu um erro de bólus. Verifique manualmente a quantidade administrada + g + Bomba suspensa + Não configurado + Loop suspenso A basal máx está limitada a %1$.2f U/h por %2$s limite bomba @@ -335,6 +341,7 @@ Basal Aplicação precisa de permissão Bluetooth + %1$d dia %1$d dias diff --git a/core/src/main/res/values-ro-rRO/strings.xml b/core/src/main/res/values-ro-rRO/strings.xml index bf6c8338ae..e9c76c48bb 100644 --- a/core/src/main/res/values-ro-rRO/strings.xml +++ b/core/src/main/res/values-ro-rRO/strings.xml @@ -105,6 +105,12 @@ Șterge Adăugare Datele vin de la o pompa diferita. Schimba driver-ul de pompa pentru a reseta starea pompei. + Rulează alarma în %1$d min + Bolus a raportat o eroare. Verifică manual cantitatea livrată + g + Livrare de insulină suspendată + Nu este configurat + Buclă suspendată Se limitează maximul ratei bazale la %1$.2f U/o datorită %2$s limită pompă @@ -417,6 +423,7 @@ Sortează Aplicația are nevoie de permisiune Bluetooth + %1$d zi %1$d zile diff --git a/core/src/main/res/values-ru-rRU/strings.xml b/core/src/main/res/values-ru-rRU/strings.xml index 12a6ec6359..829d248bb4 100644 --- a/core/src/main/res/values-ru-rRU/strings.xml +++ b/core/src/main/res/values-ru-rRU/strings.xml @@ -114,6 +114,12 @@ Добавить новый Добавить строку сверху Данные поступают с другой помпы. Измените драйвер помпы, чтобы сбросить ее состояние. + Напомнить через %1$d мин + Возможна ошибка в подаче болюса. Проверьте реальное количество поданного инсулина + грамм + Работа помпы остановлена + Не сконфигурировано + ЗЦ остановлен Макс базальный уровень ограничен до %1$.2f ед/ч вследствие %2$s лимит помпы @@ -491,6 +497,7 @@ Ошибка во время последнего выполнения Autotune Обнаружен другой запуск Autotune, выполнение отменено Приложению требуется разрешение Bluetooth + %1$d день %1$d дня diff --git a/core/src/main/res/values-sk-rSK/strings.xml b/core/src/main/res/values-sk-rSK/strings.xml index 93d2595c0d..3dfb1c8956 100644 --- a/core/src/main/res/values-sk-rSK/strings.xml +++ b/core/src/main/res/values-sk-rSK/strings.xml @@ -114,6 +114,16 @@ Pridať nový Pridať novú nad Dáta prichádzajú z inej pumpy. Zmeňte ovládač pre obnovenie stavu pumpy. + Glykémia + Kalibrácia + Spustiť výstrahu za %1$d min + Bolus zaznamenal chybu. Overte prosím manuálne reálne podané množstvo + Pripomenutie bolusu + Trvanie + g + Pumpa pozastavená + Nenakonfigurované + Uzavretý okruh pozastavený Max bazál obmedzený na %1$.2f JI/h: %2$s limit pumpy @@ -491,6 +501,8 @@ Chyba pri poslednom spustení Autotune Bola zistená iná spustená úloha Autotune, spustenie zrušené Aplikácia vyžaduje povolenie bluetooth + + Chýbajúce povolenie SMS príkazov %1$d deň %1$d dní diff --git a/core/src/main/res/values-sr-rCS/strings.xml b/core/src/main/res/values-sr-rCS/strings.xml index 6f676893c7..f2c270ce22 100644 --- a/core/src/main/res/values-sr-rCS/strings.xml +++ b/core/src/main/res/values-sr-rCS/strings.xml @@ -2,6 +2,8 @@ + Sačuvaj + Bolus je prijavio grešku. Ručno proverite stvarnu isporučenu količinu @@ -26,4 +28,5 @@ + diff --git a/core/src/main/res/values-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml index b8b7a0d4c2..41e7dcaf7c 100644 --- a/core/src/main/res/values-sv-rSE/strings.xml +++ b/core/src/main/res/values-sv-rSE/strings.xml @@ -110,6 +110,12 @@ Lägg till Lägg till nytt ovan Data kommer från en annan pump. Byt pumpdrivrutin för att återställa. + Larma om %1$d min + Ett fel rapporterades under bolus. Vänligen kontrollera pumpen manuellt + g + Pump pausad + Inte konfigurerad + Loop pausad Max basal: %1$.2f E/h pga %2$s pumpbegränsning @@ -422,6 +428,7 @@ Basal Applikationen behöver bluetooth-behörighet + %1$d dag %1$d dagar diff --git a/core/src/main/res/values-tr-rTR/strings.xml b/core/src/main/res/values-tr-rTR/strings.xml index 0e02a6649d..a4e9c7d678 100644 --- a/core/src/main/res/values-tr-rTR/strings.xml +++ b/core/src/main/res/values-tr-rTR/strings.xml @@ -20,6 +20,7 @@ Bağlantı kesildi Bağlantı kesiliyor Bağlantının kesilmesi bekleniyor + AAPS başladı %1$.1f Ü %1$.2f Ü %1$+.2f Ü @@ -113,6 +114,16 @@ Yeni ekle Yukarı yeni ekle Veriler farklı pompadan geliyor. Pompa durumunu sıfırlamak için pompa sürücüsünü değiştirin. + + Kalibrasyon + Alarmı %1$d dakika içinde çalıştır + Bolus bir hata bildirdi. Gerçek teslim edilen miktarı manuel olarak kontrol edin + Bolus hatırlatıcısı + Süre + gr + Pompa durduldu + Yapılandırılmadı + Döngü duraklatıldı %2$s nedeniyle max bazal oranı %1$.2f Ü/s ile sınırlı pompa sınırı @@ -279,6 +290,7 @@ Sürüm %1$s mevcut %1$s sürümünün süresi %2$s tarihinde sona eriyor + Lütfen telefonunu yeniden başlat, yada AAPS sistem ayarları üzerinden yeniden başlat.\nAksi taktirde Android APS hiç bir günlük tutmayacak (takip ve doğrulama, algoritmanın düzenli çalışmasi için önemli)! P S @@ -359,6 +371,7 @@ AYARLARI DIŞA AKTAR AYARLARI İÇE AKTAR VERİTABANLARINI SIFIRLA + TEMİZLEME VERİTABANLARI VERİTABANINI DIŞA AKTAR VERİTABANINI İÇE AKTAR OTP DIŞA AKTAR @@ -395,6 +408,7 @@ »%1$s« sınırların dışında »%1$s« %2$.2f sınırların dışında Bazal değer + AAPSClient sürümü, AAPS sürümü ile eşleşmiyor. Lütfen güncelle. BOLUS %1$.2f Ü Karbonhidrat %1$d g @@ -482,9 +496,13 @@ OtoAyar Profili ile %1$s profili güncellensin mi? Giriş Profili ile %1$s profili geri alınsın mı? Profil geçersiz + OtoAyar profil değiştirme olmadan çalıştı + OtoAyar çalıştı ve profil otomatik olarak değiştirildi Son OtoAyar çalışması sırasında hata oluştu Başka bir OtoAyar çalıştırması tespit edildi, çalıştırma iptal edildi Uygulama bluetooth iznine ihtiyac duyuyor + + SMS izni eksik %1$d gün %1$d gün diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml index efaf4f43d9..227137ecf2 100644 --- a/core/src/main/res/values-zh-rCN/strings.xml +++ b/core/src/main/res/values-zh-rCN/strings.xml @@ -110,6 +110,12 @@ 添加新条目 在顶部新增 数据来自不同的胰岛素泵,修改泵的驱动配置用来重置泵的状态。 + 在 %1$d 分钟内运行提醒 + 大剂量输注报告了一个错误。请手动检查真实输注量 + + 泵暂停了 + 未配置 + 闭环暂停了 最大基础率被限定为 %1$.2f U/h 由于 %2$s 泵限制 @@ -434,6 +440,7 @@ 用户 应用程序需要蓝牙权限。 + %1$d 天 diff --git a/implementation/src/main/res/values-af-rZA/strings.xml b/implementation/src/main/res/values-af-rZA/strings.xml new file mode 100644 index 0000000000..5c6ca7f27a --- /dev/null +++ b/implementation/src/main/res/values-af-rZA/strings.xml @@ -0,0 +1,6 @@ + + + Gemiste BG lesings + Versoek + Toestemming + diff --git a/implementation/src/main/res/values-bg-rBG/strings.xml b/implementation/src/main/res/values-bg-rBG/strings.xml new file mode 100644 index 0000000000..49ee870c9f --- /dev/null +++ b/implementation/src/main/res/values-bg-rBG/strings.xml @@ -0,0 +1,8 @@ + + + Липсват данни за КЗ + Време е за болус!\nВключи болус съветника и направи изчисление отново. + Искане + Разрешение + Вашият телефон не поддържа оптимизация на батерията - може да се появят проблеми! + diff --git a/implementation/src/main/res/values-ca-rES/strings.xml b/implementation/src/main/res/values-ca-rES/strings.xml new file mode 100644 index 0000000000..82b7a9e260 --- /dev/null +++ b/implementation/src/main/res/values-ca-rES/strings.xml @@ -0,0 +1,7 @@ + + + Falten lectures de glucèmia + Hora d’aplicar bolus!\nExecuteu l\'assistent de bolus i torneu a fer els càlculs. + Permís + Sembla que aquest dispositiu no permet optimitzar la bateria amb llistes blanques, això pot provocar problemes de rendiment. + diff --git a/implementation/src/main/res/values-cs-rCZ/strings.xml b/implementation/src/main/res/values-cs-rCZ/strings.xml new file mode 100644 index 0000000000..1b85e127cb --- /dev/null +++ b/implementation/src/main/res/values-cs-rCZ/strings.xml @@ -0,0 +1,23 @@ + + + xDrip+ není nainstalován + Kalibrace odeslána do xDripu+ + Gly + Chybějící glykémie + Čas k jídlu + Povolit poradce s bolusem + Při vysoké glykémii použijte připomenutí, abyste začali jíst později, namísto výsledku z kalkulátoru („prebolus“) + Poradce pro bolus + Máte vysokou glykémii. Namísto jídla doporučujeme vyčkat na lepší glykémii a připomenout, až bude čas na jídlo. Přejete si poslat korekční bolus a připomenout, až bude čas k jídlu? V tomto případě nebudou zapsané žádné sacharidy, a později opět musíte spustit kalkulátor, jakmile vám to připomeneme. + Čas na bolus!\nSpusťte Bolusovou kalkulačku a proveďte výpočet znovu. + Příkaz je právě prováděn + Hodnota bazálu pod povoleným minimem. Nenastaveno! + Požadavek + Povolení + %1$s potřebuje vypnout optimalizace baterie pro optimální výkon + Pro oznámení vyžaduje aplikace oprávnění systémového okna + Aplikace potřebuje oprávnění k přístupu k poloze kvůli skenování BT a WiFi identifikaci + Aby bylo možné nahrávat logy a exportovat nastavení, je nutné pro aplikaci povolit oprávnění přístupu k úložišti + Chyba žádosti o oprávnění + Toto zařízení zřejmě neumožňuje vypnout optimalizaci baterie - může docházet k problémům s výkonem. + diff --git a/implementation/src/main/res/values-da-rDK/strings.xml b/implementation/src/main/res/values-da-rDK/strings.xml new file mode 100644 index 0000000000..21afb27b6b --- /dev/null +++ b/implementation/src/main/res/values-da-rDK/strings.xml @@ -0,0 +1,9 @@ + + + Manglende BS målinger + Tid til bolus!\nKør Bolus-guiden og lav beregningen igen. + Anmod + Tilladelse + Fejl under forespørgsel af tilladelser + Denne enhed synes ikke at understøtte batterioptimering whitelisting - du kan opleve problemer med ydeevnen. + diff --git a/implementation/src/main/res/values-de-rDE/strings.xml b/implementation/src/main/res/values-de-rDE/strings.xml new file mode 100644 index 0000000000..7087956f6a --- /dev/null +++ b/implementation/src/main/res/values-de-rDE/strings.xml @@ -0,0 +1,9 @@ + + + BZ-Werte fehlen + Zeit für den nächsten Bolus!\nFühre den Bolus-Assistenten aus, um die Berechnung erneut durchzuführen. + Anfordern + Berechtigung + Fehler beim Anfordern der Erlaubnis + Dieses Gerät scheint keine Deaktivierung der Energieoptimierung zu unterstützen - das könnte zu Leistungsproblemen führen. + diff --git a/implementation/src/main/res/values-el-rGR/strings.xml b/implementation/src/main/res/values-el-rGR/strings.xml new file mode 100644 index 0000000000..68096394e4 --- /dev/null +++ b/implementation/src/main/res/values-el-rGR/strings.xml @@ -0,0 +1,7 @@ + + + Χαμένες μετρήσεις BG + Αίτημα + Άδεια + Αυτή η συσκευή δεν φαίνεται να υποστηρίζει τη λίστα κατάτμησης βελτιστοποίησης μπαταρίας - ενδέχεται να αντιμετωπίσετε προβλήματα απόδοσης. + diff --git a/implementation/src/main/res/values-es-rES/strings.xml b/implementation/src/main/res/values-es-rES/strings.xml new file mode 100644 index 0000000000..ec1d9000f1 --- /dev/null +++ b/implementation/src/main/res/values-es-rES/strings.xml @@ -0,0 +1,9 @@ + + + Faltan lecturas de glucosa + ¡Hora de comer!\nEjecutar el asistente de bolo y calcular de nuevo. + Solicitar + Permiso + Error al solicitar permisos + Este dispositivo no parece soportar la optimización de la batería por los ajustes - pueden ocurrir problemas de funcionamiento. + diff --git a/implementation/src/main/res/values-fr-rFR/strings.xml b/implementation/src/main/res/values-fr-rFR/strings.xml new file mode 100644 index 0000000000..c103a937d3 --- /dev/null +++ b/implementation/src/main/res/values-fr-rFR/strings.xml @@ -0,0 +1,17 @@ + + + xDrip+ n\'est pas installé + Étalonnage envoyé à xDrip+ + Gly + Valeurs de glycémie manquantes + Il est temps de manger + Activer l\'assistant bolus + Utiliser un rappel pour commencer le repas à la place du résultat de l\'assistant quand la glycémie est élevée (\"pré-bolus\") + Assistant bolus + Vous avez une glycémie élevée. Au lieu de manger maintenant, il est recommandé d\'attendre une meilleure glycémie. Voulez-vous faire un bolus de correction maintenant et avoir une alerte quand il sera temps de manger ? Dans ce cas, aucun glucide ne sera enregistré et vous devrez utiliser l\'assistant à nouveau lorsque nous vous le rappelons. + Il est temps de faire le bolus !\nExécutez l\'Assistant et faites de nouveau le calcul. + Demande + Autorisation + Erreur lors de la demande des autorisations + Ce périphérique ne semble pas permettre l\'optimisation de la batterie par une liste blanche - vous pourriez rencontrer des problèmes de performance. + diff --git a/implementation/src/main/res/values-ga-rIE/strings.xml b/implementation/src/main/res/values-ga-rIE/strings.xml new file mode 100644 index 0000000000..3ea04e700d --- /dev/null +++ b/implementation/src/main/res/values-ga-rIE/strings.xml @@ -0,0 +1,2 @@ + + diff --git a/implementation/src/main/res/values-hr-rHR/strings.xml b/implementation/src/main/res/values-hr-rHR/strings.xml new file mode 100644 index 0000000000..093ba40b1b --- /dev/null +++ b/implementation/src/main/res/values-hr-rHR/strings.xml @@ -0,0 +1,5 @@ + + + Pogreška pri traženju dopuštenja + Čini se da ovaj uređaj ne podržava stavljanje na popis dopuštenih za optimizaciju baterije - mogli biste imati problema s performansama. + diff --git a/implementation/src/main/res/values-hu-rHU/strings.xml b/implementation/src/main/res/values-hu-rHU/strings.xml new file mode 100644 index 0000000000..3ea04e700d --- /dev/null +++ b/implementation/src/main/res/values-hu-rHU/strings.xml @@ -0,0 +1,2 @@ + + diff --git a/implementation/src/main/res/values-it-rIT/strings.xml b/implementation/src/main/res/values-it-rIT/strings.xml new file mode 100644 index 0000000000..2e638608b7 --- /dev/null +++ b/implementation/src/main/res/values-it-rIT/strings.xml @@ -0,0 +1,9 @@ + + + Letture BG mancanti + Tempo di fare un bolo!\nEsegui il calcolatore e fai di nuovi i calcoli. + Richiesta + Autorizzazione + Errore nel richiedere le autorizzazioni + Questo dispositivo non sembra supportare la whitelist dell\'ottimizzazione batteria: potrebbero verificarsi problemi di prestazioni. + diff --git a/implementation/src/main/res/values-iw-rIL/strings.xml b/implementation/src/main/res/values-iw-rIL/strings.xml new file mode 100644 index 0000000000..c2cd76ffc9 --- /dev/null +++ b/implementation/src/main/res/values-iw-rIL/strings.xml @@ -0,0 +1,9 @@ + + + לא התקבלו קריאות סוכר + זמן להזריק בולוס!\nהשתמשו במחשבון וחשבו מחדש. + בקשה + הרשאה + שגיאה בעת בקשת הרשאות + נראה שמכשיר זה אינו תומך ברשימת היתרים למיטוב הסוללה - ייתכן שתיתקל בבעיות ביצועים. + diff --git a/implementation/src/main/res/values-ko-rKR/strings.xml b/implementation/src/main/res/values-ko-rKR/strings.xml new file mode 100644 index 0000000000..15a8140f02 --- /dev/null +++ b/implementation/src/main/res/values-ko-rKR/strings.xml @@ -0,0 +1,7 @@ + + + 혈당 읽기가 누락되었습니다. + 요청 + 권한 + 이 장치는 배터리 최적화 화이트리스트를 지원하지 않습니다 - 성능 문제가 발생할 수 있습니다. + diff --git a/implementation/src/main/res/values-lt-rLT/strings.xml b/implementation/src/main/res/values-lt-rLT/strings.xml new file mode 100644 index 0000000000..ed22337507 --- /dev/null +++ b/implementation/src/main/res/values-lt-rLT/strings.xml @@ -0,0 +1,8 @@ + + + Negauti KG duomenys + Laikas bolusui!\nĮjunkite Skaičiuotuvą ir pakartokite skaičiavimus. + Užklausa + Leidimas + Šis įrenginys nepalaiko baterijos optimizavimo išimčių - galite patirti veikimo nesklandumų. + diff --git a/implementation/src/main/res/values-nl-rNL/strings.xml b/implementation/src/main/res/values-nl-rNL/strings.xml new file mode 100644 index 0000000000..413941d14b --- /dev/null +++ b/implementation/src/main/res/values-nl-rNL/strings.xml @@ -0,0 +1,9 @@ + + + Geen BG metingen + Tijd om te bolussen!\nVoer de boluswizard uit en maak de berekening opnieuw. + Verzoek + Toestemming + Fout bij het vragen van toestemming + Dit apparaat lijkt geen ondersteuning te bieden voor whitelisten voor batterijoptimalisatie - u kunt prestatieproblemen ervaren. + diff --git a/implementation/src/main/res/values-no-rNO/strings.xml b/implementation/src/main/res/values-no-rNO/strings.xml new file mode 100644 index 0000000000..d4b08ead14 --- /dev/null +++ b/implementation/src/main/res/values-no-rNO/strings.xml @@ -0,0 +1,9 @@ + + + Mangler BS-målinger + Tid for bolus!\nStart bolus-veiviser og gjør beregning på nytt. + Forespørsel + Tillatelse + Feil under spørring etter tillatelser + Det ser ikke ut som mobilen støtter registrering av apper som unntas fra batterioptimalisering - du kan oppleve ytelsesproblemer. + diff --git a/implementation/src/main/res/values-pl-rPL/strings.xml b/implementation/src/main/res/values-pl-rPL/strings.xml new file mode 100644 index 0000000000..51b71ce4c1 --- /dev/null +++ b/implementation/src/main/res/values-pl-rPL/strings.xml @@ -0,0 +1,8 @@ + + + Pominięte odczyty BG + Czas na bolus!\nUruchom Kalkulator bolusa aby ponownie wykonać obliczenia. + Żądanie + Uprawnienia + To urządzenie nie obsługuje białej listy optymalizacji baterii - mogą wystąpić problemy z wydajnością. + diff --git a/implementation/src/main/res/values-pt-rBR/strings.xml b/implementation/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000000..9230c82859 --- /dev/null +++ b/implementation/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,9 @@ + + + Leituras Glic. perdidas + Hora do bolus!\nAbra o assistente de bolus e faça o cálculo novamente. + Pedido + Permissão + Erro alterando permissões + Este dispositivo não parece suportar a optimização de bateria na lista de permissões - pode ter problemas de desempenho. + diff --git a/implementation/src/main/res/values-pt-rPT/strings.xml b/implementation/src/main/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000000..68404076ad --- /dev/null +++ b/implementation/src/main/res/values-pt-rPT/strings.xml @@ -0,0 +1,8 @@ + + + Leituras Glicose perdidas + Hora de fazer o bólus!\nExecute o assistente de bólus e faça o cálculo novamente. + Pedido + Permissão + Este dispositivo parece não suportar a otimização de bateria na lista de permissões - pode ter problemas de desempenho. + diff --git a/implementation/src/main/res/values-ro-rRO/strings.xml b/implementation/src/main/res/values-ro-rRO/strings.xml new file mode 100644 index 0000000000..66b75b2df0 --- /dev/null +++ b/implementation/src/main/res/values-ro-rRO/strings.xml @@ -0,0 +1,8 @@ + + + Lipsesc date glicemie + Timpul sa faci bolus!\nRuleaza Calculatorul de Bolus pentru a face calculele din nou. + Cerință + Permisiune + Acest dispozitiv nu permite folosirea excluderii din lista de optimizare a bateriei - se poate să întâmpinați probleme de performanță. + diff --git a/implementation/src/main/res/values-ru-rRU/strings.xml b/implementation/src/main/res/values-ru-rRU/strings.xml new file mode 100644 index 0000000000..16b19604e8 --- /dev/null +++ b/implementation/src/main/res/values-ru-rRU/strings.xml @@ -0,0 +1,9 @@ + + + Пропущенные данные СК + Пора дать болюс!\nЗапустите помощник болюса и повторите расчет. + Запрос + Права доступа + Ошибка при запросе разрешения + Это устройство не поддерживает меню оптимизации батареи - могут быть проблемы с производительностью. + diff --git a/implementation/src/main/res/values-sk-rSK/strings.xml b/implementation/src/main/res/values-sk-rSK/strings.xml new file mode 100644 index 0000000000..187c9c8ee0 --- /dev/null +++ b/implementation/src/main/res/values-sk-rSK/strings.xml @@ -0,0 +1,23 @@ + + + xDrip+ nie je nainštalovaný + Kalibrácia odoslaná do xDrip+ + Glykémia + Chýbajúce hodnoty glykémie + Čas na jedlo + Povoliť bolusového poradcu + Pri vysokej glykémii spustiť pripomienku namiesto výsledku z kalkulačky, aby ste začali jesť neskôr (tzv. \"prebolus\") + Bolusový poradca + Máte vysokú glykémiu. Namiesto jedla doporučujeme počkať na lepšiu glykémiu a pripomenúť, keď bude čas na jedlo. Prajete si poslať korekčný bolus a pripomenúť, keď bude čas na jedlo? V tomto prípade nebudú zapísané žiadne sacharidy, a neskôr musíte opäť spustiť kalkulačku, akonáhle vám to pripomenieme. + Čas na bolus!\nSpustite Bolusovú kalkulačku a urobte výpočet znova. + Príkaz sa práve vykonáva + Hodnota bazálu pod povoleným minimom. Profil nenastavený! + Požiadavka + Povolenie + %1$s potrebuje vypnúť optimalizáciu batérie pre optimálny výkon + Aplikácia vyžaduje pre oznámenia systémové oprávnenie + Aplikácia vyžaduje oprávnenie polohy, pre vyhľadávanie BT a identifikáciu WiFi + Aby bolo možné nahrávať logy a exportovať nastavenia, je nutné pre aplikáciu povoliť oprávnenie prístupu k úložisku + Chyba pri žiadosti o oprávnenie + Toto zariadenie zrejme neumožňuje vypnúť optimalizáciu batérie - môže dochádzať k problémom s výkonom. + diff --git a/implementation/src/main/res/values-sr-rCS/strings.xml b/implementation/src/main/res/values-sr-rCS/strings.xml new file mode 100644 index 0000000000..474373efd0 --- /dev/null +++ b/implementation/src/main/res/values-sr-rCS/strings.xml @@ -0,0 +1,4 @@ + + + Čini se da ovaj uređaj ne podržava stavljanje na belu listu za optimizaciju baterije – mogli biste imati problema s performansama. + diff --git a/implementation/src/main/res/values-sv-rSE/strings.xml b/implementation/src/main/res/values-sv-rSE/strings.xml new file mode 100644 index 0000000000..a3d1bddb09 --- /dev/null +++ b/implementation/src/main/res/values-sv-rSE/strings.xml @@ -0,0 +1,8 @@ + + + BG-värden saknas + Dags för bolus!\nKör Bolusguiden och gör beräkningar igen. + Begäran + Behörighet + Denna enhet verkar inte ha stöd för vitlistning från batterioptimering. Du eventuellt råka ut för problem pga detta. + diff --git a/implementation/src/main/res/values-tr-rTR/strings.xml b/implementation/src/main/res/values-tr-rTR/strings.xml new file mode 100644 index 0000000000..266ea65485 --- /dev/null +++ b/implementation/src/main/res/values-tr-rTR/strings.xml @@ -0,0 +1,23 @@ + + + xDrip+ uygulaması yüklenmemiş + Kalibrasyon xDrip+ a gönderildi + + Kaçırılan KŞ Okumaları + Yemek zamanı + Bolus danışmanını etkinleştir + Yüksek glisemi sırasında sihirbaz sonucu yerine daha sonra yemeye başlamak için hatırlatıcı kullanın (\"pre-bolus\") + Bolus danışmanı + Yüksek glisemiksiniz. Şimdi yemek yemek yerine daha iyi glisemi beklemeniz önerilir. Şimdi bir düzeltme bolusu yapmak ve yemek zamanı geldiğinde size hatırlatmak ister misiniz? Bu durumda karbonhidrat kaydı yapılmaz ve size hatırlattığımızda sihirbazı tekrar kullanmanız gerekir. + Bolus zamanı!\nBolus sihirbazını çalıştırın ve yeniden hesaplama yapın. + Komut şu anda çalıştırıldı + Bazal değer minimumun altında. Profil ayarlanmadı! + İstek + Yetki + %1$s, düzgün bir şekilde çalışması için pil optimizasyonu yapılmalıdır + Uygulama, bildirimler için sistem iznine ihtiyaç duyuyor + Uygulamanın BT taraması ve WiFi tanımlaması için konum iznine ihtiyacı var + Uygulamanın, günlük dosyalarını saklayabilmesi ve ayarları dışa aktarabilmesi için depolama iznine ihtiyacı var + İzin istenirken hata + Bu cihaz, program için pil optimizasyonunu desteklemiyor gibi görünüyor - performans sorunları yaşayabilirsiniz. + diff --git a/implementation/src/main/res/values-zh-rCN/strings.xml b/implementation/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000000..ed66795bec --- /dev/null +++ b/implementation/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,8 @@ + + + 血糖读数丢失 + 输注胰岛素时间到了!\n请运行大剂量向导,然后再次进行计算。 + 请求 + 权限 + 此设备似乎不支持电池优化白名单 - 您可能会遇到性能问题。 + diff --git a/openhumans/src/main/res/values-tr-rTR/strings.xml b/openhumans/src/main/res/values-tr-rTR/strings.xml index 25fbb8e6c1..84eba7359d 100644 --- a/openhumans/src/main/res/values-tr-rTR/strings.xml +++ b/openhumans/src/main/res/values-tr-rTR/strings.xml @@ -12,6 +12,7 @@ Yalnızca şarj olurken yükleyin Open Humans Yükleniyor… Open Humans Bildirimleri + AAPS, Open Humans\'a yükleniyor. Bu biraz zaman alabilir. Open Humans\'dan çıkış yaptınız Bu bilerek yapılmadıysa tekrar oturum açmak için burayı tıklayın. Şimdi yükle diff --git a/plugins/src/main/res/values-af-rZA/strings.xml b/plugins/src/main/res/values-af-rZA/strings.xml new file mode 100644 index 0000000000..20fec0ff5f --- /dev/null +++ b/plugins/src/main/res/values-af-rZA/strings.xml @@ -0,0 +1,40 @@ + + + + SMS Communicator + SMS + Toegelate telefoon nommers + +XXXXXXXXXX;+YYYYYYYYYY + Om kalibrasie %1$.2f te stuur antwoord met kode %2$s + Bolus het misluk + Laat afstandbeheerde bevele toe via SMS + Loop is gedeaktiveer + Loop is geaktiveerd + Lus geaktiveer + Afstandbeheerde bevel word nie toegelaat nie + Afstandbeheerde bolus nie beskikbaar nie. Probeer later weer. + Om profiel te verander na %1$s %2$d%% antwoord met %3$s + Om basal e %1$d%% vir %2$d min te begin kies %3$s + Om lus op te skort vir %1$d minute antwoord met kode %2$s + Temp basale %1$.2fU/h vir %2$d min suksesvol geaktiveerd + Verlengde bolus %1$.2fU vir %2$d min is begin + Tydelike basale %1$d%% vir %2$d min hardloop + Tydelike basale aktivering het gefaal + Verlengde bolus het misluk + Stop tydelike basale antwoord met kode %1$s + Stop tydelike basale antwoord met kode %1$s + Tydelike basale gekanselleer + Verlengde bolus gekanselleer + Kansellassie van tydelike basale het gefaal + Kansellasie van verlengde bolus het misluk + Onbekende opdrag of verkeerde opsie + Verkeerde duur + Lus opgeskort + Lus hervat + Ongeldige SMS selfoon nommer + Ongeldig boodskap teks + Delta: + IAB: + Bolus: + Basale: + diff --git a/plugins/src/main/res/values-bg-rBG/strings.xml b/plugins/src/main/res/values-bg-rBG/strings.xml new file mode 100644 index 0000000000..d1c9478802 --- /dev/null +++ b/plugins/src/main/res/values-bg-rBG/strings.xml @@ -0,0 +1,88 @@ + + + + SMS комуникатор + SMS + от приложението AUTHENTICATOR за: %1$s , последвано от PIN + Допълнителен PIN в края на токен + Допълнителни цифри, които следва да бъдат залепени в края на всяка генерирана еднократна парола + Код за проверка: + OTP + PIN + Кодът за проверката се състои от 6 цифри, от приложението за аудиентикация (известно като OTP), следвани от 3 или повече цифри на задължителния PIN. + Нулиране на удостоверители + Нулиране на ключва + Сигурни ли сте, че ще анулирате ключа на Authenticator? Той ще направи всички конфигурирани в момента аудиентикатори невалидни, и вие ще трябва да ги настроите отново. + Генериран е нов ключ! Моля, използвайте актуализирания QRCode. + Експортиране на OTP парола + Сигурни ли сте, че искате да копирате OTP паролата в клипборда?\n\nВие може да се нуждаете само от това, ако вашето приложение за автентичност има проблеми със сканирането на QRCode, искате да го въведете ръчно или искате да конфигурирате хардуерен OTP токен чрез специално приложение. + OTP парола (във Base32 формат) е експортирана и копирана в клипборда. Поставете го в автентикатор или хардуерен OTP! + 1. Инсталиране на удостоверител + 3. Тест на еднократна парола + Нулиране на удостоверители + На всеки следящ телефона инсталирайте приложение Аутентификатор, който поддържа RFC 6238 ТОТР токени. Популярни безплатни приложения:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Потребител + Разрешени телефонни номера + +XXXXXXXXXX;+YYYYYYYYYY + Зa zадаване на временна цел %1$s отговорете с код %2$s + За да спрете временната цел отговорете с код %1$s + За да изключите услугата за отдалечен SMS контрол отговорете с код %1$s.\n\nИмайте предвид, че можете да го активирате само от AAPS смартфона. + Отдалечен SMS контрол е изключен. Можете да го включите от AndroidAPS телефона. + За да изпратите калибрация %1$.2f отговорете с код %2$s + Болус отказан + Минимално време в минути, което трябва да е изминало след отдалечен болус, преди да може да бъде доставен следващият + Колко най-малко минути трябва да минат между доставката на два болуса + За вашата сигурност, променете тази настройка, трябва да добавите най-малко 2 телефонни номера. + Болус от %1$.2fЕ доставен успешно + Болус от %1$.2fЕ доставен успешно + Временна цел от %1$s за %2$d минути + Временна цел от %1$s за %2$d минути стартирана успешно + Временна цел успешно спряна + Позволи отдалечени команди чрез SMS + APS е деактивиран + APS е активиран + APS е включен + За свързване с помпа отговорете с код %1$s + Връзката с помпата е неуспешна + За да спрете помпата за %1$d минути отговорете с код %2$s + Помпата е разкачена + Връзката с помпа е възстановена + Отдалеченото управление е забранено + Отдалечено стартиране на болус не е възможно. Опитайте отново по-късно. + За да стартирате базал от %1$.2fЕ/ч за %2$d мин отговорете с код %3$s + За да превключите профила към %1$s %2$d%% отговорете с код %3$s + За да започнете удължен болус %1$.2fЕ за %2$d мин отговорете с код %3$s + За да въведете %1$dг в %2$s отговорете с код %3$s + За да стартирате базал от %1$d%%Е/ч за %2$d мин отговорете с код %3$s + За да спрете APS за %1$d минути отговорете с код %2$s + За възстановяване на кръга отговорете с код %1$s + За активирнае на кръга отговорете с код %1$s + За изключване на кръга отговорете с код %1$s + Временен базал от %1$.2fЕ/ч за %2$d мин стартиран успешно + Удължен болус %1$.2fU за %2$d мин стартиран успешно + Въглехидрати %1$dг въведени + Въвеждане на%1$dг въглехидрати - НЕУСПЕШНО + Временен базал от %1$d%%Е/ч за %2$d мин стартиран успешно + Неуспешно стартиране на временен базал + Неуспешно стартиране на удължен болус + За да спрете времен базал отговорете с код %1$s + За да спрете удължения болус отговорете с код %1$s + Временният базал е отменен + Удължен болус спрян + Спирането на временния базал е неуспешно + Неуспешно спиране на удължен болус + Непозната команда или грешен отговор + В момента се обработва друг болус. Моля опитай по-късни. + Грешна продължителност + APS забранен + APS възобновен + Грешен тел номер за SMS + Калибрацията е изпратена. Получаването трябва да бъде разрешено в xDrip +. + xDrip+ не получава калибрации + Невалиден текст на съобщение + Изпращане на SMS, ако помпата е недостъпна + Докладвай недостъпна помпа + Изменение (делта): + IOB: + Болус: + Базал: + diff --git a/plugins/src/main/res/values-ca-rES/strings.xml b/plugins/src/main/res/values-ca-rES/strings.xml new file mode 100644 index 0000000000..eb3dd14d3e --- /dev/null +++ b/plugins/src/main/res/values-ca-rES/strings.xml @@ -0,0 +1,88 @@ + + + + Comunicador SMS + SMS + de l\'app d\'autenticació per: %1$s seguit per PIN + PIN obligatori addicional al final del token + Dígits addicionals que han de ser memoritzats i afegits al final de cada clau d\'un sol ús + Codi per comprovar: + OTP + PIN + El codi de verificació consta de 6 dígits mostrats per l\'app Autenticador (coneguts com OTP), seguits de 3 o més dígits del PIN obligatori. + Restablir autenticadors + Restablir clau d\'Autenticador + Esteu segurs que voleu restablir la clau de l\'Autenticador (OTP)? Els Autenticadors configurats fins ara deixaran de ser vàlids i els haureu de tornar a configurar. + Nova clau d\'Autenticador generada! Utilitzeu QRCode actualitzat per aprovisionar autenticadors. + Exportant secret OTP + Esteu segurs que voleu copiar el secret OTP al porta-retalls (clipboard)?\n\nNomés és necessari si la vostra app d\'autenticació te problemes per escanejar el QRCode, si voleu introduir-lo manualment o si voleu configurar un token OTP hardware amb una app dedicada. + Secret OTP (en format Base32) exportat i copiat al porta-retalls. Enganxeu-lo a l\'autenticador o gravador hardware d\'OTP! + 1. Instal·lar autenticador + 3. Provar clau d\'un sol ús + Restablir autenticadors + Instal·leu a cada telèfon seguidor una app d\'autenticació compatible amb tokens RFC 6238 TOTP. Apps gratuites populars:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Usuari + Nrs. de telèfon permesos + +XXXXXXXXXX;+YYYYYYYYYY + Per definir un Objectiu Temporal %1$s contesteu amb el codi %2$s + Per cancel·lar Objectiu Temporal contesteu amb el codi %1$s + Per desactivar el Servei Remot d\'SMS contesteu amb el codi %1$s.\n\nRecordeu que només el podreu reactivar des del mòbil amb AAPS principal. + Servei Remot d\'SMS aturat. Per reactivar-lo, utilitzeu AAPS des del mòbil principal. + Per enviar calibració %1$.2f contesteu amb el codi %2$s + Error de bolus + Mínim nr. de minuts que han de passar entre un bolus remot i el següent + Quants minuts han de passar, com a mínim, entre un bolus i el següent + Per la vostra seguretat, per editar aquesta configuració haureu d\'afegir al menys 2 nrs. de telèfon. + Bolus %1$.2f U llliurat correctament + Bolus d\'àpat %1$.2f U lliurat correctament + Objectiu %1$s per %2$d minuts + Objectiu %1$s per %2$d minuts definit correctament + Objectiu Temporal cancel·lat correctament + Permetre ordres remotes via SMS + El llaç s\'ha desactivat + El llaç s\'ha activat + Llaç activat + Per connectar la bomba, contesteu amb el codi %1$s + La connexió a la bomba ha fallat + Per desconnectar la bomba %1$d minuts contesteu amb el codi %2$s + Bomba desconnectada + Bomba reconnectada + Ordre remota no permesa + Bolus remot no disponible. Torneu-ho a intentar més tard. + Per iniciar basal de %1$.2f U/h durant %2$d min. contesteu amb el codi %3$s + Per canviar el perfil a %1$s %2$d%% contesteu amb el codi %3$s + Per iniciar bolus estès de %1$.2f U durant %2$d min. contesteu amb el codi %3$s + Per introduir %1$dg en %2$s contesteu amb el codi %3$s + Per iniciar basal %1$d%% durant %2$d min. contesteu amb el codi %3$s + Per interrompre el llaç durant %1$d minuts contesteu amb el codi %2$s + Per reprendre el llaç contesteu amb el codi %1$s + Per activar el llaç contesteu amb el codi %1$s + Per desactivar el llaç contesteu amb el codi %1$s + Basal temporal %1$.2fU/h durant %2$d min iniciada correctament + Bolus estès %1$.2fU durant %2$d min iniciat correctament + Carbs %1$d g introduïts correctament + Error en introduir %1$dg de carbs + Basal temporal %1$d%% durant %2$d min iniciada ok + Error en iniciar basal temporal + Error en iniciar bolus estès + Per aturar basal temporal contesteu amb el codi %1$s + Per aturar bolus estès contesteu amb el codi %1$s + Basal temporal cancel·lada + Bolus estès cancel·lat + Error en cancel·lar basal temporal + Error en cancel·lar bolus estès + Ordre desconeguda o resposta incorrecta + Hi ha un altre bolus en cua. Proveu més tard. + Durada errònia + Llaç aturat + Llaç reprès + Número de telf. per SMS no vàlid + Calibració enviada. Cal que la recepció a xDrip+ estigui activada. + xDrip+ no està rebent calibracions + Cos de missatge incorrecte + Enviar SMS si es produeix esdeveniment de bomba inaccessible + Reportar bomba inaccessible + Delta: + IOB: + Bolus: + Basal: + diff --git a/plugins/src/main/res/values-cs-rCZ/strings.xml b/plugins/src/main/res/values-cs-rCZ/strings.xml new file mode 100644 index 0000000000..078f37105c --- /dev/null +++ b/plugins/src/main/res/values-cs-rCZ/strings.xml @@ -0,0 +1,105 @@ + + + + SMS komunikátor + SMS + Vzdálené ovládání AAPS pomocí SMS příkazů. + z aplikace Authenticator pro: %1$s následováno kódem PIN + Další povinný kód PIN na konci tokenu + Další číslice, které by měly být zapamatovány a přidány na konec každého vygenerovaného jednorázového hesla + Nastavení Autentikátoru + Kód pro kontrolu: + OTP + PIN + Ověřovací kód se skládá ze 6 číslic zobrazených aplikací Authenticator (známé jako OTP) následované 3 nebo více číslicemi povinného kódu PIN. + Resetovat autentikátory + Resetovat klíč pro autentikátory + Opravdu chcete obnovit ověřovací klíč? Vyresetujete všechny aktuálně nakonfigurované autentikátory a budete je muset znovu nastavit. + Byl vygenerován nový klíč autentikátoru! Prosím, použijte aktualizovaný QR kód pro nastavení autentikátorů. + Export OTP tajného klíče + Jste si jisti, že chcete zkopírovat tajný OTP klíč do schránky?\n\nPravděpodobně to budete potřebovat pouze v případě, když bude mít vaše ověřovací aplikace problém se skenováním QR kodu, chcete ho zadat ručně, nebo chcete nakonfigurovat hardwarový OTP token pomocí specializované aplikace. + Tajné OTP heslo (ve formátu Base32) bylo vyexportováno a zkopírováno do schránky. Vložte ho do autentikátoru nebo programátoru OTP hardwaru! + 1. Nainstalujte Autentikátor + 2. Naskenujte kód pro nastavení kódů OTP AAPS + 3. Otestujte jednorázové heslo + Resetovat autentikátory + Na každém sledovacím telefonu nainstalujte Authentikátor, který podporuje tokeny TOTP RFC 6238. Nejoblíbenější bezplatné aplikace jsou:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Obnovením autentikátoru uděláte všechny již poskytnuté autentikátory neplatné. Budete je muset znovu nastavit! + Nesprávný kód. Příkaz zrušen. + Vypršel časový limit při čekání na dokončení předchozí komunikace s pumpou + Uživatel + Povolená tel. čísla + +XXXXXXXXXX;+YYYYYYYYYY + K potvrzení bolusu %1$.2fU odpověz SMS s kódem %2$s + Pro potvrzení bolusu na jídlo %1$.2fU odpovězte pomocí SMS s kódem %2$s + Pro nastavení dočasného cíle %1$s odpovězte pomocí SMS s kódem %2$s + Pro zrušení dočasného cíle odpovězte pomocí SMS s kódem %1$s + Chcete-li deaktivovat Vzdálené řízení přes SMS, odpovězte pomocí SMS s kódem %1$s.\n\nUpozornění: tuto funkci budete moci znovu aktivovat pouze z telefonu s hlavní verzí AAPS. + Služba Vzdáleného řízení přes SMS zastavena. Chcete-li ji znovu aktivovat, použijte telefon s hlavní verzí AAPS. + Odeslání kalibrace %1$.2f potvrďte kódem %2$s + Chyba při aplikování bolusu + Minimální počet minut, které musí uplynout mezi dvěma bolusy podanými přes vzdálené řízení + Kolik minut (minimálně) musí uplynout mezi dvěma bolusy + Úprava tohoto nastavení v zájmu vaší bezpečnosti vyžaduje, abyste zadali alespoň 2 telefonní čísla. + Bolus %1$.2f U aplikován úspěšně + Bolus na jídlo %1$.2f U byl úspěšně aplikován + Cíl %1$s na %2$d minut + Cíl %1$s na %2$d minut byl úspěšně nastaven + Dočasný cíl byl úspěšně zrušen + Povolit posílání příkazů přes SMS + Smyčka byla zakázána + Smyčka byla povolena + Smyčka je povolena + Chcete-li připojit pumpu, odpovězte pomocí SMS s kódem %1$s + Připojení k pumpě selhalo + Chcete-li odpojit pumpu na %1$d minut, odpovězte pomocí SMS s kódem %2$s + Pumpa odpojena + Pumpa byla znovu připojena + Vzdálený příkaz není povolen + Vzdálený bolus není momentálně povolen. Zkuste to později. + Pro spuštění bazálu %1$.2f U/h na %2$d min odpovězte SMS s kódem %3$s + Pro přepnutí profilu na %1$s %2$d%% odpovězte SMS s kódem %3$s + Pro spuštění prodlouženého bolusu %1$.2f U na %2$d min odpovězte SMS s kódem %3$s + Pro zadání %1$dg na %2$s odpovězte pomocí SMS s kódem %3$s + Pro spuštění bazálu %1$d%% na %2$d min odpovězte SMS s kódem %3$s + K pozastavení smyčky na %1$d minut odpověz SMS s kódem %2$s + Chcete-li obnovit smyčku, odpovězte SMS s kódem %1$s + Chcete-li povolit smyčku, odpovězte SMS s kódem %1$s + Chcete-li zakázat smyčku, odpovězte SMS s kódem %1$s + Dočasný bazál %1$.2fU/h na %2$d minut spuštěn + Prodloužený bolus %1$.2fU na %2$d min úspěšně spuštěn + Sacharidy %1$d g byly úspěšně zadány + Zadání %1$d g sacharidů se nezdařilo + Dočasný bazál %1$d%% na %2$d minut úspěšně spuštěn + Spuštění dočasného bazálu selhalo + Spuštění prodlouženého bolusu selhalo + Na zastavení dočasného bazálu odpovězte SMS s kódem %1$s + Pro zastavení prodlouženého bolusu odpovězte SMS s kódem %1$s + Dočasný bazál zastaven + Prodloužený bolus zastaven + Rušení dočasného bazálu selhalo + Zastavení prodlouženého bolusu selhalo + Neznámý příkaz nebo chybná odpověď + Ve frontě je další bolus. Zkuste to znovu později. + Chybná doba trvání + Smyčka pozastavena + Smyčka obnovena + Špatné telefonní číslo + Kalibrace odeslána. Příjem musí být v xDripu+ povolený. + xDrip+ nepřijímá kalibrace + Neplatné tělo zprávy + Odeslat SMS, pokud je detekována nedostupná pumpa + Nahlásit nedostupnou pumpu + Chybný formát + Glykémie: + Poslední glykémie: + Rozdíl: + IOB: + Bolus: + Bazál: + před %1$d min + Pozastaveno (%1$d min) + Načtení stavu selhalo + Přepnutí profilu vytvořeno + Trvání dočasného bazálu musí být násobkem %1$d minut a musí být větší než 0. + QR kód pro nastavení jednorázového hesla + diff --git a/plugins/src/main/res/values-da-rDK/strings.xml b/plugins/src/main/res/values-da-rDK/strings.xml new file mode 100644 index 0000000000..25ab50b94b --- /dev/null +++ b/plugins/src/main/res/values-da-rDK/strings.xml @@ -0,0 +1,91 @@ + + + + SMS Kommunikator + SMS + Fjernstyr AndroidAPS ved hjælp af SMS-kommandoer. + fra Authenticator app til: %1$s efterfulgt af PIN + Yderligere obligatorisk pinkode i slutningen + Yderligere cifre, der skal huskes og påsættes i slutningen af hver genereret engangsadgangskode + Kode, der skal kontrolleres: + OTP + PIN + Bekræftelseskoden består af 6 cifre som vises af Autentificerings-app (kendt som OTP) efterfulgt af 3 eller flere cifre i obligatorisk PIN-kode. + Nulstil Autentificering + Nulstil Autentificeringsnøgle + Er du sikker på at du vil nulstille autentificeringsnøgle? Det vil gøre alle aktuelt konfigurerede autentificatorer ugyldige, og du bliver nødt til at sætte dem op igen. + Ny autentificeringsnøgle blev genereret! Brug venligst opdateret QR kode til at levere autentificatorer. + Eksporterer OTP hemmelighed + Er du sikker på, at du vil kopiere OTP hemmelighed til udklipsholderen?\n\nDu behøver den kun, hvis din autentificeringsapp har problemer med at scanne QR kode, du vil indtaste den manuelt, eller du vil konfigurere hardware OTP token ved hjælp af en dedikeret app. + OTP hemmelige (i Base32 format) eksporteret og kopieret til udklipsholder. Indsæt det i autentifikatoren eller hardware OTP brænder! + 1. Installer Authenticator + 2. Scan kode for at opsætte AAPS OTP-koder + 3. Test Engangsadgangskode + Nulstil Autentificering + På hver follower telefon installeres Authenticator app, der understøtter RFC 6238 TOTP tokens. Populære gratis apps er:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Bruger + Tilladte telefonnumre + +XXXXXXXXXX;+YYYYYYYY + For at indstille midlertidig mål %1$s svar med koden %2$s + For at annullere midlertidig mål, svar med koden %1$s + For at deaktivere SMS fjernstyring svar med koden %1$s.\n\nHusk på, at du kun vil være i stand til at genaktivere den direkte fra AAPS-master-smartphone. + SMS fjernstyring stoppet. For at genaktivere det, brug AAPS på master smartphone. + For at sende kalibrering %1$.2f svar med kode %2$s + Bolus mislykkedes + Mindste antal minutter, der skal gå mellem én fjernbolus og den næste + Hvor mange minutter der mindst skal gå mellem en bolus og den næste + Af hensyn til din sikkerhed, skal du tilføje mindst 2 telefonnumre for at redigere denne præference. + Bolus %1$.2fIE leveret succesfuldt + Måltidsbolus %1$.2f IE leveret uden fejl + Mål %1$s i %2$d minutter + Mål %1$s i %2$d minutter er angivet succesfuldt + Midlertidig mål er annulleret succesfuldt + Tillad fjernkommandoer via SMS + Loop er blevet deaktiveret + Loop er blevet aktiveret + Loop er aktiveret + For at forbinde pumpen svar med koden %1$s + Forbindelse til pumpe mislykkedes + For at frakoble pumpen i %1$d minutter, svar med kode %2$s + Pumpe afbrudt + Pumpe tilsluttet igen + Fjernkommandoen er ikke tilladt + Fjernbolus er ikke tilgængelig. Prøv igen senere. + For at starte basal %1$.2f E/t i %2$d minutter svar med kode %3$s + For at skifte profil til %1$s %2$d%% svar med kode %3$s + For at starte udvidet bolus %1$.2f IE i %2$d minnutter svar med koden %3$s + For at indtaste %1$dg ved %2$s svar med kode %3$s + For at starte basal %1$d%% i %2$d minutter svar med kode %3$s + For at suspendere loop i %1$d minutter svar med kode %2$s + For at genoptage loop svar med koden %1$s + For at aktivere loop svar med kode %1$s + For at deaktivere loop, svar med kode %1$s + Temp basal %1$.2fE/t i %2$d min startet med succes + Udvidet bolus %1$.2f IE for %2$d min er startet succesfuldt + Kulhydrater %1$d g angivet med succes + Indtastning af %1$dg kulhydrater mislykkedes + Midlertidig basal %1$d%% E/t i %2$d min startet med succes + Midlertidig basal start mislykkedes + Udvidet bolus start mislykkedes + For at annullere midlertidig blodsukkermål, svar med kode %1$s + For at stoppe forlænget bolus svar med koden %1$s + Midlertidig basal annulleret + Forlænget bolus annulleret + Annullering af midlertidig basal mislykkedes + Annullering af forlænget bolus mislykkedes + Ukendt kommando eller forkert svar + Der er en anden bolus i kø. Prøv igen senere. + Forkert varighed + Loop suspenderet + Loop genoptaget + Ugyldigt SMS telefonnummer + Kalibrering sendt. Modtagelse skal være aktiveret i xDrip+. + xDrip+ modtager ikke kalibreringer + Ugyldigt beskedindhold + Send sms, hvis der udløses en utilgængelig pumpebegivenhed + Rapportér pumpe utilgængeligt + Delta: + IOB: + Bolus: + Basal: + QR-kode til opsætning af engangs kodeord + diff --git a/plugins/src/main/res/values-de-rDE/strings.xml b/plugins/src/main/res/values-de-rDE/strings.xml new file mode 100644 index 0000000000..638e5ecaac --- /dev/null +++ b/plugins/src/main/res/values-de-rDE/strings.xml @@ -0,0 +1,89 @@ + + + + SMS-Kommunikator + SMS + von der Authenticator App für: %1$s gefolgt von der PIN + Zusätzliche obligatorische PIN am Token-Ende + Zusätzliche Ziffern, die auswendig gelernt und am Ende jedes generierten Einmal-Passworts angehängt werden sollten. + Zu prüfender Code: + OTP + PIN + Der Verifizierungscode besteht aus 6 Ziffern, die von Authenticator App (auch OTP genannt) angezeigt werden, gefolgt von 3 oder mehr Ziffern der obligatorischen PIN. + Authentifikators zurücksetzen + Authentifikatorschlüssel zurücksetzen + Willst Du wirklich den Authentifikatorschlüssel zurücksetzen? Dies wird alle momentan genutzten Authentifikatoren ungültig machen und Du musst sie neu einrichten. + Neuer Authentifizierungsschlüssel generiert! Bitte verwende den aktualisierten QR-Code für die Bereitstellung von Authentifikatoren. + OTP-Secret exportieren + Willst Du wirklich das OTP Secret in die Zwischenablage kopieren?\n\nDas ist nur erforderlich, wenn Deine Authentifizierungs-App Probleme mit dem Scannen des QR-Codes hat. Du kannst es auch manuell eingeben oder einen Hardware-OTP-Token mit einer bestimmten App verwenden. + OTP Secret (im Base32 Format) exportiert und in die Zwischenablage kopiert. Setze es von dort in Deine Authentifizierungs-App ein. + 1. Authentifikator installieren + 3. Teste das Einmal-Passwort + Authentifikators zurücksetzen + Installiere auf jedem Follower-Phone eine Authenticator-App, die RFC 6238 TOTP-Token unterstützt. Beliebte kostenlose Apps sind:\n Authy\n Google Authenticator\n LastPass Authenticator\n FreeOTP Authenticator + Nutzer + Erlaubte Telefonnummern + +XXXXXXXXXX;+YYYYYYYYYY + Um ein temporäres Ziel von %1$s zu setzen, antworte mit dem Code %2$s + Um das temporäre Ziel zu stoppen, antworte mit dem Code %1$s + Um die SMS-Fernsteuerung zu deaktivieren, antworte mit dem Code %1$s\n\nBeachte, dass Du diesen nur am AAPS-Master-Smartphone wieder aktivieren kannst. + SMS-Fernsteuerung gestoppt. Verwende das AAPS-Master-Smartphone, um sie wieder zu aktivieren. + Um die Kalibrierung %1$.2f zu senden, antworte mit dem Code %2$s. + Bolus fehlgeschlagen + Minimale Dauer in Minuten, die nach einem Remote-Bolus verstrichen sein muss, bevor ein neuer abgegeben werden kann. + Anzahl der Minuten, die mindestens zwischen zwei Remote-Bolusabgaben liegen müssen. + Aus Sicherheitsgründen musst Du mindestens zwei Telefonnummern eintragen, um diese Voreinstellung zu ändern. + Bolus %1$.2f IE erfolgreich abgegeben + Mahlzeiten-Bolus %1$.2f IE erfolgreich abgegeben + Ziel %1$s für %2$d Minuten + Ziel %1$s für %2$d Minuten erfolgreich gesetzt. + Temporäres Ziel wurde erfolgreich abgebrochen + Erlaube Fernsteuerung per SMS + Loop wurde deaktiviert. + Lopp wurde aktiviert. + Loop ist aktiviert. + Um die Pumpe zu verbinden, antworte mit dem Code %1$s + Verbindung zur Pumpe fehlgeschlagen + Um die Verbindung zur Pumpe für %1$d Minuten zu trennen, antworte mit dem Code %2$s + Verbindung zur Pumpe getrennt + Verbindung zur Pumpe wiederhergestellt + Ferngesteuerte Befehle sind nicht erlaubt. + Bolusabgabe aus der Ferne nicht verfügbar. Versuche es später erneut. + Um eine Basalrate von %1$.2f IE/h für %2$d Minuten zu setzen, antworte mit dem Code %3$s + Um das Profil auf %1$s %2$d%% zu setzen, antworte mit dem Code %3$s + Um einen Verzögerungs-Bolus von %1$.2f IE über %2$d Minuten abzugeben, antworte mit dem Code %3$s + Um %1$dg Kohlenhydrate um %2$s einzugeben, antworte mit dem Code %3$s + Um die Basalrate von %1$d%% für %2$d Minuten zu setzen, antworte mit dem Code %3$s + Um das Loopen für %1$d Minuten zu pausieren, antworte mit dem Code %2$s. + Um den Loop fortzusetzen, antworte mit dem Code %1$s + Um den Loop zu aktivieren, antworte mit dem Code %1$s + Um den Loop zu deaktivieren, antworte mit dem Code %1$s + TBR mit %1$.2f IE/h für %2$d min wurde erfolgreich gestartet. + Der erweiterte Bolus %1$.2f IE/h für %2$d Minuten wurde erfolgreich gestartet + %1$d g Kohlenhydrate erfolgreich erfasst + Eingabe von %1$d g Kohlenhydraten ist fehlgeschlagen. + Die temporäre Basalrate wurde erfolgreich für %2$d Minuten auf %1$d%% gesetzt. + Das Starten der TBR ist fehlgeschlagen. + Die Abgabe des erweiterten Bolus ist fehlgeschlagen. + Antworte mit dem Code %1$s, um die temporäre Basalrate zu beenden. + Antworte mit dem Code %1$s, um den erweiterten Bolus zu beenden. + TBR abgebrochen + Die Abgabe des erweiterten Bolus wurde abgebrochen. + Das Abbrechen der TBR ist fehlgeschlagen. + Der Abbruch des erweiterten Bolus ist fehlgeschlagen. + Unbekannter Befehl oder falsche Antwort + In der Warteschlange befindet sich ein weiterer Bolus. Bitte später erneut versuchen. + Falsche Dauer + Loop pausiert + Loop wurde fortgesetzt + Falsche/ungültige Telefonnummer + Kalibrierung gesendet. Das Empfangen von Kalbrierungen muss in xDrip+ aktiviert sein+. + xDrip+ erhält keine Kalibrierungen + Ungültiger Inhalt + SMS senden, wenn Pumpe nicht erreichbar + Hinweis Pumpe nicht erreichbar + Delta: + IOB: + Bolus: + Basal: + QR Code für einmaliges Passwort einrichten + diff --git a/plugins/src/main/res/values-el-rGR/strings.xml b/plugins/src/main/res/values-el-rGR/strings.xml new file mode 100644 index 0000000000..7acb63bd0d --- /dev/null +++ b/plugins/src/main/res/values-el-rGR/strings.xml @@ -0,0 +1,67 @@ + + + + SMS Επικοινωνία + SMS + Χρήστης + Επιτρεπτά τηλεφωνικά νούμερα + +XXXXXXXXXX;+YYYYYYYYYY + Για να ορίσετε τον Προσωρινό Στόχο %1$s απαντήστε με κωδικό %2$s + Για να ακυρώσετε Προσωρινό Στόχο απαντήστε με κωδικό %1$s + Για να απενεργοποιήσετε το SMS Απομακρυσμένη Υπηρεσία απαντήστε με κωδικό %1$s.\n\n μπορείτε να το ενεργοποιήσετε ξανά απευθείας μόνο από το AAPS master smartphone. + Η απομάκρυσμένη υπηρεσία SMS σταμάτησε. Για να την ενεργοποιήσετε πάλι, χρησιμοποιήστε το AAPS στο κύριο τηλέφωνο. + Για αποστολή καλιμπραρίσματος %1$.2f στείλτε με κωδικό %2$s + Αποτυχία Bolus + Ελάχιστος χρόνος σε λεπτά που πρέπει να μεσολαβήσει μεταξύ μίας απομακρυσμένης έγχυσης (bolus) και της επόμενης + Πόσα λεπτά, τουλάχιστον, πρέπει να μεσολαβήσουν μεταξύ μιας έγχυσης (bolus) και της επόμενης + Για την ασφάλειά σας, για να επεξεργαστείτε αυτή την προτίμηση πρέπει να προσθέσετε τουλάχιστον 2 αριθμούς τηλεφώνου. + Bolus %1$.2fU δόθηκε επιτυχώς + Γευματική Bolus %1$.2fU μονάδες δόθηκε επιτυχώς + Στόχος %1$s για %2$d λεπτά + Στόχος %1$s για %2$d λεπτά ορίστηκε με επιτυχία + Ο προσωρινός στόχος ακυρώθηκε με επιτυχία + Άδεια για απομακρυσμένες εντολές μέσω SMS + Το κύκλωμα απενεργοποιήθηκε + Το κύκλωμα ενεργοποιήθηκε + Κύκλωμα ενεργοποιημένο + Για να συνδέσετε την αντλία απαντήστε με κωδικό %1$s + Αποτυχία σύνδεσης με την αντλία + Για αποσύνδεση αντλίας για %1$d λεπτά απαντήστε με κωδικό %2$s + Η αντλία αποσυνδέθηκε + Η αντλία επανασυνδέθηκε + Δεν επιτρέπεται απομακρυσμένη εντολή + Απομακρυσμένο bolus μη διαθέσιμο. Δοκιμάστε ξανά αργότερα. + Για έναρξη βασικού %1$.2fU/h για %2$d λεπτά απαντήστε με κωδικό %3$s + Για αλλαγή προφίλ σε %1$s %2$d%% στείλτε κωδικό %3$s + Για έναρξη εκτεταμένου bolus %1$.2fU για %2$d λεπτά απαντήστε με κωδικό %3$s + Για να εισαγάγετε %1$dg στο %2$s απαντήστε με κωδικό %3$s + Για έναρξη βασικού %1$d%% για %2$d λεπτά στείλτε κωδικό %3$s + Για αναστολή κυκλκώματος για %1$d λεπτών στείλτε με κωδικό %2$s + Για να συνεχίσετε το κύκλωμα απαντήστε με κωδικό %1$s + Για να ενεργοποιήσετε το κύκλωμα απαντήστε με κωδικό %1$s + Για να απενεργοποιήσετε το κύκλωμα απαντήστε με κωδικό %1$s + Προσωρινός Ρυθμός %1$.2fU/h για %2$d λεπτά ξεκίνησε επιτυχώς + Εκτεταμένο bolus %1$.2fU για %2$d λεπτά ξεκίνησε επιτυχώς + Υδατάνθρακες %1$d g εισήχθησαν επιτυχώς + Η εισαγωγή %1$dg υδατανθράκων απέτυχε + Προσωρινός Ρυθμός %1$d%% για %2$d λεπτά ξεκίνησε επιτυχώς + Εκκίνηση Προσωρινού Ρυθμού απέτυχε + Έναρξη εκτεταμένου bolus απέτυχε + Για κλείσιμο Προσωρινού Ρυθμού στείλτε κωδικό %1$s + Για κλείσιμο Εκτεταμένου bolus στείλτε κωδικό %1$s + Ο Προσωρινός Ρυθμός ακυρώθηκε + Εκτεταμένο bolus ακυρώθηκε + Ακύρωση Προσωρινού Ρυθμού απέτυχε + Η ακύρωση του Εκτεταμένου bolus απέτυχε + Άγνωστη εντολή ή λάθος απάντηση + Λάθος διάρκεια + Κύκλωμα σε αναστολή + Επαναφορά κυκλώματος + Μη έγκυρος αριθμός τηλεφώνου για SMS + το xDrip+ δεν λαμβάνει βαθμονόμηση + Μη έγκυρο μήνυμα + Διαφορά: + IOB: + Bolus: + Βασικός Ρυθμός: + diff --git a/plugins/src/main/res/values-es-rES/strings.xml b/plugins/src/main/res/values-es-rES/strings.xml new file mode 100644 index 0000000000..e16216dcb7 --- /dev/null +++ b/plugins/src/main/res/values-es-rES/strings.xml @@ -0,0 +1,92 @@ + + + + Comunicador SMS + SMS + Control remoto de AAPS usando comandos SMS. + desde la aplicación de autenticación para: %1$s seguido de PIN + PIN obligatorio adicional al final del token + Los dígitos adicionales se deben memorizar y pegar al final de cada una de las contraseñas generadas por One Time Password + Código para comprobar: + OTP + PIN + El código de verificación consta de 6 dígitos mostrados por la aplicación Authenticator (conocido como OTP) seguido de 3 o más dígitos del PIN obligatorio. + Restablecer autentificadores + Restablecer clave de autentificación + ¿Está seguro de que desea restablecer la clave del autenticador? Los autenticadores configurados actualmente no seran válidos, y tendrá que volver a configurarlos. + ¡Se ha generado una clave de autenticador nueva! Utilice QRCode actualizado para suministrar autenticadores. + Exportando OTP secreto + ¿Estás seguro que deseas copiar el secreto OTP al portapapeles?\n\nSólo lo necesitas si tu aplicación de autentificación tiene problemas para escanear el código QR, quieres introducirlo manualmente o quieres configurar el token de hardware OTP usando una aplicación dedicada. + OTP secreto (en formato Base32) exportado y copiado en portapapeles. Pegalo en el autenticador o grabador hardware OTP! + 1. Instalar autenticador + 2. Escanea el código para configurar los códigos AAPS OTP + 3. Probar la contraseña de Uso único + Restablecer autentificadores + En cada teléfono seguidor, instale la aplicación Authenticator que admita tokens RFC 6238 TOTP. Las aplicaciones gratuitas populares son:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Al reiniciar el autenticador, haces que todos los autenticadores previos no sean válidos. ¡Necesitarás configurarlos de nuevo! + Usuario + Números de teléfono permitidos + XXXXXXXXXX +; + YYYYYYYYYY + Para establecer un basal temporal %1$s responder con el código %2$s + Para cancelar la basal temporal, responder con el código %1$s + Para inhabilitar la respuesta de servicio remoto de SMS, responder con el código %1$s.\n\nTenga en cuenta que solamente será capaz de reactivarlo directamente desde el móvil con la AAPS maestro. + Servicio remoto de SMS detenido. Para reactivarlo, utilice AAPS en el movil maestro. + Para enviar calibración %1$.2f responder con código %2$s + Bolo fallido + Número mínimo de minutos que deben transcurrir entre un bolo remoto y el siguiente + Cuántos minutos deben transcurrir, al menos, entre un bolo y el siguiente + Por su seguridad, para editar esta preferencia es necesario añadir al menos 2 números de teléfono. + Bolo %1$.2fU entregado correctamente + Bolo de comida %1$.2f U entregado correctamente + Objetivo %1$s para %2$d minutos + Objetivo %1$s para %2$d minutos establecido correctamente + Objetivo temporal cancelado correctamente + Permitir comandos remotos vía SMS + El lazo se ha desactivado + El lazo se ha activado + Lazo activo + Para conectar la bomba, responder con el código %1$s + Error al conectar a la bomba + Para desconectar la bomba durante %1$dminutos, responde con el código %2$s + Bomba desconectada + Bomba reconectada + Comando remoto no permitido + El bolo remoto no está disponible. Inténtalo de nuevo más tarde. + Para iniciar una basal de %1$.2fU/h durante %2$d min, responder con el código %3$s + Para cambiar el perfil a %1$s %2$d%% responder con el código %3$s + Para iniciar un bolo extendido de %1$.2fU durante %2$d minutos, responder con el código %3$s + Para introducir %1$dg en %2$s, responder con el código %3$s + Para iniciar una basal de %1$d%% durante %2$d min, responder con el código %3$s + Para suspender el lazo durante %1$d minutos, responde con el código %2$s + Para reanudar el lazo, responde con el código %1$s + Para activar el lazo, responder con el código %1$s + Para desactivar el lazo, responder con el código %1$s + Basal temporal %1$.2fU/h durante %2$d minutos iniciada correctamente + Bolo extendido de %1$.2fU durante %2$d minutos se inició correctamente + Carbohidratos %1$d g ingresados correctamente + Error al introducir %1$dg de carbohidratos + Basal temporal de %1$d%% durante %2$d minutos iniciada correctamente + Error al iniciar la basal temporal + Error al iniciar el bolo extendido + Para cancelar la basal temporal, responder con el código %1$s + Para parar el bolo extendido, responder con el código %1$s + Basal temporal cancelada + Bolo extendido cancelado + Error al cancelar la basal temporal + Error al cancelar el bolo extendido + Comando desconocido o respuesta incorrecta + Hay otro bolo en cola. Inténtalo de nuevo más tarde. + Duración incorrecta + Lazo suspendido + Lazo reanudado + Número de teléfono incorrecto para SMS + Calibración enviada. La recepción debe estar habilitada en xDrip+. + xDrip+ no está recibiendo calibraciones + El cuerpo del mensaje es inválido + Enviar SMS si se activa un evento de bomba inaccesible + Reportar bomba inalcanzable + Delta: + IOB: + Bolo: + Dosis Basal: + Código QR para la configuración de la contraseña de un sólo uso + diff --git a/plugins/src/main/res/values-fr-rFR/strings.xml b/plugins/src/main/res/values-fr-rFR/strings.xml new file mode 100644 index 0000000000..cd997ae3ec --- /dev/null +++ b/plugins/src/main/res/values-fr-rFR/strings.xml @@ -0,0 +1,92 @@ + + + + Communicateur SMS + SMS + Commander à distance AAPS en utilisant les commandes SMS. + depuis l\'application Authenticator pour : %1$s suivie du code PIN + Code PIN obligatoire à la fin de l\'OTP + Chiffres supplémentaires qui doivent être mémorisés et collés à la fin de chaque OTP généré + Code à vérifier : + OTP + PIN + Le code de vérification est composé de 6 chiffres affichés par l\'application Authenticator (appelée OTP) suivi du code PIN obligatoire constitué de 3 chiffres ou plus. + Réinitialiser les authentificateurs + Réinitialiser la clé de l\'Authentificateur + Voulez-vous réinitialiser la clé de l\'Authenticateur ? Cela rendra tous authentificateurs configurés invalides, et vous devrez les configurer à nouveau. + Nouvelle clé de l\'Authenticateur générée ! Veuillez utiliser le QRCode mis à jour pour les authentificateurs. + Exportation de l\'OTP secret + Êtes-vous sûr de vouloir copier l\'OTP secret dans le presse-papiers ?\n\nVous pouvez en avoir besoin uniquement si votre application d\'authentification a des problèmes pour scanner le QRCode, si vous voulez le saisir manuellement ou si vous voulez configurer un jeton OTP matériel en utilisant une application dédiée. + OTP secret (au format Base32) exporté et copié dans le presse-papiers. Collez-le dans l\'authentificateur ou le graveur OTP matériel ! + 1. Installation l\'Authentificateur + 2. Scannez le code pour configurer les codes OTP AAPS + 3. Test Mot-de-Passe-Unique (OTP) + Réinitialiser les authentificateurs + Sur chaque téléphone suiveur, installez une appli. Authentificateur qui prend en charge les jetons RFC 6238 TOTP. Les applications libres populaires sont:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + En réinitialisant l\'Authentificateur, vous invalidez tous les authentificateurs déjà initialisés. Vous devrez les reconfigurer ! + Patient + Numéros de tél autorisés + +XXXXXXXXXX;+YYYYYYYYYY + Pour définir la cible temp %1$s, renvoyez le code %2$s + Pour annuler la cible temp, renvoyez le code %1$s + Pour désactiver les commandes à distance SMS, renvoyez le code %1$s.\n\nGardez à l\'esprit que vous ne pourrez le réactiver que directement à partir de l\'application AAPS du smartphone maître. + Service de commande à distance SMS arrêté. Pour le réactiver, utilisez AAPS sur le smartphone maître. + Pour envoyer la calibration %1$.2f, renvoyez le code %2$s + Échec du Bolus + Nombre minimum de minutes qu\'il doit y avoir entre un bolus distant et le suivant + Combien de minutes doit-il y avoir, au minimum, entre un bolus et le suivant + Pour votre sécurité, pour modifier cette préférence vous devez ajouter au moins 2 numéros de téléphone. + Bolus de %1$.2f U délivré avec succès + Bolus repas de %1$.2f U délivré avec succès + Cible %1$s pendant %2$d minutes + Cible %1$s pendant %2$d minutes définie avec succès + Cible Temp annulée avec succès + Autoriser les commandes à distance par SMS + La Boucle a été désactivée + La Boucle a été activée + La Boucle est activée + Pour connecter la pompe, renvoyez le code %1$s + Echec de la connexion pompe + Pour déconnecter la pompe pendant %1$d min, renvoyez le code %2$s + Pompe déconnectée + Pompe reconnectée + La commande à distance n\'est pas autorisée + Bolus à distance non disponible. Réessayez plus tard. + Pour démarrer la basal de %1$.2f U/h pendant %2$d min, renvoyez le code %3$s + Pour changer le profil vers %1$s %2$d%%, renvoyez le code %3$s + Pour démarrer le bolus étendu de %1$.2f U/h pendant %2$d min, renvoyez le code %3$s + Pour entrer %1$dg à %2$s, renvoyez le code %3$s + Pour démarrer la Basal %1$d%% pendant %2$d min, renvoyez le code %3$s + Pour suspendre la boucle pendant %1$d min, renvoyez le code %2$s + Pour reprendre la boucle, renvoyez le code %1$s + Pour activer la boucle, renvoyez le code %1$s + Pour désactiver la boucle, renvoyez le code %1$s + Démarrage réussi pour %1$.2fU/h de basal temp pour %2$d min + Le Bolus étendu %1$.2fU pendant %2$d min a commencé avec succès + %1$d g de glucides entrés avec succès + L\'entrée de %1$dg de glucides a échoué + Démarrage réussi pour %1$d%% de Basal temporaire pour %2$d min + Le démarrage du basal temporaire a échoué + Le départ du Bolus étendu a échoué + Pour arrêter la basal temp, renvoyez le code %1$s + Pour arrêter le bolus étendu, renvoyez le code %1$s + Basal temporaire annulé + Bolus étendu annulé + Echec de l\'annulation du basal temporaire + Échec de l\'annulation du Bolus étendu + Commande inconnue ou mauvaise réponse + Un autre bolus est en file d\'attente. Réessayez plus tard. + Durée incorrecte + Boucle suspendue + Boucle relancée + Num tél du SMS est invalide + Étalonnage envoyé. La réception doit être activée dans xDrip+. + xDrip+ ne reçoit pas les étalonnages + Message invalide + Envoyer un SMS si l\'événement Pompe hors de portée est déclenché + Signaler Pompe hors de portée + Delta: + IA: + Bolus: + Basal: + Code QR pour configurer un mot de passe à usage unique + diff --git a/plugins/src/main/res/values-ga-rIE/strings.xml b/plugins/src/main/res/values-ga-rIE/strings.xml new file mode 100644 index 0000000000..33c47da0fc --- /dev/null +++ b/plugins/src/main/res/values-ga-rIE/strings.xml @@ -0,0 +1,15 @@ + + + + SMS + Is lúb díchumasaithe + Is lúb cumasaithe + Is lúb cumasaithe + Cealú TBR teip + Lúb ar fionraí + Lúb atógáil + Deilte: + IOB: + Bólas: + Bunaidh: + diff --git a/plugins/src/main/res/values-hr-rHR/strings.xml b/plugins/src/main/res/values-hr-rHR/strings.xml new file mode 100644 index 0000000000..0fef4c22e5 --- /dev/null +++ b/plugins/src/main/res/values-hr-rHR/strings.xml @@ -0,0 +1,9 @@ + + + + Daljinsko upravljanje AndroidAPS-om pomoću SMS naredbi. + 2. Skenirajte kod za postavljanje AAPS OTP kodova + Poništavanjem autentifikatora činite sve već osigurane autentifikatore nevažećima. Morat ćete ih ponovno postaviti! + Delta: + QR kod za postavljanje jednokratne lozinke + diff --git a/plugins/src/main/res/values-hu-rHU/strings.xml b/plugins/src/main/res/values-hu-rHU/strings.xml new file mode 100644 index 0000000000..bf1e1af079 --- /dev/null +++ b/plugins/src/main/res/values-hu-rHU/strings.xml @@ -0,0 +1,6 @@ + + + + OTP + PIN + Bázis: + diff --git a/plugins/src/main/res/values-it-rIT/strings.xml b/plugins/src/main/res/values-it-rIT/strings.xml new file mode 100644 index 0000000000..5da346df04 --- /dev/null +++ b/plugins/src/main/res/values-it-rIT/strings.xml @@ -0,0 +1,91 @@ + + + + Comunicazioni SMS + SMS + Controlla AAPS in remoto usando i comandi SMS. + da app autenticatore: %1$s seguito da PIN + PIN obbligatorio aggiuntivo a fine token + Cifre aggiuntive che devono essere memorizzate e incollate alla fine di ogni OTP generata + Codice controllo: + OTP + PIN + Il codice di verifica è composto da 6 cifre visualizzate dall\'app autenticatore (note come OTP) seguite da 3 o più cifre del PIN obbligatorio. + Resetta autenticatori + Resetta chiave autenticatore + Sei sicuro di resettare la chiave autenticatore? Renderà non validi tutti gli autenticatori attualmente configurati e sarà necessario configurarli nuovamente. + La nuova chiave autenticatore è stata generata! Usa il QRCode aggiornato per fornire gli autenticatori. + Esportazione OTP secret + Sei sicuro di voler copiare l\'OTP secret negli appunti?\n\nPotresti averne bisogno solo se la tua app autenticatore ha problemi con la scansione del QRCode, vuoi inserirlo manualmente o vuoi configurare un token OTP hardware usando un\'app dedicata. + OTP secret (in formato Base32) esportato e copiato negli appunti. Incollalo nell\'autenticatore o nel configuratore hardware di OTP! + 1. Installa l\'autenticatore + 2. Scansione il codice per configurare i codici OTP di AAPS + 3. Testa OTP + Resetta autenticatori + Su ogni telefono follower installa una app autenticatore che supporta i token RFC 6238 TOTP. App gratuite popolari sono:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Resettando l\'autenticatore rendi non validi tutti gli autenticatori già forniti. Dovrai configurarli di nuovo! + Utente + Numeri di telefono consentiti + +XXXXXXXXXX;+YYYYYYYYYY + Per impostare il Temp-Target %1$s rispondi con il codice %2$s + Per cancellare il Temp-Target rispondi col codice %1$s + Per disabilitare il servizio di controllo remoto tramite SMS rispondi col codice %1$s.\n\nRicorda che potrai riattivarlo solo in maniera diretta dallo smartphone master in cui è installato AAPS. + Servizio di controllo remoto tramite SMS stoppato. Per riattivarlo, usa lo smartphone master in cui è installato AAPS. + Per inviare la calibrazione %1$.2f rispondi col codice %2$s + Bolo fallito + Numero minimo di minuti che devono trascorrere tra un bolo remoto e il successivo + Quanti minuti devono trascorrere, almeno, tra un bolo e il successivo + Per la tua sicurezza, per modificare questa preferenza hai bisogno di aggiungere almeno 2 numeri di telefono. + Bolo di %1$.2f U erogato con successo + Bolo pasto di %1$.2f U erogato con successo + Target %1$s per %2$d minuti + Target %1$s per %2$d minuti impostato con successo + Temp-Target cancellato con successo + Consenti comandi remoti tramite SMS + Il loop è stato disabilitato + Il loop è stato abilitato + Il loop è abilitato + Per connettere il micro rispondi col codice %1$s + Connessione al micro fallita + Per disconnettere il micro per %1$d minuti rispondi col codice %2$s + Micro disconnesso + Micro riconnesso + Il comando da remoto non è permesso + Bolo remoto non disponibile. Riprova più tardi. + Per avviare la basale %1$.2f U/h per %2$d min rispondi col codice %3$s + Per passare al profilo %1$s %2$d%% rispondi col codice %3$s + Per avviare il bolo esteso %1$.2f U/h per %2$d min rispondi col codice %3$s + Per inserire %1$dg a %2$s rispondi col codice %3$s + Per avviare la basale %1$d%% per %2$d min rispondi col codice %3$s + Per sospendere il loop per %1$d minuti rispondi col codice %2$s + Per riprendere il loop rispondi col codice %1$s + Per abilitare il loop rispondi col codice %1$s + Per disabilitare il loop rispondi col codice %1$s + Basale temporanea %1$.2fU/h per %2$d min avviata con successo + Bolo esteso %1$.2fU/h per %2$d min avviato con successo + CHO %1$d g inseriti con successo + Inserimento di %1$dg di CHO fallito + Basale temporanea %1$d%% per %2$d min avviata con successo + Avvio basale temporanea fallito + Avvio bolo esteso fallito + Per stoppare la basale temporanea rispondi col codice %1$s + Per stoppare il bolo esteso rispondi col codice %1$s + Basale temporanea cancellata + Bolo esteso cancellato + Basale temporanea: cancellazione fallita + Bolo esteso: cancellazione fallita + Comando sconosciuto o risposta errata + C\'è un altro bolo in coda. Riprova più tardi. + Durata errata + Loop sospeso + Loop ripreso + Numero di telefono SMS non valido + xDrip+ non sta ricevendo calibrazioni + Corpo del messaggio non valido + Invia SMS se si verifica l\'evento \"micro irraggiungibile\" + Segnala micro irraggiungibile + Delta: + IOB: + Bolo: + Basale: + Codice QR per configurare OTP + diff --git a/plugins/src/main/res/values-iw-rIL/strings.xml b/plugins/src/main/res/values-iw-rIL/strings.xml new file mode 100644 index 0000000000..bac97e5bd2 --- /dev/null +++ b/plugins/src/main/res/values-iw-rIL/strings.xml @@ -0,0 +1,89 @@ + + + + תקשורת SMS + SMS + מיישום מאמת עבור: %1$s ואחריו PIN + תוספת PIN חובה בסוף האסימון + ספרות נוספות שיש לשנן ולהדביק בסוף כל אחת מהסיסמאות החד פעמיות + קוד לבדיקה: + OTP + PIN + קוד האימות מורכב מ-6 ספרות המוצגות על ידי יישום מאמת (הידוע בתור OTP) ואחריו 3 או יותר ספרות של PIN הכרחי. + איפוס מאמתים + איפוס מפתח אימות + האם אתם בטוחים שברצונכם לאפס את מפתח האימות? איפוס יהפוך את כל המאמתים המוגדרים כעת לבלתי תקפים, ותצטרכו להגדיר אותם מחדש. + מפתח אימות חדש הופק! נא להשתמש בקוד QR מעודכן כדי לאפשר אימות. + יצוא סוד OTP + אתם בטוחים שברצונכם להעתיק את סוד ה-OTP ללוח ההעתקה?\n\nייתכן שתצטרכו לעשות זאת רק אם יישום האימות נתקל בבעיות בסריקת קוד QR, או שברצונכם להכניס אותו ידנית או להגדיר אסימון OTP של חומרה באמצעות יישום ייעודי. + סוד OTP (בפורמט Base32) יוצא והועתק אל לוח ההעתקה. הדביקו אותו לתוך תוכנת האימות או בחומרת צריבת OTP! + 1. התקנת מאמת + 3. ניסוי סיסמה חד-פעמית + איפוס מאמתים + בכל אחד מהטלפונים העוקבים, התקינו יישום מאמת התומך באסימוני RFC 6238 TOTP. יישומים פופולריים בחינם הם:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + משתמש + מספרי טלפון מורשים + +XXXXXXXXXX;+YYYYYYYYYY + להגדרת המטרה הזמנית %1$s יש להשיב עם הקוד %2$s + לביטול המטרה הזמנית יש להשיב עם הקוד %1$s + לביטול שירות השליטה מרחוק באמצעות SMS השיבו עם הקוד %1$s. \n\nהשירות ניתן להפעלה מחדש ממכשיר ה-AAPS הראשי בלבד. + שירות השליטה מרחוק באמצעות SMS מופסק. על מנת להפעילו, השתמשו ב-AAPS במכשיר הראשי. + כדי לשלוח ערך כיול %1$.2f יש להשיב עם הקוד %2$s + הבולוס נכשל + מספר המינימלי (בדקות) שחייב לחלוף בין בולוס מרוחק אחד למשנהו + מספר הדקות המינימלי שצריכות לחלוף, בין בולוס אחד למשנהו + למען בטחונכם, על מנת לערוך את העדפה זו, עליכם להוסיף לפחות שני מספרי טלפון. + בולוס %1$.2f יחידות ניתן בהצלחה + בולוס עבור ארוחה %1$.2fU ניתן בהצלחה + ערך מטרה %1$s למשך %2$d דקות + יעד %1$s עבור %2$d דקות הוגדר בהצלחה + יעד זמני בוטל בהצלחה + אפשר שליטה מרחוק באמצעות SMS + הלולאה הושבתה + הלולאה הופעלה + לולאה פעילה + לחיבור המשאבה יש להשיב עם הקוד %1$s + החיבור אל המשאבה נכשל + לניתוק המשאבה למשך %1$d דקות השיבו עם הקוד %2$s + המשאבה מנותקת + המשאבה חוברה מחדש + פקודה מרוחקת אינה מותרת + בולוס מרחוק אינו זמין. נסו שוב מאוחר יותר. + להפעלת בזאלי %1$.2f יח\' לשעה למשך %2$d דקות יש להשיב עם הקוד %3$s + להחלפת פרופיל ל- %1$s %2$d %% הקש את הקוד %3$s + למתן בולוס ממושך %1$.2f יח\' למשך %2$d דקות יש להשיב עם הקוד %3$s + למתן %1$d גר\' ב-%2$s יש להשיב עם הקוד %3$s + להפעלת בזאלי %1$d%% למשך %2$d דקות הקש קוד %3$s + להשהיית הלולאה למשך %1$d דקות יש להשיב עם הקוד %2$s + להפעלת הלולאה מחדש יש להשיב עם הקוד %1$s + כדי לאפשר הלולאה יש להשיב עם הקוד %1$s + להשבתת הלולאה יש להשיב עם הקוד %1$s + בזאלי זמני %1$.2f יחידות\\שעה למשך %2$d דקות הופעל בהצלחה + בולוס ממושך %1$.2f יחידות למשך %2$d דקות הופעל בהצלחה + %1$d גר\' פחמימות נקלטו בהצלחה + קליטת %1$d גר\' פחמימות נכשלה + בזאלי זמני %1$d%% למשך %2$d דקות הופעל בהצלחה + הפעלת בזאלי זמני נכשלה + הפעלת בולוס ממושך נכשלה + להפסקת בזאלי זמני הקש קוד %1$s + להפסקת בולוס ממושך יש להשיב עם הקוד %1$s + בזאלי זמני בוטל + בולוס ממושך בוטל + ביטול בזאלי זמני ניכשל + ביטול בולוס ממושך נכשל + פקודה לא מוכרת או תגובה שגויה + ישנו בולוס נוסף בתור. נסו שוב מאוחר יותר. + משך שגוי + לולאה מושהית + לולאה חודשה + מספר טלפון ל-SMS אינו תקין + הכיול נשלח. יש לאשר את קבלת כיולים ב-xDrip+. + xDrip אינו מקבל כיולים + גוף ההודעה אינו חוקי + שולח SMS אם מופעל אירוע \"המשאבה אינה נגישה\" + דווח שהמשאבה אינה נגישה + דלתא: + אינסולין פעיל: + בולוס: + אינסולין בזאלי: + ברקוד QR ליצירת סיסמה חד פעמית + diff --git a/plugins/src/main/res/values-ko-rKR/strings.xml b/plugins/src/main/res/values-ko-rKR/strings.xml new file mode 100644 index 0000000000..7a9ff2acbb --- /dev/null +++ b/plugins/src/main/res/values-ko-rKR/strings.xml @@ -0,0 +1,88 @@ + + + + SMS 통신기 + SMS + 인증 어플에서: %1$s 뒤에 PIN + 암호 끝에 더해지는 자동형성 PIN + 부가적인 숫자를 생성되는 일회성 비밀번호 끝에 더하고 기억해야 함. + 확인용 code: + OTP + PIN + 유효한 코드는 인증 어플에서 보여지는 6개의 숫자 (OTP) 뒤에 자동형성 PIN의 3개 또는 그 이상의 숫자가 이어져야 함. + 인증 초기화 + 인증 암호 초기화 + 인증 암호를 초기화하는 것이 확실합니까? 현재 설정된 인증 암호를 모두 무효화 시키며, 이들을 모두 다시 설정해야 합니다. + 새로운 인증 암호가 생성되었습니다! 준비된 인증 어플에서 업데이트된 QRCode를 사용하십시오. + OTP 비밀번호 내보내기 + OTP 비밀번호의 클립보드 복사를 원하는 것이 확실합니까?\n\n 이는 인증 어플이 QRCode를 스캐닝하는데 문제가 있을 때, 비밀번호 수동 입력을 원할 때, 또는 공용 어플 사용 시에 하드웨어 OTP 암호 설정을 원할 때에만 필요합니다. + OTP 비밀번호 (Base32 포맷)가 클립보드에 내보내져서 복사되었습니다. 인증 어플 또는 하드웨어 OTP burner에 붙여넣기 하십시오! + 1. 인증어플 설치하기 + 3. 일회성 비밀번호 테스트 + 인증 초기화 + 각각의 팔로워 폰에 RFC 6238 TOTP 암호를 사용하는 인증 어플을 설치합니다. 대중적인 무료 어플은 다음과 같습니다:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator. + 사용자 + 허가된 전화번호 + +XXXXXXXXXX;+YYYYYYYYYY + 임시목표 %1$s를 설정하려면 %2$s를 입력하고 답장하세요 + 임시목표를 취소하려면 %1$s를 입력하고 답장하세요 + SMS 원격 기능을 비활성화려면 %1$s를 입력하고 답장하세요.\n\nAAPS 마스터폰을 통해서만 다시 활성화할 수 있습니다. + SMS 원격 기능이 중지되었습니다. 다시 활성화하려면 AAPS 마스터폰을 이용하세요. + 보정값 %1$.2f을 전송하려면 %2$s 를 입력하고 답장하세요 + Bolus failed + 원격 Bolus를 주입한 후 얼마간의 시간이 흐른 후에야 다음 원격 Bolus주입이 가능합니다 + 원격 Bolus를 주입한 후 몇분이 지나야 다음 원격 Bolus 주입이 가능하게 합니까 + 안전을 위하여 이 설정을 수정하기 위해 최소 2개의 폰 번호를 추가해야합니다. + Bolus %1$.2f U이 성공적으로 주입되었습니다. + 식사 Bolus %1$.2f U 이 성공적으로 주입되었습니다. + %2$d 분 동안 목표 %1$s + %2$d 분 동안 목표 %1$s 설정이 완료되었습니다 + 임시 목표 취소가 완료되었습니다 + SMS 원격 명령 사용하기 + Loop가 중지되었습니다. + Loop가 실행되었습니다. + Loop가 실행중입니다. + 코드 %1$s을(를) 사용하여 펌프에 연결하기 + 펌프에 연결하지 못했습니다. + %1$d분 동안 펌프 연결을 끊으려면 코드 %2$s를 입력하세요. + 펌프가 연결되지 않았습니다. + 펌프가 다시 연결되었습니다. + 원격 명령이 허가되지 않았습니다 + 원격 주입이 불가능합니다. 나중에 다시 시도해주세요. + %2$d분동안 basal %1$.2fU/h 주입하려면 %3$s을(를) 입력하세요. + 프로파일 %1$s %2$d%%로 변경하려면 %3$s 를 입력하고 답장하세요 + %2$d분동안 확장bolus %1$.2fU 주입하려면 %3$s을(를) 입력하세요. + %2$s에 %1$dg을 입력하려면 %3$s를 입력하고 답장하세요 + %2$d 분 동안 Basal %1$d%% 주입하려면 %3$s을 입력하고 답장하세요 + %1$d분동안 Loop 일시중지하려면 %2$s 를 입력하고 답장하세요 + 코드 %1$s을(를) 사용하여 loop의 작동 다시 시작하기 + 코드 %1$s을(를) 사용하여 loop의 작동 활성화하기 + 코드 %1$s을(를) 사용하여 loop의 작동 비활성화하기 + Temp Basal %1$.2fU/h for %2$d min started successfully + Extended bolus %1$.2fU for %2$d min started successfully + 탄수화물 %1$dg 입력이 완료되었습니다. + 탄수화물 %1$dg 입력이 실패하였습니다 + Temp basal %1$d%% for %2$d min started successfully + Temp Basal start failed + Extended bolus start failed + 임시Basal을 중지하려면 %1$s 를 입력하고 답장하세요 + 확장 Bolus를 중지하려면 %1$s 를 입력하고 답장하세요 + Temp Basal canceled + Extended bolus canceled + Canceling Temp Basal failed + Canceling extended bolus failed + 알려지지 않은 명령이거나 잘못된 답장입니다 + 대기열에 또다른 bolus가 있습니다. 이후에 다시 시도하세요. + 기간이 잘못되었습니다. + Loop가 일시중지 되었습니다. + Loop가 재실행 되었습니다. + SMS폰번호가 유효하지 않습니다 + 보정 전송됨. xDrip에서 수신이 되도록 설정되어 있어야 합니다+. + xDrip+에서 보정값을 받지 못합니다. + 잘못된 메시지 내용 + 허용되지 않는 펌프 이벤트가 발생하면 SMS를 보내기 + 허용되지 않는 펌프 기록 + Delta: + IOB: + Bolus: + Basal: + diff --git a/plugins/src/main/res/values-lt-rLT/strings.xml b/plugins/src/main/res/values-lt-rLT/strings.xml new file mode 100644 index 0000000000..c2f9b647d9 --- /dev/null +++ b/plugins/src/main/res/values-lt-rLT/strings.xml @@ -0,0 +1,88 @@ + + + + SMS komunikatorius + SMS + iš Authenticator programėlės: %1$s, po to - PIN + Papildomas privalomas PIN kodas žymeklio gale + Papildomi skaitmenys, kuriuos reikia atsiminti ir pridėti kiekvieno sugeneruoto slaptažodžio pabaigoje + Kodas patikrinimui: + OTP + PIN + Patvirtinimo kodą sudaro 6 skaitmenys, kuriuos rodo Authenticator programa (dar vadinama OTP), po 3 ar daugiau privalomo PIN skaitmenų. + Atstatyti tapatybės nustatymą + Atstatyti autentifikatoriaus kodą + Ar tikrai norite iš naujo nustatyti autentifikatoriaus raktą? Dėl to visi šiuo metu konfigūruojami autentifikatoriai negalios, ir jums reikės juos nustatyti dar kartą. + Sukurtas naujas autentifikavimo raktas! Autentifikatoriams pateikti naudokite atnaujintą QR kodą. + Eksportuojamas OTP kodas + Ar tikrai norite nukopijuoti OTP slaptažodį į mainų sritį?\n\nTai gali būti reikalinga tik tuo atveju, jei jūsų programai kyla problemų identifikuojant nuskaitant QR kodą. Arba norite jį įvesti rankiniu būdu ar sukonfigūruoti įrangos OTP prieigos raktą naudodami specialią programą. + OTP kodas (Base32 formatas) eksportuotas ir nukopijuotas į mainų sritį. Įklijuokite jį į autentifikatorių arba OTP programą! + 1. Įdiegti Authenticator + 3. Patikrinti vienkartinį slaptažodį + Atstatyti tapatybės nustatymą + Kiekviename telefone, palaikančiame RFC 6238 TOTP prieigos raktus, įdiekite autentifikavimo programą. Populiariausios nemokamos programos yra:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Vartotojas + Leidžiami telefono numeriai + +370XXXXXXXX; +370YYYYYYYY + Norėdami nustatyti laikiną tikslą %1$s, atsakykite su kodu %2$s + Norėdami atšaukti laikiną tikslą, atsakykite su kodu %1$s + Norėdami išjungti SMS nuotolinį valdymą, atsakykite kodu %1$s.\n\n Turėkite omenyje, kad jūs funkciją galėsite atnaujinti tiesiai tik iš AAPS pagrindinio telefono. + SMS nuotolinio valdymo funkcija sustojo. Norėdami ją atnaujinti, naudokite AAPS pagrindinį išmanųjį telefoną. + Norėdami nusiųsti kalibraciją %1$.2f, atsakykite kodu %2$s + Bolusas nesuleistas + Minimalus minučių skaičius, kuris turi praeiti nuo vieno boluso, suleisto nuotoliniu būdu iki kito + Kiek mažiausiai minučių turi praeiti tarp vieno ir kito boluso + Jūsų saugumui, norėdami redaguoti šį pasirinkimą, jums reikia pridėti ne mažiau kaip 2 telefono numerius. + %1$.2f vv bolusas sėkmingai suleistas + Bolusas %1$.2f vv sėkmingai suleistas + Tikslas %1$s %2$d min. + Tikslas %1$s %2$d min. nustatytas sėkmingai + Laikinas tikslas atšauktas sėkmingai + Leisti nuotolines komandas SMS žinutėmis + Ciklas buvo išjungtas + Ciklas buvo įjungtas + Ciklas įjungtas + Pompos prijungimui atsakykite su kodu %1$s + Nepavyko prisijungti prie pompos + Norėdami atjungti pompą %1$d min., atsakykite kodu %2$s + Pompa atjungta + Pompa prijungta + Nuotolinis valdymas negalimas + Nuotolinis bolusas negalimas. Bandykite vėliau. + Norėdami aktyvuoti %1$.2f vv/val bazę, kurios trukmė %2$d min, atsakykite kodu %3$s + Norėdami perjungti profilį %1$s %2$d%%, atsakykite kodu %3$s + Norint pradėti ištęstinį bolusą %1$.2f vv %2$d min., atsakykite kodu %3$s + Įvedimui %1$dg %2$s atsakykite kodu %3$s + Norėdami aktyvuoti %1$d%% bazę %2$d min., atsakykite kodu %3$s + Norėdami sustabdyti Ciklą %1$d min., atsakykite kodu %2$s + Ciklo atnaujinimui atsakykite su kodu %1$s + Ciklo įjungimui atsakykite su kodu %1$s + Ciklo išjungimui atsakykite su kodu %1$s + %1$.2f vv/val laikina bazė, kurios trukmė %2$d min., aktyvuota sėkmingai + %1$.2f vv ištęstas bolusas, kurio trukmė %2$d min., aktyvuotas sėkmingai + %1$d g angliavandenių įrašyti sėkmingai + Įvesti %1$dg angliavandenių nepavyko + %1$d%% laikina bazė, kurios trukmė %2$d min., aktyvuota sėkmingai + Laikina bazė neaktyvuota + Ištęstinis bolusas nepradėtas + Norėdami sustabdyti laikiną bazę, atsakykite kodu %1$s + Norėdami sustabdyti ištęstinį bolusą, atsakykite kodu %1$s + Laikina bazė atšaukta + Ištęstinis bolusas atšauktas + Laikinos bazės atšaukti nepavyko + Nepavyko atšaukti ištęstinio boluso + Nežinoma komanda arba neteisingas atsakymas + Kitas bolusas laukia eilėje. Bandykite dar kartą vėliau. + Neteisinga trukmė + Ciklas sustabdytas + Ciklas atnaujintas + Neteisingas SMS telefono numeris + Kalibracija išsiųsta. xDrip+ programoje turi būti įgalintas gavimas. + xDrip+ negauna kalibracijų + Neteisingas pranešimas + Siųsti SMS, jei aptinkamas įrašas apie nepasiekiamą pompą + Pranešti apie nepasiekiamą pompą + Pokytis: + AIO: + Bolusas: + Valandinė bazė: + diff --git a/plugins/src/main/res/values-nl-rNL/strings.xml b/plugins/src/main/res/values-nl-rNL/strings.xml new file mode 100644 index 0000000000..f1324be33d --- /dev/null +++ b/plugins/src/main/res/values-nl-rNL/strings.xml @@ -0,0 +1,90 @@ + + + + SMS Commando\'s + SMS + Bedien AAPS op afstand met SMS commando\'s. + van de Authenticator-app voor: %1$s gevolgd door PIN + Extra verplichte PIN aan einde van token + Extra cijfers die je moet onthouden, en aan het eind van elk gegenereerd eenmalig wachtwoord moet toevoegen. + Te controleren code: + OTP + PIN + De verificatiecode bestaat uit 6 cijfers die worden afgebeeld door de Authenticator-app (bekend als OTP), gevolgd door 3 of meer cijfers van de verplichte PIN-code. + Reset Authentificatie + Reset Authentificatie-sleutel + Weet je zeker dat je de Autentificatie-sleutel wilt resetten? Met deze actie maak je alle Authentificatie instellingen van verbonden telefoons ongeldig, en je zult ze opnieuw moeten instellen. + Er is een nieuwe Authentificatie-sleutel gegenereerd! Gebruik de nieuwe QR-Code voor het instellen van geautoriseerde telefoons. + OTP-secret wordt geëxporteerd + Weet je zeker dat je het OTP-secret naar het klembord wilt kopiëren?\n\nJe hebt dit alleen nodig als je Authenticator-app problemen heeft met het scannen van QR-codes, als je het handmatig wilt invullen of als je een hardware OTP-token met een speciale app wilt configureren. + OTP-secret (in Base32-formaat) is geëxporteerd en gekopieerd naar het klembord. Plak het in de Authenticator-app of de app van de hardware OTP-token! + 1. Installeer Authenticator app + 3. Test eenmalig wachtwoord (One Time Password) + Reset Authentificatie + Installeer de Authenticator-app op elke volger telefoon die RFC 6238 TOTP tokens ondersteunt. Populaire gratis apps zijn:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Gebruiker + Geautoriseerde telefoon nummers + +XXXXXXXXXX;+YYYYYYYYYY + Om tijdelijk streefdoel %1$s in te stellen antwoord met code %2$s + Om tijdelijk streefdoel te annuleren antwoord met code %1$s + Om de SMS Remote Service uit te zetten, antwoord met code %1$s. \n\nDenk er aan dat je deze alleen weer aan kunt zetten op de AAPS master smartphone. + De controle via SMS is uitgezet. Gebruik AAPS op de master smartphone om deze weer te aan te zetten. + Om calibratie %1$.2f te verzenden antwoord met de code %2$s + Bolus mislukt + Minimum aantal minuten dat moet verstrijken tussen de ene bolus op afstand en de volgende + Hoeveel minuten er ten minste moeten verstrijken tussen de ene bolus en de volgende + Voor de veiligheid moet je ten minste 2 telefoonnummers toevoegen om deze instelling te kunnen bijwerken. + Bolus van %1$.2f E succesvol toegediend + Maaltijdbolus van %1$.2f E succesvol toegediend + Streefdoel %1$s gedurende %2$d minuten + Streefdoel %1$s gedurende %2$d minuten succesvol ingesteld + Tijdelijk streefdoel is geannuleerd + Sta SMS commando\'s toe + Loop was uitgeschakeld + Loop was ingeschakeld + Loop is ingeschakeld + Om verbinding te maken met pomp antwoord met code %1$s + Verbinding maken met pomp is mislukt + Om de pomp te ontkoppelen gedurende %1$d minuten antwoord met code %2$s + Pomp verbinding verbroken + Pomp opnieuw verbonden + Commando\'s op afstand zijn niet toegestaan + Bolus op afstand niet beschikbaar. Probeer het later opnieuw. + Om een basaal van %1$.2f E/uur gedurende %2$d min te starten, antwoord met code %3$s + Om naar profiel %1$s %2$d%% te wisselen antwoord met code %3$s + Om een vertraagde bolus van %1$.2f E gedurende %2$d min te starten, antwoord met code %3$s + Om %1$dg in te voeren om %2$s antwoord met code %3$s + Om een basaal van %1$d%% gedurende %2$d min te starten antwoord met code %3$s + Om de loop te onderbreken gedurende %1$d minuten antwoord met de code %2$s + Om loop te hervatten antwoord met code %1$s + Om loop in te schakelen antwoord met code %1$s + Om loop uit te schakelen antwoord met code %1$s + Tijdelijk basaal %1$.2fE/uur voor %2$d minuten succesvol gestart + Vertraagde bolus %1$.2fE voor %2$d minuten succesvol gestart + Koolhydraten %1$d g succesvol ingevoerd + Invoeren van %1$dg koolhydraten is mislukt + Tijdelijk basaal van %1$d%% voor %2$d minuten succesvol gestart + Start tijdelijk basaal mislukt + Starten vertraagde bolus is mislukt + Om het tijdelijke basaal te stoppen antwoord met de code %1$s + Om de vertraagde bolus te stoppen antwoord met de code %1$s + Tijdelijk basaal afgebroken + Vertraagde bolus is geannuleerd + Afbreken van tijdelijk basaal mislukt + Annuleren van vertraagde bolus is mislukt + Onbekende opdracht of verkeerd antwoord + Er staat een andere bolus in de wachtrij. Probeer het later opnieuw. + Verkeerde tijdsduur + Loop onderbroken + Loop hervat + Foutief SMS telefoon nummer + Kalibratie verzonden. xDrip+ moet zo zijn ingesteld dat hij het ontvangen van kalibraties toestaat. + xDrip+ ontvangt geen kalibraties + Ongeldige inhoud van het bericht + Stuur SMS wanneer de pomp onbereikbaar is + Melding pomp onbereikbaar + Verschil: + IOB: + Bolus: + Basaal: + QR Code voor het instellen van een eenmalig wachtwoord + diff --git a/plugins/src/main/res/values-no-rNO/strings.xml b/plugins/src/main/res/values-no-rNO/strings.xml new file mode 100644 index 0000000000..822428ff96 --- /dev/null +++ b/plugins/src/main/res/values-no-rNO/strings.xml @@ -0,0 +1,90 @@ + + + + SMS-tjeneste + SMS + Fjernstyre AAPS ved å bruke SMS-kommandoer. + fra Authenticator appen for: %1$s etterfulgt av PIN + PIN kode som legges til på slutten av token + Ytterligere sifre som MÅ memoreres og legges til på slutten av hvert generert engangspassord + Kode som skal kontrolleres: + OTP + PIN + Bekreftelseskoden består av 6 sifre som vises av Authenticator appen (kjent som OTP) etterfulgt av 3 eller flere siffer for obligatorisk PIN-kode. + Tilbakestill Authenticators + Tilbakestill Authenticator nøkkel + Er du sikker på at du vil tilbakestille Authenticator nøkkel? Dette vil gjøre alle lagrede Authenticators ugyldige, og du må sette dem opp på nytt igjen. + Ny Authenticator nøkkel ble generert! Vennligst bruk oppdatert QR kode til å aktivere autentiserere. + Eksporterer OTP hemmelig kode + Er du sikker på at du vil kopiere OTP hemmelig kode til utklippstavlen?\n\nDu trenger bare det hvis din Authenticator app har problemer med skanning av QRCode og du ønsker å legge den inn manuelt, eller du ønsker å konfigurere maskinvare OTP-kode ved hjelp av dedikert app. + OTP hemmelig kode (i base32-format) er eksportert og kopiert til utklippstavlen. Lim den inn i Authenticator app eller hardware OTP system! + 1. Installer Authenticator + 3. Test engangspassord + Tilbakestill Authenticators + I hver følger telefon installerer du en Authenticator-app som støtter RFC 6238 TOTP token. Populære gratis apper er:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Bruker + Godkjente mobilnumre + +XXXXXXXXXX;+YYYYYYYYYY + For å sette Temp Target på %1$s, svar med kode %2$s + For å avbryte Temp Target, svar med kode %1$s + For å deaktivere fjernstyring via SMS-meldinger, svar med kode %1$s.\n\nHusk at du vil kunne reaktivere den igjen kun fra AAPS hovedtelefon. + Fjernstyring via SMS-meldinger er stanset. For å reaktivere, bruk AAPS på hovedtelefonen. + For å sende kalibrering %1$.2f, svar med kode %2$s + Bolus mislyktes + Minimum antall minutter som må forløpe mellom en fjernstyrt bolus og den neste + Minimum antall minutter mellom en fjernstyrt bolus og neste + For din egen sikkerhet, må du legge til minst 2 telefonnumre for å endre denne innstillingen. + Bolus på %1$.2f E er levert + Måltidsbolus på %1$.2f E er levert + Temp target på %1$s er satt i %2$d minutter + Temp target på %1$s i %2$d minutter ble lagret + Temp Target ble fjernet + Tillat fjernstyring via SMS-meldinger + Loop har blitt deaktivert + Loop har blitt aktivert + Loop er aktivert + For å koble til pumpen, svar med kode %1$s + Tilkobling til pumpen mislyktes + For å koble fra pumpen i %1$d minutter, svar med koden %2$s + Pumpe frakoblet + Pumpen tilkoblet igjen + Fjernstyringskommando er ikke tillatt + Fjernstyringsbolus er ikke tilgjengelig. Prøv igjen senere. + For å starte basal %1$.2f E/t i %2$d minutter, svar med kode %3$s + For å bytte profil til %1$s %2$d%%, svar med kode %3$s + For å starte forlenget bolus %1$.2f E i %2$d minutter, svar med kode %3$s + For å angi %1$dg kl. %2$s, svar med kode %3$s + For å starte basal %1$d%% i %2$d minutter, svar med kode %3$s + For å pause loop i %1$d minutter, svar med kode %2$s + For å gjenoppta loop, svar med kode %1$s + For å aktivere loop, svar med kode %1$s + For å deaktivere loop, svar med kode %1$s + Vellykket start av temp basal %1$.2fE/t i %2$d minutter + Vellykket start av forlenget bolus %1$.2fE i %2$d minutter + Vellykket registrering av %1$dg KH + Registrering av %1$dg karbohydrater mislyktes + Vellykket start av temp basal %1$d%% i %2$d minutter + Mislykket start av temp basal + Mislykket start av forlenget bolus + For å avbryte Temp basal, svar med kode %1$s + For å stoppe forlenget bolus, svar med kode %1$s + Temp basal avbrutt + Forlenget bolus avbrutt + Mislykket kansellering av Temp basal + Mislykket kansellering av forlenget bolus + Ukjent kommando eller feil svar + Det ligger en annen bolus i køen. Prøv igjen senere. + Feil varighet + Loop er pauset + Loop gjenopptatt + Ugyldig mobilnummer for SMS + Kalibrering sendt. Mottak må være aktivert i xDrip+. + xDrip+ tar ikke imot kalibreringer + Ugyldig innhold i meldingen + Send SMS hvis det ikke oppnås kontakt med pumpa + Rapporter når kontakt med pumpe ikke oppnås + Delta: + IOB: + Bolus: + Basal: + QR-kode for oppsett av engangspassord + diff --git a/plugins/src/main/res/values-pl-rPL/strings.xml b/plugins/src/main/res/values-pl-rPL/strings.xml new file mode 100644 index 0000000000..06e2d417f8 --- /dev/null +++ b/plugins/src/main/res/values-pl-rPL/strings.xml @@ -0,0 +1,88 @@ + + + + Komunikator SMS + SMS + z aplikacji Authenticator dla: %1$s, z doklejonym PIN-em + Dodatkowy obowiązkowy PIN na końcu tokenu + Dodatkowe cyfry, które powinny być zapamiętywane i przyklejone na końcu każdego wygenerowanego hasła jednorazowego + Kod do sprawdzenia: + OTP + PIN + Kod weryfikacyjny składa się z 6 cyfr wyświetlanych przez aplikację uwierzytelniającą (tzw. OTP) po których następują co najmniej 3 cyfry obowiązkowego PIN-u. + Resetuj uwierzytelnianie + Resetuj klucz uwierzytelniania + Czy na pewno zresetować klucz uwierzytelniający? Spowoduje to, że wszystkie aktualnie skonfigurowane uwierzytelniania będą niepoprawne i konieczne będzie ponowne ich skonfigurowanie. + Nowy klucz uwierzytelniający został wygenerowany! Proszę użyć zaktualizowanego kodu QRCode do potwierdzenia uwierzytelniania. + Eksportowanie sekretu OTP + Czy na pewno chcesz skopiować klucz tajny OTP do schowka?\n\nMożesz tego potrzebować jeśli Twoja aplikacja uwierzytelniająca (authenticator) ma problemy ze skanowaniem kodu QR, chcesz wprowadzić klucz ręcznie lub chcesz skonfigurować sprzętowy token OTP za pomocą dedykowanej aplikacji. + Klucz tajny OTP (w formacie Base32) został wyeksportowany i skopiowany do schowka. Wklej go przy ręcznym dodawaniu konta w aplikacji authenticator lub użyj w aplikacji konfigurującej tokeny sprzętowe! + 1. Zainstaluj uwierzytelnianie + 3. Sprawdź hasło jednorazowe + Resetuj uwierzytelnianie + Na każdym telefonie śledzącym zainstalować aplikację uwierzytelniania obsługującą tokeny TOTP RFC 6238 Popularne darmowe aplikacje:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Użytkownik + Dozwolone numery telefonów + +XXXXXXXXXX;+YYYYYYYYYY + Aby ustawić cel tymczasowy %1$s odeślij w SMS kod %2$s + Aby anulować cel docelowy odeślij w SMS kod %1$s + Aby wyłączyć zdalne sterowanie SMS-ami odeślij kod %1$s.\n\nPamiętaj że możesz to ponownie włączyć tylko bezpośrednio w aplikacji AAPS na głównym telefonie. + Zatrzymano zdalne sterowanie SMS-ami. Aby ponownie włączyć użyj aplikacji AAPS na głównym telefonie. + Aby wysłać kalibrację %1$.2f wprowadź kod %2$s + Bolus nieudany + Minimalna liczba minut która musi upłynąć pomiędzy jednym a drugim zdalnie podawanym bolusem + Ile co najmniej minut musi upłynąć pomiędzy jednym a drugim bolusem + Dla twojego bezpieczeństwa, aby zmienić to ustawienie musisz dodać co najmniej 2 numery telefonów. + Bolus %1$.2f U podany prawidłowo + Pomyślnie podano %1$.2f U bolusa posiłkowego + Cel %1$s na %2$d minut + Pomyślnie ustawiono cel %1$s na %2$d minuty + Pomyślnie anulowano cel tymczasowy + Zezwalaj na komendy zdalne via SMS + Pętla (Loop) została wyłączona + Pętla (Loop) została włączona + Pętla (Loop) jest włączona + Aby podłączyć pompę odpowiedz kodem %1$s + Połączenie z pompą nie powiodło się + Aby odłączyć pompę na %1$d minut odpowiedz kodem %2$s + Pompa odłączona + Pompa ponownie podłączona + Zdalne komendy nie są dozwolone + Bolus zdalny niedostępny. Spróbuj ponownie później. + Aby rozpocząć bazę %1$.2f U/h przez %2$d min. odpowiedz kodem %3$s + Aby przełączyć profil na %1$s %2$d%% odpowiedz kodem %3$s + Aby rozpocząć bolus przedłużony %1$.2f U przez %2$d min. odpowiedz kodem %3$s + Aby wprowadzić %1$dg o %2$s odeślij w SMS kod %3$s + Aby rozpocząć bolus przedłużony %1$d%% przez %2$d min. odpowiedz kodem %3$s + Aby wstrzymać pętle na %1$d minut odpowiedz kodem %2$s + Aby wznowić pętlę odpowiedz kodem %1$s + Aby włączyć pętlę odpowiedz kodem %1$s + Aby wyłączyć pętlę odpowiedz kodem %1$s + Tymczasowa baza %1$.2fU/h przez %2$d min rozpoczęta + Bolus przedłużony %1$.2fU na %2$d min. rozpoczęty pomyślnie + Pomyślnie wprowadzono %1$d g węglowodanów + Próba wprowadzenia %1$dg węglowodanów nie powiodła się + Tymczasowa baza %1$d%% przez %2$d min. pomyślnie rozpoczęta + Rozpoczęcie tymczasowej bazy nie powiodło się + Nie powiodło się podanie bolusa przedłużonego + Aby zatrzymać bazę tymczasową wprowadź kod %1$s + Aby zatrzymać bolus przedłużony wprowadź kod %1$s + Baza tymczasowa anulowana + Przedłużony bolus anulowano + Anulowanie tymczasowej bazy nie powiodło się + Anulowanie bolusa przedłużonego nie powiodło się + Nieznane polecenie lub błędna odpowiedź + W kolejce oczekuje inny bolus. Spróbuj ponownie później. + Zły czas trwania + Pętla wstrzymana + Pętla wznowiona + Nieprawidłowy numer telefonu SMS + Kalibracja wysłana. Odbiór musi być włączony w xDrip+. + xDrip+ nie odbiera kalibracji + Błędny tekst wiadomości + Wyślij SMS, jeśli wyzwolone jest zdarzenie pompy nieosiągalnej + Zgłoś nieosiągalną pompę + Delta: + IOB: + Bolus: + Baza: + diff --git a/plugins/src/main/res/values-pt-rBR/strings.xml b/plugins/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000000..e863e6991c --- /dev/null +++ b/plugins/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,92 @@ + + + + Comunicador SMS + SMS + Controle remotamente o AndroidAPS usando comandos SMS. + do aplicativo Autenticador para: %1$s seguido por PIN + PIN adicional obrigatório no fim do token + Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Password-Única que seja gerada + Código para verificar: + CÓDIGO + PIN + O código de verificação consiste em 6 dígitos exibidos pelo app Autenticador (conhecido como OTP) seguido por 3 ou mais dígitos do PIN obrigatório. + Repor Autenticadores + Repor Chave Autenticador + Tem certeza de redefinir chave Authenticador? Ele tornará todos os Authenticators configurados atualmente como inválidos, e precisará de os configurar novamente. + Nova Chave do Autenticador foi gerada! Por favor, use o QRCode atualizado para os autenticadores. + Exportando senha OTP + Tem certeza de que deseja copiar a senha OTP para a área de transferência?\n\nGeralmente, isso somente é necessário se o aplicativo autenticador apresenta problemas para escanear o QRCode, se você quer inserir a senha manualmente ou se você deseja configurar um token físico (hardware) de OTP usando um aplicativo dedicado. + Senha OTP (no formato Base32) exportada e copiada para a área de transferência. Cole-a em um aplicativo autenticador ou gravador de dispositivo OTP físico! + 1. Instalar Autenticador + 2. Escaneie o QR Code para configurar os códigos OTP do AAPS + 3. Teste Uma-Password-Única + Repor Autenticadores + Instalar uma app Autenticador que suporte Tokens RFC 6238 TOTP em cada telefone seguidor. Populares aplicativos gratuitos são:\n • Authy\n • o Google Authenticator\n • LastPass Autenticador\n • FreeOTP Autenticador + Ao redefinir o autenticador, você torna todos os autenticadores já provisionados inválidos. Você precisará configurá-los novamente! + Usuário + Números de telefone permitidos + +XXXXXXXXXX;+YYYYYYYYYY + Para definir o Alvo Tempo %1$s responda com o código %2$s + Para cancelar Alvo Temp responda com o código %1$s + Para desativar o Serviço Remoto SMS de responda com o código %1$s.\n\nTenha em mente que será capaz de o reativar diretamente apenas a partir do celular principal do AAPS. + SMS Serviço Remoto interrompido. Para reativá-lo, use o AAPS no telemóvel mestre. + Para enviar calibração %1$.2f responder com código %2$s + Bolus falhou + Número mínimo de minutos que deve decorrer entre um bólus remoto e o próximo + Quantos minutos deve decorrer, pelo menos, entre um bólus e o próximo + Para sua segurança, para editar esta preferência você precisa adicionar pelo menos 2 números de telefone. + Bolus %1$.2f U aplicado com sucesso + Bolus da refeição %1$.2f U aplicado com sucesso + Alvo %1$s para %2$d minutos + Alvo %1$s para %2$d minutos definido com sucesso + Alvo Temp cancelado com êxito + Permitir comandos remotos via SMS + Loop foi desativado + Loop foi ativado + Loop ativado + Para conectar à bomba responda com o código %1$s + Conexão com a bomba falhou + Para desconectar a bomba por %1$d minutos responda com código %2$s + Bomba desconectada + Bomba reconectada + O comando remoto não é permitido + O bolus remoto não está disponível. Tente novamente mais tarde. + Para começar o basal %1$.2fU/h durante%2$d min responda com o código %3$s + Para mudar o perfil para %1$s %2$d%% responda com o código %3$s + Para começar o bólus estendido %1$.2fU/h para %2$d min responda com o código %3$s + Para inserir %1$dg em %2$s responda com código %3$s + Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s + Para suspender o loop por %1$d minutos resposta com código %2$s + Para retomar o loop responda com o código %1$s + Para ativar o loop responda com o código %1$s + Para desativar o loop responda com o código %1$s + Basal temporária %1$.2fU/h para %2$d min iniciada com êxito + Bólus estendido %1$.2fU/h para %2$d min iniciado com êxito + Carboidratos %1$d g inseridos com sucesso + Introdução de %1$dg de hidratos falhou + Basal temporária %1$d%% U/h durante%2$d min iniciada com êxito + Falha ao iniciar basal temp + Falha ao iniciar o bolus estendido + Para parar a basal temporária responda com o código %1$s + Para parar o bólus temporário responda com o código %1$s + basal temporária cancelada + Bólus estendido cancelado + Cancelamento do basal temporário falhou + Falhou o cancelamento do bolus extendido + Comando desconhecido ou resposta errada + Há outra bolus na fila. Tente novamente mais tarde. + Duração errada + Loop suspenso + Loop retomado + Número de telefone inválido para comunicação por SMS + Calibração enviada. O recebimento deve estar ativado no xDrip+. + xDrip+ não está recebendo calibrações + Corpo da mensagem inválido + Enviar SMS se um evento de bomba inacessível for identificado + Reportar bomba inacessível + Delta: + IOB: + Bolus: + Basal: + Código QR para configuração de senha de uso único + diff --git a/plugins/src/main/res/values-pt-rPT/strings.xml b/plugins/src/main/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000000..fff9faba46 --- /dev/null +++ b/plugins/src/main/res/values-pt-rPT/strings.xml @@ -0,0 +1,88 @@ + + + + Comunicador SMS + SMS + da app Authenticator para: %1$s seguido pelo PIN + PIN obrigatório adicional no token final + Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Senha-Única que seja gerada + Código para verificar: + OTP + PIN + O código de verificação consiste em 6 dígitos exibidos pela app Authenticator (conhecido como OTP) seguido de 3 ou mais dígitos de PIN obrigatório. + Repor Autenticadores + Repor Chave Autenticador + Tem certeza de redefinir chave Authenticador? Ele tornará todos os Authenticators configurados actualmente como inválidos, e precisará de os configurar novamente. + Nova Chave do Autenticador foi gerada! Por favor, use o QRCode actualizado para os autenticadores. + A exportar segredo da OTP + Tem a certeza de que deseja copiar o segredo da OTP para a área de transferêencia?\n\nSó pode precisar se a app do seu autenticador tiver problemas para digitalizar QRCode, deseja digitá-lo manualmente ou deseja configurar o token OTP de hardware usando app dedicada. + Segredo da OTP (em formato Base32) exportado e copiado na áreas de transferênca. Cole-o no autenticador ou no hardware OTP burner! + 1. Instalar Autenticador + 3. Testar Uma-Senha-Única (OTP) + Repor Autenticadores + Instalar uma app Autenticador que suporte Tokens RFC 6238 TOTP em cada telefone seguidor. Populares aplicativos gratuitos são:\n • Authy\n • o Google Authenticator\n • LastPass Autenticador\n • FreeOTP Autenticador + Utilizador + Número de telefones permitidos + +XXXXXXXXXX;+YYYYYYYYYY + Para definir o Alvo Temporário %1$s responda com o código %2$s + Para cancelar Alvo Temporário responda com o código %1$s + Para desactivar o Serviço Remoto SMS de responda com o código %1$s.\n\nTenha em mente que será capaz de o reactivar directamente apenas a partir do telemóvel mestre do AAPS. + SMS Serviço Remoto interrompido. Para reactivá-lo, use o AAPS no telemóvel mestre. + Para enviar calibração %1$.2f responder com código %2$s + Bólus falhado + Número mínimo de minutos que deve decorrer entre um bólus remoto e o próximo + Quantos minutos deve decorrer, pelo menos, entre um bólus e o próximo + Para sua segurança, para editar esta preferência precisa adicionar pelo menos 2 números de telefone. + Bólus %1$.2f U administrado com sucesso + Bólus de Refeição %1$.2f U administrado com sucesso + Alvo %1$s para %2$d minutos + Alvo %1$s para %2$d minutos definido com sucesso + Alvo Temporário cancelado com êxito + Permitir comandos remotos via SMS + Loop foi desactivado + Loop foi activado + Loop activado + Para ligar a bomba responda com o código %1$s + Ligação à bomba falhou + Para remover a bomba por %1$d minutos responda com o código %2$s + Bomba removida + Bomba ligada novamente + O comando remoto não é permitido + O bólus remoto não está disponível. Tente novamente mais tarde. + Para iniciar basal %1$.2f U/h por %2$d min responda com o código %3$s + Para mudar o perfil para %1$s %2$d%% responda com o código %3$s + Para iniciar bólus prolongado %1$.2f U por %2$d min responda com o código %3$s + Para inserir %1$dg em %2$s responda com código %3$s + Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s + Para suspender o loop por %1$d minutos resposta com código %2$s + Para retomar o loop responda com o código %1$s + Para activar o loop responda com o código %1$s + Para desativar o loop responda com o código %1$s + Basal temporária %1$.2fU/h para %2$d min iniciada com êxito + Bólus prolongado %1$.2fU/h para %2$d min iniciado com êxito + Hidratos %1$d g inseridos com sucesso + Introdução de %1$dg de hidratos falhou + Basal temporária %1$d%% U/h durante%2$d min iniciada com êxito + Início basal temporária falhou + Falha ao iniciar o bólus prolongado + Para parar a basal temporária responda com o código %1$s + Para parar o bólus prolongado responda com o código %1$s + Basal temporária cancelada + Bólus prolongado cancelado + Não foi possível cancelar a basal temporária + Falhou a cancelar bólus prolongado + Comando desconhecido ou resposta errada + Existe outro bólus em espera. Tente novamente mais tarde. + Duração errada + Loop suspenso + Loop retomado + Número de telefone de SMS inválido + Calibração enviada. Receção tem de estar ativada na xDrip+. + O xDrip+ não está a receber as calibrações + Corpo da mensagem inválido + Enviar SMS se evento de bomba inacessível for acionado + Reportar bomba inacessível + Delta: + IA: + Bólus: + Basal: + diff --git a/plugins/src/main/res/values-ro-rRO/strings.xml b/plugins/src/main/res/values-ro-rRO/strings.xml new file mode 100644 index 0000000000..bc762bd907 --- /dev/null +++ b/plugins/src/main/res/values-ro-rRO/strings.xml @@ -0,0 +1,88 @@ + + + + Comunicator SMS + SMS + de la aplicația Authenticator pentru: %1$s urmat de PIN + PIN obligatoriu suplimentar la sfârșitul token-ului + Cifre suplimentare care ar trebui să fie memorate și adăugate la sfârșitul fiecărei parole unice generate + Cod de verificat: + OTP + cod PIN + Codul de verificare constă din 6 cifre afişate de către aplicaţia Authentificator (cunoscută ca OTP), urmat de 3 sau mai multe cifre de PIN obligatoriu. + Resetați Authenticatori + Resetați cheia pentru Authenticator + Sunteți sigur că vreți sa resetați cheia pentru Authenticator? Acest lucru va invalida toți Authenticatorii configurați și va trebui să ii setați din nou. + S-a generat o nouă cheie pentru Authenticator! Vă rugăm să utilizați QRCode actualizat pentru a configura autentificatori. + Se exporta secretul OTP + Sunteţi sigur că doriţi să copiaţi secretul OTP în clipboard?\n\nS-ar putea să aveţi nevoie doar dacă aplicaţia dumneavoastră de autentificare are probleme de scanare a QRCode, doriţi să o introduceţi manual sau doriţi să configuraţi token-ul hardware OTP folosind aplicaţia dedicată. + Secret OTP (în formatul Base32) exportat şi copiat în clipboard. Lipiţi-l în autentificator sau in hardware OTP burner! + 1. Instalați Authenticator + 3. Testați o parolă unică + Resetați Authenticatori + Pe fiecare telefon urmăritor instalați o aplicație de tip Authenticator care suporta tokens RFC 6238 TOTP. Asemenea aplicații gratuite populare sunt:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Utilizator + Numere de telefon permise + + XXXXXXXXXX; + YYYYYYYYYY + Pentru a seta tinta temporara %1$s raspundeti cu: %2$s + Pentru a anula tinta temporara raspundeți cu: %1$s + Pentru a dezactiva serviciul SMS la distanta raspundeti cu: %1$s.\n\nRetineti ca o sa il puteti reactiva doar direct de pe smartphone-ul master AAPS. + Serviciul SMS la distanta s-a oprit. Pentru a il reactiva, utilizati AAPS de pe smartphone-ul master. + Pentru a trimite calibrarea cu %1$.2f răspundeți cu codul %2$s + Bolusare eșuată + Numarul minim de minute care trebuie sa treaca intre un bolus la distanta si urmatorul + Cate minute trebuie sa treaca, cel puţin, intre un bolus si următorul + Pentru siguranta dumneavoastra, pentru a edita aceasta preferinta trebuie sa adaugati cel putin 2 numere de telefon. + Bolusul de %1$.2fU a fost livrat cu succes + Bolusul de masa de %1$.2fU a fost livrat cu succes + Țintă %1$s pentru %2$d minute + Tinta %1$s pentru %2$d minute este setata cu succes + Tinta temporara anulata cu succes + Permite comenzi de la distanță, prin SMS + Bucla a fost dezactivată + Bucla a fost activată + Bucla este activată + Pentru a conecta pompa raspundeti cu codul %1$s + Conectarea cu pompa a esuat + Pentru a deconecta pompa timp de %1$d minute, răspundeți cu: %2$s + Pompă deconectată + Pompă reconectată + Comanda de la distanță nu este permisă + Bolus de la distanță nu este disponibil. Încearcă din nou mai târziu. + Pentru a iniția bazala de %1$.2fU/h pentru %2$d min trimiteți codul %3$s + Pentru a schimba profilul în %1$s %2$d%% trimiteți codul %3$s + Pentru a iniția bolusul extins de %1$.2fU/h pentru %2$d min trimiteți codul %3$s + Pentru a introduce %1$dg la %2$s, raspundeti cu: %3$s + Pentru a iniția bazala de %1$d%% pentru %2$d min trimiteți codul %3$s + Pentru suspendarea buclei pentru %1$d minute trimiteți codul %2$s + Pentru a reactiva bucla inchisa, raspundeti cu %1$s + Pentru a activa bucla inchisa, raspundeti cu %1$s + Pentru a dezactiva bucla inchisa, raspundeti cu %1$s + Bazala temporară %1$.2fU/h pentru %2$d minute a fost trimisă cu succes + Bolusul extins de %1$.2fU pentru %2$d min a fost inițiat + %1$dg carbohidrați introduși cu succes + Introducerea a %1$dg de carbohidrati a esuat + Bazala temporară %1$d%% pentru %2$d minute a fost stabilită cu succes + Trimiterea bazalei temporare a eșuat + Pornirea bolusului extins a eșuat + Pentru oprirea bazalei temporare, răspundeți cu codul %1$s + Pentru oprirea bolusului extins, răspundeți cu codul %1$s + Bazala temporară a fost anulată + Bolus extins anulat + Renunțarea la bazala temporară a eșuat + Anularea bolusului extins a eșuat + Comandă necunoscută sau răspuns greșit + Există un alt bolus în coada de așteptare. Încercați din nou mai târziu. + Durată greșită + Buclă suspendată + Buclă restabilită + Număr de telefon SMS invalid + Calibrare trimisă. Recepționarea trebuie să fie activată și în xDrip+. + xDrip+ nu recepționează calibrări + Conținutul mesajului nu este valid + Trimite SMS dacă este generata o alarma de eroare conexiune pompa + Raportează pompa inaccesibilă + Diferență: + IOB: + Bolus: + Bazală: + diff --git a/plugins/src/main/res/values-ru-rRU/strings.xml b/plugins/src/main/res/values-ru-rRU/strings.xml new file mode 100644 index 0000000000..f6f72bcd77 --- /dev/null +++ b/plugins/src/main/res/values-ru-rRU/strings.xml @@ -0,0 +1,92 @@ + + + + SMS коммуникатор + SMS + Дистанционное управление AAPS при помощи команд SMS. + из приложения Authenticator для %1$s и дополните пином в конце + Дополнительный обязательный пин-код в конце маркера + Дополнительные цифры, которые должны быть запомнены и добавлены в конце каждого сгенерированного одноразового пароля + Код для проверки: + OTP + ПИН-код + Проверочный код состоит из 6 цифр, отображаемых приложением Authenticator (известным как OTP), за которым следует 3 или более цифр обязательного PIN-кода. + Сбросить аутентификаторы + Сбросить ключ идентификации + Вы действительно хотите сбросить ключ аутентификации? Все сконфигурированные в настоящее время ключи станут недопустимы, и придется их настроить заново. + Создан новый ключ аутентификации! Для идентификации используйте обновленный QRCode. + Экспорт секретного кода OTP + Вы действительно хотите скопировать пароль OTP в буфер обмена?\n\nЭто может потребоваться только в том случае, если у вашего приложения идентификации проблемы при сканировании QR кода, вы хотите ввести его вручную или настроить аппаратный маркер OTP с помощью специального приложения. + Секретный одноразовый код OTP (в формате Base32) экспортирован и скопирован в буфер обмена. Вставьте его в систему идентификации или аппаратный маркер OTP! + 1. Установить Аутентификатор + 2. Сканируйте код для настройки OTP кодов AAPS + 3. Одноразовый Пароль + Сбросить аутентификаторы + В каждом отслеживающем телефоне установите приложение Authenticator, поддерживающее маркеры TOTP RFC 6238. Популярные бесплатные приложения: \n Authy\n Google Authenticator\n LastPass Authenticator\n FreeOTP Authenticator + После сброса аутентификатора вы делаете все созданные идентификаторы недействительными. Вам нужно будет снова создать их! + Пользователь + разрешенные телефонные номера + + XXXXXXXXXX; + YYYYYYYYYY + Чтобы установить временную цель %1$s ответьте кодом %2$s + Чтобы отменить временную цель ответьте кодом %1$s + Чтобы отключить службу удаленных SMS-сообщений ответьте кодом %1$s.\n\n Имейте в виду, что вы сможете вновь активировать ее только с основного телефона AAPS. + Удаленная служба SMS остановлена. Для ее реактивации используйте AAPS на главном смартфоне. + чтобы отправить калибровку %1$.2f ответьте кодом %2$s + Подача болюса не состоялась + Минимальное количество минут между одним удаленным болюсом и следующим + Минимум минут, должных пройти между одним болюсом и следующим + В целях безопасности, для изменения этого параметра необходимо добавить не менее 2 телефонных номеров. + Болюс %1$.2fед. подан успешно + Болюс на еду %1$.2f ед. подан успешно + Цель %1$s на %2$d минут + Цель %1$s на %2$d минут установлена успешно + Временная цель успешно отменена + разрешить команды через смс + зцикл был деактивирован + зцикл был активирован + зцикл работает + Чтобы подсоединить помпу ответьте кодом %1$s + Ошибка подключения к помпе + Для разъединения с помпой на %1$d мин ответьте кодом %2$s + Помпа отключена + Связь с помпой возобновлена + удаленная команда не разрешена + Удаленный болюс недоступен, повторите попытку позже. + Для начала подачи базала %1$.2f ед./ч на %2$d мин. ответьте кодом %3$s + Для переключения профиля на %1$s %2$d%% ответьте кодом %3$s + Для начала подачи пролонгированного болюса %1$.2fед. на %2$d мин. ответьте кодом %3$s + Чтобы ввести %1$d г в %2$s ответьте кодом %3$s + Для начала подачи базала %1$d%% на %2$d мин. ответьте кодом %3$s + для приостановки цикла на %1$d мин ответьте кодом %2$s + Чтобы возобновить цикл ответьте кодом %1$s + Чтобы включить цикл ответьте кодом %1$s + Чтобы отключить цикл ответьте кодом %1$s + врем базал %1$.2fU/h на %2$d мин начат успешно + Пролонгированный болюс %1$.2fед. на %2$d мин. начат успешно + Углеводы %1$d г введены успешно + Не удалось ввести %1$d г углеводов + Врем. базал %1$d%% на %2$d мин. начат успешно + неуспех старта врем базала + Не удалось начать подачу пролонгированного болюса + Для прекращения подачи врем. базала ответьте кодом %1$s + Для прекращения подачи пролонгированного болюса ответьте кодом %1$s + врем базал отменен + Пролонгированный болюс отменен + отмена врем базала не состоялась + Сбой отмены пролонгированного болюса + Неизвестная команда или неверный ответ + В очереди есть еще один болюс. Повторите попытку позже. + неверное значение длительности + ЗЦ остановлен + ЗЦикл возобновлен + неверный номер телефона для смс + Калибровка отправлена. В xDrip+ должен быть включена возможность приема. + xDrip + не получает калибровки + Недопустимое тело сообщения + Отправить SMS, если инициируется запись о недоступности помпы + Сообщить о недоступности помпы + дельта: + IOB: активный инсулин + болюс: + базал: + QR код для введения временного пароля + diff --git a/plugins/src/main/res/values-sk-rSK/strings.xml b/plugins/src/main/res/values-sk-rSK/strings.xml new file mode 100644 index 0000000000..a1c75045c7 --- /dev/null +++ b/plugins/src/main/res/values-sk-rSK/strings.xml @@ -0,0 +1,105 @@ + + + + SMS komunikátor + SMS + Ovládanie AAPS na diaľku použitím SMS príkazov. + z aplikácie Authenticator pre: %1$s nasledované kódom PIN + Ďalší povinný kód PIN na konci tokenu + Ďalšie číslice, ktoré by mali byť zapamätané a pridané na koniec každého vygenerovaného jednorázového hesla + Nastavenie autentifikátora + Kód pre kontrolu: + OTP + PIN + Overovací kód sa skladá zo 6 číslic zobrazených aplikáciou Authenticator (známej ako OTP) nasledované 3, alebo viacerými číslicami povinného kódu PIN. + Resetovať autentifikátory + Resetovať autentifikačný kľúč + Ste si istý, že chcete obnoviť autentifikačný kľúč? Vyresetujete tým všetky aktuálne nakonfigurované autentikátory a budete ich musieť znovu nastaviť. + Bol vygenerovaný nový autentifikačný kľúč! Prosím, použite aktualizovaný QR kód pre nastavenie autentifikátorov. + Export OTP tajného kľúča + Ste si istý, že chcete skopírovať tajný OTP kľúč do schránky?\n\nPravdepodobne to budete potrebovať iba v prípade, keď bude mať vaša overovacia aplikácia problém so skenováním QR kódu, chcete ho zadať ručne, alebo chcete nakonfigurovať hardwarový OTP token pomocou špeciálnej aplikácie. + Tajné OTP heslo (vo formáte Base32) bolo vyexportované a skopírované do schránky. Vložte ho do autentikátora, alebo programátora OTP hardwaru! + 1. Nainštalujte Autentifikátor + 2. Naskenujte kód pre nastavenie AAPS OTP kódov + 3. Odtestujte jednorázové heslo + Resetovať autentifikátory + Na každom sledovacom telefóne nainštalujte Autentifikátor, ktorý podporuje tokeny TOTP RFC 6238. Najobľúbenejšie bezplatné aplikácie sú:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Resetovaním autentifikátora budú všetky už poskytnuté autentifikátory neplatné. Budete ich musieť znovu nastaviť! + Nesprávný kód. Príkaz zrušený. + Vypršal časový limit pri čakaní na dokončenie predchádzajúcej komunikácie s pumpou + Používateľ + Povolené telefónne čísla + +421XXXXXXXXX;+421YYYYYYYYY + Pre podanie bolusu %1$.2fJI odpovedz SMS kódom %2$s + Pre podanie bolusu k jedlu %1$.2fJI odpovedz SMS kódom %2$s + Pre nastavenie dočasného cieľa %1$s odpovedz SMS kódom %2$s + Pre zrušenie dočasného bazálu odpovedzte SMS s kódom %1$s + Pre vypnutie služby SMS komunikátora odpovedz SMS kódom %1$s.\n\n\Majte na pamäti, že opätovná reaktivácia je možná len priamo na AAPS master telefóne. + SMS komunikátor zastavený. Na jeho reaktiváciu, použite AAPS na master telefóne. + Pre odoslanie kalibrácie %1$.2f odpovedz SMS kódom %2$s + Chyba pri aplikovaní bolusu + Minimálny počet minút, ktorý musí uplynúť medzi jedným vzdialeným bolusom a tým nasledujúcim + Aspoň koľko minút musí uplynúť, medzi jedným vzdialeným bolusom a tým nasledujúcim + Pre vašu bezpečnosť, musíte pridať aspoň 2 telefónne čísla, aby ste zmenili toto prednastavenie. + Bolus %1$.2f JI podaný úspešne + Bolus na jedlo %1$.2f JI podaný úspešne + Cieľ %1$s na %2$d minút + Cieľ %1$s na %2$d minút bol úspešne nastavený + Dočasný cieľ úspešne zrušený + Povoliť príkazy na diaľku cez SMS + Uzavretý okruh bol deaktivovaný + Uzavretý okruh bol aktivovaný + Uzavretý okruh je aktivovaný + Ak chcete pripojiť pumpu, odpovedzte pomocou SMS s kódom %1$s + Pripojenie k pumpe zlyhalo + Ak chcete odpojiť pumpu na %1$d minút, odpovedzte pomocou SMS s kódom %2$s + Pumpa odpojená + Pumpa bola znovu pripojená + Príkazy na diaľku nie sú povolené + Diaľkovo ovládaný bolus nie je momentálne povolený. Skúste to neskôr. + Pre spustenie bazálu %1$.2f JI/h na %2$d min odpovedzte SMS s kódom %3$s + Pre prepnutie profilu na %1$s %2$d%% odpovedzte SMS s kódom %3$s + Pre spustenie predĺženého bolusu %1$.2f JI na %2$d min odpovedzte SMS s kódom %3$s + Pre zadanie %1$dg na %2$s odpovedz SMS kódom %3$s + Pre spustenie bazálu %1$d%% na %2$d min odpovedzte SMS s kódom %3$s + Pre pozastavenie uzavretého okruhu na %1$d minút odpovedaj SMS s kódom %2$s + Pre obnovenie uzavretého okruhu, odpovedzte SMS s kódom %1$s + Pre povolenie uzavretého okruhu, odpovedzte SMS s kódom %1$s + Pre zakázanie uzavretého okruhu, odpovedzte SMS s kódom %1$s + Dočasný bazál %1$.2fJI/h spustený na %2$d minút + Predĺžený bolus %1$.2fJI na %2$d min úspešne spustený + Sacharidy %1$d g zadané úspešne + Zadanie %1$dg sacharidov sa nepodarilo + Dočasný bazál %1$d%% na %2$d minút úspešne spustený + Spustenie dočasného bazálu zlyhalo + Spustenie predĺženého bolusu zlyhalo + Na zastavenie dočasného bazálu odpovedzte SMS s kódom %1$s + Na zastavenie predĺženého bolusu odpovedzte SMS s kódom %1$s + Dočasný bazál zrušený + Predĺžený bolus zastavený + Zrušenie dočasného bazálu zlyhalo + Zastavenie predĺženého bolusu zlyhalo + Neznámy príkaz alebo chybná odpoveď + Vo fronte je ďalší bolus. Skúste to znovu neskôr. + Nesprávna doba trvania + Uzavretý okruh pozastavený + Uzavretý okruh obnovený + Chybné telefónne číslo + Kalibrácia odoslaná. Príjem kalibrácií musí byť povolený v xDrip+. + xDrip+ neprijíma kalibrácie + Neplatný obsah správy + Odoslať SMS, pokiaľ pumpa nie je dostupná + Nahlásiť nedostupnú pumpu + Chybný formát + Glykémia: + Posledná glykémia: + Rozdiel: + IOB: + Bolus: + Bazál: + pred %1$d min + Pozastavený (%1$d min) + Načítanie stavu zlyhalo + Prepnutie profilu vytvorené + Trvanie dočasného bazálu musí byť násobkom %1$d minút a musí byť väčšie ako 0. + QR kód pre nastavenie jednorázového hesla + diff --git a/plugins/src/main/res/values-sr-rCS/strings.xml b/plugins/src/main/res/values-sr-rCS/strings.xml new file mode 100644 index 0000000000..c06688ea2e --- /dev/null +++ b/plugins/src/main/res/values-sr-rCS/strings.xml @@ -0,0 +1,46 @@ + + + + SMS komunikator + Daljinsko upravljanje AAPS-om pomoću SMS naredbi. + Dozvoljeni brojevi telefona + +XXXXXXXXXX;+YYYYYYYYYY + Da bi podesili privremeni cilj %1$s odgovori sa kodom %2$s + Da otkažete privremenog cilja odgovorI sa kodom %1$s + Da bi onemogućili SMS usluga na daljinu odgovori sa kodom %1$s.\n\nImaj na umu da ćeš moći da ga ponovo aktiviraš direktno samo sa AAPS glavnog pametnog telefona. + SMS usluga na daljinu je zaustavljen. Da bi je ponovo aktivirali, koristite AAPS na glavnom pametnom telefonu. + Za slanje kalibracije %1$.2f odgovori sa kodom %2$s + Bolus nije uspeo + Minimalni broj minuta koji mora da prođe između jednog daljinskog bolusa i sledećeg + Koliko minuta mora da prođe najmanje između jednog bolusa i sledećeg + Radi tvoje sigurnosti, za izmenu ove postavke, moraš dodati najmanje 2 telefonska broja. + Bolus %1$.2f U je uspešno isporučen + Bolus za obrok %1$.2f U je uspešno isporučen + Cilj %1$s za %2$d minuta + Cilj %1$s za %2$d minuta je uspešno postavljen + Privremeni cilj uspješno je otkazan + Dozvoli daljinske komande putem SMS-a + Petlja je onemogućena + Petlja je omogućena + Petlja je omogućena + Za povezivanje pumpe, odgovori sa kodom %1$s + Povezivanje sa pumpom nije uspelo + Za isključivanje pumpe na %1$d minuta, odgovori sa kodom %2$s + Pumpa nije povezana + Pumpa je ponovo povezana + Daljinska komanda nije dozvoljena + Daljinski bolus nije dostupan. Pokušaj ponovo kasnije. + Za početak bazala %1$.2f U/h za %2$d min odgovori sa kodom %3$s + Za promenu profila na %1$s %2$d%% odgovori sa kodom %3$s + Za početak produženog bolusa %1$.2f U za %2$d min, odgovori sa kodom %3$s + Za unos %1$dg u %2$s odgovori sa kodom %3$s + Za početak bazala %1$d%% za %2$d min, odgovori sa kodom %3$s + Za obustavljanje petlje na %1$d minuta, odgovori sa kodom %2$s + Za nastavak petlje odgovori sa kodom %1$s + Za omogućavanje petlje odgovori sa kodom %1$s + Za onemogućavanje petlje odgovori sa kodom %1$s + Delta: + IOB: + Bolus: + Basal: + diff --git a/plugins/src/main/res/values-sv-rSE/strings.xml b/plugins/src/main/res/values-sv-rSE/strings.xml new file mode 100644 index 0000000000..ee3658d266 --- /dev/null +++ b/plugins/src/main/res/values-sv-rSE/strings.xml @@ -0,0 +1,88 @@ + + + + SMS-tjänst + SMS + från autentiseringsapp för: %1$s följt av PIN-kod + PIN-kod som läggs till på slutet + Ytterligare siffror som ska memoreras och läggas till i slutet av varje genererat engångslösenord + Kod att kontrollera: + OTP + PIN-kod + Verifieringskoden består av sex siffror som visas av autentiseringsappen (känd som OTP) följt av 3 eller fler siffror som är en valbar PIN-kod. + Återställ autentiserare + Återställ autentiseringsnyckel + Är du säker på att återställa autentiseringsnyckeln? Det gör alla konfigurerade autentiseringsappar ogiltiga och du kommer behöva ställa in dem igen. + Ny autentiseringsnyckel genererades! Använd uppdaterad QR-kod till att aktivera autentiserare. + Exporterar OTP-hemlighet + Är du säker på att du vill kopiera OTP-hemligheten till Urklipp?\n\nDu behöver bara göra detta om din autentiseringsapp har problem QR-koder så du vill ange den manuellt eller om du vill konfigurera OTP-token med hjälp av en dedikerad app. + OTP-hemligheten exporteras och kopieras till klippbordet i Base32-format. Klistra in den i autentiseringsfunktionen eller OTP-brännaren! + 1. Installera autentiseringsapp + 3. Testa engångslösenord + Återställ autentiserare + På varje följartelefon behöver man installera en autentiseringsapp som stöder RFC 6238 TOTP tokens. Populära gratisappar är:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Ditt namn + Godkända telefonnummer + +4670XXXXXXX; +4670YYYYYYY + För att sätta ett temporärt mål på %1$s svara med kod %2$s + För att avbryta temporärt mål, svara med kod: %1$s + För att inaktivera fjärrkommandon via SMS, svara med kod: %1$s \n\nTänk på att måste ha tillgång till huvudtelefonen för att kunna återaktivera. + Fjärrkommandon via SMS stoppas. För att återaktivera detta, använd Konfigurationsverktyget på huvudtelefonen. + För att skicka kalibrering %1$.2f, svara med kod %2$s + Bolus misslyckades + Minsta antal minuter som måste förflyta mellan en fjärrbolus och nästa + Minsta antal minuter mellan fjärrbolus + För att redigera den här inställningen måste du, för din säkerhet, lägga till minst 2 telefonnummer. + Bolus %1$.2f enheter levererat + Bolus på %1$.2f enheter levererat + Temporärt mål på %1$s är satt i %2$d minuter + Temporärt mål på %1$s är satt i %2$d minuter + Temporärt mål avbrutet + Tillåt fjärrstyrning via SMS + Loop inaktiverad. + Loop aktiverad + Loop är aktiverad + För att ansluta pumpen, svara med kod %1$s + Anslutning till pump misslyckades + För att koppla från pumpen i %1$d minuter, svara med kod %2$s + Pump frånkopplad + Pump återansluten + Otillåtet fjärrkommando + Fjärrbolus inte tillgängligt. Försök igen senare. + För att starta temp basal %1$.2f enheter/tim i %2$d min, svara med kod %3$s + För att byta till profil %1$s %2$d%% svara med kod %3$s + För att starta förlängd bolus med %1$.2f enheter över %2$d min, svara med kod %3$s + Om du vill ange %1$dg kl. %2$s, svara med kod %3$s + För att starta temp basal %1$d%% i %2$d min, svara med kod %3$s + För att pausa loop i %1$d minuter, svara med kod %2$s + För att återuppta loopen, svara med kod %1$s + För att aktivera loopen, svara med kod %1$s + För att inaktivera loopen, svara med kod %1$s + Temp basal %1$.2f enheter/tim i %2$d min startad + Förlängd bolus %1$.2f enheter över %2$d min har startats + %1$dg kolhydrater registrerat + Misslyckades med att registrera %1$dg kolhydrater + Temp basal %1$d%% enheter/tim i %2$d min startad + Fel vid start av temp basal + Lyckades inte starta förlängd bolus + För att stoppa temp basal, svara med kod %1$s + För att stoppa förlängd bolus, svara med kod %1$s + Temp basal avbruten + Förlängd bolus avbruten + Misslyckades med att avbryta temp basal + Avbryter förlängd bolus + Okänt kommando eller fel svar + Det finns en annan bolus i kö. Försök igen senare. + Fel duration + Loop pausad + Loop återupptagen + Ogiltigt telefonnummer för SMS + Kalibrering skickad. Observera att xDrip+ måste vara inställd att ta emot kalibreringar. + xDrip+ tar inte emot kalibreringar + Ogiltigt innehåll i meddelande + Skicka SMS om pumpen inte kan nås + Rapportera om pump inte kan nås + Delta: + IOB: + Bolus: + Basal: + diff --git a/plugins/src/main/res/values-tr-rTR/strings.xml b/plugins/src/main/res/values-tr-rTR/strings.xml new file mode 100644 index 0000000000..950efffb5b --- /dev/null +++ b/plugins/src/main/res/values-tr-rTR/strings.xml @@ -0,0 +1,92 @@ + + + + SMS Kominikatör + SMS + SMS komutlarını kullanarak AAPS\'yi uzaktan kontrol edin. + authenticator uygulamasından %1$s için PIN girin + İlave zorunlu şifre (PIN) + Oluşturulan Her Tek Kullanımlık Şifrenin sonunda ezberlenmesi ve yapıştırılması gereken ek şifre + Kontrol edilecek kod: + OTP + PIN + Doğrulama kodu, Authenticator uygulaması (OTP olarak bilinir) tarafından görüntülenen 6 haneden ve ardından 3 veya daha fazla zorunlu PIN hanesinden oluşur. + Kimlik Doğrulayıcıları (OTP) Sıfırla + Kimlik Doğrulayıcı Anahtarını Sıfırla + Kimlik Doğrulayıcı (Authenticator) anahtarını sıfırlamak istediğinizden emin misiniz? Şu anda yapılandırılmış tüm Kimlik Doğrulayıcıları geçersiz kılar ve bunları yeniden ayarlamanız gerekir. + Yeni Kimlik Doğrulayıcı (Authenticator) Anahtarı oluşturuldu! Kimlik doğrulayıcıları için lütfen güncellenmiş QRCode\'u kullanın. + OTP dışa aktarma + OTP secret panoya kopyalamak istediğinizden emin misiniz?\n\nYalnızca kimlik doğrulama uygulamanızın QRCode\'u tarama sorunları varsa, bunu elle girmek veya uygulamayı kullanarak OTP donanımı yapılandırmak istiyorsanız buna ihtiyacınız olabilir. + OTP secret (Base32 formatında) dışa aktarıldı ve panoya kopyalandı. Doğrulayıcıya veya OTP donanım yazıcısına yapıştırın! + 1. Doğrulayıcıyı (Authenticator) yükleyin + 2. AAPS OTP kod kurulumu için QR kodu tarayın + 3. Tek Kullanımlık Parolayı (OTP) Test Edin + Doğrulayıcıları (Authenticators) Sıfırla + Her takipçi telefonunda, RFC 6238 TOTP belirteçlerini destekleyen Kimlik Doğrulayıcı uygulamasını yükleyin. Popüler ücretsiz uygulamalar şunlardır:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Kimlik doğrulayıcıyı sıfırlayarak, önceden sağlanmış tüm doğrulayıcıları geçersiz kılarsınız. Onları tekrar kurmanız gerekecek! + Kullanıcı + İzinli telefon numaraları + +XXXXXXXXXX;+YYYYYYYYYY + Geçici Hedefi %1$s yapmak için %2$s koduyla yanıt verin + Geçici Hedefi iptal etmek için %1$s koduyla yanıt verin + SMS Uzak Hizmet desteğini devre dışı bırakmak için %1$s koduyla yanıt verin.\n\nBu hizmeti yalnızca AAPS yüklü ana telefondan yeniden etkinleştirebileceğinizi unutmayın. + SMS Uzak Hizmeti durduruldu. Yeniden etkinleştirmek için ana telefondaki APPS\'i kullanın. + Kalibrasyon için %1$.2f gönderilecek, kod ile cevap ver %2$s + Bolus başarısız oldu + Bir sms bolusu ile bir sonraki bolus arasında geçmesi gereken minimum dakika sayısı + Bir sms bolus gönderimi ile bir sonraki bolus arasında en az kaç dakika geçsin? + Güvenliğiniz için en az 2 telefon numarası eklemeniz gerekir. + %1$.2f U Bolus başarıyla gönderildi + %1$.2f U Yemek Bolusu başarıyla gönderildi + Hedef %2$d dakika boyunca %1$s + Hedef %2$d dakika boyunca %1$s olarak başarıyla ayarlandı + Geçici Hedef başarıyla iptal edildi + SMS ile uzaktan komutlara izin ver + Döngü devre dışı bırakıldı + Döngü etkinleştirildi + Döngü etkin + Pompaya bağlanmak için %1$s koduyla yanıt verin + Pompa bağlantısı başarısız + Pompanın bağlantısını %1$d dakika boyunca kesmek için %2$s koduyla yanıtlayın + Pompa bağlantısı kesildi + Pompa yeniden bağlandı + Uzaktan komuta izin verilmez + Uzaktan bolus gönderilemiyor. Daha sonra tekrar deneyin. + %2$d dk boyunca bazalı %1$.2f Ü/sa yapmak için %3$s koduyla yanıtlayın + Profili %1$s %2$d%% olarak değiştirmek için %3$s koduyla yanıtlayın + %2$d dakika boyunca %1$.2f U yayma bolus başlatmak için %3$s koduyla yanıtlayın + %2$s\'de %1$dg girmek için %3$s koduyla yanıtlayın + %2$d dk boyunca bazal %1$d%% başlatmak için %3$s koduyla yanıtlayın + Döngüyü %1$d dakika askıya almak için %2$s koduyla yanıtlayın + Döngüye devam etmek için %1$s koduyla yanıtlayın + Döngüyü etkinleştirmek için %1$s koduyla yanıtlayın + Döngüyü iptal etmek için %1$s koduyla yanıtlayın + Geçici bazal %1$.2fÜ/s %2$d dakika için başarıyla başlatıldı + %1$.2fU yayma bolus %2$d dakika boyunca başarıyla başlatıldı + %1$d g karbonhidrat başarıyla sisteme girildi + %1$d g karbonhidrat girilemedi + %2$d dakikalık geçici bazal %1$d%% başarıyla başlatıldı + Geçici bazal başlatma başarısız oldu + Yayma bolus başlatma başarısız oldu + Geçici bazalı durdurmak için %1$s kodunu gir + Yayma bolusu durdurmak için %1$s koduyla yanıtlayın + Geçici bazal iptal edildi + Yayma bolus iptal edildi + Geçici bazal iptal edilemedi + Yayma bolus iptal edilemedi + Bilinmeyen komut veya yanlış cevap + Sırada başka bir bolus var. Daha sonra tekrar deneyin. + Yanlış süre + Döngü duraklatıldı + Döngü devam ettirildi + Geçersiz SMS telefon numarası + Kalibrasyon gönderildi. Alma xDrip+\'ta etkinleştirilmelidir. + xDrip+ kalibrasyonları almıyor + Geçersiz mesaj + Pompa ulaşılamazsa SMS gönder + Pompaya ulaşılamadığını bildir + Delta: + AİNS: + Bolus: + Bazal: + Tek kullanımlık şifre kurulumu için QR Kodu + diff --git a/plugins/src/main/res/values-zh-rCN/strings.xml b/plugins/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000000..ca3e93e362 --- /dev/null +++ b/plugins/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,89 @@ + + + + SMS短信通讯器 + 手机SMS + 从验证码生成器应用获取%1$s的随机码,并附加PIN码 + 验证码末尾强制附加的PIN码 + 在每次生成的一次性随机密码末尾,需要记住并强制附加的数字。 + 验证码检查: + OTP随机 + PIN固定 + 验证码包含6位数字,由验证器应用程序生成(称为OTP),然后再包含3位或3位以上的必填数字PIN码。 + 重置身份验证器 + 重置身份验证器的密钥 + 你确定要重置验证器密钥吗?它将导致以前配置的OTP随机验证码无效,您需要重新设置它们(在遥控手机的OTP应用上)。 + 生成了新的身份验证器密钥!请使用更新的二维码设置验证器。 + 导出OTP密钥 + 你确定要将OTP密钥复制到剪贴板?\n\n只有在验证器应用扫描二维码出现问题时,你才需要这么做。可能你想手动输入二维码,或者使用专用的应用程序配置硬件OTP令牌。 + 将OTP密钥 (Base32 格式) 导出并复制到剪贴板。粘贴它到身份验证器或硬件OTP中! + 1. 安装身份验证器app + 3. 测试一次性验证码 + 重置身份验证器 + 在其他遥控手机上安装支持RFC 6238 TOTP令牌协议的应用程序。常用的免费应用有:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + 用户 + 允许的手机号码 + +XXXXXXXXXX;+YYYYYYYYYY + 要设置临时目标 %1$s,请回复验证码 %2$s + 要取消临时目标,请回复验证码 %1$s + 要禁用短信遥控服务,请回复验证码%1$s.\n\n请记住,你只能在AAPS闭环手机上重新激活此功能。 + 短信遥控服务已禁用。要重新激活它,请使用AAPS闭环手机。 + 要发送校准值 %1$.2f 回复如下代码 %2$s + 大剂量输注失败 + 一次远程遥控输注命令与下一次命令之间必须经过的最小分钟数 + 两次短信遥控胰岛素输注的时间间隔 + 为了您的安全,您需要添加至少两个电话号码。 + 成功输注大剂量%1$.2fU + 成功输注餐时大剂量%1$.2fU + 目标 %1$s 执行 %2$d 分钟 + 目标 %1$s 执行 %2$d 分钟设置成功 + 临时目标已成功取消 + 通过SMS短信允许远程命令 + 闭环已经被禁用 + 闭环已经被启用 + 闭环被启用 + 连接泵,请回复验证码:%1$s + 连接泵失败 + 断开泵%1$d分钟,请回复验证码:%2$s + 泵已断开 + 泵已重新连接 + 远程命令没有被允许 + 远程大剂量不可用。请稍后再试。 + 执行基础率%1$.2fU/h持续时间%2$d分钟,请回复验证码:%3$s + 要切换配置文件到 %1$s %2$d%% 请回复代码 %3$s + 要开始扩展大剂量 %1$.2fU/h 持续时间%2$d 分钟,请回复验证码:%3$s + 要在 %2$s 输入 %1$d 克,请回复验证码 %3$s + 要开始基础率 %1$d%% 持续时间%2$d 分钟,请回复如下代码 %3$s + 要暂停闭环 %1$d 分钟请回复如下代码 %2$s + 恢复闭环,请回复验证码:%1$s + 启用闭环,请回复验证码:%1$s + 禁用闭环,请回复验证码:%1$s + 临时基础率 %1$.2fU/h 持续 %2$d 分钟启用成功了 + 扩展大剂量 %1$.2fU/h 持续时间 %2$d 分钟已经启用成功了 + 碳水%1$d克输入成功 + 输入 %1$d 克碳水化合物失败 + 临时基础率 %1$d%% 持续时间 %2$d 分钟 启用成功了 + 开始临时基础率失败了 + 开始扩展大剂量失败了 + 要停止临时基础率,请回复如下代码 %1$s + 要停止扩展大剂量,请回复如下代码 %1$s + 临时基础率取消了 + 扩展大剂量已经取消了 + 取消临时基础率失败 + 取消扩展大剂量失败 + 未知的命令或者错误的回复 + 队列中在执行另一个大剂量命令,请稍后再试。 + 错误的持续时间 + 闭环暂停了 + 闭环恢复了 + 无效的SMS手机号码 + 校准已发送。必须在 xDrip+ 中启用接收功能。 + xDrip+未接收校准 + 无效消息 + 如果触发泵连接丢失事件,则发送短信通知。 + 泵连接丢失报告 + 增量: + IOB活性胰岛素: + 大剂量: + 基础率: + 用于安装一次性随机验证码的二维码 + diff --git a/ui/src/main/res/values-af-rZA/strings.xml b/ui/src/main/res/values-af-rZA/strings.xml new file mode 100644 index 0000000000..f6ef331c8f --- /dev/null +++ b/ui/src/main/res/values-af-rZA/strings.xml @@ -0,0 +1,9 @@ + + + Geen aksie gekies, niks sal gebeur + Begin aktiwiteit TT + Begin eet gou TT + Begin hipo TT + Tyd verskil + min + diff --git a/ui/src/main/res/values-bg-rBG/strings.xml b/ui/src/main/res/values-bg-rBG/strings.xml new file mode 100644 index 0000000000..23dc87c145 --- /dev/null +++ b/ui/src/main/res/values-bg-rBG/strings.xml @@ -0,0 +1,10 @@ + + + Няма избрано действие, нищо няма да се изпълни + Старт на вр.цел за физ. активност + Старт на вр. цел за Eating soon + Старт на вр. цел при хипо + времево отместване + мин + Напомни за болус по-късно + diff --git a/ui/src/main/res/values-ca-rES/strings.xml b/ui/src/main/res/values-ca-rES/strings.xml new file mode 100644 index 0000000000..86efe6ff86 --- /dev/null +++ b/ui/src/main/res/values-ca-rES/strings.xml @@ -0,0 +1,9 @@ + + + Cap acció sel·leccionada, no passarà res + Iniciar OT: Esport + Iniciar OT: Menjar aviat + Iniciar OT: Hipo + Decalatge horari + min + diff --git a/ui/src/main/res/values-cs-rCZ/strings.xml b/ui/src/main/res/values-cs-rCZ/strings.xml new file mode 100644 index 0000000000..fe1f60711a --- /dev/null +++ b/ui/src/main/res/values-cs-rCZ/strings.xml @@ -0,0 +1,16 @@ + + + Žádná akce nevybrána, nic se neprovede + Aplikováno omezení! + Aplikováno omezení bolusu + Aplikováno omezení sacharidů + DC + Dialog zrušen + Spustit dočasný cíl Aktivita + Spustit dočasný cíl Před jídlem + Spustit dočasný cíl Hypoglykémie + Časový posun + min + Upozornit později na bolus + nastavit připomenutí + diff --git a/ui/src/main/res/values-da-rDK/strings.xml b/ui/src/main/res/values-da-rDK/strings.xml new file mode 100644 index 0000000000..a8bebf5ec1 --- /dev/null +++ b/ui/src/main/res/values-da-rDK/strings.xml @@ -0,0 +1,12 @@ + + + Ingen handling valgt, intet vil ske + Dialog annulleret + Start Aktivitets mål + Start \"Spiser snart\" mål + Begynd Hypo mål + Tidsforskydning + min. + Påmind om at bolus senere + Indstil påmindelse + diff --git a/ui/src/main/res/values-de-rDE/strings.xml b/ui/src/main/res/values-de-rDE/strings.xml new file mode 100644 index 0000000000..acefcde665 --- /dev/null +++ b/ui/src/main/res/values-de-rDE/strings.xml @@ -0,0 +1,12 @@ + + + Keine Aktion ausgewählt, nichts wird geschehen. + Dialog abgebrochen + Starte Aktivitäts-TT + Starte Essens-TT + Starte Hypo-TT + Zeitversatz + Min. + Später an Bolus erinnern + Erinnerung einstellen + diff --git a/ui/src/main/res/values-el-rGR/strings.xml b/ui/src/main/res/values-el-rGR/strings.xml new file mode 100644 index 0000000000..cd02ed9df4 --- /dev/null +++ b/ui/src/main/res/values-el-rGR/strings.xml @@ -0,0 +1,9 @@ + + + Δεν έχει επιλεγεί καμία ενέργεια, δεν υπάρχει τίποτα να κάνει + Εκκίνηση δραστηριότητας TT + Εκκίνηση Τρώω σύντομα ΤΤ + Εκκίνηση TT Υπογλυκαιμίας + Χρονική μετατόπιση + min + diff --git a/ui/src/main/res/values-es-rES/strings.xml b/ui/src/main/res/values-es-rES/strings.xml new file mode 100644 index 0000000000..63daaa7e1c --- /dev/null +++ b/ui/src/main/res/values-es-rES/strings.xml @@ -0,0 +1,12 @@ + + + No se ha seleccionado ninguna opción, por lo que no se realizará ningún cambio + Diálogo cancelado + Iniciar OT Actividad + Iniciar OT Comiendo Pronto + Iniciar OT Hipo + Retardo + min + Recordar ejecutar el bolo más tarde + establecer recordatorio + diff --git a/ui/src/main/res/values-fr-rFR/strings.xml b/ui/src/main/res/values-fr-rFR/strings.xml new file mode 100644 index 0000000000..fd728208ac --- /dev/null +++ b/ui/src/main/res/values-fr-rFR/strings.xml @@ -0,0 +1,16 @@ + + + Aucune action sélectionnée, rien ne se passera + Restriction appliquée ! + Restriction de bolus appliquée + Restriction des glucides appliquée + CT + Boîte de dialogue annulée + Début Activités + Début Repas Imminent + Début Traitement Hypo + Décalage horaire + min + Rappel du bolus plus tard + définir un rappel + diff --git a/ui/src/main/res/values-ga-rIE/strings.xml b/ui/src/main/res/values-ga-rIE/strings.xml new file mode 100644 index 0000000000..8299f50396 --- /dev/null +++ b/ui/src/main/res/values-ga-rIE/strings.xml @@ -0,0 +1,4 @@ + + + nóim + diff --git a/ui/src/main/res/values-hr-rHR/strings.xml b/ui/src/main/res/values-hr-rHR/strings.xml new file mode 100644 index 0000000000..3ea04e700d --- /dev/null +++ b/ui/src/main/res/values-hr-rHR/strings.xml @@ -0,0 +1,2 @@ + + diff --git a/ui/src/main/res/values-hu-rHU/strings.xml b/ui/src/main/res/values-hu-rHU/strings.xml new file mode 100644 index 0000000000..3ea04e700d --- /dev/null +++ b/ui/src/main/res/values-hu-rHU/strings.xml @@ -0,0 +1,2 @@ + + diff --git a/ui/src/main/res/values-it-rIT/strings.xml b/ui/src/main/res/values-it-rIT/strings.xml new file mode 100644 index 0000000000..211466ace7 --- /dev/null +++ b/ui/src/main/res/values-it-rIT/strings.xml @@ -0,0 +1,12 @@ + + + Nessuna azione selezionata, non succederà nulla + Finestra di dialogo cancellata + Avvia TT Attività fisica + Avvia TT Pasto a breve + Avvia TT Ipoglicemia + Offset + min + Ricorda di fare il bolo + imposta promemoria + diff --git a/ui/src/main/res/values-iw-rIL/strings.xml b/ui/src/main/res/values-iw-rIL/strings.xml new file mode 100644 index 0000000000..a19b2c1cf9 --- /dev/null +++ b/ui/src/main/res/values-iw-rIL/strings.xml @@ -0,0 +1,12 @@ + + + לא נבחרה פעולה, דבר לא יתבצע. + דו-שיח בוטל + התחל פעילות TT + התחל TT אוכלים בקרוב + הפעלת היפו TT + היסט זמן + דק\' + תזכורת להזרקת בולוס אח\"כ + קביעת תזכורת + diff --git a/ui/src/main/res/values-ko-rKR/strings.xml b/ui/src/main/res/values-ko-rKR/strings.xml new file mode 100644 index 0000000000..cd54bbae3f --- /dev/null +++ b/ui/src/main/res/values-ko-rKR/strings.xml @@ -0,0 +1,9 @@ + + + 선택한 실행이 없습니다. 아무런 실행이 되지 않습니다. + 활동 임시목표 시작 + 식사직전 임시목표 시작 + 저혈당 임시목표 시작 + 시간 이동 + + diff --git a/ui/src/main/res/values-lt-rLT/strings.xml b/ui/src/main/res/values-lt-rLT/strings.xml new file mode 100644 index 0000000000..de3664f8c6 --- /dev/null +++ b/ui/src/main/res/values-lt-rLT/strings.xml @@ -0,0 +1,11 @@ + + + Veiksmas nepasirinktas, nieko neįvyks + Pradėti Aktyvumo LT + Pradėti Netrukus valgysiu LT + Pradėti \"Hipo\" LT + Laiko poslinkis + min. + Priminti apie bolusą vėliau + nustatyti priminimą + diff --git a/ui/src/main/res/values-nl-rNL/strings.xml b/ui/src/main/res/values-nl-rNL/strings.xml new file mode 100644 index 0000000000..294fe8eb74 --- /dev/null +++ b/ui/src/main/res/values-nl-rNL/strings.xml @@ -0,0 +1,12 @@ + + + Geen actie geselecteerd, er zal niets uitgevoerd worden + Dialoog geannuleerd + Start inspanning TT + Start binnenkort eten TT + Start Hypo TT + Tijdverschuiving + min + Herinner later te bolussen + herinnering instellen + diff --git a/ui/src/main/res/values-no-rNO/strings.xml b/ui/src/main/res/values-no-rNO/strings.xml new file mode 100644 index 0000000000..02f55de263 --- /dev/null +++ b/ui/src/main/res/values-no-rNO/strings.xml @@ -0,0 +1,12 @@ + + + Ingen handling valgt. Ingenting endres + Dialog avbrutt + Start Trening TT + Start Spise snart TT + Start Hypo TT + Tidsforskyvning + min + Påminnelse til å gi bolus senere + angi påminnelse + diff --git a/ui/src/main/res/values-pl-rPL/strings.xml b/ui/src/main/res/values-pl-rPL/strings.xml new file mode 100644 index 0000000000..855e83f919 --- /dev/null +++ b/ui/src/main/res/values-pl-rPL/strings.xml @@ -0,0 +1,10 @@ + + + Nie wybrano żadnej akcji, zdarzenie nie będzie wprowadzone + Rozpocznij TT Ćwiczenia + Rozpocznij TT WkrótcePosiłek + Rozpocznij TT Hipo + Przesunięcie czasu + min + Przypomnij o bolusie + diff --git a/ui/src/main/res/values-pt-rBR/strings.xml b/ui/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000000..a81fc28800 --- /dev/null +++ b/ui/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,11 @@ + + + Nenhuma acção seleccionada, nada irá acontecer + Janela cancelada + Iniciar atividade TT + Iniciar Comer em breve TT + Começar TT Hipo + Fuso horário + min + definir lembrete + diff --git a/ui/src/main/res/values-pt-rPT/strings.xml b/ui/src/main/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000000..178e7d64f2 --- /dev/null +++ b/ui/src/main/res/values-pt-rPT/strings.xml @@ -0,0 +1,10 @@ + + + Nenhuma ação seleccionada, nada irá acontecer + Iniciar AT de atividade + Iniciar AT de Comer em breve + Iniciar AT de Hipo + Fuso horário + min + Lembrete para bólus mais tarde + diff --git a/ui/src/main/res/values-ro-rRO/strings.xml b/ui/src/main/res/values-ro-rRO/strings.xml new file mode 100644 index 0000000000..4779b9598b --- /dev/null +++ b/ui/src/main/res/values-ro-rRO/strings.xml @@ -0,0 +1,10 @@ + + + Nicio acțiune selectată, nu se va întâmpla nimic + Start TT activitate + Start TT mănânc-în-curând + Start TT hipo + Decalaj + min + Amintește-mi sa fac bolus mai târziu + diff --git a/ui/src/main/res/values-ru-rRU/strings.xml b/ui/src/main/res/values-ru-rRU/strings.xml new file mode 100644 index 0000000000..905fbb5465 --- /dev/null +++ b/ui/src/main/res/values-ru-rRU/strings.xml @@ -0,0 +1,12 @@ + + + Действие не выбрано, ничего не произойдет + Диалог отменен + Включить временную цель TT Нагрузка + Включить временную цель TT Ожидаемый прием пищи + Начать временную цель ТТ Гипо + Смещение по времени + мин + Напомнить о болюсе позже + установить напоминание + diff --git a/ui/src/main/res/values-sk-rSK/strings.xml b/ui/src/main/res/values-sk-rSK/strings.xml new file mode 100644 index 0000000000..654c988433 --- /dev/null +++ b/ui/src/main/res/values-sk-rSK/strings.xml @@ -0,0 +1,16 @@ + + + Žiadna akcia nevybraná, nič sa neudeje + Aplikované obmedzenie! + Aplikované obmedzenie bolusu + Aplikované obmedzenie sacharidov + TT + Dialóg zrušený + Spustiť Dočasný cieľ Aktivita + Spustiť Dočasný cieľ Blížiace sa jedlo + Spustiť doč. cieľ Hypo + Časový posun + min + Upozorniť na bolus neskôr + nastaviť pripomienku + diff --git a/ui/src/main/res/values-sr-rCS/strings.xml b/ui/src/main/res/values-sr-rCS/strings.xml new file mode 100644 index 0000000000..3ea04e700d --- /dev/null +++ b/ui/src/main/res/values-sr-rCS/strings.xml @@ -0,0 +1,2 @@ + + diff --git a/ui/src/main/res/values-sv-rSE/strings.xml b/ui/src/main/res/values-sv-rSE/strings.xml new file mode 100644 index 0000000000..8f6b907a8d --- /dev/null +++ b/ui/src/main/res/values-sv-rSE/strings.xml @@ -0,0 +1,11 @@ + + + Ingen åtgärd vald. Inget ändras. + Starta \"Träning\" + Starta \"Äta snart\" + Starta \"Hypo\" + KH-tid + min + Påminn om bolus senare + ställ in påminnelse + diff --git a/ui/src/main/res/values-tr-rTR/strings.xml b/ui/src/main/res/values-tr-rTR/strings.xml new file mode 100644 index 0000000000..c2dbc4ada8 --- /dev/null +++ b/ui/src/main/res/values-tr-rTR/strings.xml @@ -0,0 +1,16 @@ + + + Seçili eylem yok, hiçbir şey olmayacak + Sınırlaması uygulanır! + Bolus kısıtlaması uygulandı + Karbonhidrat kısıtlaması uygulandı + GH + İletişim kutusu iptal edildi + Egzersiz Başlat GH + Yakında Öğün GH + Hipo GH başlat + Saat farkı + dk. + Bolusu daha sonra hatırlat + hatırlatıcıyı kur + diff --git a/ui/src/main/res/values-zh-rCN/strings.xml b/ui/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000000..cc169f13ba --- /dev/null +++ b/ui/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,12 @@ + + + 没有选择任何行动,不会做出任何改变 + 对话框已取消 + 开始运动临时目标 + 开始很快吃饭TT(临时目标) + 开始低的临时目标 + 时区偏移 + 分钟 + 稍后提醒输注大剂量 + 设置提醒 + From ae29621c114126b480581490d5717329ea5fcdd6 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 11:22:34 +0100 Subject: [PATCH 57/77] Widget -> ui module --- app/src/main/AndroidManifest.xml | 21 -------- .../info/nightscout/androidaps/MainApp.kt | 4 +- .../fragments/HistoryBrowserData.kt | 3 +- .../androidaps/db/CompatDBHelper.kt | 6 +-- .../nightscout/androidaps/di/AppModule.kt | 5 +- .../info/nightscout/androidaps/di/UIModule.kt | 4 +- .../implementations/ActivityNamesImpl.kt | 11 +++++ .../aps/openAPSSMB/DetermineBasalResultSMB.kt | 5 +- .../general/nsclient/NSClientFragment.kt | 2 +- .../general/overview/OverviewFragment.kt | 8 ++-- .../general/overview/OverviewPlugin.kt | 4 -- .../general/overview/StatusLightHandler.kt | 4 +- .../IobCobCalculatorPlugin.kt | 19 ++++++-- .../androidaps/receivers/KeepAliveWorker.kt | 4 +- .../PrepareIobAutosensGraphDataWorker.kt | 11 ++--- .../workflow/PreparePredictionsWorker.kt | 4 +- app/src/main/res/layout/actions_fragment.xml | 2 +- .../main/res/layout/dialog_extendedbolus.xml | 2 +- app/src/main/res/layout/overview_fragment.xml | 2 +- .../main/res/layout/overview_info_layout.xml | 4 +- .../main/res/layout/treatments_fragment.xml | 2 +- app/src/main/res/values/strings.xml | 17 ------- app/src/main/res/xml/widget_info.xml | 2 +- automation/src/main/res/values/strings.xml | 1 - .../androidaps/interfaces/ActivityNames.kt | 5 ++ .../interfaces/VariableSensitivityResult.kt | 5 ++ .../plugins/general/overview/OverviewData.kt | 27 ++++++----- .../graphExtensions/BolusDataPoint.kt | 0 .../graphExtensions/CarbsDataPoint.kt | 0 .../graphExtensions/DeviationDataPoint.kt | 3 ++ .../EffectiveProfileSwitchDataPoint.kt | 0 .../graphExtensions/ExtendedBolusDataPoint.kt | 0 .../graphExtensions/FixedLineGraphSeries.java | 0 .../graphExtensions/GlucoseValueDataPoint.kt | 0 .../InMemoryGlucoseValueDataPoint.kt | 0 .../graphExtensions/ScaledDataPoint.kt | 0 .../graphExtensions/TherapyEventDataPoint.kt | 0 .../TimeAsXAxisLabelFormatter.java | 0 .../androidaps/utils/TrendCalculator.kt | 2 +- .../userEntry/UserEntryPresentationHelper.kt | 2 +- .../src/main/res/drawable/anim_carbs.xml | 0 ...ml => ic_actions_start_extended_bolus.xml} | 0 .../main/res/drawable/ic_cp_basal_no_tbr.xml | 0 .../res/drawable/ic_cp_basal_tbr_high.xml | 0 .../main/res/drawable/ic_cp_basal_tbr_low.xml | 0 .../res/drawable/ic_cp_bolus_carbs_red.xml | 0 .../ic_swap_vert_black_48dp_green.xml | 0 .../src/main/res/drawable/ic_x_swap_vert.xml | 0 core/src/main/res/values/strings.xml | 17 +++++++ ui/build.gradle | 3 +- ui/src/main/AndroidManifest.xml | 24 ++++++++++ .../java/info/nightscout/ui}/widget/Widget.kt | 48 +++++++++++-------- .../ui}/widget/WidgetConfigureActivity.kt | 7 ++- .../src/main/res/layout/widget_configure.xml | 0 .../src/main/res/layout/widget_layout.xml | 4 +- .../src/main/res/values-v31/themes.xml | 0 {app => ui}/src/main/res/values/styles.xml | 0 {app => ui}/src/main/res/values/themes.xml | 0 58 files changed, 169 insertions(+), 125 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/interfaces/VariableSensitivityResult.kt rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt (92%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/BolusDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/CarbsDataPoint.kt (100%) create mode 100644 core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/DeviationDataPoint.kt rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ExtendedBolusDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/FixedLineGraphSeries.java (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ScaledDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TherapyEventDataPoint.kt (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TimeAsXAxisLabelFormatter.java (100%) rename {app => core}/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt (98%) rename {app => core}/src/main/res/drawable/anim_carbs.xml (100%) rename core/src/main/res/drawable/{ic_actions_startextbolus.xml => ic_actions_start_extended_bolus.xml} (100%) rename {app => core}/src/main/res/drawable/ic_cp_basal_no_tbr.xml (100%) rename {app => core}/src/main/res/drawable/ic_cp_basal_tbr_high.xml (100%) rename {app => core}/src/main/res/drawable/ic_cp_basal_tbr_low.xml (100%) rename {app => core}/src/main/res/drawable/ic_cp_bolus_carbs_red.xml (100%) rename {app => core}/src/main/res/drawable/ic_swap_vert_black_48dp_green.xml (100%) rename {app => core}/src/main/res/drawable/ic_x_swap_vert.xml (100%) rename {app/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/widget/Widget.kt (89%) rename {app/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/widget/WidgetConfigureActivity.kt (92%) rename {app => ui}/src/main/res/layout/widget_configure.xml (100%) rename {app => ui}/src/main/res/layout/widget_layout.xml (99%) rename {app => ui}/src/main/res/values-v31/themes.xml (100%) rename {app => ui}/src/main/res/values/styles.xml (100%) rename {app => ui}/src/main/res/values/themes.xml (100%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c2622522a8..cd227043a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -46,27 +46,6 @@ android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> - - - - - - - - - - - - - - diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.kt b/app/src/main/java/info/nightscout/androidaps/MainApp.kt index 674cc9a10a..378525e3c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.kt @@ -45,10 +45,10 @@ import info.nightscout.androidaps.utils.ActivityMonitor import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.ProcessLifecycleListener import info.nightscout.androidaps.utils.locale.LocaleHelper -import info.nightscout.androidaps.widget.updateWidget import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.ui.widget.Widget import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.exceptions.UndeliverableException import io.reactivex.rxjava3.kotlin.plusAssign @@ -155,7 +155,7 @@ class MainApp : DaggerApplication() { // schedule widget update refreshWidget = Runnable { handler.postDelayed(refreshWidget, 60000) - updateWidget(this) + Widget.updateWidget(this) } handler.postDelayed(refreshWidget, 60000) } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/HistoryBrowserData.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/HistoryBrowserData.kt index 2fba78b07c..03cc11b01e 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/HistoryBrowserData.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/HistoryBrowserData.kt @@ -49,8 +49,7 @@ class HistoryBrowserData @Inject constructor( activePlugin, defaultValueHelper, profileFunction, - repository, - fabricPrivacy + repository ) iobCobCalculator = IobCobCalculatorPlugin( diff --git a/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt b/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt index 53aaf55b13..684b1f74ec 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt +++ b/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt @@ -8,7 +8,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData -import info.nightscout.androidaps.widget.updateWidget +import info.nightscout.ui.widget.Widget import io.reactivex.rxjava3.disposables.Disposable import javax.inject.Inject import javax.inject.Singleton @@ -25,7 +25,7 @@ class CompatDBHelper @Inject constructor( .changeObservable() .doOnSubscribe { rxBus.send(EventNewBG(null)) - updateWidget(context) + Widget.updateWidget(context) } .subscribe { /** @@ -38,7 +38,7 @@ class CompatDBHelper @Inject constructor( it.filterIsInstance().maxByOrNull { gv -> gv.timestamp }?.let { gv -> aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg $gv") rxBus.send(EventNewBG(gv)) - updateWidget(context) + Widget.updateWidget(context) newestGlucoseValue = gv } it.filterIsInstance().minOfOrNull { gv -> gv.timestamp }?.let { timestamp -> diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt index 62fbea8b1f..d8da3f08b6 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt @@ -8,7 +8,9 @@ import dagger.Provides import dagger.android.HasAndroidInjector import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.implementations.ActivityNamesImpl import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.AndroidPermission import info.nightscout.androidaps.interfaces.Autotune import info.nightscout.androidaps.interfaces.BolusTimer @@ -40,7 +42,6 @@ import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsI import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import info.nightscout.androidaps.plugins.general.nsclient.DataSyncSelectorImplementation import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData -import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation import info.nightscout.androidaps.utils.DateUtil @@ -60,6 +61,7 @@ import info.nightscout.implementation.CarbTimerImpl import info.nightscout.implementation.LocalAlertUtilsImpl import info.nightscout.implementation.XDripBroadcastImpl import info.nightscout.implementation.queue.CommandQueueImplementation +import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import javax.inject.Singleton @@ -136,6 +138,7 @@ open class AppModule { @Binds fun bindBolusTimerInterface(bolusTimer: BolusTimerImpl): BolusTimer @Binds fun bindAndroidPermissionInterface(androidPermission: AndroidPermissionImpl): AndroidPermission @Binds fun bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils + @Binds fun bindActivityNamesInterface(activityNames: ActivityNamesImpl): ActivityNames } } diff --git a/app/src/main/java/info/nightscout/androidaps/di/UIModule.kt b/app/src/main/java/info/nightscout/androidaps/di/UIModule.kt index 160601bad2..b2b9d80777 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/UIModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/UIModule.kt @@ -2,9 +2,9 @@ package info.nightscout.androidaps.di import dagger.Module import dagger.android.ContributesAndroidInjector -import info.nightscout.androidaps.widget.WidgetConfigureActivity +import info.nightscout.ui.widget.WidgetConfigureActivity import info.nightscout.androidaps.skins.SkinListPreference -import info.nightscout.androidaps.widget.Widget +import info.nightscout.ui.widget.Widget @Module @Suppress("unused") diff --git a/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt b/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt new file mode 100644 index 0000000000..7e78556ef4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.implementations + +import info.nightscout.androidaps.MainActivity +import info.nightscout.androidaps.interfaces.ActivityNames +import javax.inject.Inject + +class ActivityNamesImpl @Inject constructor() : ActivityNames { + + override val mainActivityClass: Class<*> + get() = MainActivity::class.java +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.kt index d45fbfe26c..9e7401f7c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.kt @@ -1,16 +1,17 @@ package info.nightscout.androidaps.plugins.aps.openAPSSMB import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.interfaces.VariableSensitivityResult import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.aps.loop.APSResult import org.json.JSONException import org.json.JSONObject -class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector) : APSResult(injector) { +class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector) : APSResult(injector), VariableSensitivityResult { private var eventualBG = 0.0 private var snoozeBG = 0.0 - var variableSens: Double? = null + override var variableSens: Double? = null internal constructor(injector: HasAndroidInjector, result: JSONObject) : this(injector) { date = dateUtil.now() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt index ce17603785..0d86b3288a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt @@ -136,6 +136,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider { binding.url.text = nsClientPlugin.url() binding.status.text = nsClientPlugin.status val size = dataSyncSelector.queueSize() - binding.queue.text = if (size >= 0) size.toString() else rh.gs(R.string.notavailable) + binding.queue.text = if (size >= 0) size.toString() else rh.gs(R.string.value_unavailable_short) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index 9c6693f8b7..ccb34fabba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -35,8 +35,6 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.databinding.OverviewFragmentBinding -import info.nightscout.ui.dialogs.CalibrationDialog -import info.nightscout.ui.dialogs.CarbsDialog import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.dialogs.LoopDialog import info.nightscout.androidaps.dialogs.ProfileSwitchDialog @@ -108,6 +106,8 @@ import info.nightscout.androidaps.utils.wizard.QuickWizard import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.weardata.EventData +import info.nightscout.ui.dialogs.CalibrationDialog +import info.nightscout.ui.dialogs.CarbsDialog import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.util.Locale @@ -799,7 +799,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList runOnUiThread { _binding ?: return@runOnUiThread binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units) - ?: rh.gs(R.string.notavailable) + ?: rh.gs(R.string.value_unavailable_short) binding.infoLayout.bg.setTextColor(lastBgColor) binding.infoLayout.arrow.setImageResource(trendArrow.directionToIcon()) binding.infoLayout.arrow.setColorFilter(lastBgColor) @@ -813,7 +813,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units) } else { binding.infoLayout.deltaLarge.text = "" - binding.infoLayout.delta.text = "Δ " + rh.gs(R.string.notavailable) + binding.infoLayout.delta.text = "Δ " + rh.gs(R.string.value_unavailable_short) binding.infoLayout.avgDelta.text = "" binding.infoLayout.longAvgDelta.text = "" } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt index 9131b131df..0ba5e04740 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt @@ -23,8 +23,6 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewCalcProgress import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewNotification -import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale -import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress @@ -81,8 +79,6 @@ class OverviewPlugin @Inject constructor( rxBus.send(EventDismissNotification(id)) } - class DeviationDataPoint(x: Double, y: Double, var color: Int, scale: Scale) : ScaledDataPoint(x, y, scale) - override fun onStart() { super.onStart() overviewMenus.loadGraphConfig() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt index 85ebc8a98a..37790752ff 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt @@ -67,7 +67,7 @@ class StatusLightHandler @Inject constructor( if (pump.model().supportBatteryLevel || erosBatteryLinkAvailable) { handleLevel(careportal_battery_level, R.string.key_statuslights_bat_critical, 26.0, R.string.key_statuslights_bat_warning, 51.0, pump.batteryLevel.toDouble(), "%") } else { - careportal_battery_level?.text = rh.gs(R.string.notavailable) + careportal_battery_level?.text = rh.gs(R.string.value_unavailable_short) careportal_battery_level?.setTextColor(rh.gac(careportal_battery_level.context, R.attr.defaultTextColor)) } } @@ -81,7 +81,7 @@ class StatusLightHandler @Inject constructor( warnColors.setColorByAge(view, therapyEvent.value, warn, urgent) view?.text = therapyEvent.value.age(rh.shortTextMode(), rh, dateUtil) } else { - view?.text = if (rh.shortTextMode()) "-" else rh.gs(R.string.notavailable) + view?.text = if (rh.shortTextMode()) "-" else rh.gs(R.string.value_unavailable_short) } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt index c048c7133a..a6f96631d8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt @@ -13,11 +13,22 @@ import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.ExtendedBolus import info.nightscout.androidaps.database.entities.TemporaryBasal import info.nightscout.androidaps.database.interfaces.end -import info.nightscout.androidaps.events.* +import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.events.EventConfigBuilderChange +import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged +import info.nightscout.androidaps.events.EventNewBG +import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.iobCalc import info.nightscout.androidaps.extensions.toTemporaryBasal -import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginDescription +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.OverviewData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData @@ -25,12 +36,10 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHi import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.workflow.CalculationWorkflow -import info.nightscout.androidaps.events.Event -import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt index 8cf63218e9..4245c645f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt @@ -34,10 +34,10 @@ import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.widget.updateWidget import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.ui.widget.Widget import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.abs @@ -117,7 +117,7 @@ class KeepAliveWorker( } lastRun = dateUtil.now() - updateWidget(context) + Widget.updateWidget(context) localAlertUtils.shortenSnoozeInterval() localAlertUtils.checkStaleBGAlert() checkPump() diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareIobAutosensGraphDataWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareIobAutosensGraphDataWorker.kt index 35228af096..1ed9abf4e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareIobAutosensGraphDataWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareIobAutosensGraphDataWorker.kt @@ -15,12 +15,13 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.OverviewData import info.nightscout.androidaps.plugins.general.overview.OverviewMenus -import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface +import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DeviationDataPoint import info.nightscout.androidaps.plugins.general.overview.graphExtensions.FixedLineGraphSeries import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint @@ -29,10 +30,8 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCa import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag -import java.util.ArrayList import javax.inject.Inject import kotlin.math.abs import kotlin.math.max @@ -87,7 +86,7 @@ class PrepareIobAutosensGraphDataWorker( val bgiArrayPrediction: MutableList = ArrayList() data.overviewData.maxBGIValue = Double.MIN_VALUE - val devArray: MutableList = ArrayList() + val devArray: MutableList = ArrayList() data.overviewData.maxDevValueFound = Double.MIN_VALUE val ratioArray: MutableList = ArrayList() @@ -168,7 +167,7 @@ class PrepareIobAutosensGraphDataWorker( } else if (autosensData.type == "csf") { color = rh.gac( ctx, R.attr.deviationGreyColor) } - devArray.add(OverviewPlugin.DeviationDataPoint(time.toDouble(), autosensData.deviation, color, data.overviewData.devScale)) + devArray.add(DeviationDataPoint(time.toDouble(), autosensData.deviation, color, data.overviewData.devScale)) data.overviewData.maxDevValueFound = maxOf(data.overviewData.maxDevValueFound, abs(autosensData.deviation), abs(bgi)) } @@ -260,7 +259,7 @@ class PrepareIobAutosensGraphDataWorker( // DEVIATIONS data.overviewData.deviationsSeries = BarGraphSeries(Array(devArray.size) { i -> devArray[i] }).also { - it.setValueDependentColor { data: OverviewPlugin.DeviationDataPoint -> data.color } + it.setValueDependentColor { data: DeviationDataPoint -> data.color } } // RATIO diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt index eb909cbd41..2377af0fd3 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt @@ -9,6 +9,7 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus import info.nightscout.androidaps.plugins.general.overview.OverviewData @@ -19,8 +20,7 @@ import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Point import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper -import java.util.* +import java.util.Calendar import javax.inject.Inject import kotlin.math.ceil import kotlin.math.max diff --git a/app/src/main/res/layout/actions_fragment.xml b/app/src/main/res/layout/actions_fragment.xml index 62e8661ca8..8c4fa406a7 100644 --- a/app/src/main/res/layout/actions_fragment.xml +++ b/app/src/main/res/layout/actions_fragment.xml @@ -107,7 +107,7 @@ style="@style/GrayButton" android:layout_width="0dp" android:layout_height="wrap_content" - android:drawableTop="@drawable/ic_actions_startextbolus" + android:drawableTop="@drawable/ic_actions_start_extended_bolus" android:paddingStart="0dp" android:paddingEnd="0dp" android:text="@string/overview_extendedbolus_button" diff --git a/app/src/main/res/layout/dialog_extendedbolus.xml b/app/src/main/res/layout/dialog_extendedbolus.xml index 19ec26126c..c62642b775 100644 --- a/app/src/main/res/layout/dialog_extendedbolus.xml +++ b/app/src/main/res/layout/dialog_extendedbolus.xml @@ -23,7 +23,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:importantForAccessibility="no" - app:srcCompat="@drawable/ic_actions_startextbolus" /> + app:srcCompat="@drawable/ic_actions_start_extended_bolus" /> + android:contentDescription="@string/a11y_autosens_label" /> + android:icon="@drawable/ic_actions_start_extended_bolus" /> Show detailed IOB Break down IOB into bolus and basal IOB on the watchface not successful - please check phone - n/a Patient type Child Teenage @@ -415,7 +414,6 @@ Absorption settings Meal max absorption time [h] Time in hours where is expected all carbs from meal will be absorbed - rangetodisplay OAPS UPLD BAS @@ -550,7 +548,6 @@ Ignore 5m Ignore 15m Ignore 30m - req History browser Notify on SMB Show SMB on the watch like a standard bolus. @@ -650,7 +647,6 @@ Bolus snooze dia divisor Max daily safety multiplier Current basal safety multiplier - n/a virtualpump_uploadstatus Virtual Pump Type Pump Definition @@ -908,7 +904,6 @@ Graph Chart menu Clear filter - Trend arrow Cannula User entry Use values of your largest food you usually eat\n @@ -978,18 +973,6 @@ correct outcome with % correct outcome with units Not available - high - in range - low - falling rapidly - falling - falling slowly - stable - rising slowly - rising - rising rapidly - none - unknown graph blood glucose quality recalculated diff --git a/app/src/main/res/xml/widget_info.xml b/app/src/main/res/xml/widget_info.xml index 801dca46d9..7743c8c7de 100644 --- a/app/src/main/res/xml/widget_info.xml +++ b/app/src/main/res/xml/widget_info.xml @@ -1,6 +1,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Auto sens %3$s %1$s %2$s BG difference BG difference [%1$s] diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt new file mode 100644 index 0000000000..80f7f61049 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.interfaces + +interface ActivityNames { + val mainActivityClass: Class<*> +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/VariableSensitivityResult.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/VariableSensitivityResult.kt new file mode 100644 index 0000000000..bee69b6c00 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/VariableSensitivityResult.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.interfaces + +interface VariableSensitivityResult { + var variableSens: Double? +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt similarity index 92% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt index 6f0b64bc6d..0682f3646e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt @@ -1,11 +1,13 @@ package info.nightscout.androidaps.plugins.general.overview import android.content.Context +import androidx.annotation.AttrRes import androidx.annotation.ColorInt +import androidx.annotation.DrawableRes import com.jjoe64.graphview.series.BarGraphSeries import com.jjoe64.graphview.series.DataPoint import com.jjoe64.graphview.series.LineGraphSeries -import info.nightscout.androidaps.R +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.data.IobTotal import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper @@ -19,20 +21,21 @@ import info.nightscout.androidaps.extensions.valueToUnits import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface +import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DeviationDataPoint import info.nightscout.androidaps.plugins.general.overview.graphExtensions.FixedLineGraphSeries import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper -import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP -import java.util.* +import java.util.Calendar import javax.inject.Inject import javax.inject.Singleton @@ -45,8 +48,7 @@ class OverviewData @Inject constructor( private val activePlugin: ActivePlugin, private val defaultValueHelper: DefaultValueHelper, private val profileFunction: ProfileFunction, - private val repository: AppRepository, - private val fabricPrivacy: FabricPrivacy + private val repository: AppRepository ) { var rangeToDisplay = 6 // for graph @@ -163,7 +165,7 @@ class OverviewData @Inject constructor( if (temporaryBasal?.isInProgress == false) temporaryBasal = null temporaryBasal?.let { "T:" + it.toStringShort() } ?: rh.gs(R.string.pump_basebasalrate, profile.getBasal()) - } ?: rh.gs(R.string.notavailable) + } ?: rh.gs(R.string.value_unavailable_short) fun temporaryBasalDialogText(iobCobCalculator: IobCobCalculator): String = profileFunction.getProfile()?.let { profile -> @@ -172,9 +174,9 @@ class OverviewData @Inject constructor( "\n" + rh.gs(R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil) } ?: "${rh.gs(R.string.basebasalrate_label)}: ${rh.gs(R.string.pump_basebasalrate, profile.getBasal())}" - } ?: rh.gs(R.string.notavailable) + } ?: rh.gs(R.string.value_unavailable_short) - fun temporaryBasalIcon(iobCobCalculator: IobCobCalculator): Int = + @DrawableRes fun temporaryBasalIcon(iobCobCalculator: IobCobCalculator): Int = profileFunction.getProfile()?.let { profile -> iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal -> val percentRate = temporaryBasal.convertedToPercent(dateUtil.now(), profile) @@ -186,7 +188,8 @@ class OverviewData @Inject constructor( } } ?: R.drawable.ic_cp_basal_no_tbr - fun temporaryBasalColor(context: Context?, iobCobCalculator: IobCobCalculator): Int = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { rh.gac(context , R.attr.basal) } + @AttrRes fun temporaryBasalColor(context: Context?, iobCobCalculator: IobCobCalculator): Int = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { rh.gac(context, R + .attr.basal) } ?: rh.gac(context, R.attr.defaultTextColor) /* @@ -239,7 +242,7 @@ class OverviewData @Inject constructor( * SENSITIVITY */ - fun lastAutosensData(iobCobCalculator: IobCobCalculator) = iobCobCalculator.ads.getLastAutosensData("Overview", aapsLogger, dateUtil) + fun lastAutosensData(iobCobCalculator: IobCobCalculator) : AutosensData? = iobCobCalculator.ads.getLastAutosensData("Overview", aapsLogger, dateUtil) /* * Graphs @@ -291,7 +294,7 @@ class OverviewData @Inject constructor( var maxDevValueFound = Double.MIN_VALUE val devScale = Scale() - var deviationsSeries: BarGraphSeries = BarGraphSeries() + var deviationsSeries: BarGraphSeries = BarGraphSeries() var maxRatioValueFound = 5.0 //even if sens data equals 0 for all the period, minimum scale is between 95% and 105% var minRatioValueFound = -maxRatioValueFound diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/BolusDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/BolusDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/BolusDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/BolusDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/CarbsDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/CarbsDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/CarbsDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/CarbsDataPoint.kt diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/DeviationDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/DeviationDataPoint.kt new file mode 100644 index 0000000000..2d55f6cd99 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/DeviationDataPoint.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.general.overview.graphExtensions + +class DeviationDataPoint(x: Double, y: Double, var color: Int, scale: Scale) : ScaledDataPoint(x, y, scale) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/EffectiveProfileSwitchDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ExtendedBolusDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ExtendedBolusDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ExtendedBolusDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ExtendedBolusDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/FixedLineGraphSeries.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/FixedLineGraphSeries.java similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/FixedLineGraphSeries.java rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/FixedLineGraphSeries.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ScaledDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ScaledDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ScaledDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/ScaledDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TherapyEventDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TherapyEventDataPoint.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TherapyEventDataPoint.kt rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TherapyEventDataPoint.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TimeAsXAxisLabelFormatter.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TimeAsXAxisLabelFormatter.java similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TimeAsXAxisLabelFormatter.java rename to core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/TimeAsXAxisLabelFormatter.java diff --git a/app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt b/core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt similarity index 98% rename from app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt rename to core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt index 2d161808a6..024de884a5 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt @@ -1,6 +1,6 @@ package info.nightscout.androidaps.utils -import info.nightscout.androidaps.R +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.entities.GlucoseValue.TrendArrow.* diff --git a/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt b/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt index 2cc1a020f2..4d968bb875 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt @@ -46,7 +46,7 @@ class UserEntryPresentationHelper @Inject constructor( Sources.CarbDialog -> R.drawable.ic_cp_bolus_carbs Sources.WizardDialog -> R.drawable.ic_calculator Sources.QuickWizard -> R.drawable.ic_quick_wizard - Sources.ExtendedBolusDialog -> R.drawable.ic_actions_startextbolus + Sources.ExtendedBolusDialog -> R.drawable.ic_actions_start_extended_bolus Sources.TTDialog -> R.drawable.ic_temptarget_high Sources.ProfileSwitchDialog -> R.drawable.ic_actions_profileswitch Sources.LoopDialog -> R.drawable.ic_loop_closed diff --git a/app/src/main/res/drawable/anim_carbs.xml b/core/src/main/res/drawable/anim_carbs.xml similarity index 100% rename from app/src/main/res/drawable/anim_carbs.xml rename to core/src/main/res/drawable/anim_carbs.xml diff --git a/core/src/main/res/drawable/ic_actions_startextbolus.xml b/core/src/main/res/drawable/ic_actions_start_extended_bolus.xml similarity index 100% rename from core/src/main/res/drawable/ic_actions_startextbolus.xml rename to core/src/main/res/drawable/ic_actions_start_extended_bolus.xml diff --git a/app/src/main/res/drawable/ic_cp_basal_no_tbr.xml b/core/src/main/res/drawable/ic_cp_basal_no_tbr.xml similarity index 100% rename from app/src/main/res/drawable/ic_cp_basal_no_tbr.xml rename to core/src/main/res/drawable/ic_cp_basal_no_tbr.xml diff --git a/app/src/main/res/drawable/ic_cp_basal_tbr_high.xml b/core/src/main/res/drawable/ic_cp_basal_tbr_high.xml similarity index 100% rename from app/src/main/res/drawable/ic_cp_basal_tbr_high.xml rename to core/src/main/res/drawable/ic_cp_basal_tbr_high.xml diff --git a/app/src/main/res/drawable/ic_cp_basal_tbr_low.xml b/core/src/main/res/drawable/ic_cp_basal_tbr_low.xml similarity index 100% rename from app/src/main/res/drawable/ic_cp_basal_tbr_low.xml rename to core/src/main/res/drawable/ic_cp_basal_tbr_low.xml diff --git a/app/src/main/res/drawable/ic_cp_bolus_carbs_red.xml b/core/src/main/res/drawable/ic_cp_bolus_carbs_red.xml similarity index 100% rename from app/src/main/res/drawable/ic_cp_bolus_carbs_red.xml rename to core/src/main/res/drawable/ic_cp_bolus_carbs_red.xml diff --git a/app/src/main/res/drawable/ic_swap_vert_black_48dp_green.xml b/core/src/main/res/drawable/ic_swap_vert_black_48dp_green.xml similarity index 100% rename from app/src/main/res/drawable/ic_swap_vert_black_48dp_green.xml rename to core/src/main/res/drawable/ic_swap_vert_black_48dp_green.xml diff --git a/app/src/main/res/drawable/ic_x_swap_vert.xml b/core/src/main/res/drawable/ic_x_swap_vert.xml similarity index 100% rename from app/src/main/res/drawable/ic_x_swap_vert.xml rename to core/src/main/res/drawable/ic_x_swap_vert.xml diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 2f69ade6be..e3dffa9a06 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -84,6 +84,7 @@ enable_missed_bg_readings enable_carbs_required_alert_local smscommunicator_report_pump_unreachable + rangetodisplay Refresh @@ -208,6 +209,22 @@ Pump suspended Not configured Loop suspended + Trend arrow + Auto sens + n/a + req + falling rapidly + falling + falling slowly + stable + rising slowly + rising + rising rapidly + none + unknown + high + in range + low Limiting max basal rate to %1$.2f U/h because of %2$s diff --git a/ui/build.gradle b/ui/build.gradle index cae8d77b2a..c5102ae041 100644 --- a/ui/build.gradle +++ b/ui/build.gradle @@ -13,7 +13,8 @@ android { } dependencies { - implementation project(':core') implementation project(':shared') implementation project(':database') + implementation project(':core') + implementation project(':graphview') } \ No newline at end of file diff --git a/ui/src/main/AndroidManifest.xml b/ui/src/main/AndroidManifest.xml index a5918e68ab..3e2b647f2e 100644 --- a/ui/src/main/AndroidManifest.xml +++ b/ui/src/main/AndroidManifest.xml @@ -1,4 +1,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/widget/Widget.kt b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/widget/Widget.kt rename to ui/src/main/java/info/nightscout/ui/widget/Widget.kt index 4ef921680d..195a1f88a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/widget/Widget.kt +++ b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.widget +package info.nightscout.ui.widget import android.app.PendingIntent import android.appwidget.AppWidgetManager @@ -14,15 +14,21 @@ import android.view.View import android.widget.RemoteViews import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.MainActivity -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.extensions.directionToIcon import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.valueToUnitsString -import info.nightscout.androidaps.interfaces.* -import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.GlucoseUnit +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.VariableSensitivityResult import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.general.overview.OverviewData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider @@ -31,7 +37,8 @@ import info.nightscout.androidaps.utils.TrendCalculator import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP -import java.util.* +import info.nightscout.ui.R +import java.util.Locale import javax.inject.Inject import kotlin.math.abs @@ -43,6 +50,7 @@ class Widget : AppWidgetProvider() { @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var overviewData: OverviewData @Inject lateinit var trendCalculator: TrendCalculator + @Inject lateinit var activityNames: ActivityNames @Inject lateinit var rh: ResourceHelper @Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider @Inject lateinit var dateUtil: DateUtil @@ -58,6 +66,13 @@ class Widget : AppWidgetProvider() { // This object doesn't behave like singleton, // many threads were created. Making handler static resolve this issue private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) + + fun updateWidget(context: Context) { + context.sendBroadcast(Intent().also { + it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, AppWidgetManager.getInstance(context)?.getAppWidgetIds(ComponentName(context, Widget::class.java))) + it.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE + }) + } } private val intentAction = "OpenApp" @@ -88,7 +103,7 @@ class Widget : AppWidgetProvider() { val alpha = sp.getInt(WidgetConfigureActivity.PREF_PREFIX_KEY + appWidgetId, WidgetConfigureActivity.DEFAULT_OPACITY) // Create an Intent to launch MainActivity when clicked - val intent = Intent(context, MainActivity::class.java).also { it.action = intentAction } + val intent = Intent(context, activityNames.mainActivityClass).also { it.action = intentAction } val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) // Widgets allow click handlers to only launch pending intents views.setOnClickPendingIntent(R.id.widget_layout, pendingIntent) @@ -109,7 +124,7 @@ class Widget : AppWidgetProvider() { private fun updateBg(views: RemoteViews) { val units = profileFunction.getUnits() - views.setTextViewText(R.id.bg, overviewData.lastBg?.valueToUnitsString(units) ?: rh.gs(R.string.notavailable)) + views.setTextViewText(R.id.bg, overviewData.lastBg?.valueToUnitsString(units) ?: rh.gs(R.string.value_unavailable_short)) views.setTextColor( R.id.bg, when { overviewData.isLow -> rh.gc(R.color.widget_low) @@ -132,9 +147,9 @@ class Widget : AppWidgetProvider() { views.setTextViewText(R.id.avg_delta, Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units)) views.setTextViewText(R.id.long_avg_delta, Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units)) } else { - views.setTextViewText(R.id.delta, rh.gs(R.string.notavailable)) - views.setTextViewText(R.id.avg_delta, rh.gs(R.string.notavailable)) - views.setTextViewText(R.id.long_avg_delta, rh.gs(R.string.notavailable)) + views.setTextViewText(R.id.delta, rh.gs(R.string.value_unavailable_short)) + views.setTextViewText(R.id.avg_delta, rh.gs(R.string.value_unavailable_short)) + views.setTextViewText(R.id.long_avg_delta, rh.gs(R.string.value_unavailable_short)) } // strike through if BG is old @@ -142,7 +157,7 @@ class Widget : AppWidgetProvider() { else views.setInt(R.id.bg, "setPaintFlags", Paint.ANTI_ALIAS_FLAG) views.setTextViewText(R.id.time_ago, dateUtil.minAgo(rh, overviewData.lastBg?.timestamp)) - views.setTextViewText(R.id.time_ago_short, "(" + dateUtil.minAgoShort(overviewData.lastBg?.timestamp) + ")") + //views.setTextViewText(R.id.time_ago_short, "(" + dateUtil.minAgoShort(overviewData.lastBg?.timestamp) + ")") } private fun updateTemporaryBasal(views: RemoteViews) { @@ -240,7 +255,7 @@ class Widget : AppWidgetProvider() { // Show variable sensitivity val request = loop.lastRun?.request - if (request is DetermineBasalResultSMB) { + if (request is VariableSensitivityResult) { val isfMgdl = profileFunction.getProfile()?.getIsfMgdl() val variableSens = request.variableSens if (variableSens != isfMgdl && variableSens != null && isfMgdl != null) { @@ -256,11 +271,4 @@ class Widget : AppWidgetProvider() { } else views.setViewVisibility(R.id.variable_sensitivity, View.GONE) } else views.setViewVisibility(R.id.variable_sensitivity, View.GONE) } -} - -internal fun updateWidget(context: Context) { - context.sendBroadcast(Intent().also { - it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, AppWidgetManager.getInstance(context)?.getAppWidgetIds(ComponentName(context, Widget::class.java))) - it.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE - }) } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/widget/WidgetConfigureActivity.kt b/ui/src/main/java/info/nightscout/ui/widget/WidgetConfigureActivity.kt similarity index 92% rename from app/src/main/java/info/nightscout/androidaps/widget/WidgetConfigureActivity.kt rename to ui/src/main/java/info/nightscout/ui/widget/WidgetConfigureActivity.kt index 4647b86454..4b93788fea 100644 --- a/app/src/main/java/info/nightscout/androidaps/widget/WidgetConfigureActivity.kt +++ b/ui/src/main/java/info/nightscout/ui/widget/WidgetConfigureActivity.kt @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.widget +package info.nightscout.ui.widget import android.appwidget.AppWidgetManager import android.content.Intent import android.os.Bundle import android.widget.SeekBar import dagger.android.DaggerActivity -import info.nightscout.androidaps.databinding.WidgetConfigureBinding import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.ui.databinding.WidgetConfigureBinding import javax.inject.Inject /** @@ -18,7 +18,6 @@ class WidgetConfigureActivity : DaggerActivity() { companion object { - @Suppress("PrivatePropertyName") const val PREF_PREFIX_KEY = "appwidget_" const val DEFAULT_OPACITY = 25 } @@ -51,7 +50,7 @@ class WidgetConfigureActivity : DaggerActivity() { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { value = progress saveTitlePref(appWidgetId, value) - updateWidget(this@WidgetConfigureActivity) + Widget.updateWidget(this@WidgetConfigureActivity) } }) diff --git a/app/src/main/res/layout/widget_configure.xml b/ui/src/main/res/layout/widget_configure.xml similarity index 100% rename from app/src/main/res/layout/widget_configure.xml rename to ui/src/main/res/layout/widget_configure.xml diff --git a/app/src/main/res/layout/widget_layout.xml b/ui/src/main/res/layout/widget_layout.xml similarity index 99% rename from app/src/main/res/layout/widget_layout.xml rename to ui/src/main/res/layout/widget_layout.xml index a15711a490..b88784d9bd 100644 --- a/app/src/main/res/layout/widget_layout.xml +++ b/ui/src/main/res/layout/widget_layout.xml @@ -305,7 +305,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:contentDescription="@string/extended_bolus" - android:src="@drawable/ic_actions_startextbolus" /> + android:src="@drawable/ic_actions_start_extended_bolus" /> Date: Wed, 2 Nov 2022 11:56:54 +0100 Subject: [PATCH 58/77] pump submodule --- .../Steampunk_graphics_source_link.md | 0 demo_keystore.jks => _docs/demo_keystore.jks | Bin {gource => _docs/gource}/sample.bat | 0 {icons => _docs/icons}/action_add.svg | 0 {icons => _docs/icons}/action_minus.svg | 0 .../icons}/actions_cancelextbolus.svg | 0 {icons => _docs/icons}/actions_refill.svg | 0 .../icons}/actions_startextbolus.svg | 0 {icons => _docs/icons}/actions_temptarget.svg | 0 {icons => _docs/icons}/add.svg | 0 {icons => _docs/icons}/as.svg | 0 {icons => _docs/icons}/auto_delta.svg | 0 {icons => _docs/icons}/autotune.svg | 0 .../battery-charging-wireless-10-burnin.svg | 0 .../battery-charging-wireless-20-burnin.svg | 0 .../battery-charging-wireless-30-burnin.svg | 0 .../battery-charging-wireless-40-burnin.svg | 0 .../battery-charging-wireless-50-burnin.svg | 0 .../battery-charging-wireless-60-burnin.svg | 0 .../battery-charging-wireless-70-burnin.svg | 0 .../battery-charging-wireless-80-burnin.svg | 0 .../battery-charging-wireless-90-burnin.svg | 0 .../battery-charging-wireless-burnin.svg | 0 .../battery-burnin/battery-unknown-burnin.svg | 0 .../mask-burnin-battery-raw.svg | 0 .../battery-source/mask-burnin-battery.svg | 0 .../battery/battery-charging-wireless-10.svg | 0 .../battery/battery-charging-wireless-20.svg | 0 .../battery/battery-charging-wireless-30.svg | 0 .../battery/battery-charging-wireless-40.svg | 0 .../battery/battery-charging-wireless-50.svg | 0 .../battery/battery-charging-wireless-60.svg | 0 .../battery/battery-charging-wireless-70.svg | 0 .../battery/battery-charging-wireless-80.svg | 0 .../battery/battery-charging-wireless-90.svg | 0 .../battery/battery-charging-wireless.svg | 0 .../icons}/battery/battery-outline.svg | 0 .../icons}/battery/battery-unknown.svg | 0 {icons => _docs/icons}/bolus.svg | 0 {icons => _docs/icons}/byoda.svg | 0 {icons => _docs/icons}/calculator.svg | 0 {icons => _docs/icons}/calibration.svg | 0 {icons => _docs/icons}/cancel.svg | 0 {icons => _docs/icons}/clone.svg | 0 {icons => _docs/icons}/clone_48.svg | 0 {icons => _docs/icons}/combo.svg | 0 {icons => _docs/icons}/compare_profiles.svg | 0 .../ic_br_cob_iob_orig.svg | 0 .../ic_cob_detailed_orig.svg | 0 .../complications-source/ic_cob_iob_orig.svg | 0 .../ic_ins_burnin_orig.svg | 0 .../complications-source/ic_ins_orig.svg | 0 .../ic_iob_detailed_orig.svg | 0 .../icons}/complications/ic_aaps_full.svg | 0 .../icons}/complications/ic_basal.svg | 0 .../icons}/complications/ic_br_cob_iob.svg | 0 .../icons}/complications/ic_carbs.svg | 0 .../icons}/complications/ic_cob_detailed.svg | 0 .../icons}/complications/ic_cob_iob.svg | 0 .../icons}/complications/ic_ins.svg | 0 .../icons}/complications/ic_ins_burnin.svg | 0 .../icons}/complications/ic_iob_detailed.svg | 0 .../icons}/complications/ic_sgv.svg | 0 {icons => _docs/icons}/confirm.svg | 0 {icons => _docs/icons}/cp_aaps_offline.svg | 0 {icons => _docs/icons}/cp_age_batterie.svg | 0 {icons => _docs/icons}/cp_age_canula.svg | 0 {icons => _docs/icons}/cp_age_insulin.svg | 0 {icons => _docs/icons}/cp_age_sensor.svg | 0 {icons => _docs/icons}/cp_announcement.svg | 0 {icons => _docs/icons}/cp_basal_end.svg | 0 {icons => _docs/icons}/cp_basal_no_tbr.svg | 0 {icons => _docs/icons}/cp_basal_tbr_high.svg | 0 {icons => _docs/icons}/cp_basal_tbr_low.svg | 0 {icons => _docs/icons}/cp_bgcheck.svg | 0 {icons => _docs/icons}/cp_bgcheck2.svg | 0 {icons => _docs/icons}/cp_bolus_carbs.svg | 0 {icons => _docs/icons}/cp_bolus_combo.svg | 0 .../icons}/cp_bolus_correction.svg | 0 {icons => _docs/icons}/cp_bolus_meal.svg | 0 {icons => _docs/icons}/cp_bolus_snack.svg | 0 {icons => _docs/icons}/cp_cgm_insert.svg | 0 {icons => _docs/icons}/cp_cgm_profile.svg | 0 {icons => _docs/icons}/cp_cgm_start.svg | 0 {icons => _docs/icons}/cp_cgm_target.svg | 0 {icons => _docs/icons}/cp_exercise.svg | 0 {icons => _docs/icons}/cp_note.svg | 0 {icons => _docs/icons}/cp_pump_battery.svg | 0 {icons => _docs/icons}/cp_pump_canula.svg | 0 {icons => _docs/icons}/cp_pump_cartridge.svg | 0 {icons => _docs/icons}/cp_question.svg | 0 {icons => _docs/icons}/danar_useropt.svg | 0 {icons => _docs/icons}/danarhistory.svg | 0 {icons => _docs/icons}/danarprofile.svg | 0 {icons => _docs/icons}/danars.svg | 0 {icons => _docs/icons}/danarstat.svg | 0 {icons => _docs/icons}/excel.svg | 0 {icons => _docs/icons}/export_settings.svg | 0 {icons => _docs/icons}/ic_DoubleDown.svg | 0 {icons => _docs/icons}/ic_DoubleUp.svg | 0 {icons => _docs/icons}/ic_Flat.svg | 0 {icons => _docs/icons}/ic_FortyFiveDown.svg | 0 {icons => _docs/icons}/ic_FortyFiveUp.svg | 0 {icons => _docs/icons}/ic_Invalid.svg | 0 {icons => _docs/icons}/ic_SingleDown.svg | 0 {icons => _docs/icons}/ic_SingleUp.svg | 0 {icons => _docs/icons}/ic_error.svg | 0 {icons => _docs/icons}/ic_exit_to_app.svg | 0 {icons => _docs/icons}/ic_home_loop.svg | 0 {icons => _docs/icons}/ic_maintenance.svg | 0 {icons => _docs/icons}/ic_notif_aaps.svg | 0 {icons => _docs/icons}/ic_notif_nsclient.svg | 0 .../icons}/ic_notif_pumpcontrol.svg | 0 {icons => _docs/icons}/ic_warning.svg | 0 {icons => _docs/icons}/icon_snooze.svg | 0 {icons => _docs/icons}/import_settings.svg | 0 {icons => _docs/icons}/insight.svg | 0 {icons => _docs/icons}/insight_128.svg | 0 {icons => _docs/icons}/local_activate.svg | 0 {icons => _docs/icons}/local_reset.svg | 0 {icons => _docs/icons}/local_save.svg | 0 {icons => _docs/icons}/log_delete.svg | 0 {icons => _docs/icons}/log_settings.svg | 0 {icons => _docs/icons}/loop.svg | 0 {icons => _docs/icons}/loop_closed.svg | 0 {icons => _docs/icons}/loop_disabled.svg | 0 {icons => _docs/icons}/loop_disconnected.svg | 0 {icons => _docs/icons}/loop_lgs.svg | 0 {icons => _docs/icons}/loop_off.svg | 0 {icons => _docs/icons}/loop_open.svg | 0 {icons => _docs/icons}/loop_paused.svg | 0 {icons => _docs/icons}/loop_reconnect.svg | 0 {icons => _docs/icons}/loop_resume.svg | 0 {icons => _docs/icons}/loop_superbolus.svg | 0 {icons => _docs/icons}/pod.svg | 0 {icons => _docs/icons}/quickwizard.svg | 0 {icons => _docs/icons}/remove.svg | 0 {icons => _docs/icons}/reset_database.svg | 0 {icons => _docs/icons}/send_log.svg | 0 {icons => _docs/icons}/setting_off.svg | 0 {icons => _docs/icons}/setting_on.svg | 0 {icons => _docs/icons}/target_activity.svg | 0 {icons => _docs/icons}/target_cancel.svg | 0 {icons => _docs/icons}/target_eatingsoon.svg | 0 {icons => _docs/icons}/target_hypo.svg | 0 {icons => _docs/icons}/target_manual.svg | 0 .../icons}/temp-basal/icon_cp_basal_100px.psd | Bin .../icons}/temp-basal/icon_cp_basal_150px.psd | Bin .../icons}/temp-basal/icon_cp_basal_200px.psd | Bin .../icons}/temp-basal/icon_cp_basal_50px.psd | Bin .../icons}/temp-basal/icon_cp_basal_75px.psd | Bin {icons => _docs/icons}/temptarget_flat.svg | 0 {icons => _docs/icons}/temptarget_high.svg | 0 {icons => _docs/icons}/temptarget_low.svg | 0 {icons => _docs/icons}/veo.svg | 0 {icons => _docs/icons}/visibility.svg | 0 {icons => _docs/icons}/x_swap_vert.svg | 0 {icons => _docs/icons}/xdrip.svg | 0 {logo => _docs/logo}/androiaps.eps | Bin {logo => _docs/logo}/androiaps_tshirt.pdf | 0 {logo => _docs/logo}/androidaps.ai | 0 {logo => _docs/logo}/androidaps.pdf | 0 {logo => _docs/logo}/androidaps2.ai | 0 {logo => _docs/logo}/androidaps2.pdf | 0 {logo => _docs/logo}/background-01.svg | 0 {logo => _docs/logo}/background.ai | 0 {logo => _docs/logo}/background.pdf | 0 {logo => _docs/logo}/blueowl-web.png | Bin {logo => _docs/logo}/drawing.png | Bin {logo => _docs/logo}/drawing.svg | 0 {logo => _docs/logo}/ic_launcher-web.png | Bin .../logo}/ic_launcher_round-web.png | Bin {logo => _docs/logo}/icons.ai | 0 {logo => _docs/logo}/icons.pdf | 0 {logo => _docs/logo}/icons.svg | 0 {logo => _docs/logo}/logo.md | 0 {logo => _docs/logo}/logo_androidaps.ai | 0 {logo => _docs/logo}/logo_androidaps.pdf | 0 {logo => _docs/logo}/logo_androidaps.svg | 0 {logo => _docs/logo}/logoanaps.png | Bin {logo => _docs/logo}/notif_icon.png | Bin {logo => _docs/logo}/notificationdot.png | Bin {logo => _docs/logo}/notificationdot2.png | Bin {logo => _docs/logo}/nsclient/white.png | Bin {logo => _docs/logo}/old/AndroidAPS Icon.ai | 0 {logo => _docs/logo}/old/AndroidAPS Icon.png | Bin {logo => _docs/logo}/pattern.ai | 0 {logo => _docs/logo}/pattern.pdf | 0 {logo => _docs/logo}/pattern.svg | 0 {logo => _docs/logo}/screenshot.png | Bin {logo => _docs/logo}/tshirt.png | Bin .../revoking_leaked_apks.md | 0 app/build.gradle | 24 +++++------ crowdin.yml | 40 +++++++++--------- insight/build.gradle | 3 +- {combo => pump/combo}/.gitignore | 0 {combo => pump/combo}/build.gradle | 0 {combo => pump/combo}/consumer-rules.pro | 0 {combo => pump/combo}/proguard-rules.pro | 0 .../combo}/src/main/AndroidManifest.xml | 0 .../d/ruffy/ruffy/driver/IRTHandler.aidl | 0 .../d/ruffy/ruffy/driver/IRuffyService.aidl | 0 .../d/ruffy/ruffy/driver/display/Menu.aidl | 0 .../d/ruffy/ruffy/driver/package-info.java | 0 .../combo/di/ComboActivitiesModule.kt | 0 .../androidaps/combo/di/ComboModule.kt | 0 .../plugins/pump/combo/ComboFragment.kt | 0 .../plugins/pump/combo/ComboPlugin.java | 0 .../plugins/pump/combo/ComboPump.java | 0 .../plugins/pump/combo/data/ComboErrorUtil.kt | 0 .../combo/events/EventComboPumpUpdateGUI.kt | 0 .../combo/ruffyscripter/BasalProfile.java | 0 .../ruffyscripter/BolusProgressReporter.java | 0 .../combo/ruffyscripter/CommandResult.java | 0 .../combo/ruffyscripter/PumpErrorCodes.java | 0 .../pump/combo/ruffyscripter/PumpState.java | 0 .../combo/ruffyscripter/PumpWarningCodes.java | 0 .../combo/ruffyscripter/RuffyCommands.java | 0 .../combo/ruffyscripter/RuffyScripter.java | 0 .../ruffyscripter/WarningOrErrorCode.java | 0 .../ruffyscripter/commands/BaseCommand.java | 0 .../ruffyscripter/commands/BolusCommand.java | 0 .../commands/CancelTbrCommand.java | 0 .../combo/ruffyscripter/commands/Command.java | 0 .../commands/CommandException.java | 0 .../commands/ConfirmAlertCommand.java | 0 .../commands/ReadBasalProfileCommand.java | 0 .../commands/ReadHistoryCommand.java | 0 .../commands/ReadPumpStateCommand.java | 0 .../commands/ReadQuickInfoCommand.java | 0 .../commands/SetBasalProfileCommand.java | 0 .../ruffyscripter/commands/SetTbrCommand.java | 0 .../combo/ruffyscripter/history/Bolus.java | 0 .../ruffyscripter/history/HistoryRecord.java | 0 .../ruffyscripter/history/PumpAlert.java | 0 .../ruffyscripter/history/PumpHistory.java | 0 .../history/PumpHistoryRequest.java | 0 .../pump/combo/ruffyscripter/history/Tbr.java | 0 .../pump/combo/ruffyscripter/history/Tdd.java | 0 .../d/ruffy/ruffy/driver/display/Menu.java | 0 .../ruffy/driver/display/MenuAttribute.java | 0 .../ruffy/ruffy/driver/display/MenuType.java | 0 .../ruffy/driver/display/menu/BolusType.java | 0 .../ruffy/driver/display/menu/MenuBlink.java | 0 .../ruffy/driver/display/menu/MenuDate.java | 0 .../ruffy/driver/display/menu/MenuTime.java | 0 .../combo}/src/main/res/drawable/ic_combo.xml | 0 .../main/res/layout/combopump_fragment.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../combo}/src/main/res/values/arrays.xml | 0 .../combo}/src/main/res/values/strings.xml | 0 .../combo}/src/main/res/xml/pref_combo.xml | 0 .../plugins/pump/combo/ComboPluginTest.kt | 0 .../androidaps/plugins/pump/combo/TestBase.kt | 0 {dana => pump/dana}/.gitignore | 0 {dana => pump/dana}/build.gradle | 0 {dana => pump/dana}/consumer-rules.pro | 0 {dana => pump/dana}/proguard-rules.pro | 0 .../1.json | 0 .../dana}/src/main/AndroidManifest.xml | 0 .../androidaps/dana/DanaFragment.kt | 0 .../nightscout/androidaps/dana/DanaPump.kt | 0 .../dana/activities/DanaHistoryActivity.kt | 0 .../activities/DanaUserOptionsActivity.kt | 0 .../androidaps/dana/comm/RecordTypes.kt | 0 .../dana/database/DanaHistoryDatabase.kt | 0 .../dana/database/DanaHistoryRecord.kt | 0 .../dana/database/DanaHistoryRecordDao.kt | 0 .../androidaps/dana/di/DanaHistoryModule.kt | 0 .../androidaps/dana/di/DanaModule.kt | 0 .../dana/events/EventDanaRNewStatus.kt | 0 .../dana}/src/main/res/drawable/ic_dana_i.xml | 0 .../src/main/res/drawable/ic_dana_rs.xml | 0 .../src/main/res/layout/danar_fragment.xml | 0 .../res/layout/danar_history_activity.xml | 0 .../main/res/layout/danar_history_item.xml | 0 .../layout/danar_user_options_activity.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-ar-rSA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-cy-rGB/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fi-rFI/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ja-rJP/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../dana}/src/main/res/values/arrays.xml | 0 .../dana}/src/main/res/values/strings.xml | 0 .../info/nightscout/androidaps/TestBase.kt | 0 .../androidaps/TestBaseWithProfile.kt | 0 .../androidaps/dana/DanaPumpTest.kt | 0 {danar => pump/danar}/.gitignore | 0 {danar => pump/danar}/build.gradle | 4 +- {danar => pump/danar}/consumer-rules.pro | 0 {danar => pump/danar}/proguard-rules.pro | 0 .../danar}/src/main/AndroidManifest.xml | 0 .../danaRKorean/DanaRKoreanPlugin.kt | 0 .../comm/MessageHashTableRKorean.kt | 0 .../danaRKorean/comm/MsgCheckValue_k.kt | 0 .../comm/MsgInitConnStatusBasic_k.kt | 0 .../comm/MsgInitConnStatusBolus_k.kt | 0 .../comm/MsgInitConnStatusTime_k.kt | 0 .../comm/MsgSettingBasalProfileAll_k.kt | 0 .../danaRKorean/comm/MsgSettingBasal_k.kt | 0 .../danaRKorean/comm/MsgStatusBasic_k.kt | 0 .../danaRKorean/comm/MsgStatus_k.kt | 0 .../services/DanaRKoreanExecutionService.java | 0 .../androidaps/danaRv2/DanaRv2Plugin.java | 0 .../danaRv2/comm/MessageHashTableRv2.kt | 0 .../danaRv2/comm/MsgCheckValue_v2.kt | 0 .../danaRv2/comm/MsgHistoryEventsV2.kt | 0 .../comm/MsgSetAPSTempBasalStart_v2.kt | 0 .../danaRv2/comm/MsgSetHistoryEntry_v2.kt | 0 .../danaRv2/comm/MsgStatusAPS_v2.kt | 0 .../services/DanaRv2ExecutionService.java | 0 .../androidaps/danar/AbstractDanaRPlugin.java | 0 .../androidaps/danar/DanaRPlugin.java | 0 .../androidaps/danar/SerialIOThread.java | 0 .../androidaps/danar/comm/MessageBase.kt | 0 .../danar/comm/MessageHashTableBase.kt | 0 .../danar/comm/MessageHashTableR.kt | 0 .../danar/comm/MessageOriginalNames.kt | 0 .../androidaps/danar/comm/MsgBolusProgress.kt | 0 .../androidaps/danar/comm/MsgBolusStart.kt | 0 .../danar/comm/MsgBolusStartWithSpeed.kt | 0 .../androidaps/danar/comm/MsgBolusStop.kt | 0 .../androidaps/danar/comm/MsgCheckValue.kt | 0 .../androidaps/danar/comm/MsgError.kt | 0 .../androidaps/danar/comm/MsgHistoryAlarm.kt | 0 .../androidaps/danar/comm/MsgHistoryAll.kt | 0 .../danar/comm/MsgHistoryAllDone.kt | 0 .../danar/comm/MsgHistoryBasalHour.kt | 0 .../androidaps/danar/comm/MsgHistoryBolus.kt | 0 .../androidaps/danar/comm/MsgHistoryCarbo.kt | 0 .../danar/comm/MsgHistoryDailyInsulin.kt | 0 .../androidaps/danar/comm/MsgHistoryDone.kt | 0 .../androidaps/danar/comm/MsgHistoryError.kt | 0 .../danar/comm/MsgHistoryGlucose.kt | 0 .../androidaps/danar/comm/MsgHistoryNew.kt | 0 .../danar/comm/MsgHistoryNewDone.kt | 0 .../androidaps/danar/comm/MsgHistoryRefill.kt | 0 .../danar/comm/MsgHistorySuspend.kt | 0 .../danar/comm/MsgInitConnStatusBasic.kt | 0 .../danar/comm/MsgInitConnStatusBolus.kt | 0 .../danar/comm/MsgInitConnStatusOption.kt | 0 .../danar/comm/MsgInitConnStatusTime.kt | 0 .../androidaps/danar/comm/MsgPCCommStart.kt | 0 .../androidaps/danar/comm/MsgPCCommStop.kt | 0 .../danar/comm/MsgSetActivateBasalProfile.kt | 0 .../danar/comm/MsgSetBasalProfile.kt | 0 .../androidaps/danar/comm/MsgSetCarbsEntry.kt | 0 .../danar/comm/MsgSetExtendedBolusStart.kt | 0 .../danar/comm/MsgSetExtendedBolusStop.kt | 0 .../danar/comm/MsgSetSingleBasalProfile.kt | 0 .../danar/comm/MsgSetTempBasalStart.kt | 0 .../danar/comm/MsgSetTempBasalStop.kt | 0 .../androidaps/danar/comm/MsgSetTime.kt | 0 .../danar/comm/MsgSetUserOptions.kt | 0 .../danar/comm/MsgSettingActiveProfile.kt | 0 .../androidaps/danar/comm/MsgSettingBasal.kt | 0 .../danar/comm/MsgSettingBasalProfileAll.kt | 0 .../danar/comm/MsgSettingGlucose.kt | 0 .../danar/comm/MsgSettingMaxValues.kt | 0 .../androidaps/danar/comm/MsgSettingMeal.kt | 0 .../danar/comm/MsgSettingProfileRatios.kt | 0 .../danar/comm/MsgSettingProfileRatiosAll.kt | 0 .../danar/comm/MsgSettingPumpTime.kt | 0 .../danar/comm/MsgSettingShippingInfo.kt | 0 .../danar/comm/MsgSettingUserOptions.kt | 0 .../androidaps/danar/comm/MsgStatus.kt | 0 .../androidaps/danar/comm/MsgStatusBasic.kt | 0 .../danar/comm/MsgStatusBolusExtended.kt | 0 .../androidaps/danar/comm/MsgStatusProfile.kt | 0 .../danar/comm/MsgStatusTempBasal.kt | 0 .../androidaps/danar/di/DanaRCommModule.kt | 0 .../androidaps/danar/di/DanaRModule.kt | 0 .../danar/di/DanaRServicesModule.kt | 0 .../AbstractDanaRExecutionService.java | 0 .../danar/services/DanaRExecutionService.java | 0 .../info/nightscout/androidaps/utils/CRC.kt | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../danar}/src/main/res/values/strings.xml | 0 .../danar}/src/main/res/xml/pref_danar.xml | 0 .../src/main/res/xml/pref_danarkorean.xml | 0 .../danar}/src/main/res/xml/pref_danarv2.xml | 0 .../info/nightscout/androidaps/TestBase.kt | 0 .../androidaps/TestBaseWithProfile.kt | 0 .../nightscout/androidaps/TestPumpPlugin.kt | 0 .../plugins/pump/danaR/DanaRPluginTest.kt | 0 .../plugins/pump/danaR/comm/DanaRTestBase.kt | 0 .../pump/danaR/comm/MessageHashTableRTest.kt | 0 .../danaR/comm/MessageOriginalNamesTest.kt | 0 .../pump/danaR/comm/MsgBolusProgressTest.kt | 0 .../pump/danaR/comm/MsgBolusStartTest.kt | 0 .../danaR/comm/MsgBolusStartWithSpeedTest.kt | 0 .../pump/danaR/comm/MsgBolusStopTest.kt | 0 .../pump/danaR/comm/MsgCheckValueTest.kt | 0 .../plugins/pump/danaR/comm/MsgErrorTest.kt | 0 .../pump/danaR/comm/MsgHistoryAlarmTest.kt | 0 .../pump/danaR/comm/MsgHistoryAllDoneTest.kt | 0 .../pump/danaR/comm/MsgHistoryAllTest.kt | 0 .../danaR/comm/MsgHistoryBasalHourTest.kt | 0 .../pump/danaR/comm/MsgHistoryBolusTest.kt | 0 .../pump/danaR/comm/MsgHistoryCarboTest.kt | 0 .../danaR/comm/MsgHistoryDailyInsulinTest.kt | 0 .../pump/danaR/comm/MsgHistoryDoneTest.kt | 0 .../pump/danaR/comm/MsgHistoryErrorTest.kt | 0 .../pump/danaR/comm/MsgHistoryGlucoseTest.kt | 0 .../pump/danaR/comm/MsgHistoryNewDoneTest.kt | 0 .../pump/danaR/comm/MsgHistoryNewTest.kt | 0 .../pump/danaR/comm/MsgHistoryRefillTest.kt | 0 .../pump/danaR/comm/MsgHistorySuspendTest.kt | 0 .../danaR/comm/MsgInitConnStatusBasicTest.kt | 0 .../danaR/comm/MsgInitConnStatusBolusTest.kt | 0 .../danaR/comm/MsgInitConnStatusOptionTest.kt | 0 .../danaR/comm/MsgInitConnStatusTimeTest.kt | 0 .../pump/danaR/comm/MsgPCCommStartTest.kt | 0 .../pump/danaR/comm/MsgPCCommStopTest.kt | 0 .../comm/MsgSetActivateBasalProfileTest.kt | 0 .../pump/danaR/comm/MsgSetBasalProfileTest.kt | 0 .../pump/danaR/comm/MsgSetCarbsEntryTest.kt | 0 .../comm/MsgSetExtendedBolusStartTest.kt | 0 .../danaR/comm/MsgSetExtendedBolusStopTest.kt | 0 .../comm/MsgSetSingleBasalProfileTest.kt | 0 .../danaR/comm/MsgSetTempBasalStartTest.kt | 0 .../plugins/pump/danaR/comm/MsgSetTimeTest.kt | 0 .../pump/danaR/comm/MsgSetUserOptionsTest.kt | 0 .../danaR/comm/MsgSettingActiveProfileTest.kt | 0 .../comm/MsgSettingBasalProfileAllTest.kt | 0 .../pump/danaR/comm/MsgSettingBasalTest.kt | 0 .../pump/danaR/comm/MsgSettingGlucoseTest.kt | 0 .../danaR/comm/MsgSettingMaxValuesTest.kt | 0 .../pump/danaR/comm/MsgSettingMealTest.kt | 0 .../comm/MsgSettingProfileRatiosAllTest.kt | 0 .../danaR/comm/MsgSettingProfileRatiosTest.kt | 0 .../pump/danaR/comm/MsgSettingPumpTimeTest.kt | 0 .../danaR/comm/MsgSettingShippingInfoTest.kt | 0 .../danaR/comm/MsgSettingUserOptionsTest.kt | 0 .../pump/danaR/comm/MsgStatusBasicTest.kt | 0 .../danaR/comm/MsgStatusBolusExtendedTest.kt | 0 .../pump/danaR/comm/MsgStatusProfileTest.kt | 0 .../pump/danaR/comm/MsgStatusTempBasalTest.kt | 0 .../plugins/pump/danaR/comm/MsgStatusTest.kt | 0 .../pump/danaR/comm/RecordTypesTest.kt | 0 .../pump/danaRKorean/DanaRKoreanPluginTest.kt | 0 .../comm/MessageHashTableRKoreanTest.kt | 0 .../plugins/pump/danaRv2/DanaRv2PluginTest.kt | 0 .../danaRv2/comm/MessageHashTableRv2Test.kt | 0 .../pump/danaRv2/comm/MsgCheckValueRv2Test.kt | 0 .../danaRv2/comm/MsgHistoryEventsRv2Test.kt | 0 .../comm/MsgSetAPSTempBasalStartRv2Test.kt | 0 .../danaRv2/comm/MsgSetHistoryEntryRv2Test.kt | 0 .../pump/danaRv2/comm/MsgStatusAPSRv2Test.kt | 0 .../nightscout/androidaps/utils/CRCTest.kt | 0 {danars => pump/danars}/.gitignore | 0 {danars => pump/danars}/build.gradle | 2 +- {danars => pump/danars}/consumer-rules.pro | 0 {danars => pump/danars}/proguard-rules.pro | 0 .../danars}/src/main/AndroidManifest.xml | 0 .../androidaps/danars/DanaRSPlugin.kt | 0 .../danars/activities/BLEScanActivity.kt | 0 .../danars/activities/EnterPinActivity.kt | 0 .../activities/PairingHelperActivity.kt | 0 .../danars/comm/DanaRSMessageHashTable.kt | 0 .../androidaps/danars/comm/DanaRSPacket.kt | 0 .../DanaRSPacketAPSBasalSetTemporaryBasal.kt | 0 .../comm/DanaRSPacketAPSHistoryEvents.kt | 0 .../comm/DanaRSPacketAPSSetEventHistory.kt | 0 .../comm/DanaRSPacketBasalGetBasalRate.kt | 0 .../comm/DanaRSPacketBasalGetProfileNumber.kt | 0 ...anaRSPacketBasalSetCancelTemporaryBasal.kt | 0 .../DanaRSPacketBasalSetProfileBasalRate.kt | 0 .../comm/DanaRSPacketBasalSetProfileNumber.kt | 0 .../comm/DanaRSPacketBasalSetSuspendOff.kt | 0 .../comm/DanaRSPacketBasalSetSuspendOn.kt | 0 .../DanaRSPacketBasalSetTemporaryBasal.kt | 0 .../comm/DanaRSPacketBolusGet24CIRCFArray.kt | 0 .../comm/DanaRSPacketBolusGetBolusOption.kt | 0 .../comm/DanaRSPacketBolusGetCIRCFArray.kt | 0 ...aRSPacketBolusGetCalculationInformation.kt | 0 ...anaRSPacketBolusGetStepBolusInformation.kt | 0 .../comm/DanaRSPacketBolusSet24CIRCFArray.kt | 0 .../comm/DanaRSPacketBolusSetBolusOption.kt | 0 .../comm/DanaRSPacketBolusSetExtendedBolus.kt | 0 ...DanaRSPacketBolusSetExtendedBolusCancel.kt | 0 .../DanaRSPacketBolusSetStepBolusStart.kt | 0 .../comm/DanaRSPacketBolusSetStepBolusStop.kt | 0 .../comm/DanaRSPacketEtcKeepConnection.kt | 0 .../comm/DanaRSPacketEtcSetHistorySave.kt | 0 .../comm/DanaRSPacketGeneralGetPumpCheck.kt | 0 ...naRSPacketGeneralGetShippingInformation.kt | 0 .../DanaRSPacketGeneralGetShippingVersion.kt | 0 ...anaRSPacketGeneralGetUserTimeChangeFlag.kt | 0 ...RSPacketGeneralInitialScreenInformation.kt | 0 ...DanaRSPacketGeneralSetHistoryUploadMode.kt | 0 ...PacketGeneralSetUserTimeChangeFlagClear.kt | 0 .../danars/comm/DanaRSPacketHistory.kt | 0 .../danars/comm/DanaRSPacketHistoryAlarm.kt | 0 .../comm/DanaRSPacketHistoryAllHistory.kt | 0 .../danars/comm/DanaRSPacketHistoryBasal.kt | 0 .../comm/DanaRSPacketHistoryBloodGlucose.kt | 0 .../danars/comm/DanaRSPacketHistoryBolus.kt | 0 .../comm/DanaRSPacketHistoryCarbohydrate.kt | 0 .../danars/comm/DanaRSPacketHistoryDaily.kt | 0 .../danars/comm/DanaRSPacketHistoryPrime.kt | 0 .../danars/comm/DanaRSPacketHistoryRefill.kt | 0 .../danars/comm/DanaRSPacketHistorySuspend.kt | 0 .../comm/DanaRSPacketHistoryTemporary.kt | 0 .../danars/comm/DanaRSPacketNotifyAlarm.kt | 0 .../DanaRSPacketNotifyDeliveryComplete.kt | 0 .../DanaRSPacketNotifyDeliveryRateDisplay.kt | 0 .../DanaRSPacketNotifyMissedBolusAlarm.kt | 0 .../comm/DanaRSPacketOptionGetPumpTime.kt | 0 ...DanaRSPacketOptionGetPumpUTCAndTimeZone.kt | 0 .../comm/DanaRSPacketOptionGetUserOption.kt | 0 .../comm/DanaRSPacketOptionSetPumpTime.kt | 0 ...DanaRSPacketOptionSetPumpUTCAndTimeZone.kt | 0 .../comm/DanaRSPacketOptionSetUserOption.kt | 0 .../danars/comm/DanaRSPacketReviewBolusAvg.kt | 0 .../comm/DanaRSPacketReviewGetPumpDecRatio.kt | 0 .../danars/di/DanaRSActivitiesModule.kt | 0 .../androidaps/danars/di/DanaRSCommModule.kt | 0 .../androidaps/danars/di/DanaRSModule.kt | 0 .../danars/di/DanaRSServicesModule.kt | 0 .../danars/dialogs/PairingProgressDialog.java | 0 .../danars/encryption/BleEncryption.java | 0 .../danars/encryption/EncryptionType.kt | 0 .../danars/events/EventDanaRSDeviceChange.kt | 0 .../events/EventDanaRSPairingSuccess.kt | 0 .../androidaps/danars/services/BLEComm.kt | 0 .../danars/services/DanaRSService.kt | 0 .../jniLibs/arm64-v8a/libBleEncryption.so | Bin .../jniLibs/armeabi-v7a/libBleEncryption.so | Bin .../src/main/jniLibs/x86/libBleEncryption.so | Bin .../main/jniLibs/x86_64/libBleEncryption.so | Bin .../res/layout/danars_blescanner_activity.xml | 0 .../res/layout/danars_blescanner_item.xml | 0 .../res/layout/danars_enter_pin_activity.xml | 0 .../layout/danars_pairing_progress_dialog.xml | 0 .../danars}/src/main/res/xml/pref_danars.xml | 0 .../info/nightscout/androidaps/TestBase.kt | 0 .../androidaps/TestBaseWithProfile.kt | 0 .../androidaps/danars/DanaRSPluginTest.kt | 0 .../androidaps/danars/DanaRSTestBase.kt | 0 .../DanaRSPacketBasalSetTemporaryBasalTest.kt | 0 .../comm/DanaRSPacketHistoryAlarmTest.kt | 0 .../DanaRSPacketNotifyDeliveryCompleteTest.kt | 0 .../DanaRSPacketOptionSetUserOptionTest.kt | 0 .../androidaps/danars/comm/DanaRSTestBase.kt | 0 .../danars/comm/DanaRsMessageHashTableTest.kt | 0 ...naRsPacketApsBasalSetTemporaryBasalTest.kt | 0 .../comm/DanaRsPacketApsHistoryEventsTest.kt | 0 .../DanaRsPacketApsSetEventHistoryTest.kt | 0 .../comm/DanaRsPacketBasalGetBasalRateTest.kt | 0 .../DanaRsPacketBasalGetProfileNumberTest.kt | 0 ...sPacketBasalSetCancelTemporaryBasalTest.kt | 0 ...anaRsPacketBasalSetProfileBasalRateTest.kt | 0 .../DanaRsPacketBasalSetProfileNumberTest.kt | 0 .../DanaRsPacketBasalSetSuspendOffTest.kt | 0 .../comm/DanaRsPacketBasalSetSuspendOnTest.kt | 0 .../DanaRsPacketBolusGetBolusOptionTest.kt | 0 ...acketBolusGetCalculationInformationTest.kt | 0 .../DanaRsPacketBolusGetCirCfArrayTest.kt | 0 ...sPacketBolusGetStepBolusInformationTest.kt | 0 .../DanaRsPacketBolusSetBolusOptionTest.kt | 0 ...RsPacketBolusSetExtendedBolusCancelTest.kt | 0 .../DanaRsPacketBolusSetExtendedBolusTest.kt | 0 .../DanaRsPacketBolusSetStepBolusStartTest.kt | 0 .../DanaRsPacketBolusSetStepBolusStopTest.kt | 0 .../comm/DanaRsPacketEtcKeepConnectionTest.kt | 0 .../comm/DanaRsPacketEtcSetHistorySaveTest.kt | 0 .../DanaRsPacketGeneralGetPumpCheckTest.kt | 0 ...PacketGeneralGetShippingInformationTest.kt | 0 ...naRsPacketGeneralGetShippingVerisonTest.kt | 0 ...sPacketGeneralGetUserTimeChangeFlagTest.kt | 0 ...cketGeneralInitialScreenInformationTest.kt | 0 ...RsPacketGeneralSetHistoryUploadModeTest.kt | 0 ...etGeneralSetUserTimeChangeFlagClearTest.kt | 0 .../comm/DanaRsPacketHistoryAllHistoryTest.kt | 0 .../comm/DanaRsPacketHistoryBasalTest.kt | 0 .../DanaRsPacketHistoryBloodGlucoseTest.kt | 0 .../comm/DanaRsPacketHistoryBolusTest.kt | 0 .../DanaRsPacketHistoryCarbohydrateTest.kt | 0 .../comm/DanaRsPacketHistoryDailyTest.kt | 0 .../comm/DanaRsPacketHistoryPrimeTest.kt | 0 .../comm/DanaRsPacketHistoryRefillTest.kt | 0 .../comm/DanaRsPacketHistorySuspendTest.kt | 0 .../comm/DanaRsPacketHistoryTemporaryTest.kt | 0 .../comm/DanaRsPacketNotifyAlarmTest.kt | 0 ...naRsPacketNotifyDeliveryRateDisplayTest.kt | 0 .../DanaRsPacketNotifyMissedBolusAlarmTest.kt | 0 .../comm/DanaRsPacketOptionGetPumpTimeTest.kt | 0 .../DanaRsPacketOptionGetUserOptionTest.kt | 0 .../comm/DanaRsPacketOptionSetPumpTimeTest.kt | 0 .../comm/DanaRsPacketReviewBolusAvgTest.kt | 0 .../DanaRsPacketReviewGetPumpDecRatioTest.kt | 0 {diaconn => pump/diaconn}/build.gradle | 0 {diaconn => pump/diaconn}/consumer-rules.pro | 0 {diaconn => pump/diaconn}/proguard-rules.pro | 0 .../1.json | 0 .../diaconn}/src/main/AndroidManifest.xml | 0 .../androidaps/diaconn/DiaconnG8Fragment.kt | 0 .../androidaps/diaconn/DiaconnG8Plugin.kt | 0 .../androidaps/diaconn/DiaconnG8Pump.kt | 0 .../activities/DiaconnG8BLEScanActivity.kt | 0 .../activities/DiaconnG8HistoryActivity.kt | 0 .../DiaconnG8UserOptionsActivity.kt | 0 .../diaconn/api/DiaconnApiResponse.kt | 0 .../diaconn/api/DiaconnApiService.kt | 0 .../diaconn/api/DiaconnLogUploader.kt | 0 .../androidaps/diaconn/common/RecordTypes.kt | 0 .../database/DiaconnHistoryDatabase.kt | 0 .../diaconn/database/DiaconnHistoryRecord.kt | 0 .../database/DiaconnHistoryRecordDao.kt | 0 .../diaconn/di/DiaconnG8ActivitiesModule.kt | 0 .../androidaps/diaconn/di/DiaconnG8Module.kt | 0 .../diaconn/di/DiaconnG8PacketModule.kt | 0 .../diaconn/di/DiaconnG8ServiceModule.kt | 0 .../diaconn/di/DiaconnHistoryModule.kt | 0 .../diaconn/di/DiaconnLogUploaderModule.kt | 0 .../events/EventDiaconnG8DeviceChange.kt | 0 .../diaconn/events/EventDiaconnG8NewStatus.kt | 0 .../events/EventDiaconnG8PumpLogReset.kt | 0 .../diaconn/packet/AppCancelSettingPacket.kt | 0 .../packet/AppCancelSettingResponsePacket.kt | 0 .../diaconn/packet/AppConfirmSettingPacket.kt | 0 .../packet/AppConfirmSettingResponsePacket.kt | 0 .../diaconn/packet/BasalLimitInquirePacket.kt | 0 .../packet/BasalLimitInquireResponsePacket.kt | 0 .../diaconn/packet/BasalPauseReportPacket.kt | 0 .../diaconn/packet/BasalPauseSettingPacket.kt | 0 .../packet/BasalPauseSettingResponsePacket.kt | 0 .../diaconn/packet/BasalSettingPacket.kt | 0 .../packet/BasalSettingReportPacket.kt | 0 .../packet/BasalSettingResponsePacket.kt | 0 .../packet/BatteryWarningReportPacket.kt | 0 .../packet/BigAPSMainInfoInquirePacket.kt | 0 .../BigAPSMainInfoInquireResponsePacket.kt | 0 .../diaconn/packet/BigLogInquirePacket.kt | 0 .../packet/BigLogInquireResponsePacket.kt | 0 .../packet/BigMainInfoInquirePacket.kt | 0 .../BigMainInfoInquireResponsePacket.kt | 0 .../diaconn/packet/BolusSpeedInquirePacket.kt | 0 .../packet/BolusSpeedInquireResponsePacket.kt | 0 .../diaconn/packet/BolusSpeedSettingPacket.kt | 0 .../packet/BolusSpeedSettingReportPacket.kt | 0 .../packet/BolusSpeedSettingResponsePacket.kt | 0 .../diaconn/packet/ConfirmReportPacket.kt | 0 .../diaconn/packet/DiaconnG8Packet.java | 0 .../DiaconnG8ResponseMessageHashTable.kt | 0 ...iaconnG8SettingResponseMessageHashTable.kt | 0 .../packet/DisplayTimeInquirePacket.kt | 0 .../DisplayTimeInquireResponsePacket.kt | 0 .../packet/DisplayTimeoutSettingPacket.kt | 0 .../DisplayTimeoutSettingResponsePacket.kt | 0 .../packet/IncarnationInquirePacket.kt | 0 .../IncarnationInquireResponsePacket.kt | 0 .../packet/InjectionBasalReportPacket.kt | 0 .../packet/InjectionBasalSettingPacket.kt | 0 .../InjectionBasalSettingResponsePacket.kt | 0 .../packet/InjectionBlockReportPacket.kt | 0 .../packet/InjectionCancelSettingPacket.kt | 0 .../InjectionCancelSettingResponsePacket.kt | 0 ...njectionExtendedBolusResultReportPacket.kt | 0 .../InjectionExtendedBolusSettingPacket.kt | 0 ...ctionExtendedBolusSettingResponsePacket.kt | 0 .../packet/InjectionMealSettingPacket.kt | 0 .../InjectionMealSettingResponsePacket.kt | 0 .../packet/InjectionSnackInquirePacket.kt | 0 .../InjectionSnackInquireResponsePacket.kt | 0 .../InjectionSnackResultReportPacket.kt | 0 .../packet/InjectionSnackSettingPacket.kt | 0 .../InjectionSnackSettingResponsePacket.kt | 0 .../diaconn/packet/InsulinLackReportPacket.kt | 0 .../diaconn/packet/LanguageInquirePacket.kt | 0 .../packet/LanguageInquireResponsePacket.kt | 0 .../diaconn/packet/LanguageSettingPacket.kt | 0 .../packet/LanguageSettingResponsePacket.kt | 0 .../diaconn/packet/LogStatusInquirePacket.kt | 0 .../packet/LogStatusInquireResponsePacket.kt | 0 .../diaconn/packet/RejectReportPacket.kt | 0 .../diaconn/packet/SerialNumInquirePacket.kt | 0 .../packet/SerialNumInquireResponsePacket.kt | 0 .../diaconn/packet/SneckLimitInquirePacket.kt | 0 .../packet/SneckLimitInquireResponsePacket.kt | 0 .../diaconn/packet/SoundInquirePacket.kt | 0 .../packet/SoundInquireResponsePacket.kt | 0 .../diaconn/packet/SoundSettingPacket.kt | 0 .../packet/SoundSettingResponsePacket.kt | 0 .../diaconn/packet/TempBasalInquirePacket.kt | 0 .../packet/TempBasalInquireResponsePacket.kt | 0 .../diaconn/packet/TempBasalReportPacket.kt | 0 .../diaconn/packet/TempBasalSettingPacket.kt | 0 .../packet/TempBasalSettingResponsePacket.kt | 0 .../diaconn/packet/TimeInquirePacket.kt | 0 .../packet/TimeInquireResponsePacket.kt | 0 .../diaconn/packet/TimeReportPacket.kt | 0 .../diaconn/packet/TimeSettingPacket.kt | 0 .../packet/TimeSettingResponsePacket.kt | 0 .../diaconn/pumplog/LOG_ALARM_BATTERY.kt | 0 .../diaconn/pumplog/LOG_ALARM_BLOCK.kt | 0 .../diaconn/pumplog/LOG_ALARM_SHORTAGE.kt | 0 .../pumplog/LOG_CHANGE_INJECTOR_SUCCESS.kt | 0 .../pumplog/LOG_CHANGE_NEEDLE_SUCCESS.kt | 0 .../pumplog/LOG_CHANGE_TUBE_SUCCESS.kt | 0 .../diaconn/pumplog/LOG_INJECTION_1DAY.kt | 0 .../pumplog/LOG_INJECTION_1DAY_BASAL.kt | 0 .../pumplog/LOG_INJECTION_1HOUR_BASAL.kt | 0 .../pumplog/LOG_INJECTION_DUAL_NORMAL.kt | 0 .../diaconn/pumplog/LOG_INJECT_DUAL_FAIL.kt | 0 .../pumplog/LOG_INJECT_DUAL_SUCCESS.kt | 0 .../diaconn/pumplog/LOG_INJECT_MEAL_FAIL.kt | 0 .../pumplog/LOG_INJECT_MEAL_SUCCESS.kt | 0 .../diaconn/pumplog/LOG_INJECT_NORMAL_FAIL.kt | 0 .../pumplog/LOG_INJECT_NORMAL_SUCCESS.kt | 0 .../diaconn/pumplog/LOG_INJECT_SQUARE_FAIL.kt | 0 .../pumplog/LOG_INJECT_SQUARE_SUCCESS.kt | 0 .../diaconn/pumplog/LOG_RESET_SYS_V3.kt | 0 .../diaconn/pumplog/LOG_SET_DUAL_INJECTION.kt | 0 .../pumplog/LOG_SET_SQUARE_INJECTION.kt | 0 .../diaconn/pumplog/LOG_SUSPEND_RELEASE_V2.kt | 0 .../diaconn/pumplog/LOG_SUSPEND_V2.kt | 0 .../diaconn/pumplog/LOG_TB_START_V3.kt | 0 .../diaconn/pumplog/LOG_TB_STOP_V3.kt | 0 .../diaconn/pumplog/PumplogUtil.java | 0 .../diaconn/service/BLECommonService.kt | 0 .../diaconn/service/DiaconnG8Service.kt | 0 .../layout/diaconn_g8_blescanner_activity.xml | 0 .../res/layout/diaconn_g8_blescanner_item.xml | 0 .../main/res/layout/diaconn_g8_fragment.xml | 0 .../layout/diaconn_g8_history_activity.xml | 0 .../res/layout/diaconn_g8_history_item.xml | 0 .../diaconn_g8_user_options_activity.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../diaconn}/src/main/res/values/arrays.xml | 0 .../diaconn}/src/main/res/values/colors.xml | 0 .../diaconn}/src/main/res/values/ids.xml | 0 .../diaconn}/src/main/res/values/strings.xml | 0 .../src/main/res/xml/pref_diaconn.xml | 0 {medtronic => pump/medtronic}/.gitignore | 0 {medtronic => pump/medtronic}/Changelog.txt | 0 {medtronic => pump/medtronic}/build.gradle | 6 +-- .../medtronic}/consumer-rules.pro | 0 .../medtronic}/proguard-rules.pro | 0 .../medtronic}/src/main/AndroidManifest.xml | 0 .../pump/medtronic/MedtronicFragment.kt | 0 .../pump/medtronic/MedtronicPumpPlugin.kt | 0 .../comm/MedtronicCommunicationManager.kt | 0 .../pump/medtronic/comm/MedtronicConverter.kt | 0 .../comm/history/MedtronicHistoryDecoder.kt | 0 .../MedtronicHistoryDecoderInterface.kt | 0 .../comm/history/MedtronicHistoryEntry.kt | 0 .../history/MedtronicHistoryEntryInterface.kt | 0 .../medtronic/comm/history/RawHistoryPage.kt | 0 .../comm/history/RecordDecodeStatus.kt | 0 .../comm/history/cgms/CGMSHistoryEntry.kt | 0 .../comm/history/cgms/CGMSHistoryEntryType.kt | 0 .../cgms/MedtronicCGMSHistoryDecoder.kt | 0 .../pump/MedtronicPumpHistoryDecoder.kt | 0 .../comm/history/pump/PumpHistoryEntry.kt | 0 .../comm/history/pump/PumpHistoryEntryType.kt | 0 .../comm/history/pump/PumpHistoryResult.kt | 0 .../comm/message/CarelinkLongMessageBody.kt | 0 .../comm/message/CarelinkShortMessageBody.kt | 0 .../GetHistoryPageCarelinkMessageBody.kt | 0 .../medtronic/comm/message/MessageBody.kt | 0 .../pump/medtronic/comm/message/PacketType.kt | 0 .../comm/message/PumpAckMessageBody.kt | 0 .../medtronic/comm/message/PumpMessage.kt | 0 .../comm/message/UnknownMessageBody.kt | 0 .../pump/medtronic/comm/ui/MedtronicUIComm.kt | 0 .../comm/ui/MedtronicUIPostprocessor.kt | 0 .../pump/medtronic/comm/ui/MedtronicUITask.kt | 0 .../medtronic/data/MedtronicHistoryData.kt | 0 .../pump/medtronic/data/dto/BasalProfile.kt | 0 .../medtronic/data/dto/BasalProfileEntry.kt | 0 .../medtronic/data/dto/BatteryStatusDTO.kt | 0 .../pump/medtronic/data/dto/BolusDTO.kt | 0 .../pump/medtronic/data/dto/BolusWizardDTO.kt | 0 .../pump/medtronic/data/dto/ClockDTO.kt | 0 .../pump/medtronic/data/dto/DailyTotalsDTO.kt | 0 .../pump/medtronic/data/dto/PumpSettingDTO.kt | 0 .../data/dto/PumpTimeStampedRecord.kt | 0 .../data/dto/RLHistoryItemMedtronic.kt | 0 .../pump/medtronic/data/dto/TempBasalPair.kt | 0 .../medtronic/data/dto/TempBasalProcessDTO.kt | 0 .../pump/medtronic/defs/BasalProfileStatus.kt | 0 .../pump/medtronic/defs/BatteryType.kt | 0 .../medtronic/defs/MedtronicCommandType.kt | 0 .../defs/MedtronicCustomActionType.kt | 0 .../medtronic/defs/MedtronicDeviceType.kt | 0 .../defs/MedtronicNotificationType.kt | 0 .../defs/MedtronicStatusRefreshType.kt | 0 .../medtronic/defs/MedtronicUIResponseType.kt | 0 .../pump/medtronic/defs/PumpBolusType.kt | 0 .../medtronic/defs/PumpConfigurationGroup.kt | 0 .../pump/medtronic/di/MedtronicModule.kt | 0 .../dialog/MedtronicHistoryActivity.kt | 0 .../medtronic/driver/MedtronicPumpStatus.kt | 0 .../EventMedtronicPumpConfigurationChanged.kt | 0 .../events/EventMedtronicPumpValuesChanged.kt | 0 .../service/RileyLinkMedtronicService.kt | 0 .../pump/medtronic/util/MedtronicConst.kt | 0 .../pump/medtronic/util/MedtronicUtil.kt | 0 .../main/res/drawable/ic_medtronic_veo.xml | 0 .../main/res/layout/medtronic_fragment.xml | 0 .../res/layout/medtronic_history_activity.xml | 0 .../res/layout/medtronic_history_item.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-ar-rSA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-cy-rGB/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fi-rFI/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../medtronic}/src/main/res/values/arrays.xml | 0 .../src/main/res/values/strings.xml | 0 .../src/main/res/xml/pref_medtronic.xml | 0 .../info/nightscout/androidaps/TestBase.kt | 0 .../comm/MedtronicConverterUTest.java | 0 .../comm/MedtronicHistoryDataUTest.kt | 0 .../pump/MedtronicPumpHistoryDecoderUTest.kt | 0 .../history/pump/PumpHistoryEntryUTest.java | 0 .../data/MedtronicHistoryDataUTest.kt | 0 .../medtronic/data/dto/BasalProfileUTest.java | 0 .../src/test/resources/tbr_1724.json | 0 .../src/test/resources/tbr_data.json | 0 .../src/test/resources/tbr_data_special.json | 0 .../omnipod-common}/.gitignore | 0 .../omnipod-common}/build.gradle | 0 .../omnipod-common}/consumer-rules.pro | 0 .../omnipod-common}/proguard-rules.pro | 0 .../src/main/AndroidManifest.xml | 0 .../common/definition/OmnipodCommandType.kt | 0 .../omnipod/common/di/OmnipodInjectHelpers.kt | 0 .../omnipod/common/di/OmnipodWizardModule.kt | 0 .../queue/command/CommandDeactivatePod.java | 0 .../command/CommandDisableSuspendAlerts.kt | 0 .../command/CommandHandleTimeChange.java | 0 .../queue/command/CommandPlayTestBeep.java | 0 .../queue/command/CommandResumeDelivery.java | 0 .../queue/command/CommandSilenceAlerts.java | 0 .../queue/command/CommandSuspendDelivery.java | 0 .../CommandUpdateAlertConfiguration.java | 0 .../activation/PodActivationWizardActivity.kt | 0 .../fragment/action/InitializePodFragment.kt | 0 .../fragment/action/InsertCannulaFragment.kt | 0 .../action/PodActivationActionFragmentBase.kt | 0 .../fragment/info/AttachPodFragment.kt | 0 .../fragment/info/PodActivatedFragment.kt | 0 .../info/StartPodActivationFragment.kt | 0 .../action/InitializePodViewModel.kt | 0 .../action/InsertCannulaViewModel.kt | 0 .../PodActivationActionViewModelBase.kt | 0 .../viewmodel/info/AttachPodViewModel.kt | 0 .../viewmodel/info/PodActivatedViewModel.kt | 0 .../info/StartPodActivationViewModel.kt | 0 .../activity/OmnipodWizardActivityBase.kt | 0 .../common/fragment/ActionFragmentBase.kt | 0 .../common/fragment/InfoFragmentBase.kt | 0 .../common/fragment/WizardFragmentBase.kt | 0 .../common/viewmodel/ActionViewModelBase.kt | 0 .../wizard/common/viewmodel/ViewModelBase.kt | 0 .../PodDeactivationWizardActivity.kt | 0 .../fragment/action/DeactivatePodFragment.kt | 0 .../fragment/info/PodDeactivatedFragment.kt | 0 .../fragment/info/PodDiscardedFragment.kt | 0 .../info/StartPodDeactivationFragment.kt | 0 .../action/DeactivatePodViewModel.kt | 0 .../viewmodel/info/PodDeactivatedViewModel.kt | 0 .../viewmodel/info/PodDiscardedViewModel.kt | 0 .../info/StartPodDeactivationViewModel.kt | 0 .../ic_omnipod_overview_pod_management.xml | 0 ...ic_omnipod_overview_refresh_pod_status.xml | 0 .../ic_omnipod_overview_resume_delivery.xml | 0 .../drawable/ic_omnipod_overview_set_time.xml | 0 .../ic_omnipod_overview_silence_alerts.xml | 0 .../ic_omnipod_overview_suspend_delivery.xml | 0 .../drawable/ic_omnipod_wizard_success.xml | 0 .../src/main/res/drawable/ic_pod.xml | 0 .../ic_pod_management_activate_pod.xml | 0 .../ic_pod_management_deactivate_pod.xml | 0 .../ic_pod_management_discard_pod.xml | 0 .../ic_pod_management_play_test_beep.xml | 0 .../ic_pod_management_pod_history.xml | 0 .../drawable/ic_pod_management_pulse_log.xml | 0 .../omnipod_common_overview_buttons.xml | 0 .../omnipod_common_overview_pod_info.xml | 0 ..._common_pod_activation_wizard_activity.xml | 0 ...ommon_pod_deactivation_wizard_activity.xml | 0 ...pod_common_wizard_action_page_fragment.xml | 0 .../omnipod_common_wizard_base_fragment.xml | 0 ...nipod_common_wizard_info_page_fragment.xml | 0 .../omnipod_common_wizard_nav_buttons.xml | 0 ...ipod_common_wizard_progress_indication.xml | 0 ...pod_activation_wizard_navigation_graph.xml | 0 ...d_deactivation_wizard_navigation_graph.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../src/main/res/values/dimens.xml | 0 .../src/main/res/values/strings.xml | 0 .../src/main/res/values/styles.xml | 0 .../omnipod-dash}/.gitignore | 0 .../omnipod-dash}/build.gradle | 8 ++-- .../omnipod-dash}/consumer-rules.pro | 0 .../omnipod-dash}/detekt-config.yml | 0 .../omnipod-dash}/proguard-rules.pro | 0 .../omnipod/dash/history/DashHistoryTest.kt | 0 .../omnipod/dash/history/RxSchedulerRule.kt | 0 .../src/main/AndroidManifest.xml | 0 .../dash/EventOmnipodDashPumpValuesChanged.kt | 0 .../omnipod/dash/OmnipodDashPumpPlugin.kt | 0 .../dash/di/OmnipodDashHistoryModule.kt | 0 .../pump/omnipod/dash/di/OmnipodDashModule.kt | 0 .../di/OmnipodDashWizardViewModelsModule.kt | 0 .../omnipod/dash/driver/OmnipodDashManager.kt | 0 .../dash/driver/OmnipodDashManagerImpl.kt | 0 .../pump/omnipod/dash/driver/comm/Id.kt | 0 .../pump/omnipod/dash/driver/comm/Ids.kt | 0 .../dash/driver/comm/OmnipodDashBleManager.kt | 0 .../driver/comm/OmnipodDashBleManagerImpl.kt | 0 .../dash/driver/comm/ServiceDiscoverer.kt | 0 .../driver/comm/callbacks/BleCommCallbacks.kt | 0 .../comm/callbacks/WriteConfirmation.kt | 0 .../dash/driver/comm/command/BleCommand.kt | 0 .../driver/comm/command/BleCommandType.kt | 0 .../dash/driver/comm/endecrypt/EnDecrypt.kt | 0 .../dash/driver/comm/endecrypt/Nonce.kt | 0 .../driver/comm/exceptions/BusyException.kt | 0 .../comm/exceptions/ConnectException.kt | 0 .../CouldNotParseMessageException.kt | 0 .../CouldNotParseResponseException.kt | 0 .../comm/exceptions/CouldNotReadResponse.kt | 0 .../CouldNotSendCommandException.kt | 0 .../exceptions/FailedToConnectException.kt | 0 .../comm/exceptions/MessageIOException.kt | 0 .../comm/exceptions/NotConnectedException.kt | 0 .../comm/exceptions/PairingException.kt | 0 .../driver/comm/exceptions/ScanException.kt | 0 .../ScanFailFoundTooManyException.kt | 0 .../SessionEstablishmentException.kt | 0 .../pump/omnipod/dash/driver/comm/io/BleIO.kt | 0 .../dash/driver/comm/io/CharacteristicType.kt | 0 .../omnipod/dash/driver/comm/io/CmdBleIO.kt | 0 .../omnipod/dash/driver/comm/io/DataBleIO.kt | 0 .../dash/driver/comm/io/IncomingPackets.kt | 0 .../comm/message/CrcMismatchException.kt | 0 .../comm/message/IncorrectPacketException.kt | 0 .../dash/driver/comm/message/MessageIO.kt | 0 .../dash/driver/comm/message/MessagePacket.kt | 0 .../dash/driver/comm/message/MessageType.kt | 0 .../message/StringLengthPrefixEncoding.kt | 0 .../dash/driver/comm/packet/BlePacket.kt | 0 .../dash/driver/comm/packet/PayloadJoiner.kt | 0 .../driver/comm/packet/PayloadSplitter.kt | 0 .../dash/driver/comm/pair/KeyExchange.kt | 0 .../dash/driver/comm/pair/LTKExchanger.kt | 0 .../dash/driver/comm/pair/PairMessage.kt | 0 .../dash/driver/comm/pair/PairResult.kt | 0 .../driver/comm/scan/BleDiscoveredDevice.kt | 0 .../scan/DiscoveredInvalidPodException.kt | 0 .../dash/driver/comm/scan/PodScanner.kt | 0 .../dash/driver/comm/scan/ScanCollector.kt | 0 .../dash/driver/comm/session/Connection.kt | 0 .../session/ConnectionStateChangeHandler.kt | 0 .../driver/comm/session/DisconnectHandler.kt | 0 .../driver/comm/session/EapAkaAttribute.kt | 0 .../dash/driver/comm/session/EapMessage.kt | 0 .../dash/driver/comm/session/EapSqn.kt | 0 .../dash/driver/comm/session/Milenage.kt | 0 .../dash/driver/comm/session/ResponseUtil.kt | 0 .../dash/driver/comm/session/Session.kt | 0 .../driver/comm/session/SessionEstablisher.kt | 0 .../dash/driver/comm/session/SessionKeys.kt | 0 .../omnipod/dash/driver/event/PodEvent.kt | 0 .../driver/pod/command/DeactivateCommand.kt | 0 .../driver/pod/command/GetStatusCommand.kt | 0 .../driver/pod/command/GetVersionCommand.kt | 0 .../pod/command/ProgramAlertsCommand.kt | 0 .../driver/pod/command/ProgramBasalCommand.kt | 0 .../driver/pod/command/ProgramBeepsCommand.kt | 0 .../driver/pod/command/ProgramBolusCommand.kt | 0 .../pod/command/ProgramInsulinCommand.kt | 0 .../pod/command/ProgramTempBasalCommand.kt | 0 .../driver/pod/command/SetUniqueIdCommand.kt | 0 .../pod/command/SilenceAlertsCommand.kt | 0 .../driver/pod/command/StopDeliveryCommand.kt | 0 .../pod/command/SuspendDeliveryCommand.kt | 0 .../dash/driver/pod/command/base/Command.kt | 0 .../driver/pod/command/base/CommandType.kt | 0 .../pod/command/base/HeaderEnabledCommand.kt | 0 .../pod/command/base/NonceEnabledCommand.kt | 0 .../command/base/builder/CommandBuilder.kt | 0 .../builder/HeaderEnabledCommandBuilder.kt | 0 .../builder/NonceEnabledCommandBuilder.kt | 0 .../program/BasalInsulinProgramElement.kt | 0 .../BasalShortInsulinProgramElement.kt | 0 .../BolusShortInsulinProgramElement.kt | 0 .../CurrentBasalInsulinProgramElement.kt | 0 .../command/insulin/program/CurrentSlot.kt | 0 .../program/ShortInsulinProgramElement.kt | 0 .../program/TempBasalInsulinProgramElement.kt | 0 .../insulin/program/util/ProgramBasalUtil.kt | 0 .../program/util/ProgramTempBasalUtil.kt | 0 .../pod/definition/ActivationProgress.kt | 0 .../dash/driver/pod/definition/AlarmType.kt | 0 .../pod/definition/AlertConfiguration.kt | 0 .../driver/pod/definition/AlertTrigger.kt | 0 .../dash/driver/pod/definition/AlertType.kt | 0 .../driver/pod/definition/BasalProgram.kt | 0 .../pod/definition/BeepRepetitionType.kt | 0 .../dash/driver/pod/definition/BeepType.kt | 0 .../driver/pod/definition/DeliveryStatus.kt | 0 .../dash/driver/pod/definition/Encodable.kt | 0 .../driver/pod/definition/NakErrorType.kt | 0 .../driver/pod/definition/PodConstants.kt | 0 .../dash/driver/pod/definition/PodStatus.kt | 0 .../driver/pod/definition/ProgramReminder.kt | 0 .../driver/pod/definition/SoftwareVersion.kt | 0 .../pod/response/ActivationResponseBase.kt | 0 .../response/AdditionalStatusResponseBase.kt | 0 .../pod/response/AlarmStatusResponse.kt | 0 .../pod/response/DefaultStatusResponse.kt | 0 .../dash/driver/pod/response/NakResponse.kt | 0 .../dash/driver/pod/response/Response.kt | 0 .../dash/driver/pod/response/ResponseBase.kt | 0 .../dash/driver/pod/response/ResponseType.kt | 0 .../pod/response/SetUniqueIdResponse.kt | 0 .../driver/pod/response/VersionResponse.kt | 0 .../dash/driver/pod/state/CommandConfirmed.kt | 0 .../pod/state/OmnipodDashPodStateManager.kt | 0 .../state/OmnipodDashPodStateManagerImpl.kt | 0 .../omnipod/dash/driver/pod/util/AlertUtil.kt | 0 .../omnipod/dash/driver/pod/util/HasValue.kt | 0 .../dash/driver/pod/util/MessageUtil.kt | 0 .../driver/pod/util/RandomByteGenerator.kt | 0 .../driver/pod/util/X25519KeyGenerator.kt | 0 .../pump/omnipod/dash/history/DashHistory.kt | 0 .../dash/history/data/HistoryRecord.kt | 0 .../pump/omnipod/dash/history/data/Record.kt | 0 .../omnipod/dash/history/data/ResultStates.kt | 0 .../dash/history/database/Converters.kt | 0 .../history/database/DashHistoryDatabase.kt | 0 .../dash/history/database/HistoryRecordDao.kt | 0 .../history/database/HistoryRecordEntity.kt | 0 .../dash/history/mapper/HistoryMapper.kt | 0 .../omnipod/dash/ui/DashPodHistoryActivity.kt | 0 .../dash/ui/DashPodManagementActivity.kt | 0 .../dash/ui/OmnipodDashOverviewFragment.kt | 0 .../DashPodActivationWizardActivity.kt | 0 .../action/DashInitializePodViewModel.kt | 0 .../action/DashInsertCannulaViewModel.kt | 0 .../viewmodel/info/DashAttachPodViewModel.kt | 0 .../info/DashPodActivatedViewModel.kt | 0 .../info/DashStartPodActivationViewModel.kt | 0 .../DashPodDeactivationWizardActivity.kt | 0 .../action/DashDeactivatePodViewModel.kt | 0 .../info/DashPodDeactivatedViewModel.kt | 0 .../info/DashPodDiscardedViewModel.kt | 0 .../info/DashStartPodDeactivationViewModel.kt | 0 .../pump/omnipod/dash/util/Constants.kt | 0 .../plugins/pump/omnipod/dash/util/Flag.kt | 0 .../pump/omnipod/dash/util/Functions.kt | 0 .../plugins/pump/omnipod/dash/util/I8n.kt | 0 .../main/res/layout/omnipod_dash_overview.xml | 0 ...omnipod_dash_overview_bluetooth_status.xml | 0 .../omnipod_dash_pod_history_activity.xml | 0 .../layout/omnipod_dash_pod_history_item.xml | 0 .../layout/omnipod_dash_pod_management.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../src/main/res/values/strings.xml | 0 .../main/res/xml/omnipod_dash_preferences.xml | 0 .../driver/comm/endecrypt/EnDecryptTest.kt | 0 .../driver/comm/message/MessagePacketTest.kt | 0 .../driver/comm/message/PayloadJoinerTest.kt | 0 .../comm/message/PayloadSplitJoinTest.kt | 0 .../comm/message/PayloadSplitterTest.kt | 0 .../message/StringLengthPrefixEncodingTest.kt | 0 .../dash/driver/comm/pair/KeyExchangeTest.kt | 0 .../driver/comm/session/EapMessageTest.kt | 0 .../dash/driver/comm/session/MilenageTest.kt | 0 .../pod/command/DeactivateCommandTest.kt | 0 .../pod/command/GetStatusCommandTest.kt | 0 .../pod/command/GetVersionCommandTest.kt | 0 .../pod/command/ProgramAlertsCommandTest.kt | 0 .../pod/command/ProgramBasalCommandTest.kt | 0 .../pod/command/ProgramBeepsCommandTest.kt | 0 .../pod/command/ProgramBolusCommandTest.kt | 0 .../command/ProgramTempBasalCommandTest.kt | 0 .../pod/command/SetUniqueIdCommandTest.kt | 0 .../pod/command/SilenceAlertsCommandTest.kt | 0 .../pod/command/StopDeliveryCommandTest.kt | 0 .../pod/command/SuspendDeliveryCommandTest.kt | 0 .../pod/response/AlarmStatusResponseTest.kt | 0 .../pod/response/DefaultStatusResponseTest.kt | 0 .../driver/pod/response/NakResponseTest.kt | 0 .../pod/response/SetUniqueIdResponseTest.kt | 0 .../pod/response/VersionResponseTest.kt | 0 .../pump/omnipod/dash/util/FunctionsTest.kt | 0 .../omnipod-eros}/.gitignore | 0 .../omnipod-eros}/build.gradle | 10 ++--- .../omnipod-eros}/consumer-rules.pro | 0 .../omnipod-eros}/proguard-rules.pro | 0 .../omnipod/eros/history/ErosHistoryTest.kt | 0 .../src/main/AndroidManifest.xml | 0 .../omnipod/eros/OmnipodErosPumpPlugin.java | 0 .../pump/omnipod/eros/data/ActiveBolus.java | 0 .../eros/data/RLHistoryItemOmnipod.java | 0 .../definition/OmnipodErosStorageKeys.java | 0 .../eros/definition/PodHistoryEntryType.java | 0 .../eros/di/OmnipodErosHistoryModule.kt | 0 .../pump/omnipod/eros/di/OmnipodErosModule.kt | 0 .../di/OmnipodErosWizardViewModelsModule.kt | 0 .../action/AcknowledgeAlertsAction.java | 0 .../action/AssignAddressAction.java | 0 .../communication/action/BolusAction.java | 0 .../action/CancelDeliveryAction.java | 0 .../action/ConfigureAlertsAction.java | 0 .../action/ConfigureBeepAction.java | 0 .../action/DeactivatePodAction.java | 0 .../action/GetPodInfoAction.java | 0 .../communication/action/GetStatusAction.java | 0 .../action/InsertCannulaAction.java | 0 .../communication/action/OmnipodAction.java | 0 .../communication/action/PrimeAction.java | 0 .../action/SetBasalScheduleAction.java | 0 .../action/SetTempBasalAction.java | 0 .../communication/action/SetupPodAction.java | 0 .../service/ExpirationReminderBuilder.java | 0 .../action/service/PrimeService.java | 0 .../message/IRawRepresentable.java | 0 .../communication/message/MessageBlock.java | 0 .../message/NonceResyncableMessageBlock.java | 0 .../communication/message/OmnipodMessage.java | 0 .../communication/message/OmnipodPacket.java | 0 .../command/AcknowledgeAlertsCommand.java | 0 .../message/command/AssignAddressCommand.java | 0 .../command/BasalScheduleExtraCommand.java | 0 .../message/command/BeepConfigCommand.java | 0 .../message/command/BolusExtraCommand.java | 0 .../command/CancelDeliveryCommand.java | 0 .../command/ConfigureAlertsCommand.java | 0 .../message/command/DeactivatePodCommand.java | 0 .../message/command/FaultConfigCommand.java | 0 .../message/command/GetStatusCommand.java | 0 .../command/SetInsulinScheduleCommand.java | 0 .../message/command/SetupPodCommand.java | 0 .../command/TempBasalExtraCommand.java | 0 .../message/response/ErrorResponse.java | 0 .../message/response/StatusResponse.java | 0 .../response/StatusUpdatableResponse.java | 0 .../message/response/VersionResponse.java | 0 .../message/response/podinfo/PodInfo.java | 0 .../response/podinfo/PodInfoActiveAlerts.java | 0 .../response/podinfo/PodInfoDataLog.java | 0 .../podinfo/PodInfoDetailedStatus.java | 0 .../PodInfoFaultAndInitializationTime.java | 0 .../podinfo/PodInfoOlderPulseLog.java | 0 .../podinfo/PodInfoRecentPulseLog.java | 0 .../response/podinfo/PodInfoResponse.java | 0 .../driver/definition/ActivationProgress.java | 0 .../driver/definition/AlertConfiguration.java | 0 .../eros/driver/definition/AlertSet.java | 0 .../eros/driver/definition/AlertSlot.java | 0 .../eros/driver/definition/AlertTrigger.java | 0 .../eros/driver/definition/AlertType.java | 0 .../driver/definition/BeepConfigType.java | 0 .../eros/driver/definition/BeepRepeat.java | 0 .../eros/driver/definition/BeepType.java | 0 .../driver/definition/DeliveryStatus.java | 0 .../eros/driver/definition/DeliveryType.java | 0 .../driver/definition/ErrorEventInfo.java | 0 .../driver/definition/FaultEventCode.java | 0 .../driver/definition/FirmwareVersion.java | 0 .../driver/definition/MessageBlockType.java | 0 .../driver/definition/OmnipodConstants.java | 0 .../eros/driver/definition/OmnipodCrc.java | 0 .../eros/driver/definition/PacketType.java | 0 .../eros/driver/definition/PodInfoType.java | 0 .../driver/definition/PodProgressStatus.java | 0 .../driver/definition/TimerAlertTrigger.java | 0 .../UnitsRemainingAlertTrigger.java | 0 .../schedule/BasalDeliverySchedule.java | 0 .../schedule/BasalDeliveryTable.java | 0 .../definition/schedule/BasalSchedule.java | 0 .../schedule/BasalScheduleEntry.java | 0 .../definition/schedule/BasalTableEntry.java | 0 .../schedule/BolusDeliverySchedule.java | 0 .../definition/schedule/DeliverySchedule.java | 0 .../schedule/InsulinScheduleType.java | 0 .../driver/definition/schedule/RateEntry.java | 0 .../schedule/TempBasalDeliverySchedule.java | 0 .../ActivationTimeExceededException.java | 0 ...dAfterChangingDeliveryStatusException.java | 0 .../exception/CrcMismatchException.java | 0 .../IllegalActivationProgressException.java | 0 .../IllegalDeliveryStatusException.java | 0 .../IllegalMessageAddressException.java | 0 ...IllegalMessageSequenceNumberException.java | 0 .../exception/IllegalPacketTypeException.java | 0 .../IllegalPodProgressException.java | 0 .../exception/IllegalResponseException.java | 0 .../IllegalVersionResponseTypeException.java | 0 .../exception/MessageDecodingException.java | 0 .../exception/NonceOutOfSyncException.java | 0 .../exception/NonceResyncException.java | 0 .../exception/NotEnoughDataException.java | 0 .../driver/exception/OmnipodException.java | 0 .../driver/exception/PodFaultException.java | 0 ...ressStatusVerificationFailedException.java | 0 .../PodReturnedErrorResponseException.java | 0 ...dingCommandFailedUncertainlyException.java | 0 .../RileyLinkInterruptedException.java | 0 .../exception/RileyLinkTimeoutException.java | 0 .../RileyLinkUnexpectedException.java | 0 .../RileyLinkUnreachableException.java | 0 .../driver/manager/ErosPodStateManager.java | 0 .../eros/driver/manager/OmnipodManager.java | 0 .../driver/util/AlertConfigurationUtil.java | 0 .../omnipod/eros/driver/util/TimeUtil.java | 0 .../EventOmnipodErosActiveAlertsChanged.kt | 0 .../EventOmnipodErosFaultEventChanged.kt | 0 .../EventOmnipodErosPumpValuesChanged.kt | 0 .../eros/event/EventOmnipodErosTbrChanged.kt | 0 .../EventOmnipodErosUncertainTbrRecovered.kt | 0 .../pump/omnipod/eros/history/ErosHistory.kt | 0 .../history/database/ErosHistoryDatabase.kt | 0 .../history/database/ErosHistoryRecordDao.kt | 0 .../database/ErosHistoryRecordEntity.java | 0 .../eros/manager/AapsErosPodStateManager.java | 0 .../eros/manager/AapsOmnipodErosManager.java | 0 .../queue/command/CommandGetPodStatus.java | 0 .../queue/command/CommandReadPulseLog.java | 0 .../OmnipodRileyLinkCommunicationManager.java | 0 .../service/RileyLinkOmnipodService.java | 0 .../eros/ui/ErosPodHistoryActivity.java | 0 .../eros/ui/ErosPodManagementActivity.kt | 0 .../eros/ui/OmnipodErosOverviewFragment.kt | 0 .../ErosPodActivationWizardActivity.kt | 0 .../action/ErosInitializePodViewModel.kt | 0 .../action/ErosInsertCannulaViewModel.kt | 0 .../viewmodel/info/ErosAttachPodViewModel.kt | 0 .../info/ErosPodActivatedViewModel.kt | 0 .../info/ErosStartPodActivationViewModel.kt | 0 .../ErosPodDeactivationWizardActivity.kt | 0 .../action/ErosDeactivatePodViewModel.kt | 0 .../info/ErosPodDeactivatedViewModel.kt | 0 .../info/ErosPodDiscardedViewModel.kt | 0 .../info/ErosStartPodDeactivationViewModel.kt | 0 .../omnipod/eros/util/AapsOmnipodUtil.java | 0 .../omnipod/eros/util/OmnipodAlertUtil.java | 0 ...ic_pod_activity_reset_rileylink_config.xml | 0 .../drawable/ic_pod_management_rl_stats.xml | 0 .../main/res/layout/omnipod_eros_overview.xml | 0 ...mnipod_eros_overview_riley_link_status.xml | 0 .../omnipod_eros_pod_history_activity.xml | 0 .../layout/omnipod_eros_pod_history_item.xml | 0 .../layout/omnipod_eros_pod_management.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../src/main/res/values/strings.xml | 0 .../main/res/xml/omnipod_eros_preferences.xml | 0 .../info/nightscout/androidaps/TestBase.kt | 0 .../omnipod/eros/OmnipodErosPumpPluginTest.kt | 0 .../AapsOmnipodErosManagerTest.java | 0 .../command/AcknowledgeAlertsCommandTest.java | 0 .../command/AssignAddressCommandTest.java | 0 .../BasalScheduleExtraCommandTest.java | 0 .../command/BeepConfigCommandTest.java | 0 .../command/BolusExtraCommandTest.java | 0 .../command/CancelDeliveryCommandTest.java | 0 .../command/ConfigureAlertsCommandTest.java | 0 .../command/DeactivatePodCommandTest.java | 0 .../command/FaultConfigCommandTest.java | 0 .../message/command/GetStatusCommandTest.java | 0 .../SetInsulinScheduleCommandTest.java | 0 .../message/command/SetupPodCommandTest.java | 0 .../command/TempBasalExtraCommandTest.java | 0 .../defs/schedule/BasalTableEntryTest.java | 0 .../message/response/ErrorResponseTest.java | 0 .../message/response/StatusResponseTest.java | 0 .../message/response/VersionResponseTest.java | 0 .../podinfo/PodInfoActiveAlertsTest.java | 0 .../response/podinfo/PodInfoDataLogTest.java | 0 .../podinfo/PodInfoDetailedStatusTest.java | 0 ...PodInfoFaultAndInitializationTimeTest.java | 0 .../podinfo/PodInfoOlderPulseLogTest.java | 0 .../podinfo/PodInfoRecentPulseLogTest.java | 0 .../response/podinfo/PodInfoResponseTest.java | 0 .../eros/driver/definition/AlertSetTest.java | 0 .../schedule/BasalScheduleTest.java | 0 .../eros/driver/util/TimeUtilTest.java | 0 .../manager/AapsErosPodStateManagerTest.kt | 0 {pump-common => pump/pump-common}/.gitignore | 0 .../pump-common}/build.gradle | 0 .../pump-common}/consumer-rules.pro | 0 .../pump-common}/proguard-rules.pro | 0 .../pump-common}/src/main/AndroidManifest.xml | 0 .../plugins/pump/common/PumpPluginAbstract.kt | 0 .../pump/common/ble/BondStateReceiver.kt | 0 .../plugins/pump/common/data/PumpStatus.kt | 0 .../pump/common/data/PumpTimeDifferenceDto.kt | 0 .../pump/common/defs/BasalProfileStatus.java | 0 .../pump/common/defs/PumpDeviceState.kt | 0 .../pump/common/defs/PumpDriverState.kt | 0 .../pump/common/defs/PumpHistoryEntryGroup.kt | 0 .../pump/common/defs/PumpRunningState.kt | 0 .../pump/common/defs/PumpStatusType.kt | 0 .../pump/common/defs/PumpTypeGroupConfig.kt | 0 .../common/defs/PumpUpdateFragmentType.kt | 0 .../plugins/pump/common/defs/TempBasalPair.kt | 0 .../pump/common/di/PumpCommonModule.kt | 0 .../common/driver/PumpDriverConfiguration.kt | 0 .../driver/PumpDriverConfigurationCapable.kt | 0 .../pump/common/driver/ble/PumpBLESelector.kt | 0 .../driver/ble/PumpBLESelectorAbstract.kt | 0 .../driver/history/PumpDataConverter.kt | 0 .../driver/history/PumpHistoryDataProvider.kt | 0 .../PumpHistoryDataProviderAbstract.kt | 0 .../common/driver/history/PumpHistoryEntry.kt | 0 .../pump/common/events/EventBondChanged.kt | 0 .../pump/common/events/EventPumpChanged.kt | 0 .../EventPumpConnectionParametersChanged.kt | 0 .../events/EventPumpFragmentValuesChanged.kt | 0 .../common/events/EventRefreshButtonState.kt | 0 .../plugins/pump/common/sync/PumpDbEntry.kt | 0 .../common/sync/PumpSyncEntriesCreator.java | 0 .../pump/common/sync/PumpSyncStorage.kt | 0 .../pump/common/ui/PumpBLEConfigActivity.kt | 0 .../pump/common/ui/PumpHistoryActivity.kt | 0 .../plugins/pump/common/utils/ByteUtil.java | 0 .../plugins/pump/common/utils/ProfileUtil.kt | 0 .../plugins/pump/common/utils/StringUtil.java | 0 .../plugins/pump/common/utils/ThreadUtil.java | 0 .../res/layout/pump_ble_config_activity.xml | 0 .../res/layout/pump_ble_config_scan_item.xml | 0 .../main/res/layout/pump_history_activity.xml | 0 .../src/main/res/layout/pump_history_item.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../src/main/res/values/strings.xml | 0 {rileylink => pump/rileylink}/.gitignore | 0 {rileylink => pump/rileylink}/build.gradle | 4 +- .../rileylink}/consumer-rules.pro | 0 .../rileylink}/proguard-rules.pro | 0 .../rileylink}/src/main/AndroidManifest.xml | 0 .../plugins/pump/common/di/RileyLinkModule.kt | 0 .../dialog/RileyLinkBLEConfigActivity.kt | 0 .../EventRileyLinkDeviceStatusChange.kt | 0 .../RileyLinkCommunicationManager.java | 0 .../common/hw/rileylink/RileyLinkConst.java | 0 .../common/hw/rileylink/RileyLinkUtil.java | 0 .../pump/common/hw/rileylink/ble/RFSpy.java | 0 .../common/hw/rileylink/ble/RFSpyReader.kt | 0 .../common/hw/rileylink/ble/RileyLinkBLE.kt | 0 .../ble/RileyLinkCommunicationException.java | 0 .../hw/rileylink/ble/command/GetVersion.java | 0 .../hw/rileylink/ble/command/Reset.java | 0 .../ble/command/ResetRadioConfig.java | 0 .../ble/command/RileyLinkCommand.java | 0 .../rileylink/ble/command/SendAndListen.java | 0 .../ble/command/SetHardwareEncoding.java | 0 .../hw/rileylink/ble/command/SetPreamble.java | 0 .../rileylink/ble/command/UpdateRegister.java | 0 .../ble/data/FrequencyScanResults.java | 0 .../hw/rileylink/ble/data/FrequencyTrial.java | 0 .../hw/rileylink/ble/data/GattAttributes.java | 0 .../hw/rileylink/ble/data/RFSpyResponse.java | 0 .../hw/rileylink/ble/data/RLMessage.java | 0 .../hw/rileylink/ble/data/RLMessageType.java | 0 .../hw/rileylink/ble/data/RadioPacket.java | 0 .../hw/rileylink/ble/data/RadioResponse.java | 0 .../ble/data/encoding/Encoding4b6b.java | 0 .../data/encoding/Encoding4b6bAbstract.java | 0 .../ble/data/encoding/Encoding4b6bGeoff.java | 0 .../hw/rileylink/ble/defs/CC111XRegister.java | 0 .../hw/rileylink/ble/defs/RFSpyCommand.java | 0 .../rileylink/ble/defs/RFSpyRLResponse.java | 0 .../hw/rileylink/ble/defs/RLMessageType.kt | 0 .../hw/rileylink/ble/defs/RXFilterMode.kt | 0 .../rileylink/ble/defs/RileyLinkBLEError.java | 0 .../ble/defs/RileyLinkCommandType.java | 0 .../ble/defs/RileyLinkEncodingType.java | 0 .../ble/defs/RileyLinkFirmwareVersion.java | 0 .../ble/defs/RileyLinkTargetFrequency.kt | 0 .../hw/rileylink/ble/device/OrangeLinkImpl.kt | 0 .../ble/operations/BLECommOperation.java | 0 .../operations/BLECommOperationResult.java | 0 .../CharacteristicReadOperation.java | 0 .../CharacteristicWriteOperation.java | 0 .../operations/DescriptorWriteOperation.java | 0 .../hw/rileylink/data/BleAdvertisedData.java | 0 .../data/CommandValueDefinition.java | 0 .../hw/rileylink/data/RLHistoryItem.java | 0 .../defs/CommandValueDefinitionRLType.java | 0 .../defs/CommandValueDefinitionType.java | 0 .../hw/rileylink/defs/RileyLinkError.java | 0 .../hw/rileylink/defs/RileyLinkPumpDevice.kt | 0 .../hw/rileylink/defs/RileyLinkPumpInfo.java | 0 .../rileylink/defs/RileyLinkServiceState.java | 0 .../rileylink/defs/RileyLinkTargetDevice.java | 0 .../dialog/RileyLinkStatusActivity.kt | 0 .../dialog/RileyLinkStatusGeneralFragment.kt | 0 .../dialog/RileyLinkStatusHistoryFragment.kt | 0 .../RileyLinkBluetoothStateReceiver.kt | 0 .../service/RileyLinkBroadcastReceiver.kt | 0 .../hw/rileylink/service/RileyLinkService.kt | 0 .../rileylink/service/RileyLinkServiceData.kt | 0 .../service/tasks/DiscoverGattServicesTask.kt | 0 .../tasks/InitializePumpManagerTask.kt | 0 .../hw/rileylink/service/tasks/PumpTask.kt | 0 .../tasks/ResetRileyLinkConfigurationTask.kt | 0 .../hw/rileylink/service/tasks/ServiceTask.kt | 0 .../service/tasks/ServiceTaskExecutor.kt | 0 .../service/tasks/WakeAndTuneTask.kt | 0 .../plugins/pump/common/utils/CRC.java | 0 .../layout/riley_link_ble_config_activity.xml | 0 .../riley_link_ble_config_scan_item.xml | 0 .../src/main/res/layout/rileylink_status.xml | 0 .../layout/rileylink_status_device_item.xml | 0 .../res/layout/rileylink_status_general.xml | 0 .../res/layout/rileylink_status_history.xml | 0 .../layout/rileylink_status_history_item.xml | 0 .../main/res/menu/menu_rileylink_ble_scan.xml | 0 .../src/main/res/values-af-rZA/strings.xml | 0 .../src/main/res/values-ar-rSA/strings.xml | 0 .../src/main/res/values-bg-rBG/strings.xml | 0 .../src/main/res/values-ca-rES/strings.xml | 0 .../src/main/res/values-cs-rCZ/strings.xml | 0 .../src/main/res/values-cy-rGB/strings.xml | 0 .../src/main/res/values-da-rDK/strings.xml | 0 .../src/main/res/values-de-rDE/strings.xml | 0 .../src/main/res/values-el-rGR/strings.xml | 0 .../src/main/res/values-es-rES/strings.xml | 0 .../src/main/res/values-fi-rFI/strings.xml | 0 .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-ga-rIE/strings.xml | 0 .../src/main/res/values-hr-rHR/strings.xml | 0 .../src/main/res/values-hu-rHU/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-iw-rIL/strings.xml | 0 .../src/main/res/values-ko-rKR/strings.xml | 0 .../src/main/res/values-lt-rLT/strings.xml | 0 .../src/main/res/values-nl-rNL/strings.xml | 0 .../src/main/res/values-no-rNO/strings.xml | 0 .../src/main/res/values-pl-rPL/strings.xml | 0 .../src/main/res/values-pt-rBR/strings.xml | 0 .../src/main/res/values-pt-rPT/strings.xml | 0 .../src/main/res/values-ro-rRO/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values-sk-rSK/strings.xml | 0 .../src/main/res/values-sl-rSI/strings.xml | 0 .../src/main/res/values-sr-rCS/strings.xml | 0 .../src/main/res/values-sv-rSE/strings.xml | 0 .../src/main/res/values-ta-rIN/strings.xml | 0 .../src/main/res/values-tr-rTR/strings.xml | 0 .../src/main/res/values-zh-rCN/strings.xml | 0 .../src/main/res/values/strings.xml | 0 .../info/nightscout/androidaps/TestBase.kt | 0 .../pump/common/hw/rileylink/ble/RFSpyTest.kt | 0 .../ble/RFToolsParametrizedUTest.java | 0 .../common/hw/rileylink/ble/RFToolsUTest.java | 0 .../defs/RileyLinkFirmwareVersionTest.java | 0 settings.gradle | 28 ++++++------ 1711 files changed, 65 insertions(+), 64 deletions(-) rename Steampunk_graphics_source_link.md => _docs/Steampunk_graphics_source_link.md (100%) rename demo_keystore.jks => _docs/demo_keystore.jks (100%) rename {gource => _docs/gource}/sample.bat (100%) rename {icons => _docs/icons}/action_add.svg (100%) rename {icons => _docs/icons}/action_minus.svg (100%) rename {icons => _docs/icons}/actions_cancelextbolus.svg (100%) rename {icons => _docs/icons}/actions_refill.svg (100%) rename {icons => _docs/icons}/actions_startextbolus.svg (100%) rename {icons => _docs/icons}/actions_temptarget.svg (100%) rename {icons => _docs/icons}/add.svg (100%) rename {icons => _docs/icons}/as.svg (100%) rename {icons => _docs/icons}/auto_delta.svg (100%) rename {icons => _docs/icons}/autotune.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-10-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-20-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-30-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-40-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-50-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-60-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-70-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-80-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-90-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-charging-wireless-burnin.svg (100%) rename {icons => _docs/icons}/battery-burnin/battery-unknown-burnin.svg (100%) rename {icons => _docs/icons}/battery-source/mask-burnin-battery-raw.svg (100%) rename {icons => _docs/icons}/battery-source/mask-burnin-battery.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-10.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-20.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-30.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-40.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-50.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-60.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-70.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-80.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless-90.svg (100%) rename {icons => _docs/icons}/battery/battery-charging-wireless.svg (100%) rename {icons => _docs/icons}/battery/battery-outline.svg (100%) rename {icons => _docs/icons}/battery/battery-unknown.svg (100%) rename {icons => _docs/icons}/bolus.svg (100%) rename {icons => _docs/icons}/byoda.svg (100%) rename {icons => _docs/icons}/calculator.svg (100%) rename {icons => _docs/icons}/calibration.svg (100%) rename {icons => _docs/icons}/cancel.svg (100%) rename {icons => _docs/icons}/clone.svg (100%) rename {icons => _docs/icons}/clone_48.svg (100%) rename {icons => _docs/icons}/combo.svg (100%) rename {icons => _docs/icons}/compare_profiles.svg (100%) rename {icons => _docs/icons}/complications-source/ic_br_cob_iob_orig.svg (100%) rename {icons => _docs/icons}/complications-source/ic_cob_detailed_orig.svg (100%) rename {icons => _docs/icons}/complications-source/ic_cob_iob_orig.svg (100%) rename {icons => _docs/icons}/complications-source/ic_ins_burnin_orig.svg (100%) rename {icons => _docs/icons}/complications-source/ic_ins_orig.svg (100%) rename {icons => _docs/icons}/complications-source/ic_iob_detailed_orig.svg (100%) rename {icons => _docs/icons}/complications/ic_aaps_full.svg (100%) rename {icons => _docs/icons}/complications/ic_basal.svg (100%) rename {icons => _docs/icons}/complications/ic_br_cob_iob.svg (100%) rename {icons => _docs/icons}/complications/ic_carbs.svg (100%) rename {icons => _docs/icons}/complications/ic_cob_detailed.svg (100%) rename {icons => _docs/icons}/complications/ic_cob_iob.svg (100%) rename {icons => _docs/icons}/complications/ic_ins.svg (100%) rename {icons => _docs/icons}/complications/ic_ins_burnin.svg (100%) rename {icons => _docs/icons}/complications/ic_iob_detailed.svg (100%) rename {icons => _docs/icons}/complications/ic_sgv.svg (100%) rename {icons => _docs/icons}/confirm.svg (100%) rename {icons => _docs/icons}/cp_aaps_offline.svg (100%) rename {icons => _docs/icons}/cp_age_batterie.svg (100%) rename {icons => _docs/icons}/cp_age_canula.svg (100%) rename {icons => _docs/icons}/cp_age_insulin.svg (100%) rename {icons => _docs/icons}/cp_age_sensor.svg (100%) rename {icons => _docs/icons}/cp_announcement.svg (100%) rename {icons => _docs/icons}/cp_basal_end.svg (100%) rename {icons => _docs/icons}/cp_basal_no_tbr.svg (100%) rename {icons => _docs/icons}/cp_basal_tbr_high.svg (100%) rename {icons => _docs/icons}/cp_basal_tbr_low.svg (100%) rename {icons => _docs/icons}/cp_bgcheck.svg (100%) rename {icons => _docs/icons}/cp_bgcheck2.svg (100%) rename {icons => _docs/icons}/cp_bolus_carbs.svg (100%) rename {icons => _docs/icons}/cp_bolus_combo.svg (100%) rename {icons => _docs/icons}/cp_bolus_correction.svg (100%) rename {icons => _docs/icons}/cp_bolus_meal.svg (100%) rename {icons => _docs/icons}/cp_bolus_snack.svg (100%) rename {icons => _docs/icons}/cp_cgm_insert.svg (100%) rename {icons => _docs/icons}/cp_cgm_profile.svg (100%) rename {icons => _docs/icons}/cp_cgm_start.svg (100%) rename {icons => _docs/icons}/cp_cgm_target.svg (100%) rename {icons => _docs/icons}/cp_exercise.svg (100%) rename {icons => _docs/icons}/cp_note.svg (100%) rename {icons => _docs/icons}/cp_pump_battery.svg (100%) rename {icons => _docs/icons}/cp_pump_canula.svg (100%) rename {icons => _docs/icons}/cp_pump_cartridge.svg (100%) rename {icons => _docs/icons}/cp_question.svg (100%) rename {icons => _docs/icons}/danar_useropt.svg (100%) rename {icons => _docs/icons}/danarhistory.svg (100%) rename {icons => _docs/icons}/danarprofile.svg (100%) rename {icons => _docs/icons}/danars.svg (100%) rename {icons => _docs/icons}/danarstat.svg (100%) rename {icons => _docs/icons}/excel.svg (100%) rename {icons => _docs/icons}/export_settings.svg (100%) rename {icons => _docs/icons}/ic_DoubleDown.svg (100%) rename {icons => _docs/icons}/ic_DoubleUp.svg (100%) rename {icons => _docs/icons}/ic_Flat.svg (100%) rename {icons => _docs/icons}/ic_FortyFiveDown.svg (100%) rename {icons => _docs/icons}/ic_FortyFiveUp.svg (100%) rename {icons => _docs/icons}/ic_Invalid.svg (100%) rename {icons => _docs/icons}/ic_SingleDown.svg (100%) rename {icons => _docs/icons}/ic_SingleUp.svg (100%) rename {icons => _docs/icons}/ic_error.svg (100%) rename {icons => _docs/icons}/ic_exit_to_app.svg (100%) rename {icons => _docs/icons}/ic_home_loop.svg (100%) rename {icons => _docs/icons}/ic_maintenance.svg (100%) rename {icons => _docs/icons}/ic_notif_aaps.svg (100%) rename {icons => _docs/icons}/ic_notif_nsclient.svg (100%) rename {icons => _docs/icons}/ic_notif_pumpcontrol.svg (100%) rename {icons => _docs/icons}/ic_warning.svg (100%) rename {icons => _docs/icons}/icon_snooze.svg (100%) rename {icons => _docs/icons}/import_settings.svg (100%) rename {icons => _docs/icons}/insight.svg (100%) rename {icons => _docs/icons}/insight_128.svg (100%) rename {icons => _docs/icons}/local_activate.svg (100%) rename {icons => _docs/icons}/local_reset.svg (100%) rename {icons => _docs/icons}/local_save.svg (100%) rename {icons => _docs/icons}/log_delete.svg (100%) rename {icons => _docs/icons}/log_settings.svg (100%) rename {icons => _docs/icons}/loop.svg (100%) rename {icons => _docs/icons}/loop_closed.svg (100%) rename {icons => _docs/icons}/loop_disabled.svg (100%) rename {icons => _docs/icons}/loop_disconnected.svg (100%) rename {icons => _docs/icons}/loop_lgs.svg (100%) rename {icons => _docs/icons}/loop_off.svg (100%) rename {icons => _docs/icons}/loop_open.svg (100%) rename {icons => _docs/icons}/loop_paused.svg (100%) rename {icons => _docs/icons}/loop_reconnect.svg (100%) rename {icons => _docs/icons}/loop_resume.svg (100%) rename {icons => _docs/icons}/loop_superbolus.svg (100%) rename {icons => _docs/icons}/pod.svg (100%) rename {icons => _docs/icons}/quickwizard.svg (100%) rename {icons => _docs/icons}/remove.svg (100%) rename {icons => _docs/icons}/reset_database.svg (100%) rename {icons => _docs/icons}/send_log.svg (100%) rename {icons => _docs/icons}/setting_off.svg (100%) rename {icons => _docs/icons}/setting_on.svg (100%) rename {icons => _docs/icons}/target_activity.svg (100%) rename {icons => _docs/icons}/target_cancel.svg (100%) rename {icons => _docs/icons}/target_eatingsoon.svg (100%) rename {icons => _docs/icons}/target_hypo.svg (100%) rename {icons => _docs/icons}/target_manual.svg (100%) rename {icons => _docs/icons}/temp-basal/icon_cp_basal_100px.psd (100%) rename {icons => _docs/icons}/temp-basal/icon_cp_basal_150px.psd (100%) rename {icons => _docs/icons}/temp-basal/icon_cp_basal_200px.psd (100%) rename {icons => _docs/icons}/temp-basal/icon_cp_basal_50px.psd (100%) rename {icons => _docs/icons}/temp-basal/icon_cp_basal_75px.psd (100%) rename {icons => _docs/icons}/temptarget_flat.svg (100%) rename {icons => _docs/icons}/temptarget_high.svg (100%) rename {icons => _docs/icons}/temptarget_low.svg (100%) rename {icons => _docs/icons}/veo.svg (100%) rename {icons => _docs/icons}/visibility.svg (100%) rename {icons => _docs/icons}/x_swap_vert.svg (100%) rename {icons => _docs/icons}/xdrip.svg (100%) rename {logo => _docs/logo}/androiaps.eps (100%) rename {logo => _docs/logo}/androiaps_tshirt.pdf (100%) rename {logo => _docs/logo}/androidaps.ai (100%) rename {logo => _docs/logo}/androidaps.pdf (100%) rename {logo => _docs/logo}/androidaps2.ai (100%) rename {logo => _docs/logo}/androidaps2.pdf (100%) rename {logo => _docs/logo}/background-01.svg (100%) rename {logo => _docs/logo}/background.ai (100%) rename {logo => _docs/logo}/background.pdf (100%) rename {logo => _docs/logo}/blueowl-web.png (100%) rename {logo => _docs/logo}/drawing.png (100%) rename {logo => _docs/logo}/drawing.svg (100%) rename {logo => _docs/logo}/ic_launcher-web.png (100%) rename {logo => _docs/logo}/ic_launcher_round-web.png (100%) rename {logo => _docs/logo}/icons.ai (100%) rename {logo => _docs/logo}/icons.pdf (100%) rename {logo => _docs/logo}/icons.svg (100%) rename {logo => _docs/logo}/logo.md (100%) rename {logo => _docs/logo}/logo_androidaps.ai (100%) rename {logo => _docs/logo}/logo_androidaps.pdf (100%) rename {logo => _docs/logo}/logo_androidaps.svg (100%) rename {logo => _docs/logo}/logoanaps.png (100%) rename {logo => _docs/logo}/notif_icon.png (100%) rename {logo => _docs/logo}/notificationdot.png (100%) rename {logo => _docs/logo}/notificationdot2.png (100%) rename {logo => _docs/logo}/nsclient/white.png (100%) rename {logo => _docs/logo}/old/AndroidAPS Icon.ai (100%) rename {logo => _docs/logo}/old/AndroidAPS Icon.png (100%) rename {logo => _docs/logo}/pattern.ai (100%) rename {logo => _docs/logo}/pattern.pdf (100%) rename {logo => _docs/logo}/pattern.svg (100%) rename {logo => _docs/logo}/screenshot.png (100%) rename {logo => _docs/logo}/tshirt.png (100%) rename revoking_leaked_apks.md => _docs/revoking_leaked_apks.md (100%) rename {combo => pump/combo}/.gitignore (100%) rename {combo => pump/combo}/build.gradle (100%) rename {combo => pump/combo}/consumer-rules.pro (100%) rename {combo => pump/combo}/proguard-rules.pro (100%) rename {combo => pump/combo}/src/main/AndroidManifest.xml (100%) rename {combo => pump/combo}/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRTHandler.aidl (100%) rename {combo => pump/combo}/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRuffyService.aidl (100%) rename {combo => pump/combo}/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/display/Menu.aidl (100%) rename {combo => pump/combo}/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/package-info.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/combo/di/ComboActivitiesModule.kt (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/combo/di/ComboModule.kt (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboFragment.kt (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPump.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/data/ComboErrorUtil.kt (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/events/EventComboPumpUpdateGUI.kt (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BasalProfile.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BolusProgressReporter.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/CommandResult.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpErrorCodes.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpState.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpWarningCodes.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyCommands.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyScripter.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/WarningOrErrorCode.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BaseCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BolusCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CancelTbrCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/Command.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CommandException.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ConfirmAlertCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadBasalProfileCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadHistoryCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadPumpStateCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadQuickInfoCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetBasalProfileCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetTbrCommand.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Bolus.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/HistoryRecord.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpAlert.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistory.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistoryRequest.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tbr.java (100%) rename {combo => pump/combo}/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tdd.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/Menu.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuAttribute.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuType.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/BolusType.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuBlink.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuDate.java (100%) rename {combo => pump/combo}/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuTime.java (100%) rename {combo => pump/combo}/src/main/res/drawable/ic_combo.xml (100%) rename {combo => pump/combo}/src/main/res/layout/combopump_fragment.xml (100%) rename {combo => pump/combo}/src/main/res/values-af-rZA/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-bg-rBG/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-ca-rES/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-da-rDK/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-de-rDE/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-el-rGR/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-es-rES/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-fr-rFR/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-ga-rIE/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-hr-rHR/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-hu-rHU/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-it-rIT/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-iw-rIL/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-ko-rKR/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-lt-rLT/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-nl-rNL/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-no-rNO/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-pl-rPL/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-pt-rBR/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-pt-rPT/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-ro-rRO/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-ru-rRU/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-sk-rSK/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-sl-rSI/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-sr-rCS/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-sv-rSE/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-ta-rIN/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-tr-rTR/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values-zh-rCN/strings.xml (100%) rename {combo => pump/combo}/src/main/res/values/arrays.xml (100%) mode change 100755 => 100644 rename {combo => pump/combo}/src/main/res/values/strings.xml (100%) rename {combo => pump/combo}/src/main/res/xml/pref_combo.xml (100%) mode change 100755 => 100644 rename {combo => pump/combo}/src/test/java/info/nightscout/androidaps/plugins/pump/combo/ComboPluginTest.kt (100%) rename {combo => pump/combo}/src/test/java/info/nightscout/androidaps/plugins/pump/combo/TestBase.kt (100%) rename {dana => pump/dana}/.gitignore (100%) rename {dana => pump/dana}/build.gradle (100%) rename {dana => pump/dana}/consumer-rules.pro (100%) rename {dana => pump/dana}/proguard-rules.pro (100%) rename {dana => pump/dana}/schemas/info.nightscout.androidaps.dana.database.DanaHistoryDatabase/1.json (100%) rename {dana => pump/dana}/src/main/AndroidManifest.xml (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/comm/RecordTypes.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryDatabase.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecord.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecordDao.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/di/DanaHistoryModule.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/di/DanaModule.kt (100%) rename {dana => pump/dana}/src/main/java/info/nightscout/androidaps/dana/events/EventDanaRNewStatus.kt (100%) rename {dana => pump/dana}/src/main/res/drawable/ic_dana_i.xml (100%) rename {dana => pump/dana}/src/main/res/drawable/ic_dana_rs.xml (100%) rename {dana => pump/dana}/src/main/res/layout/danar_fragment.xml (100%) rename {dana => pump/dana}/src/main/res/layout/danar_history_activity.xml (100%) rename {dana => pump/dana}/src/main/res/layout/danar_history_item.xml (100%) rename {dana => pump/dana}/src/main/res/layout/danar_user_options_activity.xml (100%) rename {dana => pump/dana}/src/main/res/values-af-rZA/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ar-rSA/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-bg-rBG/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ca-rES/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-cy-rGB/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-da-rDK/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-de-rDE/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-el-rGR/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-es-rES/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-fi-rFI/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-fr-rFR/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ga-rIE/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-hr-rHR/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-hu-rHU/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-it-rIT/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-iw-rIL/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ja-rJP/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ko-rKR/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-lt-rLT/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-nl-rNL/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-no-rNO/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-pl-rPL/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-pt-rBR/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-pt-rPT/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ro-rRO/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ru-rRU/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-sk-rSK/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-sl-rSI/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-sr-rCS/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-sv-rSE/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-ta-rIN/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-tr-rTR/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values-zh-rCN/strings.xml (100%) rename {dana => pump/dana}/src/main/res/values/arrays.xml (100%) rename {dana => pump/dana}/src/main/res/values/strings.xml (100%) rename {dana => pump/dana}/src/test/java/info/nightscout/androidaps/TestBase.kt (100%) rename {dana => pump/dana}/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt (100%) rename {dana => pump/dana}/src/test/java/info/nightscout/androidaps/dana/DanaPumpTest.kt (100%) rename {danar => pump/danar}/.gitignore (100%) rename {danar => pump/danar}/build.gradle (93%) rename {danar => pump/danar}/consumer-rules.pro (100%) rename {danar => pump/danar}/proguard-rules.pro (100%) rename {danar => pump/danar}/src/main/AndroidManifest.xml (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MessageHashTableRKorean.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgCheckValue_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBasic_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBolus_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasalProfileAll_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasal_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatusBasic_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatus_k.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/comm/MessageHashTableRv2.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgCheckValue_v2.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEventsV2.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetAPSTempBasalStart_v2.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetHistoryEntry_v2.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgStatusAPS_v2.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/SerialIOThread.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableBase.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableR.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MessageOriginalNames.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusProgress.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStop.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgCheckValue.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAlarm.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAll.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAllDone.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBasalHour.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBolus.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryCarbo.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDailyInsulin.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDone.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryError.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryGlucose.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNew.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNewDone.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryRefill.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistorySuspend.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBasic.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBolus.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusOption.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusTime.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStart.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStop.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetActivateBasalProfile.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetBasalProfile.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetCarbsEntry.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStop.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetSingleBasalProfile.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStart.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStop.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTime.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingActiveProfile.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasal.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasalProfileAll.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingGlucose.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMaxValues.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMeal.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatios.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatiosAll.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingShippingInfo.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatus.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBasic.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBolusExtended.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusProfile.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusTempBasal.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/di/DanaRCommModule.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/di/DanaRModule.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/di/DanaRServicesModule.kt (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/services/AbstractDanaRExecutionService.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/danar/services/DanaRExecutionService.java (100%) rename {danar => pump/danar}/src/main/java/info/nightscout/androidaps/utils/CRC.kt (100%) rename {danar => pump/danar}/src/main/res/values-af-rZA/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-bg-rBG/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-ca-rES/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-da-rDK/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-de-rDE/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-el-rGR/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-es-rES/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-fr-rFR/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-ga-rIE/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-hr-rHR/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-hu-rHU/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-it-rIT/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-iw-rIL/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-ko-rKR/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-lt-rLT/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-nl-rNL/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-no-rNO/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-pl-rPL/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-pt-rBR/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-pt-rPT/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-ro-rRO/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-ru-rRU/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-sk-rSK/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-sr-rCS/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-sv-rSE/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-tr-rTR/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values-zh-rCN/strings.xml (100%) rename {danar => pump/danar}/src/main/res/values/strings.xml (100%) rename {danar => pump/danar}/src/main/res/xml/pref_danar.xml (100%) rename {danar => pump/danar}/src/main/res/xml/pref_danarkorean.xml (100%) rename {danar => pump/danar}/src/main/res/xml/pref_danarv2.xml (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/TestBase.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageHashTableRTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageOriginalNamesTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusProgressTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStopTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgCheckValueTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgErrorTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAlarmTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllDoneTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBasalHourTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBolusTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryCarboTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDailyInsulinTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDoneTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryErrorTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryGlucoseTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewDoneTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryRefillTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistorySuspendTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBasicTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBolusTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusOptionTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusTimeTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStartTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStopTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetActivateBasalProfileTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetBasalProfileTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetCarbsEntryTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStopTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetSingleBasalProfileTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTempBasalStartTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTimeTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetUserOptionsTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingActiveProfileTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalProfileAllTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingGlucoseTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMaxValuesTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMealTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosAllTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingShippingInfoTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingUserOptionsTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBasicTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBolusExtendedTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusProfileTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTempBasalTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/RecordTypesTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MessageHashTableRv2Test.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgCheckValueRv2Test.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgHistoryEventsRv2Test.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetAPSTempBasalStartRv2Test.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetHistoryEntryRv2Test.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgStatusAPSRv2Test.kt (100%) rename {danar => pump/danar}/src/test/java/info/nightscout/androidaps/utils/CRCTest.kt (100%) rename {danars => pump/danars}/.gitignore (100%) rename {danars => pump/danars}/build.gradle (94%) rename {danars => pump/danars}/consumer-rules.pro (100%) rename {danars => pump/danars}/proguard-rules.pro (100%) rename {danars => pump/danars}/src/main/AndroidManifest.xml (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/activities/BLEScanActivity.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/activities/EnterPinActivity.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/activities/PairingHelperActivity.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacket.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSBasalSetTemporaryBasal.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSHistoryEvents.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSSetEventHistory.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetBasalRate.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetProfileNumber.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetCancelTemporaryBasal.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileBasalRate.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileNumber.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOff.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOn.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasal.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGet24CIRCFArray.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetBolusOption.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCIRCFArray.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCalculationInformation.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetStepBolusInformation.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSet24CIRCFArray.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetBolusOption.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolus.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolusCancel.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStop.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcKeepConnection.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcSetHistorySave.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetPumpCheck.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingInformation.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingVersion.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetUserTimeChangeFlag.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralInitialScreenInformation.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetHistoryUploadMode.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetUserTimeChangeFlagClear.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistory.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarm.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAllHistory.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBasal.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBloodGlucose.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBolus.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryCarbohydrate.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryDaily.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryPrime.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryRefill.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistorySuspend.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryTemporary.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyAlarm.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryComplete.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryRateDisplay.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyMissedBolusAlarm.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpTime.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpUTCAndTimeZone.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetUserOption.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpTime.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpUTCAndTimeZone.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOption.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewBolusAvg.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewGetPumpDecRatio.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/di/DanaRSActivitiesModule.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/di/DanaRSModule.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/di/DanaRSServicesModule.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/dialogs/PairingProgressDialog.java (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/encryption/EncryptionType.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSDeviceChange.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSPairingSuccess.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt (100%) rename {danars => pump/danars}/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt (100%) rename {danars => pump/danars}/src/main/jniLibs/arm64-v8a/libBleEncryption.so (100%) rename {danars => pump/danars}/src/main/jniLibs/armeabi-v7a/libBleEncryption.so (100%) rename {danars => pump/danars}/src/main/jniLibs/x86/libBleEncryption.so (100%) rename {danars => pump/danars}/src/main/jniLibs/x86_64/libBleEncryption.so (100%) rename {danars => pump/danars}/src/main/res/layout/danars_blescanner_activity.xml (100%) rename {danars => pump/danars}/src/main/res/layout/danars_blescanner_item.xml (100%) rename {danars => pump/danars}/src/main/res/layout/danars_enter_pin_activity.xml (100%) rename {danars => pump/danars}/src/main/res/layout/danars_pairing_progress_dialog.xml (100%) rename {danars => pump/danars}/src/main/res/xml/pref_danars.xml (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/TestBase.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/DanaRSTestBase.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasalTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarmTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryCompleteTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOptionTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSTestBase.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsBasalSetTemporaryBasalTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsHistoryEventsTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsSetEventHistoryTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetBasalRateTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetProfileNumberTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetCancelTemporaryBasalTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileBasalRateTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileNumberTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOffTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOnTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetBolusOptionTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCalculationInformationTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCirCfArrayTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetStepBolusInformationTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetBolusOptionTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusCancelTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStopTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcKeepConnectionTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcSetHistorySaveTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetPumpCheckTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingInformationTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingVerisonTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetUserTimeChangeFlagTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralInitialScreenInformationTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetHistoryUploadModeTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetUserTimeChangeFlagClearTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryAllHistoryTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBasalTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBloodGlucoseTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBolusTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryCarbohydrateTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryDailyTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryPrimeTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryRefillTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistorySuspendTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryTemporaryTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyAlarmTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyMissedBolusAlarmTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetPumpTimeTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetUserOptionTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionSetPumpTimeTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewBolusAvgTest.kt (100%) rename {danars => pump/danars}/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewGetPumpDecRatioTest.kt (100%) rename {diaconn => pump/diaconn}/build.gradle (100%) rename {diaconn => pump/diaconn}/consumer-rules.pro (100%) rename {diaconn => pump/diaconn}/proguard-rules.pro (100%) rename {diaconn => pump/diaconn}/schemas/info.nightscout.androidaps.diaconn.database.DiaconnHistoryDatabase/1.json (100%) rename {diaconn => pump/diaconn}/src/main/AndroidManifest.xml (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Pump.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8BLEScanActivity.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8HistoryActivity.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiResponse.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiService.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnLogUploader.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/common/RecordTypes.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryDatabase.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecord.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecordDao.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ActivitiesModule.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8Module.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8PacketModule.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ServiceModule.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnHistoryModule.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnLogUploaderModule.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8DeviceChange.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8NewStatus.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8PumpLogReset.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BatteryWarningReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/ConfirmReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8Packet.java (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8ResponseMessageHashTable.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8SettingResponseMessageHashTable.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBlockReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusResultReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackResultReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/InsulinLackReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/RejectReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquirePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquireResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeReportPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingPacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingResponsePacket.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BATTERY.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BLOCK.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_SHORTAGE.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_INJECTOR_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_NEEDLE_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_TUBE_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY_BASAL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1HOUR_BASAL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_DUAL_NORMAL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_FAIL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_FAIL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_FAIL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_FAIL.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_SUCCESS.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_RESET_SYS_V3.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_DUAL_INJECTION.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_SQUARE_INJECTION.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_RELEASE_V2.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_V2.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_START_V3.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_STOP_V3.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/pumplog/PumplogUtil.java (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt (100%) rename {diaconn => pump/diaconn}/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt (100%) rename {diaconn => pump/diaconn}/src/main/res/layout/diaconn_g8_blescanner_activity.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/layout/diaconn_g8_blescanner_item.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/layout/diaconn_g8_fragment.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/layout/diaconn_g8_history_activity.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/layout/diaconn_g8_history_item.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/layout/diaconn_g8_user_options_activity.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-af-rZA/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-bg-rBG/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-ca-rES/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-da-rDK/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-de-rDE/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-el-rGR/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-es-rES/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-fr-rFR/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-ga-rIE/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-hr-rHR/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-hu-rHU/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-it-rIT/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-iw-rIL/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-ko-rKR/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-lt-rLT/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-nl-rNL/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-no-rNO/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-pl-rPL/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-pt-rBR/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-pt-rPT/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-ro-rRO/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-ru-rRU/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-sk-rSK/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-sl-rSI/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-sr-rCS/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-sv-rSE/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-ta-rIN/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-tr-rTR/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values-zh-rCN/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values/arrays.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values/colors.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values/ids.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/values/strings.xml (100%) rename {diaconn => pump/diaconn}/src/main/res/xml/pref_diaconn.xml (100%) rename {medtronic => pump/medtronic}/.gitignore (100%) rename {medtronic => pump/medtronic}/Changelog.txt (100%) rename {medtronic => pump/medtronic}/build.gradle (87%) rename {medtronic => pump/medtronic}/consumer-rules.pro (100%) rename {medtronic => pump/medtronic}/proguard-rules.pro (100%) rename {medtronic => pump/medtronic}/src/main/AndroidManifest.xml (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverter.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoder.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoderInterface.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntryInterface.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RawHistoryPage.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RecordDecodeStatus.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntryType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryResult.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkLongMessageBody.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkShortMessageBody.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/GetHistoryPageCarelinkMessageBody.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/MessageBody.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PacketType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpAckMessageBody.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpMessage.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/UnknownMessageBody.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIComm.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIPostprocessor.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUITask.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfile.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileEntry.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BatteryStatusDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusWizardDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/ClockDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/DailyTotalsDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpSettingDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpTimeStampedRecord.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/RLHistoryItemMedtronic.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BasalProfileStatus.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BatteryType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCommandType.kt (100%) mode change 100755 => 100644 rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCustomActionType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicDeviceType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicNotificationType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicStatusRefreshType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicUIResponseType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpBolusType.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpConfigurationGroup.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/di/MedtronicModule.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpConfigurationChanged.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpValuesChanged.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicConst.kt (100%) rename {medtronic => pump/medtronic}/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.kt (100%) rename {medtronic => pump/medtronic}/src/main/res/drawable/ic_medtronic_veo.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/layout/medtronic_fragment.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/layout/medtronic_history_activity.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/layout/medtronic_history_item.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-af-rZA/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ar-rSA/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-bg-rBG/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ca-rES/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-cy-rGB/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-da-rDK/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-de-rDE/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-el-rGR/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-es-rES/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-fi-rFI/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-fr-rFR/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ga-rIE/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-hr-rHR/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-hu-rHU/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-it-rIT/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-iw-rIL/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ko-rKR/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-lt-rLT/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-nl-rNL/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-no-rNO/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-pl-rPL/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-pt-rBR/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-pt-rPT/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ro-rRO/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ru-rRU/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-sk-rSK/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-sl-rSI/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-sr-rCS/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-sv-rSE/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-ta-rIN/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-tr-rTR/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values-zh-rCN/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values/arrays.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/values/strings.xml (100%) rename {medtronic => pump/medtronic}/src/main/res/xml/pref_medtronic.xml (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/TestBase.kt (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverterUTest.java (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryUTest.java (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt (100%) rename {medtronic => pump/medtronic}/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileUTest.java (100%) rename {medtronic => pump/medtronic}/src/test/resources/tbr_1724.json (100%) rename {medtronic => pump/medtronic}/src/test/resources/tbr_data.json (100%) rename {medtronic => pump/medtronic}/src/test/resources/tbr_data_special.json (100%) rename {omnipod-common => pump/omnipod-common}/.gitignore (100%) rename {omnipod-common => pump/omnipod-common}/build.gradle (100%) rename {omnipod-common => pump/omnipod-common}/consumer-rules.pro (100%) rename {omnipod-common => pump/omnipod-common}/proguard-rules.pro (100%) rename {omnipod-common => pump/omnipod-common}/src/main/AndroidManifest.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/definition/OmnipodCommandType.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodInjectHelpers.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodWizardModule.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDeactivatePod.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDisableSuspendAlerts.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandHandleTimeChange.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandPlayTestBeep.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandResumeDelivery.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSilenceAlerts.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSuspendDelivery.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandUpdateAlertConfiguration.java (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/PodActivationWizardActivity.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InitializePodFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InsertCannulaFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/PodActivationActionFragmentBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/AttachPodFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/PodActivatedFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/StartPodActivationFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InitializePodViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InsertCannulaViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/PodActivationActionViewModelBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/AttachPodViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/PodActivatedViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/StartPodActivationViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/activity/OmnipodWizardActivityBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/ActionFragmentBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/InfoFragmentBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/WizardFragmentBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ActionViewModelBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ViewModelBase.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/PodDeactivationWizardActivity.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDeactivatedFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDiscardedFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/StartPodDeactivationFragment.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/action/DeactivatePodViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDeactivatedViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDiscardedViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/StartPodDeactivationViewModel.kt (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_overview_pod_management.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_overview_refresh_pod_status.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_overview_resume_delivery.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_overview_set_time.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_overview_silence_alerts.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_overview_suspend_delivery.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_omnipod_wizard_success.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod_management_activate_pod.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod_management_deactivate_pod.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod_management_discard_pod.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod_management_play_test_beep.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod_management_pod_history.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/drawable/ic_pod_management_pulse_log.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_overview_buttons.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_overview_pod_info.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_pod_activation_wizard_activity.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_pod_deactivation_wizard_activity.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_wizard_action_page_fragment.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_wizard_base_fragment.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_wizard_info_page_fragment.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_wizard_nav_buttons.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/layout/omnipod_common_wizard_progress_indication.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/navigation/omnipod_common_pod_activation_wizard_navigation_graph.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/navigation/omnipod_common_pod_deactivation_wizard_navigation_graph.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-af-rZA/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-bg-rBG/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-ca-rES/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-da-rDK/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-de-rDE/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-el-rGR/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-es-rES/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-fr-rFR/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-ga-rIE/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-hr-rHR/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-hu-rHU/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-it-rIT/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-iw-rIL/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-ko-rKR/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-lt-rLT/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-nl-rNL/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-no-rNO/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-pl-rPL/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-pt-rBR/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-pt-rPT/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-ro-rRO/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-ru-rRU/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-sk-rSK/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-sl-rSI/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-sr-rCS/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-sv-rSE/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-ta-rIN/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-tr-rTR/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values-zh-rCN/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values/dimens.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values/strings.xml (100%) rename {omnipod-common => pump/omnipod-common}/src/main/res/values/styles.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/.gitignore (100%) rename {omnipod-dash => pump/omnipod-dash}/build.gradle (94%) rename {omnipod-dash => pump/omnipod-dash}/consumer-rules.pro (100%) rename {omnipod-dash => pump/omnipod-dash}/detekt-config.yml (100%) rename {omnipod-dash => pump/omnipod-dash}/proguard-rules.pro (100%) rename {omnipod-dash => pump/omnipod-dash}/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/AndroidManifest.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/EventOmnipodDashPumpValuesChanged.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashHistoryModule.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashModule.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashWizardViewModelsModule.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/WriteConfirmation.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/Nonce.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BusyException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ConnectException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseMessageException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseResponseException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendCommandException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/MessageIOException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/NotConnectedException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/PairingException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/SessionEstablishmentException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CharacteristicType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CmdBleIO.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/DataBleIO.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IncomingPackets.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/CrcMismatchException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/IncorrectPacketException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacket.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncoding.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadSplitter.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchange.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairMessage.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/DiscoveredInvalidPodException.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ConnectionStateChangeHandler.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/DisconnectHandler.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapAkaAttribute.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapSqn.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Milenage.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ResponseUtil.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionKeys.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramInsulinCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/CommandType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/NonceEnabledCommand.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/CommandBuilder.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/HeaderEnabledCommandBuilder.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/NonceEnabledCommandBuilder.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalInsulinProgramElement.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalShortInsulinProgramElement.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BolusShortInsulinProgramElement.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentBasalInsulinProgramElement.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentSlot.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/ShortInsulinProgramElement.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/TempBasalInsulinProgramElement.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramBasalUtil.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramTempBasalUtil.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ActivationProgress.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlarmType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertConfiguration.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertTrigger.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepRepetitionType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/DeliveryStatus.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/Encodable.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/NakErrorType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodStatus.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/SoftwareVersion.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ActivationResponseBase.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AdditionalStatusResponseBase.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponse.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponse.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponse.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/Response.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseBase.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseType.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponse.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponse.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/AlertUtil.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/HasValue.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/MessageUtil.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/RandomByteGenerator.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/X25519KeyGenerator.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodHistoryActivity.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/DashPodActivationWizardActivity.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInitializePodViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInsertCannulaViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashAttachPodViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashPodActivatedViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashStartPodActivationViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/DashPodDeactivationWizardActivity.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/action/DashDeactivatePodViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDeactivatedViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDiscardedViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashStartPodDeactivationViewModel.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Constants.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Flag.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Functions.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/I8n.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/layout/omnipod_dash_overview.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/layout/omnipod_dash_pod_history_activity.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/layout/omnipod_dash_pod_history_item.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/layout/omnipod_dash_pod_management.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-af-rZA/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-bg-rBG/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-ca-rES/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-da-rDK/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-de-rDE/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-el-rGR/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-es-rES/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-fr-rFR/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-ga-rIE/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-hr-rHR/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-hu-rHU/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-it-rIT/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-iw-rIL/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-ko-rKR/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-lt-rLT/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-nl-rNL/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-no-rNO/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-pl-rPL/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-pt-rBR/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-pt-rPT/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-ro-rRO/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-ru-rRU/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-sk-rSK/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-sl-rSI/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-sr-rCS/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-sv-rSE/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-ta-rIN/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-tr-rTR/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values-zh-rCN/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/values/strings.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/main/res/xml/omnipod_dash_preferences.xml (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncodingTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommandTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponseTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponseTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponseTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponseTest.kt (100%) rename {omnipod-dash => pump/omnipod-dash}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/FunctionsTest.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/.gitignore (100%) rename {omnipod-eros => pump/omnipod-eros}/build.gradle (89%) rename {omnipod-eros => pump/omnipod-eros}/consumer-rules.pro (100%) rename {omnipod-eros => pump/omnipod-eros}/proguard-rules.pro (100%) rename {omnipod-eros => pump/omnipod-eros}/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/AndroidManifest.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/ActiveBolus.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/RLHistoryItemOmnipod.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/OmnipodErosStorageKeys.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/PodHistoryEntryType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosHistoryModule.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosModule.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosWizardViewModelsModule.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AcknowledgeAlertsAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AssignAddressAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/BolusAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/CancelDeliveryAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureAlertsAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureBeepAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/DeactivatePodAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetPodInfoAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetStatusAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/InsertCannulaAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/OmnipodAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/PrimeAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetBasalScheduleAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetTempBasalAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetupPodAction.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/ExpirationReminderBuilder.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/PrimeService.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/IRawRepresentable.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/MessageBlock.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/NonceResyncableMessageBlock.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodMessage.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodPacket.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommand.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponse.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponse.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusUpdatableResponse.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponse.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfo.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLog.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponse.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ActivationProgress.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertConfiguration.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSet.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSlot.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertTrigger.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepConfigType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepRepeat.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryStatus.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ErrorEventInfo.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FaultEventCode.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FirmwareVersion.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/MessageBlockType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodConstants.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodCrc.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PacketType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodInfoType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodProgressStatus.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/TimerAlertTrigger.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/UnitsRemainingAlertTrigger.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliverySchedule.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliveryTable.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalSchedule.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleEntry.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalTableEntry.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BolusDeliverySchedule.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/DeliverySchedule.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/InsulinScheduleType.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/RateEntry.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/TempBasalDeliverySchedule.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/ActivationTimeExceededException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CrcMismatchException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalActivationProgressException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalDeliveryStatusException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageAddressException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageSequenceNumberException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPacketTypeException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPodProgressException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalResponseException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalVersionResponseTypeException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/MessageDecodingException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceOutOfSyncException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceResyncException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NotEnoughDataException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/OmnipodException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodFaultException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodProgressStatusVerificationFailedException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodReturnedErrorResponseException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PrecedingCommandFailedUncertainlyException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkInterruptedException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkTimeoutException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnexpectedException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnreachableException.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/ErosPodStateManager.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/OmnipodManager.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/AlertConfigurationUtil.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtil.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosActiveAlertsChanged.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosFaultEventChanged.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosPumpValuesChanged.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosTbrChanged.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosUncertainTbrRecovered.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistory.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryDatabase.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordDao.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordEntity.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManager.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandGetPodStatus.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandReadPulseLog.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/manager/OmnipodRileyLinkCommunicationManager.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/ErosPodActivationWizardActivity.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInitializePodViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInsertCannulaViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosAttachPodViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosPodActivatedViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosStartPodActivationViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/ErosPodDeactivationWizardActivity.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/action/ErosDeactivatePodViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDeactivatedViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDiscardedViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosStartPodDeactivationViewModel.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/AapsOmnipodUtil.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/OmnipodAlertUtil.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/drawable/ic_pod_activity_reset_rileylink_config.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/drawable/ic_pod_management_rl_stats.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/layout/omnipod_eros_overview.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/layout/omnipod_eros_overview_riley_link_status.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/layout/omnipod_eros_pod_history_activity.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/layout/omnipod_eros_pod_history_item.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/layout/omnipod_eros_pod_management.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-af-rZA/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-bg-rBG/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-ca-rES/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-da-rDK/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-de-rDE/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-el-rGR/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-es-rES/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-fr-rFR/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-ga-rIE/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-hr-rHR/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-hu-rHU/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-it-rIT/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-iw-rIL/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-ko-rKR/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-lt-rLT/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-nl-rNL/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-no-rNO/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-pl-rPL/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-pt-rBR/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-pt-rPT/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-ro-rRO/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-ru-rRU/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-sk-rSK/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-sl-rSI/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-sr-rCS/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-sv-rSE/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-ta-rIN/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-tr-rTR/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values-zh-rCN/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/values/strings.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/main/res/xml/omnipod_eros_preferences.xml (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/TestBase.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/AapsOmnipodErosManagerTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommandTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponseTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponseTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponseTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlertsTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLogTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTimeTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLogTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLogTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSetTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtilTest.java (100%) rename {omnipod-eros => pump/omnipod-eros}/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt (100%) rename {pump-common => pump/pump-common}/.gitignore (100%) rename {pump-common => pump/pump-common}/build.gradle (100%) rename {pump-common => pump/pump-common}/consumer-rules.pro (100%) rename {pump-common => pump/pump-common}/proguard-rules.pro (100%) rename {pump-common => pump/pump-common}/src/main/AndroidManifest.xml (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDeviceState.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpStatusType.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/TempBasalPair.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/PumpCommonModule.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpDbEntry.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncEntriesCreator.java (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncStorage.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ByteUtil.java (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ProfileUtil.kt (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/StringUtil.java (100%) rename {pump-common => pump/pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ThreadUtil.java (100%) rename {pump-common => pump/pump-common}/src/main/res/layout/pump_ble_config_activity.xml (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/res/layout/pump_ble_config_scan_item.xml (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/res/layout/pump_history_activity.xml (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/res/layout/pump_history_item.xml (100%) mode change 100755 => 100644 rename {pump-common => pump/pump-common}/src/main/res/values-af-rZA/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-bg-rBG/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-ca-rES/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-da-rDK/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-de-rDE/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-el-rGR/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-es-rES/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-fr-rFR/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-ga-rIE/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-hr-rHR/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-hu-rHU/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-it-rIT/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-iw-rIL/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-ko-rKR/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-lt-rLT/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-nl-rNL/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-no-rNO/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-pl-rPL/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-pt-rBR/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-pt-rPT/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-ro-rRO/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-ru-rRU/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-sk-rSK/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-sr-rCS/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-sv-rSE/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-tr-rTR/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values-zh-rCN/strings.xml (100%) rename {pump-common => pump/pump-common}/src/main/res/values/strings.xml (100%) rename {rileylink => pump/rileylink}/.gitignore (100%) rename {rileylink => pump/rileylink}/build.gradle (92%) rename {rileylink => pump/rileylink}/consumer-rules.pro (100%) rename {rileylink => pump/rileylink}/proguard-rules.pro (100%) rename {rileylink => pump/rileylink}/src/main/AndroidManifest.xml (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/RileyLinkModule.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/dialog/RileyLinkBLEConfigActivity.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkConst.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkBLE.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkCommunicationException.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/GetVersion.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/Reset.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/ResetRadioConfig.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/RileyLinkCommand.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SendAndListen.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetHardwareEncoding.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/UpdateRegister.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyScanResults.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyTrial.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/GattAttributes.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RFSpyResponse.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessage.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessageType.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioPacket.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioResponse.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6b.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bAbstract.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bGeoff.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/CC111XRegister.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyCommand.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyRLResponse.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkBLEError.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkCommandType.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkEncodingType.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersion.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/device/OrangeLinkImpl.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperation.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperationResult.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicReadOperation.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicWriteOperation.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/DescriptorWriteOperation.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/BleAdvertisedData.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/CommandValueDefinition.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/RLHistoryItem.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionRLType.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionType.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkError.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpDevice.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpInfo.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkServiceState.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkTargetDevice.java (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusActivity.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusHistoryFragment.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBluetoothStateReceiver.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/DiscoverGattServicesTask.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/PumpTask.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ResetRileyLinkConfigurationTask.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTask.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTaskExecutor.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/WakeAndTuneTask.kt (100%) rename {rileylink => pump/rileylink}/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/CRC.java (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/riley_link_ble_config_activity.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/riley_link_ble_config_scan_item.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/rileylink_status.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/rileylink_status_device_item.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/rileylink_status_general.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/rileylink_status_history.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/layout/rileylink_status_history_item.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/menu/menu_rileylink_ble_scan.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-af-rZA/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ar-rSA/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-bg-rBG/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ca-rES/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-cs-rCZ/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-cy-rGB/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-da-rDK/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-de-rDE/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-el-rGR/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-es-rES/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-fi-rFI/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-fr-rFR/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ga-rIE/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-hr-rHR/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-hu-rHU/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-it-rIT/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-iw-rIL/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ko-rKR/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-lt-rLT/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-nl-rNL/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-no-rNO/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-pl-rPL/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-pt-rBR/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-pt-rPT/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ro-rRO/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ru-rRU/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-sk-rSK/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-sl-rSI/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-sr-rCS/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-sv-rSE/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-ta-rIN/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-tr-rTR/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values-zh-rCN/strings.xml (100%) rename {rileylink => pump/rileylink}/src/main/res/values/strings.xml (100%) rename {rileylink => pump/rileylink}/src/test/java/info/nightscout/androidaps/TestBase.kt (100%) rename {rileylink => pump/rileylink}/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyTest.kt (100%) rename {rileylink => pump/rileylink}/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsParametrizedUTest.java (100%) rename {rileylink => pump/rileylink}/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsUTest.java (100%) rename {rileylink => pump/rileylink}/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersionTest.java (100%) diff --git a/Steampunk_graphics_source_link.md b/_docs/Steampunk_graphics_source_link.md similarity index 100% rename from Steampunk_graphics_source_link.md rename to _docs/Steampunk_graphics_source_link.md diff --git a/demo_keystore.jks b/_docs/demo_keystore.jks similarity index 100% rename from demo_keystore.jks rename to _docs/demo_keystore.jks diff --git a/gource/sample.bat b/_docs/gource/sample.bat similarity index 100% rename from gource/sample.bat rename to _docs/gource/sample.bat diff --git a/icons/action_add.svg b/_docs/icons/action_add.svg similarity index 100% rename from icons/action_add.svg rename to _docs/icons/action_add.svg diff --git a/icons/action_minus.svg b/_docs/icons/action_minus.svg similarity index 100% rename from icons/action_minus.svg rename to _docs/icons/action_minus.svg diff --git a/icons/actions_cancelextbolus.svg b/_docs/icons/actions_cancelextbolus.svg similarity index 100% rename from icons/actions_cancelextbolus.svg rename to _docs/icons/actions_cancelextbolus.svg diff --git a/icons/actions_refill.svg b/_docs/icons/actions_refill.svg similarity index 100% rename from icons/actions_refill.svg rename to _docs/icons/actions_refill.svg diff --git a/icons/actions_startextbolus.svg b/_docs/icons/actions_startextbolus.svg similarity index 100% rename from icons/actions_startextbolus.svg rename to _docs/icons/actions_startextbolus.svg diff --git a/icons/actions_temptarget.svg b/_docs/icons/actions_temptarget.svg similarity index 100% rename from icons/actions_temptarget.svg rename to _docs/icons/actions_temptarget.svg diff --git a/icons/add.svg b/_docs/icons/add.svg similarity index 100% rename from icons/add.svg rename to _docs/icons/add.svg diff --git a/icons/as.svg b/_docs/icons/as.svg similarity index 100% rename from icons/as.svg rename to _docs/icons/as.svg diff --git a/icons/auto_delta.svg b/_docs/icons/auto_delta.svg similarity index 100% rename from icons/auto_delta.svg rename to _docs/icons/auto_delta.svg diff --git a/icons/autotune.svg b/_docs/icons/autotune.svg similarity index 100% rename from icons/autotune.svg rename to _docs/icons/autotune.svg diff --git a/icons/battery-burnin/battery-charging-wireless-10-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-10-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-10-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-10-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-20-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-20-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-20-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-20-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-30-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-30-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-30-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-30-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-40-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-40-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-40-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-40-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-50-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-50-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-50-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-50-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-60-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-60-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-60-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-60-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-70-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-70-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-70-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-70-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-80-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-80-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-80-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-80-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-90-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-90-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-90-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-90-burnin.svg diff --git a/icons/battery-burnin/battery-charging-wireless-burnin.svg b/_docs/icons/battery-burnin/battery-charging-wireless-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-charging-wireless-burnin.svg rename to _docs/icons/battery-burnin/battery-charging-wireless-burnin.svg diff --git a/icons/battery-burnin/battery-unknown-burnin.svg b/_docs/icons/battery-burnin/battery-unknown-burnin.svg similarity index 100% rename from icons/battery-burnin/battery-unknown-burnin.svg rename to _docs/icons/battery-burnin/battery-unknown-burnin.svg diff --git a/icons/battery-source/mask-burnin-battery-raw.svg b/_docs/icons/battery-source/mask-burnin-battery-raw.svg similarity index 100% rename from icons/battery-source/mask-burnin-battery-raw.svg rename to _docs/icons/battery-source/mask-burnin-battery-raw.svg diff --git a/icons/battery-source/mask-burnin-battery.svg b/_docs/icons/battery-source/mask-burnin-battery.svg similarity index 100% rename from icons/battery-source/mask-burnin-battery.svg rename to _docs/icons/battery-source/mask-burnin-battery.svg diff --git a/icons/battery/battery-charging-wireless-10.svg b/_docs/icons/battery/battery-charging-wireless-10.svg similarity index 100% rename from icons/battery/battery-charging-wireless-10.svg rename to _docs/icons/battery/battery-charging-wireless-10.svg diff --git a/icons/battery/battery-charging-wireless-20.svg b/_docs/icons/battery/battery-charging-wireless-20.svg similarity index 100% rename from icons/battery/battery-charging-wireless-20.svg rename to _docs/icons/battery/battery-charging-wireless-20.svg diff --git a/icons/battery/battery-charging-wireless-30.svg b/_docs/icons/battery/battery-charging-wireless-30.svg similarity index 100% rename from icons/battery/battery-charging-wireless-30.svg rename to _docs/icons/battery/battery-charging-wireless-30.svg diff --git a/icons/battery/battery-charging-wireless-40.svg b/_docs/icons/battery/battery-charging-wireless-40.svg similarity index 100% rename from icons/battery/battery-charging-wireless-40.svg rename to _docs/icons/battery/battery-charging-wireless-40.svg diff --git a/icons/battery/battery-charging-wireless-50.svg b/_docs/icons/battery/battery-charging-wireless-50.svg similarity index 100% rename from icons/battery/battery-charging-wireless-50.svg rename to _docs/icons/battery/battery-charging-wireless-50.svg diff --git a/icons/battery/battery-charging-wireless-60.svg b/_docs/icons/battery/battery-charging-wireless-60.svg similarity index 100% rename from icons/battery/battery-charging-wireless-60.svg rename to _docs/icons/battery/battery-charging-wireless-60.svg diff --git a/icons/battery/battery-charging-wireless-70.svg b/_docs/icons/battery/battery-charging-wireless-70.svg similarity index 100% rename from icons/battery/battery-charging-wireless-70.svg rename to _docs/icons/battery/battery-charging-wireless-70.svg diff --git a/icons/battery/battery-charging-wireless-80.svg b/_docs/icons/battery/battery-charging-wireless-80.svg similarity index 100% rename from icons/battery/battery-charging-wireless-80.svg rename to _docs/icons/battery/battery-charging-wireless-80.svg diff --git a/icons/battery/battery-charging-wireless-90.svg b/_docs/icons/battery/battery-charging-wireless-90.svg similarity index 100% rename from icons/battery/battery-charging-wireless-90.svg rename to _docs/icons/battery/battery-charging-wireless-90.svg diff --git a/icons/battery/battery-charging-wireless.svg b/_docs/icons/battery/battery-charging-wireless.svg similarity index 100% rename from icons/battery/battery-charging-wireless.svg rename to _docs/icons/battery/battery-charging-wireless.svg diff --git a/icons/battery/battery-outline.svg b/_docs/icons/battery/battery-outline.svg similarity index 100% rename from icons/battery/battery-outline.svg rename to _docs/icons/battery/battery-outline.svg diff --git a/icons/battery/battery-unknown.svg b/_docs/icons/battery/battery-unknown.svg similarity index 100% rename from icons/battery/battery-unknown.svg rename to _docs/icons/battery/battery-unknown.svg diff --git a/icons/bolus.svg b/_docs/icons/bolus.svg similarity index 100% rename from icons/bolus.svg rename to _docs/icons/bolus.svg diff --git a/icons/byoda.svg b/_docs/icons/byoda.svg similarity index 100% rename from icons/byoda.svg rename to _docs/icons/byoda.svg diff --git a/icons/calculator.svg b/_docs/icons/calculator.svg similarity index 100% rename from icons/calculator.svg rename to _docs/icons/calculator.svg diff --git a/icons/calibration.svg b/_docs/icons/calibration.svg similarity index 100% rename from icons/calibration.svg rename to _docs/icons/calibration.svg diff --git a/icons/cancel.svg b/_docs/icons/cancel.svg similarity index 100% rename from icons/cancel.svg rename to _docs/icons/cancel.svg diff --git a/icons/clone.svg b/_docs/icons/clone.svg similarity index 100% rename from icons/clone.svg rename to _docs/icons/clone.svg diff --git a/icons/clone_48.svg b/_docs/icons/clone_48.svg similarity index 100% rename from icons/clone_48.svg rename to _docs/icons/clone_48.svg diff --git a/icons/combo.svg b/_docs/icons/combo.svg similarity index 100% rename from icons/combo.svg rename to _docs/icons/combo.svg diff --git a/icons/compare_profiles.svg b/_docs/icons/compare_profiles.svg similarity index 100% rename from icons/compare_profiles.svg rename to _docs/icons/compare_profiles.svg diff --git a/icons/complications-source/ic_br_cob_iob_orig.svg b/_docs/icons/complications-source/ic_br_cob_iob_orig.svg similarity index 100% rename from icons/complications-source/ic_br_cob_iob_orig.svg rename to _docs/icons/complications-source/ic_br_cob_iob_orig.svg diff --git a/icons/complications-source/ic_cob_detailed_orig.svg b/_docs/icons/complications-source/ic_cob_detailed_orig.svg similarity index 100% rename from icons/complications-source/ic_cob_detailed_orig.svg rename to _docs/icons/complications-source/ic_cob_detailed_orig.svg diff --git a/icons/complications-source/ic_cob_iob_orig.svg b/_docs/icons/complications-source/ic_cob_iob_orig.svg similarity index 100% rename from icons/complications-source/ic_cob_iob_orig.svg rename to _docs/icons/complications-source/ic_cob_iob_orig.svg diff --git a/icons/complications-source/ic_ins_burnin_orig.svg b/_docs/icons/complications-source/ic_ins_burnin_orig.svg similarity index 100% rename from icons/complications-source/ic_ins_burnin_orig.svg rename to _docs/icons/complications-source/ic_ins_burnin_orig.svg diff --git a/icons/complications-source/ic_ins_orig.svg b/_docs/icons/complications-source/ic_ins_orig.svg similarity index 100% rename from icons/complications-source/ic_ins_orig.svg rename to _docs/icons/complications-source/ic_ins_orig.svg diff --git a/icons/complications-source/ic_iob_detailed_orig.svg b/_docs/icons/complications-source/ic_iob_detailed_orig.svg similarity index 100% rename from icons/complications-source/ic_iob_detailed_orig.svg rename to _docs/icons/complications-source/ic_iob_detailed_orig.svg diff --git a/icons/complications/ic_aaps_full.svg b/_docs/icons/complications/ic_aaps_full.svg similarity index 100% rename from icons/complications/ic_aaps_full.svg rename to _docs/icons/complications/ic_aaps_full.svg diff --git a/icons/complications/ic_basal.svg b/_docs/icons/complications/ic_basal.svg similarity index 100% rename from icons/complications/ic_basal.svg rename to _docs/icons/complications/ic_basal.svg diff --git a/icons/complications/ic_br_cob_iob.svg b/_docs/icons/complications/ic_br_cob_iob.svg similarity index 100% rename from icons/complications/ic_br_cob_iob.svg rename to _docs/icons/complications/ic_br_cob_iob.svg diff --git a/icons/complications/ic_carbs.svg b/_docs/icons/complications/ic_carbs.svg similarity index 100% rename from icons/complications/ic_carbs.svg rename to _docs/icons/complications/ic_carbs.svg diff --git a/icons/complications/ic_cob_detailed.svg b/_docs/icons/complications/ic_cob_detailed.svg similarity index 100% rename from icons/complications/ic_cob_detailed.svg rename to _docs/icons/complications/ic_cob_detailed.svg diff --git a/icons/complications/ic_cob_iob.svg b/_docs/icons/complications/ic_cob_iob.svg similarity index 100% rename from icons/complications/ic_cob_iob.svg rename to _docs/icons/complications/ic_cob_iob.svg diff --git a/icons/complications/ic_ins.svg b/_docs/icons/complications/ic_ins.svg similarity index 100% rename from icons/complications/ic_ins.svg rename to _docs/icons/complications/ic_ins.svg diff --git a/icons/complications/ic_ins_burnin.svg b/_docs/icons/complications/ic_ins_burnin.svg similarity index 100% rename from icons/complications/ic_ins_burnin.svg rename to _docs/icons/complications/ic_ins_burnin.svg diff --git a/icons/complications/ic_iob_detailed.svg b/_docs/icons/complications/ic_iob_detailed.svg similarity index 100% rename from icons/complications/ic_iob_detailed.svg rename to _docs/icons/complications/ic_iob_detailed.svg diff --git a/icons/complications/ic_sgv.svg b/_docs/icons/complications/ic_sgv.svg similarity index 100% rename from icons/complications/ic_sgv.svg rename to _docs/icons/complications/ic_sgv.svg diff --git a/icons/confirm.svg b/_docs/icons/confirm.svg similarity index 100% rename from icons/confirm.svg rename to _docs/icons/confirm.svg diff --git a/icons/cp_aaps_offline.svg b/_docs/icons/cp_aaps_offline.svg similarity index 100% rename from icons/cp_aaps_offline.svg rename to _docs/icons/cp_aaps_offline.svg diff --git a/icons/cp_age_batterie.svg b/_docs/icons/cp_age_batterie.svg similarity index 100% rename from icons/cp_age_batterie.svg rename to _docs/icons/cp_age_batterie.svg diff --git a/icons/cp_age_canula.svg b/_docs/icons/cp_age_canula.svg similarity index 100% rename from icons/cp_age_canula.svg rename to _docs/icons/cp_age_canula.svg diff --git a/icons/cp_age_insulin.svg b/_docs/icons/cp_age_insulin.svg similarity index 100% rename from icons/cp_age_insulin.svg rename to _docs/icons/cp_age_insulin.svg diff --git a/icons/cp_age_sensor.svg b/_docs/icons/cp_age_sensor.svg similarity index 100% rename from icons/cp_age_sensor.svg rename to _docs/icons/cp_age_sensor.svg diff --git a/icons/cp_announcement.svg b/_docs/icons/cp_announcement.svg similarity index 100% rename from icons/cp_announcement.svg rename to _docs/icons/cp_announcement.svg diff --git a/icons/cp_basal_end.svg b/_docs/icons/cp_basal_end.svg similarity index 100% rename from icons/cp_basal_end.svg rename to _docs/icons/cp_basal_end.svg diff --git a/icons/cp_basal_no_tbr.svg b/_docs/icons/cp_basal_no_tbr.svg similarity index 100% rename from icons/cp_basal_no_tbr.svg rename to _docs/icons/cp_basal_no_tbr.svg diff --git a/icons/cp_basal_tbr_high.svg b/_docs/icons/cp_basal_tbr_high.svg similarity index 100% rename from icons/cp_basal_tbr_high.svg rename to _docs/icons/cp_basal_tbr_high.svg diff --git a/icons/cp_basal_tbr_low.svg b/_docs/icons/cp_basal_tbr_low.svg similarity index 100% rename from icons/cp_basal_tbr_low.svg rename to _docs/icons/cp_basal_tbr_low.svg diff --git a/icons/cp_bgcheck.svg b/_docs/icons/cp_bgcheck.svg similarity index 100% rename from icons/cp_bgcheck.svg rename to _docs/icons/cp_bgcheck.svg diff --git a/icons/cp_bgcheck2.svg b/_docs/icons/cp_bgcheck2.svg similarity index 100% rename from icons/cp_bgcheck2.svg rename to _docs/icons/cp_bgcheck2.svg diff --git a/icons/cp_bolus_carbs.svg b/_docs/icons/cp_bolus_carbs.svg similarity index 100% rename from icons/cp_bolus_carbs.svg rename to _docs/icons/cp_bolus_carbs.svg diff --git a/icons/cp_bolus_combo.svg b/_docs/icons/cp_bolus_combo.svg similarity index 100% rename from icons/cp_bolus_combo.svg rename to _docs/icons/cp_bolus_combo.svg diff --git a/icons/cp_bolus_correction.svg b/_docs/icons/cp_bolus_correction.svg similarity index 100% rename from icons/cp_bolus_correction.svg rename to _docs/icons/cp_bolus_correction.svg diff --git a/icons/cp_bolus_meal.svg b/_docs/icons/cp_bolus_meal.svg similarity index 100% rename from icons/cp_bolus_meal.svg rename to _docs/icons/cp_bolus_meal.svg diff --git a/icons/cp_bolus_snack.svg b/_docs/icons/cp_bolus_snack.svg similarity index 100% rename from icons/cp_bolus_snack.svg rename to _docs/icons/cp_bolus_snack.svg diff --git a/icons/cp_cgm_insert.svg b/_docs/icons/cp_cgm_insert.svg similarity index 100% rename from icons/cp_cgm_insert.svg rename to _docs/icons/cp_cgm_insert.svg diff --git a/icons/cp_cgm_profile.svg b/_docs/icons/cp_cgm_profile.svg similarity index 100% rename from icons/cp_cgm_profile.svg rename to _docs/icons/cp_cgm_profile.svg diff --git a/icons/cp_cgm_start.svg b/_docs/icons/cp_cgm_start.svg similarity index 100% rename from icons/cp_cgm_start.svg rename to _docs/icons/cp_cgm_start.svg diff --git a/icons/cp_cgm_target.svg b/_docs/icons/cp_cgm_target.svg similarity index 100% rename from icons/cp_cgm_target.svg rename to _docs/icons/cp_cgm_target.svg diff --git a/icons/cp_exercise.svg b/_docs/icons/cp_exercise.svg similarity index 100% rename from icons/cp_exercise.svg rename to _docs/icons/cp_exercise.svg diff --git a/icons/cp_note.svg b/_docs/icons/cp_note.svg similarity index 100% rename from icons/cp_note.svg rename to _docs/icons/cp_note.svg diff --git a/icons/cp_pump_battery.svg b/_docs/icons/cp_pump_battery.svg similarity index 100% rename from icons/cp_pump_battery.svg rename to _docs/icons/cp_pump_battery.svg diff --git a/icons/cp_pump_canula.svg b/_docs/icons/cp_pump_canula.svg similarity index 100% rename from icons/cp_pump_canula.svg rename to _docs/icons/cp_pump_canula.svg diff --git a/icons/cp_pump_cartridge.svg b/_docs/icons/cp_pump_cartridge.svg similarity index 100% rename from icons/cp_pump_cartridge.svg rename to _docs/icons/cp_pump_cartridge.svg diff --git a/icons/cp_question.svg b/_docs/icons/cp_question.svg similarity index 100% rename from icons/cp_question.svg rename to _docs/icons/cp_question.svg diff --git a/icons/danar_useropt.svg b/_docs/icons/danar_useropt.svg similarity index 100% rename from icons/danar_useropt.svg rename to _docs/icons/danar_useropt.svg diff --git a/icons/danarhistory.svg b/_docs/icons/danarhistory.svg similarity index 100% rename from icons/danarhistory.svg rename to _docs/icons/danarhistory.svg diff --git a/icons/danarprofile.svg b/_docs/icons/danarprofile.svg similarity index 100% rename from icons/danarprofile.svg rename to _docs/icons/danarprofile.svg diff --git a/icons/danars.svg b/_docs/icons/danars.svg similarity index 100% rename from icons/danars.svg rename to _docs/icons/danars.svg diff --git a/icons/danarstat.svg b/_docs/icons/danarstat.svg similarity index 100% rename from icons/danarstat.svg rename to _docs/icons/danarstat.svg diff --git a/icons/excel.svg b/_docs/icons/excel.svg similarity index 100% rename from icons/excel.svg rename to _docs/icons/excel.svg diff --git a/icons/export_settings.svg b/_docs/icons/export_settings.svg similarity index 100% rename from icons/export_settings.svg rename to _docs/icons/export_settings.svg diff --git a/icons/ic_DoubleDown.svg b/_docs/icons/ic_DoubleDown.svg similarity index 100% rename from icons/ic_DoubleDown.svg rename to _docs/icons/ic_DoubleDown.svg diff --git a/icons/ic_DoubleUp.svg b/_docs/icons/ic_DoubleUp.svg similarity index 100% rename from icons/ic_DoubleUp.svg rename to _docs/icons/ic_DoubleUp.svg diff --git a/icons/ic_Flat.svg b/_docs/icons/ic_Flat.svg similarity index 100% rename from icons/ic_Flat.svg rename to _docs/icons/ic_Flat.svg diff --git a/icons/ic_FortyFiveDown.svg b/_docs/icons/ic_FortyFiveDown.svg similarity index 100% rename from icons/ic_FortyFiveDown.svg rename to _docs/icons/ic_FortyFiveDown.svg diff --git a/icons/ic_FortyFiveUp.svg b/_docs/icons/ic_FortyFiveUp.svg similarity index 100% rename from icons/ic_FortyFiveUp.svg rename to _docs/icons/ic_FortyFiveUp.svg diff --git a/icons/ic_Invalid.svg b/_docs/icons/ic_Invalid.svg similarity index 100% rename from icons/ic_Invalid.svg rename to _docs/icons/ic_Invalid.svg diff --git a/icons/ic_SingleDown.svg b/_docs/icons/ic_SingleDown.svg similarity index 100% rename from icons/ic_SingleDown.svg rename to _docs/icons/ic_SingleDown.svg diff --git a/icons/ic_SingleUp.svg b/_docs/icons/ic_SingleUp.svg similarity index 100% rename from icons/ic_SingleUp.svg rename to _docs/icons/ic_SingleUp.svg diff --git a/icons/ic_error.svg b/_docs/icons/ic_error.svg similarity index 100% rename from icons/ic_error.svg rename to _docs/icons/ic_error.svg diff --git a/icons/ic_exit_to_app.svg b/_docs/icons/ic_exit_to_app.svg similarity index 100% rename from icons/ic_exit_to_app.svg rename to _docs/icons/ic_exit_to_app.svg diff --git a/icons/ic_home_loop.svg b/_docs/icons/ic_home_loop.svg similarity index 100% rename from icons/ic_home_loop.svg rename to _docs/icons/ic_home_loop.svg diff --git a/icons/ic_maintenance.svg b/_docs/icons/ic_maintenance.svg similarity index 100% rename from icons/ic_maintenance.svg rename to _docs/icons/ic_maintenance.svg diff --git a/icons/ic_notif_aaps.svg b/_docs/icons/ic_notif_aaps.svg similarity index 100% rename from icons/ic_notif_aaps.svg rename to _docs/icons/ic_notif_aaps.svg diff --git a/icons/ic_notif_nsclient.svg b/_docs/icons/ic_notif_nsclient.svg similarity index 100% rename from icons/ic_notif_nsclient.svg rename to _docs/icons/ic_notif_nsclient.svg diff --git a/icons/ic_notif_pumpcontrol.svg b/_docs/icons/ic_notif_pumpcontrol.svg similarity index 100% rename from icons/ic_notif_pumpcontrol.svg rename to _docs/icons/ic_notif_pumpcontrol.svg diff --git a/icons/ic_warning.svg b/_docs/icons/ic_warning.svg similarity index 100% rename from icons/ic_warning.svg rename to _docs/icons/ic_warning.svg diff --git a/icons/icon_snooze.svg b/_docs/icons/icon_snooze.svg similarity index 100% rename from icons/icon_snooze.svg rename to _docs/icons/icon_snooze.svg diff --git a/icons/import_settings.svg b/_docs/icons/import_settings.svg similarity index 100% rename from icons/import_settings.svg rename to _docs/icons/import_settings.svg diff --git a/icons/insight.svg b/_docs/icons/insight.svg similarity index 100% rename from icons/insight.svg rename to _docs/icons/insight.svg diff --git a/icons/insight_128.svg b/_docs/icons/insight_128.svg similarity index 100% rename from icons/insight_128.svg rename to _docs/icons/insight_128.svg diff --git a/icons/local_activate.svg b/_docs/icons/local_activate.svg similarity index 100% rename from icons/local_activate.svg rename to _docs/icons/local_activate.svg diff --git a/icons/local_reset.svg b/_docs/icons/local_reset.svg similarity index 100% rename from icons/local_reset.svg rename to _docs/icons/local_reset.svg diff --git a/icons/local_save.svg b/_docs/icons/local_save.svg similarity index 100% rename from icons/local_save.svg rename to _docs/icons/local_save.svg diff --git a/icons/log_delete.svg b/_docs/icons/log_delete.svg similarity index 100% rename from icons/log_delete.svg rename to _docs/icons/log_delete.svg diff --git a/icons/log_settings.svg b/_docs/icons/log_settings.svg similarity index 100% rename from icons/log_settings.svg rename to _docs/icons/log_settings.svg diff --git a/icons/loop.svg b/_docs/icons/loop.svg similarity index 100% rename from icons/loop.svg rename to _docs/icons/loop.svg diff --git a/icons/loop_closed.svg b/_docs/icons/loop_closed.svg similarity index 100% rename from icons/loop_closed.svg rename to _docs/icons/loop_closed.svg diff --git a/icons/loop_disabled.svg b/_docs/icons/loop_disabled.svg similarity index 100% rename from icons/loop_disabled.svg rename to _docs/icons/loop_disabled.svg diff --git a/icons/loop_disconnected.svg b/_docs/icons/loop_disconnected.svg similarity index 100% rename from icons/loop_disconnected.svg rename to _docs/icons/loop_disconnected.svg diff --git a/icons/loop_lgs.svg b/_docs/icons/loop_lgs.svg similarity index 100% rename from icons/loop_lgs.svg rename to _docs/icons/loop_lgs.svg diff --git a/icons/loop_off.svg b/_docs/icons/loop_off.svg similarity index 100% rename from icons/loop_off.svg rename to _docs/icons/loop_off.svg diff --git a/icons/loop_open.svg b/_docs/icons/loop_open.svg similarity index 100% rename from icons/loop_open.svg rename to _docs/icons/loop_open.svg diff --git a/icons/loop_paused.svg b/_docs/icons/loop_paused.svg similarity index 100% rename from icons/loop_paused.svg rename to _docs/icons/loop_paused.svg diff --git a/icons/loop_reconnect.svg b/_docs/icons/loop_reconnect.svg similarity index 100% rename from icons/loop_reconnect.svg rename to _docs/icons/loop_reconnect.svg diff --git a/icons/loop_resume.svg b/_docs/icons/loop_resume.svg similarity index 100% rename from icons/loop_resume.svg rename to _docs/icons/loop_resume.svg diff --git a/icons/loop_superbolus.svg b/_docs/icons/loop_superbolus.svg similarity index 100% rename from icons/loop_superbolus.svg rename to _docs/icons/loop_superbolus.svg diff --git a/icons/pod.svg b/_docs/icons/pod.svg similarity index 100% rename from icons/pod.svg rename to _docs/icons/pod.svg diff --git a/icons/quickwizard.svg b/_docs/icons/quickwizard.svg similarity index 100% rename from icons/quickwizard.svg rename to _docs/icons/quickwizard.svg diff --git a/icons/remove.svg b/_docs/icons/remove.svg similarity index 100% rename from icons/remove.svg rename to _docs/icons/remove.svg diff --git a/icons/reset_database.svg b/_docs/icons/reset_database.svg similarity index 100% rename from icons/reset_database.svg rename to _docs/icons/reset_database.svg diff --git a/icons/send_log.svg b/_docs/icons/send_log.svg similarity index 100% rename from icons/send_log.svg rename to _docs/icons/send_log.svg diff --git a/icons/setting_off.svg b/_docs/icons/setting_off.svg similarity index 100% rename from icons/setting_off.svg rename to _docs/icons/setting_off.svg diff --git a/icons/setting_on.svg b/_docs/icons/setting_on.svg similarity index 100% rename from icons/setting_on.svg rename to _docs/icons/setting_on.svg diff --git a/icons/target_activity.svg b/_docs/icons/target_activity.svg similarity index 100% rename from icons/target_activity.svg rename to _docs/icons/target_activity.svg diff --git a/icons/target_cancel.svg b/_docs/icons/target_cancel.svg similarity index 100% rename from icons/target_cancel.svg rename to _docs/icons/target_cancel.svg diff --git a/icons/target_eatingsoon.svg b/_docs/icons/target_eatingsoon.svg similarity index 100% rename from icons/target_eatingsoon.svg rename to _docs/icons/target_eatingsoon.svg diff --git a/icons/target_hypo.svg b/_docs/icons/target_hypo.svg similarity index 100% rename from icons/target_hypo.svg rename to _docs/icons/target_hypo.svg diff --git a/icons/target_manual.svg b/_docs/icons/target_manual.svg similarity index 100% rename from icons/target_manual.svg rename to _docs/icons/target_manual.svg diff --git a/icons/temp-basal/icon_cp_basal_100px.psd b/_docs/icons/temp-basal/icon_cp_basal_100px.psd similarity index 100% rename from icons/temp-basal/icon_cp_basal_100px.psd rename to _docs/icons/temp-basal/icon_cp_basal_100px.psd diff --git a/icons/temp-basal/icon_cp_basal_150px.psd b/_docs/icons/temp-basal/icon_cp_basal_150px.psd similarity index 100% rename from icons/temp-basal/icon_cp_basal_150px.psd rename to _docs/icons/temp-basal/icon_cp_basal_150px.psd diff --git a/icons/temp-basal/icon_cp_basal_200px.psd b/_docs/icons/temp-basal/icon_cp_basal_200px.psd similarity index 100% rename from icons/temp-basal/icon_cp_basal_200px.psd rename to _docs/icons/temp-basal/icon_cp_basal_200px.psd diff --git a/icons/temp-basal/icon_cp_basal_50px.psd b/_docs/icons/temp-basal/icon_cp_basal_50px.psd similarity index 100% rename from icons/temp-basal/icon_cp_basal_50px.psd rename to _docs/icons/temp-basal/icon_cp_basal_50px.psd diff --git a/icons/temp-basal/icon_cp_basal_75px.psd b/_docs/icons/temp-basal/icon_cp_basal_75px.psd similarity index 100% rename from icons/temp-basal/icon_cp_basal_75px.psd rename to _docs/icons/temp-basal/icon_cp_basal_75px.psd diff --git a/icons/temptarget_flat.svg b/_docs/icons/temptarget_flat.svg similarity index 100% rename from icons/temptarget_flat.svg rename to _docs/icons/temptarget_flat.svg diff --git a/icons/temptarget_high.svg b/_docs/icons/temptarget_high.svg similarity index 100% rename from icons/temptarget_high.svg rename to _docs/icons/temptarget_high.svg diff --git a/icons/temptarget_low.svg b/_docs/icons/temptarget_low.svg similarity index 100% rename from icons/temptarget_low.svg rename to _docs/icons/temptarget_low.svg diff --git a/icons/veo.svg b/_docs/icons/veo.svg similarity index 100% rename from icons/veo.svg rename to _docs/icons/veo.svg diff --git a/icons/visibility.svg b/_docs/icons/visibility.svg similarity index 100% rename from icons/visibility.svg rename to _docs/icons/visibility.svg diff --git a/icons/x_swap_vert.svg b/_docs/icons/x_swap_vert.svg similarity index 100% rename from icons/x_swap_vert.svg rename to _docs/icons/x_swap_vert.svg diff --git a/icons/xdrip.svg b/_docs/icons/xdrip.svg similarity index 100% rename from icons/xdrip.svg rename to _docs/icons/xdrip.svg diff --git a/logo/androiaps.eps b/_docs/logo/androiaps.eps similarity index 100% rename from logo/androiaps.eps rename to _docs/logo/androiaps.eps diff --git a/logo/androiaps_tshirt.pdf b/_docs/logo/androiaps_tshirt.pdf similarity index 100% rename from logo/androiaps_tshirt.pdf rename to _docs/logo/androiaps_tshirt.pdf diff --git a/logo/androidaps.ai b/_docs/logo/androidaps.ai similarity index 100% rename from logo/androidaps.ai rename to _docs/logo/androidaps.ai diff --git a/logo/androidaps.pdf b/_docs/logo/androidaps.pdf similarity index 100% rename from logo/androidaps.pdf rename to _docs/logo/androidaps.pdf diff --git a/logo/androidaps2.ai b/_docs/logo/androidaps2.ai similarity index 100% rename from logo/androidaps2.ai rename to _docs/logo/androidaps2.ai diff --git a/logo/androidaps2.pdf b/_docs/logo/androidaps2.pdf similarity index 100% rename from logo/androidaps2.pdf rename to _docs/logo/androidaps2.pdf diff --git a/logo/background-01.svg b/_docs/logo/background-01.svg similarity index 100% rename from logo/background-01.svg rename to _docs/logo/background-01.svg diff --git a/logo/background.ai b/_docs/logo/background.ai similarity index 100% rename from logo/background.ai rename to _docs/logo/background.ai diff --git a/logo/background.pdf b/_docs/logo/background.pdf similarity index 100% rename from logo/background.pdf rename to _docs/logo/background.pdf diff --git a/logo/blueowl-web.png b/_docs/logo/blueowl-web.png similarity index 100% rename from logo/blueowl-web.png rename to _docs/logo/blueowl-web.png diff --git a/logo/drawing.png b/_docs/logo/drawing.png similarity index 100% rename from logo/drawing.png rename to _docs/logo/drawing.png diff --git a/logo/drawing.svg b/_docs/logo/drawing.svg similarity index 100% rename from logo/drawing.svg rename to _docs/logo/drawing.svg diff --git a/logo/ic_launcher-web.png b/_docs/logo/ic_launcher-web.png similarity index 100% rename from logo/ic_launcher-web.png rename to _docs/logo/ic_launcher-web.png diff --git a/logo/ic_launcher_round-web.png b/_docs/logo/ic_launcher_round-web.png similarity index 100% rename from logo/ic_launcher_round-web.png rename to _docs/logo/ic_launcher_round-web.png diff --git a/logo/icons.ai b/_docs/logo/icons.ai similarity index 100% rename from logo/icons.ai rename to _docs/logo/icons.ai diff --git a/logo/icons.pdf b/_docs/logo/icons.pdf similarity index 100% rename from logo/icons.pdf rename to _docs/logo/icons.pdf diff --git a/logo/icons.svg b/_docs/logo/icons.svg similarity index 100% rename from logo/icons.svg rename to _docs/logo/icons.svg diff --git a/logo/logo.md b/_docs/logo/logo.md similarity index 100% rename from logo/logo.md rename to _docs/logo/logo.md diff --git a/logo/logo_androidaps.ai b/_docs/logo/logo_androidaps.ai similarity index 100% rename from logo/logo_androidaps.ai rename to _docs/logo/logo_androidaps.ai diff --git a/logo/logo_androidaps.pdf b/_docs/logo/logo_androidaps.pdf similarity index 100% rename from logo/logo_androidaps.pdf rename to _docs/logo/logo_androidaps.pdf diff --git a/logo/logo_androidaps.svg b/_docs/logo/logo_androidaps.svg similarity index 100% rename from logo/logo_androidaps.svg rename to _docs/logo/logo_androidaps.svg diff --git a/logo/logoanaps.png b/_docs/logo/logoanaps.png similarity index 100% rename from logo/logoanaps.png rename to _docs/logo/logoanaps.png diff --git a/logo/notif_icon.png b/_docs/logo/notif_icon.png similarity index 100% rename from logo/notif_icon.png rename to _docs/logo/notif_icon.png diff --git a/logo/notificationdot.png b/_docs/logo/notificationdot.png similarity index 100% rename from logo/notificationdot.png rename to _docs/logo/notificationdot.png diff --git a/logo/notificationdot2.png b/_docs/logo/notificationdot2.png similarity index 100% rename from logo/notificationdot2.png rename to _docs/logo/notificationdot2.png diff --git a/logo/nsclient/white.png b/_docs/logo/nsclient/white.png similarity index 100% rename from logo/nsclient/white.png rename to _docs/logo/nsclient/white.png diff --git a/logo/old/AndroidAPS Icon.ai b/_docs/logo/old/AndroidAPS Icon.ai similarity index 100% rename from logo/old/AndroidAPS Icon.ai rename to _docs/logo/old/AndroidAPS Icon.ai diff --git a/logo/old/AndroidAPS Icon.png b/_docs/logo/old/AndroidAPS Icon.png similarity index 100% rename from logo/old/AndroidAPS Icon.png rename to _docs/logo/old/AndroidAPS Icon.png diff --git a/logo/pattern.ai b/_docs/logo/pattern.ai similarity index 100% rename from logo/pattern.ai rename to _docs/logo/pattern.ai diff --git a/logo/pattern.pdf b/_docs/logo/pattern.pdf similarity index 100% rename from logo/pattern.pdf rename to _docs/logo/pattern.pdf diff --git a/logo/pattern.svg b/_docs/logo/pattern.svg similarity index 100% rename from logo/pattern.svg rename to _docs/logo/pattern.svg diff --git a/logo/screenshot.png b/_docs/logo/screenshot.png similarity index 100% rename from logo/screenshot.png rename to _docs/logo/screenshot.png diff --git a/logo/tshirt.png b/_docs/logo/tshirt.png similarity index 100% rename from logo/tshirt.png rename to _docs/logo/tshirt.png diff --git a/revoking_leaked_apks.md b/_docs/revoking_leaked_apks.md similarity index 100% rename from revoking_leaked_apks.md rename to _docs/revoking_leaked_apks.md diff --git a/app/build.gradle b/app/build.gradle index 572f6c08a8..cb0f5ceac0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -179,20 +179,20 @@ dependencies { implementation project(':ui') implementation project(':plugins') implementation project(':implementation') - implementation project(':automation') - implementation project(':combo') implementation project(':database') - implementation project(':dana') - implementation project(':danars') - implementation project(':danar') + implementation project(':pump:combo') + implementation project(':pump:dana') + implementation project(':pump:danars') + implementation project(':pump:danar') + implementation project(':pump:diaconn') implementation project(':insight') - implementation project(':pump-common') - implementation project(':rileylink') - implementation project(':medtronic') - implementation project(':omnipod-common') - implementation project(':omnipod-eros') - implementation project(':omnipod-dash') - implementation project(':diaconn') + implementation project(':pump:medtronic') + implementation project(':pump:pump-common') + implementation project(':pump:rileylink') + implementation project(':pump:omnipod-common') + implementation project(':pump:omnipod-eros') + implementation project(':pump:omnipod-dash') + implementation project(':automation') implementation project(':openhumans') implementation fileTree(include: ['*.jar'], dir: 'libs') diff --git a/crowdin.yml b/crowdin.yml index 684c1c27fc..8badd8004e 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -15,22 +15,22 @@ files: translation: /core/src/main/res/values-%android_code%/strings.xml - source: /shared/src/main/res/values/strings.xml translation: /shared/src/main/res/values-%android_code%/strings.xml - - source: /combo/src/main/res/values/strings.xml - translation: /combo/src/main/res/values-%android_code%/strings.xml - - source: /dana/src/main/res/values/strings.xml - translation: /dana/src/main/res/values-%android_code%/strings.xml - - source: /danar/src/main/res/values/strings.xml - translation: /danar/src/main/res/values-%android_code%/strings.xml - - source: /medtronic/src/main/res/values/strings.xml - translation: /medtronic/src/main/res/values-%android_code%/strings.xml - - source: /omnipod-common/src/main/res/values/strings.xml - translation: /omnipod-common/src/main/res/values-%android_code%/strings.xml - - source: /omnipod-dash/src/main/res/values/strings.xml - translation: /omnipod-dash/src/main/res/values-%android_code%/strings.xml - - source: /omnipod-eros/src/main/res/values/strings.xml - translation: /omnipod-eros/src/main/res/values-%android_code%/strings.xml - - source: /rileylink/src/main/res/values/strings.xml - translation: /rileylink/src/main/res/values-%android_code%/strings.xml + - source: /pump/combo/src/main/res/values/strings.xml + translation: /pump//combo/src/main/res/values-%android_code%/strings.xml + - source: /pump/dana/src/main/res/values/strings.xml + translation: /pump/dana/src/main/res/values-%android_code%/strings.xml + - source: /pump/danar/src/main/res/values/strings.xml + translation: /pump/danar/src/main/res/values-%android_code%/strings.xml + - source: /pump/medtronic/src/main/res/values/strings.xml + translation: /pump/medtronic/src/main/res/values-%android_code%/strings.xml + - source: /pump/omnipod-common/src/main/res/values/strings.xml + translation: /pump/omnipod-common/src/main/res/values-%android_code%/strings.xml + - source: /pump/omnipod-dash/src/main/res/values/strings.xml + translation: /pump/omnipod-dash/src/main/res/values-%android_code%/strings.xml + - source: /pump/omnipod-eros/src/main/res/values/strings.xml + translation: /pump/omnipod-eros/src/main/res/values-%android_code%/strings.xml + - source: /pump/rileylink/src/main/res/values/strings.xml + translation: /pump/rileylink/src/main/res/values-%android_code%/strings.xml - source: /insight/src/main/res/values/strings.xml translation: /insight/src/main/res/values-%android_code%/strings.xml - source: /insight/src/main/res/values/alert_codes.xml @@ -43,10 +43,10 @@ files: translation: /insight/src/main/res/values-%android_code%/exceptions.xml - source: /automation/src/main/res/values/strings.xml translation: /automation/src/main/res/values-%android_code%/strings.xml - - source: /diaconn/src/main/res/values/strings.xml - translation: /diaconn/src/main/res/values-%android_code%/strings.xml - - source: /pump-common/src/main/res/values/strings.xml - translation: /pump-common/src/main/res/values-%android_code%/strings.xml + - source: /pump/diaconn/src/main/res/values/strings.xml + translation: /pump/diaconn/src/main/res/values-%android_code%/strings.xml + - source: /pump/pump-common/src/main/res/values/strings.xml + translation: /pump/pump-common/src/main/res/values-%android_code%/strings.xml - source: /openhumans/src/main/res/values/strings.xml translation: /openhumans/src/main/res/values-%android_code%/strings.xml - source: /implementation/src/main/res/values/strings.xml diff --git a/insight/build.gradle b/insight/build.gradle index 5e69a77ba6..e81e5f65b8 100644 --- a/insight/build.gradle +++ b/insight/build.gradle @@ -23,9 +23,10 @@ android { } dependencies { + implementation project(':core') implementation project(':shared') - implementation project(':pump-common') + implementation project(':pump:pump-common') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/combo/.gitignore b/pump/combo/.gitignore similarity index 100% rename from combo/.gitignore rename to pump/combo/.gitignore diff --git a/combo/build.gradle b/pump/combo/build.gradle similarity index 100% rename from combo/build.gradle rename to pump/combo/build.gradle diff --git a/combo/consumer-rules.pro b/pump/combo/consumer-rules.pro similarity index 100% rename from combo/consumer-rules.pro rename to pump/combo/consumer-rules.pro diff --git a/combo/proguard-rules.pro b/pump/combo/proguard-rules.pro similarity index 100% rename from combo/proguard-rules.pro rename to pump/combo/proguard-rules.pro diff --git a/combo/src/main/AndroidManifest.xml b/pump/combo/src/main/AndroidManifest.xml similarity index 100% rename from combo/src/main/AndroidManifest.xml rename to pump/combo/src/main/AndroidManifest.xml diff --git a/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRTHandler.aidl b/pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRTHandler.aidl similarity index 100% rename from combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRTHandler.aidl rename to pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRTHandler.aidl diff --git a/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRuffyService.aidl b/pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRuffyService.aidl similarity index 100% rename from combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRuffyService.aidl rename to pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/IRuffyService.aidl diff --git a/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/display/Menu.aidl b/pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/display/Menu.aidl similarity index 100% rename from combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/display/Menu.aidl rename to pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/display/Menu.aidl diff --git a/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/package-info.java b/pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/package-info.java similarity index 100% rename from combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/package-info.java rename to pump/combo/src/main/aidl/org/monkey/d/ruffy/ruffy/driver/package-info.java diff --git a/combo/src/main/java/info/nightscout/androidaps/combo/di/ComboActivitiesModule.kt b/pump/combo/src/main/java/info/nightscout/androidaps/combo/di/ComboActivitiesModule.kt similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/combo/di/ComboActivitiesModule.kt rename to pump/combo/src/main/java/info/nightscout/androidaps/combo/di/ComboActivitiesModule.kt diff --git a/combo/src/main/java/info/nightscout/androidaps/combo/di/ComboModule.kt b/pump/combo/src/main/java/info/nightscout/androidaps/combo/di/ComboModule.kt similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/combo/di/ComboModule.kt rename to pump/combo/src/main/java/info/nightscout/androidaps/combo/di/ComboModule.kt diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboFragment.kt b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboFragment.kt similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboFragment.kt rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboFragment.kt diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPump.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPump.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPump.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPump.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/data/ComboErrorUtil.kt b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/data/ComboErrorUtil.kt similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/data/ComboErrorUtil.kt rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/data/ComboErrorUtil.kt diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/events/EventComboPumpUpdateGUI.kt b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/events/EventComboPumpUpdateGUI.kt similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/events/EventComboPumpUpdateGUI.kt rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/events/EventComboPumpUpdateGUI.kt diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BasalProfile.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BasalProfile.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BasalProfile.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BasalProfile.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BolusProgressReporter.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BolusProgressReporter.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BolusProgressReporter.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/BolusProgressReporter.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/CommandResult.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/CommandResult.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/CommandResult.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/CommandResult.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpErrorCodes.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpErrorCodes.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpErrorCodes.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpErrorCodes.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpState.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpState.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpState.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpState.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpWarningCodes.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpWarningCodes.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpWarningCodes.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/PumpWarningCodes.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyCommands.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyCommands.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyCommands.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyCommands.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyScripter.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyScripter.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyScripter.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/RuffyScripter.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/WarningOrErrorCode.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/WarningOrErrorCode.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/WarningOrErrorCode.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/WarningOrErrorCode.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BaseCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BaseCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BaseCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BaseCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BolusCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BolusCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BolusCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/BolusCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CancelTbrCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CancelTbrCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CancelTbrCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CancelTbrCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/Command.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/Command.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/Command.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/Command.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CommandException.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CommandException.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CommandException.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/CommandException.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ConfirmAlertCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ConfirmAlertCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ConfirmAlertCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ConfirmAlertCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadBasalProfileCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadBasalProfileCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadBasalProfileCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadBasalProfileCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadHistoryCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadHistoryCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadHistoryCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadHistoryCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadPumpStateCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadPumpStateCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadPumpStateCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadPumpStateCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadQuickInfoCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadQuickInfoCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadQuickInfoCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/ReadQuickInfoCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetBasalProfileCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetBasalProfileCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetBasalProfileCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetBasalProfileCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetTbrCommand.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetTbrCommand.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetTbrCommand.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/commands/SetTbrCommand.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Bolus.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Bolus.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Bolus.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Bolus.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/HistoryRecord.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/HistoryRecord.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/HistoryRecord.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/HistoryRecord.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpAlert.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpAlert.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpAlert.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpAlert.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistory.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistory.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistory.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistory.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistoryRequest.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistoryRequest.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistoryRequest.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/PumpHistoryRequest.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tbr.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tbr.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tbr.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tbr.java diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tdd.java b/pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tdd.java similarity index 100% rename from combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tdd.java rename to pump/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ruffyscripter/history/Tdd.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/Menu.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/Menu.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/Menu.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/Menu.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuAttribute.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuAttribute.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuAttribute.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuAttribute.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuType.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuType.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuType.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/MenuType.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/BolusType.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/BolusType.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/BolusType.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/BolusType.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuBlink.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuBlink.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuBlink.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuBlink.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuDate.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuDate.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuDate.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuDate.java diff --git a/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuTime.java b/pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuTime.java similarity index 100% rename from combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuTime.java rename to pump/combo/src/main/java/org/monkey/d/ruffy/ruffy/driver/display/menu/MenuTime.java diff --git a/combo/src/main/res/drawable/ic_combo.xml b/pump/combo/src/main/res/drawable/ic_combo.xml similarity index 100% rename from combo/src/main/res/drawable/ic_combo.xml rename to pump/combo/src/main/res/drawable/ic_combo.xml diff --git a/combo/src/main/res/layout/combopump_fragment.xml b/pump/combo/src/main/res/layout/combopump_fragment.xml similarity index 100% rename from combo/src/main/res/layout/combopump_fragment.xml rename to pump/combo/src/main/res/layout/combopump_fragment.xml diff --git a/combo/src/main/res/values-af-rZA/strings.xml b/pump/combo/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from combo/src/main/res/values-af-rZA/strings.xml rename to pump/combo/src/main/res/values-af-rZA/strings.xml diff --git a/combo/src/main/res/values-bg-rBG/strings.xml b/pump/combo/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from combo/src/main/res/values-bg-rBG/strings.xml rename to pump/combo/src/main/res/values-bg-rBG/strings.xml diff --git a/combo/src/main/res/values-ca-rES/strings.xml b/pump/combo/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from combo/src/main/res/values-ca-rES/strings.xml rename to pump/combo/src/main/res/values-ca-rES/strings.xml diff --git a/combo/src/main/res/values-cs-rCZ/strings.xml b/pump/combo/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from combo/src/main/res/values-cs-rCZ/strings.xml rename to pump/combo/src/main/res/values-cs-rCZ/strings.xml diff --git a/combo/src/main/res/values-da-rDK/strings.xml b/pump/combo/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from combo/src/main/res/values-da-rDK/strings.xml rename to pump/combo/src/main/res/values-da-rDK/strings.xml diff --git a/combo/src/main/res/values-de-rDE/strings.xml b/pump/combo/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from combo/src/main/res/values-de-rDE/strings.xml rename to pump/combo/src/main/res/values-de-rDE/strings.xml diff --git a/combo/src/main/res/values-el-rGR/strings.xml b/pump/combo/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from combo/src/main/res/values-el-rGR/strings.xml rename to pump/combo/src/main/res/values-el-rGR/strings.xml diff --git a/combo/src/main/res/values-es-rES/strings.xml b/pump/combo/src/main/res/values-es-rES/strings.xml similarity index 100% rename from combo/src/main/res/values-es-rES/strings.xml rename to pump/combo/src/main/res/values-es-rES/strings.xml diff --git a/combo/src/main/res/values-fr-rFR/strings.xml b/pump/combo/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from combo/src/main/res/values-fr-rFR/strings.xml rename to pump/combo/src/main/res/values-fr-rFR/strings.xml diff --git a/combo/src/main/res/values-ga-rIE/strings.xml b/pump/combo/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from combo/src/main/res/values-ga-rIE/strings.xml rename to pump/combo/src/main/res/values-ga-rIE/strings.xml diff --git a/combo/src/main/res/values-hr-rHR/strings.xml b/pump/combo/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from combo/src/main/res/values-hr-rHR/strings.xml rename to pump/combo/src/main/res/values-hr-rHR/strings.xml diff --git a/combo/src/main/res/values-hu-rHU/strings.xml b/pump/combo/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from combo/src/main/res/values-hu-rHU/strings.xml rename to pump/combo/src/main/res/values-hu-rHU/strings.xml diff --git a/combo/src/main/res/values-it-rIT/strings.xml b/pump/combo/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from combo/src/main/res/values-it-rIT/strings.xml rename to pump/combo/src/main/res/values-it-rIT/strings.xml diff --git a/combo/src/main/res/values-iw-rIL/strings.xml b/pump/combo/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from combo/src/main/res/values-iw-rIL/strings.xml rename to pump/combo/src/main/res/values-iw-rIL/strings.xml diff --git a/combo/src/main/res/values-ko-rKR/strings.xml b/pump/combo/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from combo/src/main/res/values-ko-rKR/strings.xml rename to pump/combo/src/main/res/values-ko-rKR/strings.xml diff --git a/combo/src/main/res/values-lt-rLT/strings.xml b/pump/combo/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from combo/src/main/res/values-lt-rLT/strings.xml rename to pump/combo/src/main/res/values-lt-rLT/strings.xml diff --git a/combo/src/main/res/values-nl-rNL/strings.xml b/pump/combo/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from combo/src/main/res/values-nl-rNL/strings.xml rename to pump/combo/src/main/res/values-nl-rNL/strings.xml diff --git a/combo/src/main/res/values-no-rNO/strings.xml b/pump/combo/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from combo/src/main/res/values-no-rNO/strings.xml rename to pump/combo/src/main/res/values-no-rNO/strings.xml diff --git a/combo/src/main/res/values-pl-rPL/strings.xml b/pump/combo/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from combo/src/main/res/values-pl-rPL/strings.xml rename to pump/combo/src/main/res/values-pl-rPL/strings.xml diff --git a/combo/src/main/res/values-pt-rBR/strings.xml b/pump/combo/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from combo/src/main/res/values-pt-rBR/strings.xml rename to pump/combo/src/main/res/values-pt-rBR/strings.xml diff --git a/combo/src/main/res/values-pt-rPT/strings.xml b/pump/combo/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from combo/src/main/res/values-pt-rPT/strings.xml rename to pump/combo/src/main/res/values-pt-rPT/strings.xml diff --git a/combo/src/main/res/values-ro-rRO/strings.xml b/pump/combo/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from combo/src/main/res/values-ro-rRO/strings.xml rename to pump/combo/src/main/res/values-ro-rRO/strings.xml diff --git a/combo/src/main/res/values-ru-rRU/strings.xml b/pump/combo/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from combo/src/main/res/values-ru-rRU/strings.xml rename to pump/combo/src/main/res/values-ru-rRU/strings.xml diff --git a/combo/src/main/res/values-sk-rSK/strings.xml b/pump/combo/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from combo/src/main/res/values-sk-rSK/strings.xml rename to pump/combo/src/main/res/values-sk-rSK/strings.xml diff --git a/combo/src/main/res/values-sl-rSI/strings.xml b/pump/combo/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from combo/src/main/res/values-sl-rSI/strings.xml rename to pump/combo/src/main/res/values-sl-rSI/strings.xml diff --git a/combo/src/main/res/values-sr-rCS/strings.xml b/pump/combo/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from combo/src/main/res/values-sr-rCS/strings.xml rename to pump/combo/src/main/res/values-sr-rCS/strings.xml diff --git a/combo/src/main/res/values-sv-rSE/strings.xml b/pump/combo/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from combo/src/main/res/values-sv-rSE/strings.xml rename to pump/combo/src/main/res/values-sv-rSE/strings.xml diff --git a/combo/src/main/res/values-ta-rIN/strings.xml b/pump/combo/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from combo/src/main/res/values-ta-rIN/strings.xml rename to pump/combo/src/main/res/values-ta-rIN/strings.xml diff --git a/combo/src/main/res/values-tr-rTR/strings.xml b/pump/combo/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from combo/src/main/res/values-tr-rTR/strings.xml rename to pump/combo/src/main/res/values-tr-rTR/strings.xml diff --git a/combo/src/main/res/values-zh-rCN/strings.xml b/pump/combo/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from combo/src/main/res/values-zh-rCN/strings.xml rename to pump/combo/src/main/res/values-zh-rCN/strings.xml diff --git a/combo/src/main/res/values/arrays.xml b/pump/combo/src/main/res/values/arrays.xml old mode 100755 new mode 100644 similarity index 100% rename from combo/src/main/res/values/arrays.xml rename to pump/combo/src/main/res/values/arrays.xml diff --git a/combo/src/main/res/values/strings.xml b/pump/combo/src/main/res/values/strings.xml similarity index 100% rename from combo/src/main/res/values/strings.xml rename to pump/combo/src/main/res/values/strings.xml diff --git a/combo/src/main/res/xml/pref_combo.xml b/pump/combo/src/main/res/xml/pref_combo.xml old mode 100755 new mode 100644 similarity index 100% rename from combo/src/main/res/xml/pref_combo.xml rename to pump/combo/src/main/res/xml/pref_combo.xml diff --git a/combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/ComboPluginTest.kt b/pump/combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/ComboPluginTest.kt similarity index 100% rename from combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/ComboPluginTest.kt rename to pump/combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/ComboPluginTest.kt diff --git a/combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/TestBase.kt b/pump/combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/TestBase.kt similarity index 100% rename from combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/TestBase.kt rename to pump/combo/src/test/java/info/nightscout/androidaps/plugins/pump/combo/TestBase.kt diff --git a/dana/.gitignore b/pump/dana/.gitignore similarity index 100% rename from dana/.gitignore rename to pump/dana/.gitignore diff --git a/dana/build.gradle b/pump/dana/build.gradle similarity index 100% rename from dana/build.gradle rename to pump/dana/build.gradle diff --git a/dana/consumer-rules.pro b/pump/dana/consumer-rules.pro similarity index 100% rename from dana/consumer-rules.pro rename to pump/dana/consumer-rules.pro diff --git a/dana/proguard-rules.pro b/pump/dana/proguard-rules.pro similarity index 100% rename from dana/proguard-rules.pro rename to pump/dana/proguard-rules.pro diff --git a/dana/schemas/info.nightscout.androidaps.dana.database.DanaHistoryDatabase/1.json b/pump/dana/schemas/info.nightscout.androidaps.dana.database.DanaHistoryDatabase/1.json similarity index 100% rename from dana/schemas/info.nightscout.androidaps.dana.database.DanaHistoryDatabase/1.json rename to pump/dana/schemas/info.nightscout.androidaps.dana.database.DanaHistoryDatabase/1.json diff --git a/dana/src/main/AndroidManifest.xml b/pump/dana/src/main/AndroidManifest.xml similarity index 100% rename from dana/src/main/AndroidManifest.xml rename to pump/dana/src/main/AndroidManifest.xml diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/comm/RecordTypes.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/comm/RecordTypes.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/comm/RecordTypes.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/comm/RecordTypes.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryDatabase.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryDatabase.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryDatabase.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryDatabase.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecord.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecord.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecord.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecord.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecordDao.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecordDao.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecordDao.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/database/DanaHistoryRecordDao.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/di/DanaHistoryModule.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/di/DanaHistoryModule.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/di/DanaHistoryModule.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/di/DanaHistoryModule.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/di/DanaModule.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/di/DanaModule.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/di/DanaModule.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/di/DanaModule.kt diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/events/EventDanaRNewStatus.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/events/EventDanaRNewStatus.kt similarity index 100% rename from dana/src/main/java/info/nightscout/androidaps/dana/events/EventDanaRNewStatus.kt rename to pump/dana/src/main/java/info/nightscout/androidaps/dana/events/EventDanaRNewStatus.kt diff --git a/dana/src/main/res/drawable/ic_dana_i.xml b/pump/dana/src/main/res/drawable/ic_dana_i.xml similarity index 100% rename from dana/src/main/res/drawable/ic_dana_i.xml rename to pump/dana/src/main/res/drawable/ic_dana_i.xml diff --git a/dana/src/main/res/drawable/ic_dana_rs.xml b/pump/dana/src/main/res/drawable/ic_dana_rs.xml similarity index 100% rename from dana/src/main/res/drawable/ic_dana_rs.xml rename to pump/dana/src/main/res/drawable/ic_dana_rs.xml diff --git a/dana/src/main/res/layout/danar_fragment.xml b/pump/dana/src/main/res/layout/danar_fragment.xml similarity index 100% rename from dana/src/main/res/layout/danar_fragment.xml rename to pump/dana/src/main/res/layout/danar_fragment.xml diff --git a/dana/src/main/res/layout/danar_history_activity.xml b/pump/dana/src/main/res/layout/danar_history_activity.xml similarity index 100% rename from dana/src/main/res/layout/danar_history_activity.xml rename to pump/dana/src/main/res/layout/danar_history_activity.xml diff --git a/dana/src/main/res/layout/danar_history_item.xml b/pump/dana/src/main/res/layout/danar_history_item.xml similarity index 100% rename from dana/src/main/res/layout/danar_history_item.xml rename to pump/dana/src/main/res/layout/danar_history_item.xml diff --git a/dana/src/main/res/layout/danar_user_options_activity.xml b/pump/dana/src/main/res/layout/danar_user_options_activity.xml similarity index 100% rename from dana/src/main/res/layout/danar_user_options_activity.xml rename to pump/dana/src/main/res/layout/danar_user_options_activity.xml diff --git a/dana/src/main/res/values-af-rZA/strings.xml b/pump/dana/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from dana/src/main/res/values-af-rZA/strings.xml rename to pump/dana/src/main/res/values-af-rZA/strings.xml diff --git a/dana/src/main/res/values-ar-rSA/strings.xml b/pump/dana/src/main/res/values-ar-rSA/strings.xml similarity index 100% rename from dana/src/main/res/values-ar-rSA/strings.xml rename to pump/dana/src/main/res/values-ar-rSA/strings.xml diff --git a/dana/src/main/res/values-bg-rBG/strings.xml b/pump/dana/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from dana/src/main/res/values-bg-rBG/strings.xml rename to pump/dana/src/main/res/values-bg-rBG/strings.xml diff --git a/dana/src/main/res/values-ca-rES/strings.xml b/pump/dana/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from dana/src/main/res/values-ca-rES/strings.xml rename to pump/dana/src/main/res/values-ca-rES/strings.xml diff --git a/dana/src/main/res/values-cs-rCZ/strings.xml b/pump/dana/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from dana/src/main/res/values-cs-rCZ/strings.xml rename to pump/dana/src/main/res/values-cs-rCZ/strings.xml diff --git a/dana/src/main/res/values-cy-rGB/strings.xml b/pump/dana/src/main/res/values-cy-rGB/strings.xml similarity index 100% rename from dana/src/main/res/values-cy-rGB/strings.xml rename to pump/dana/src/main/res/values-cy-rGB/strings.xml diff --git a/dana/src/main/res/values-da-rDK/strings.xml b/pump/dana/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from dana/src/main/res/values-da-rDK/strings.xml rename to pump/dana/src/main/res/values-da-rDK/strings.xml diff --git a/dana/src/main/res/values-de-rDE/strings.xml b/pump/dana/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from dana/src/main/res/values-de-rDE/strings.xml rename to pump/dana/src/main/res/values-de-rDE/strings.xml diff --git a/dana/src/main/res/values-el-rGR/strings.xml b/pump/dana/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from dana/src/main/res/values-el-rGR/strings.xml rename to pump/dana/src/main/res/values-el-rGR/strings.xml diff --git a/dana/src/main/res/values-es-rES/strings.xml b/pump/dana/src/main/res/values-es-rES/strings.xml similarity index 100% rename from dana/src/main/res/values-es-rES/strings.xml rename to pump/dana/src/main/res/values-es-rES/strings.xml diff --git a/dana/src/main/res/values-fi-rFI/strings.xml b/pump/dana/src/main/res/values-fi-rFI/strings.xml similarity index 100% rename from dana/src/main/res/values-fi-rFI/strings.xml rename to pump/dana/src/main/res/values-fi-rFI/strings.xml diff --git a/dana/src/main/res/values-fr-rFR/strings.xml b/pump/dana/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from dana/src/main/res/values-fr-rFR/strings.xml rename to pump/dana/src/main/res/values-fr-rFR/strings.xml diff --git a/dana/src/main/res/values-ga-rIE/strings.xml b/pump/dana/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from dana/src/main/res/values-ga-rIE/strings.xml rename to pump/dana/src/main/res/values-ga-rIE/strings.xml diff --git a/dana/src/main/res/values-hr-rHR/strings.xml b/pump/dana/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from dana/src/main/res/values-hr-rHR/strings.xml rename to pump/dana/src/main/res/values-hr-rHR/strings.xml diff --git a/dana/src/main/res/values-hu-rHU/strings.xml b/pump/dana/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from dana/src/main/res/values-hu-rHU/strings.xml rename to pump/dana/src/main/res/values-hu-rHU/strings.xml diff --git a/dana/src/main/res/values-it-rIT/strings.xml b/pump/dana/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from dana/src/main/res/values-it-rIT/strings.xml rename to pump/dana/src/main/res/values-it-rIT/strings.xml diff --git a/dana/src/main/res/values-iw-rIL/strings.xml b/pump/dana/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from dana/src/main/res/values-iw-rIL/strings.xml rename to pump/dana/src/main/res/values-iw-rIL/strings.xml diff --git a/dana/src/main/res/values-ja-rJP/strings.xml b/pump/dana/src/main/res/values-ja-rJP/strings.xml similarity index 100% rename from dana/src/main/res/values-ja-rJP/strings.xml rename to pump/dana/src/main/res/values-ja-rJP/strings.xml diff --git a/dana/src/main/res/values-ko-rKR/strings.xml b/pump/dana/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from dana/src/main/res/values-ko-rKR/strings.xml rename to pump/dana/src/main/res/values-ko-rKR/strings.xml diff --git a/dana/src/main/res/values-lt-rLT/strings.xml b/pump/dana/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from dana/src/main/res/values-lt-rLT/strings.xml rename to pump/dana/src/main/res/values-lt-rLT/strings.xml diff --git a/dana/src/main/res/values-nl-rNL/strings.xml b/pump/dana/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from dana/src/main/res/values-nl-rNL/strings.xml rename to pump/dana/src/main/res/values-nl-rNL/strings.xml diff --git a/dana/src/main/res/values-no-rNO/strings.xml b/pump/dana/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from dana/src/main/res/values-no-rNO/strings.xml rename to pump/dana/src/main/res/values-no-rNO/strings.xml diff --git a/dana/src/main/res/values-pl-rPL/strings.xml b/pump/dana/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from dana/src/main/res/values-pl-rPL/strings.xml rename to pump/dana/src/main/res/values-pl-rPL/strings.xml diff --git a/dana/src/main/res/values-pt-rBR/strings.xml b/pump/dana/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from dana/src/main/res/values-pt-rBR/strings.xml rename to pump/dana/src/main/res/values-pt-rBR/strings.xml diff --git a/dana/src/main/res/values-pt-rPT/strings.xml b/pump/dana/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from dana/src/main/res/values-pt-rPT/strings.xml rename to pump/dana/src/main/res/values-pt-rPT/strings.xml diff --git a/dana/src/main/res/values-ro-rRO/strings.xml b/pump/dana/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from dana/src/main/res/values-ro-rRO/strings.xml rename to pump/dana/src/main/res/values-ro-rRO/strings.xml diff --git a/dana/src/main/res/values-ru-rRU/strings.xml b/pump/dana/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from dana/src/main/res/values-ru-rRU/strings.xml rename to pump/dana/src/main/res/values-ru-rRU/strings.xml diff --git a/dana/src/main/res/values-sk-rSK/strings.xml b/pump/dana/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from dana/src/main/res/values-sk-rSK/strings.xml rename to pump/dana/src/main/res/values-sk-rSK/strings.xml diff --git a/dana/src/main/res/values-sl-rSI/strings.xml b/pump/dana/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from dana/src/main/res/values-sl-rSI/strings.xml rename to pump/dana/src/main/res/values-sl-rSI/strings.xml diff --git a/dana/src/main/res/values-sr-rCS/strings.xml b/pump/dana/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from dana/src/main/res/values-sr-rCS/strings.xml rename to pump/dana/src/main/res/values-sr-rCS/strings.xml diff --git a/dana/src/main/res/values-sv-rSE/strings.xml b/pump/dana/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from dana/src/main/res/values-sv-rSE/strings.xml rename to pump/dana/src/main/res/values-sv-rSE/strings.xml diff --git a/dana/src/main/res/values-ta-rIN/strings.xml b/pump/dana/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from dana/src/main/res/values-ta-rIN/strings.xml rename to pump/dana/src/main/res/values-ta-rIN/strings.xml diff --git a/dana/src/main/res/values-tr-rTR/strings.xml b/pump/dana/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from dana/src/main/res/values-tr-rTR/strings.xml rename to pump/dana/src/main/res/values-tr-rTR/strings.xml diff --git a/dana/src/main/res/values-zh-rCN/strings.xml b/pump/dana/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from dana/src/main/res/values-zh-rCN/strings.xml rename to pump/dana/src/main/res/values-zh-rCN/strings.xml diff --git a/dana/src/main/res/values/arrays.xml b/pump/dana/src/main/res/values/arrays.xml similarity index 100% rename from dana/src/main/res/values/arrays.xml rename to pump/dana/src/main/res/values/arrays.xml diff --git a/dana/src/main/res/values/strings.xml b/pump/dana/src/main/res/values/strings.xml similarity index 100% rename from dana/src/main/res/values/strings.xml rename to pump/dana/src/main/res/values/strings.xml diff --git a/dana/src/test/java/info/nightscout/androidaps/TestBase.kt b/pump/dana/src/test/java/info/nightscout/androidaps/TestBase.kt similarity index 100% rename from dana/src/test/java/info/nightscout/androidaps/TestBase.kt rename to pump/dana/src/test/java/info/nightscout/androidaps/TestBase.kt diff --git a/dana/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt b/pump/dana/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt similarity index 100% rename from dana/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt rename to pump/dana/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt diff --git a/dana/src/test/java/info/nightscout/androidaps/dana/DanaPumpTest.kt b/pump/dana/src/test/java/info/nightscout/androidaps/dana/DanaPumpTest.kt similarity index 100% rename from dana/src/test/java/info/nightscout/androidaps/dana/DanaPumpTest.kt rename to pump/dana/src/test/java/info/nightscout/androidaps/dana/DanaPumpTest.kt diff --git a/danar/.gitignore b/pump/danar/.gitignore similarity index 100% rename from danar/.gitignore rename to pump/danar/.gitignore diff --git a/danar/build.gradle b/pump/danar/build.gradle similarity index 93% rename from danar/build.gradle rename to pump/danar/build.gradle index 7fe1ba8c55..9e4191877d 100644 --- a/danar/build.gradle +++ b/pump/danar/build.gradle @@ -13,7 +13,7 @@ android { } dependencies { - implementation project(':core') - implementation project(':dana') implementation project(':shared') + implementation project(':core') + implementation project(':pump:dana') } \ No newline at end of file diff --git a/danar/consumer-rules.pro b/pump/danar/consumer-rules.pro similarity index 100% rename from danar/consumer-rules.pro rename to pump/danar/consumer-rules.pro diff --git a/danar/proguard-rules.pro b/pump/danar/proguard-rules.pro similarity index 100% rename from danar/proguard-rules.pro rename to pump/danar/proguard-rules.pro diff --git a/danar/src/main/AndroidManifest.xml b/pump/danar/src/main/AndroidManifest.xml similarity index 100% rename from danar/src/main/AndroidManifest.xml rename to pump/danar/src/main/AndroidManifest.xml diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MessageHashTableRKorean.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MessageHashTableRKorean.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MessageHashTableRKorean.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MessageHashTableRKorean.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgCheckValue_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgCheckValue_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgCheckValue_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgCheckValue_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBasic_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBasic_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBasic_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBasic_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBolus_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBolus_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBolus_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusBolus_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasalProfileAll_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasalProfileAll_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasalProfileAll_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasalProfileAll_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasal_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasal_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasal_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgSettingBasal_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatusBasic_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatusBasic_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatusBasic_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatusBasic_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatus_k.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatus_k.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatus_k.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgStatus_k.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MessageHashTableRv2.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MessageHashTableRv2.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MessageHashTableRv2.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MessageHashTableRv2.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgCheckValue_v2.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgCheckValue_v2.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgCheckValue_v2.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgCheckValue_v2.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEventsV2.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEventsV2.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEventsV2.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEventsV2.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetAPSTempBasalStart_v2.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetAPSTempBasalStart_v2.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetAPSTempBasalStart_v2.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetAPSTempBasalStart_v2.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetHistoryEntry_v2.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetHistoryEntry_v2.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetHistoryEntry_v2.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgSetHistoryEntry_v2.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgStatusAPS_v2.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgStatusAPS_v2.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgStatusAPS_v2.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgStatusAPS_v2.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/SerialIOThread.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/SerialIOThread.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/SerialIOThread.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/SerialIOThread.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableBase.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableBase.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableBase.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableBase.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableR.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableR.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableR.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageHashTableR.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageOriginalNames.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageOriginalNames.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageOriginalNames.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageOriginalNames.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusProgress.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusProgress.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusProgress.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusProgress.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStop.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStop.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStop.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStop.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgCheckValue.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgCheckValue.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgCheckValue.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgCheckValue.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAlarm.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAlarm.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAlarm.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAlarm.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAll.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAll.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAll.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAll.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAllDone.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAllDone.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAllDone.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryAllDone.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBasalHour.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBasalHour.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBasalHour.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBasalHour.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBolus.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBolus.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBolus.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryBolus.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryCarbo.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryCarbo.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryCarbo.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryCarbo.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDailyInsulin.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDailyInsulin.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDailyInsulin.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDailyInsulin.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDone.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDone.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDone.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryDone.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryError.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryError.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryError.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryError.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryGlucose.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryGlucose.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryGlucose.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryGlucose.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNew.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNew.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNew.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNew.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNewDone.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNewDone.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNewDone.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryNewDone.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryRefill.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryRefill.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryRefill.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistoryRefill.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistorySuspend.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistorySuspend.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistorySuspend.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgHistorySuspend.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBasic.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBasic.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBasic.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBasic.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBolus.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBolus.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBolus.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusBolus.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusOption.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusOption.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusOption.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusOption.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusTime.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusTime.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusTime.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgInitConnStatusTime.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStart.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStart.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStart.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStart.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStop.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStop.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStop.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgPCCommStop.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetActivateBasalProfile.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetActivateBasalProfile.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetActivateBasalProfile.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetActivateBasalProfile.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetBasalProfile.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetBasalProfile.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetBasalProfile.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetBasalProfile.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetCarbsEntry.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetCarbsEntry.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetCarbsEntry.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetCarbsEntry.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStop.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStop.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStop.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStop.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetSingleBasalProfile.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetSingleBasalProfile.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetSingleBasalProfile.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetSingleBasalProfile.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStart.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStart.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStart.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStart.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStop.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStop.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStop.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTempBasalStop.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTime.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTime.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTime.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetTime.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingActiveProfile.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingActiveProfile.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingActiveProfile.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingActiveProfile.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasal.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasal.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasal.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasal.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasalProfileAll.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasalProfileAll.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasalProfileAll.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingBasalProfileAll.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingGlucose.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingGlucose.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingGlucose.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingGlucose.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMaxValues.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMaxValues.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMaxValues.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMaxValues.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMeal.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMeal.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMeal.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingMeal.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatios.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatios.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatios.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatios.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatiosAll.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatiosAll.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatiosAll.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingProfileRatiosAll.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingShippingInfo.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingShippingInfo.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingShippingInfo.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingShippingInfo.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatus.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatus.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatus.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatus.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBasic.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBasic.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBasic.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBasic.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBolusExtended.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBolusExtended.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBolusExtended.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusBolusExtended.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusProfile.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusProfile.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusProfile.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusProfile.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusTempBasal.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusTempBasal.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusTempBasal.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgStatusTempBasal.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRCommModule.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRCommModule.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRCommModule.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRCommModule.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRModule.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRModule.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRModule.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRModule.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRServicesModule.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRServicesModule.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRServicesModule.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/di/DanaRServicesModule.kt diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/services/AbstractDanaRExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/services/AbstractDanaRExecutionService.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/services/AbstractDanaRExecutionService.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/services/AbstractDanaRExecutionService.java diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/services/DanaRExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/services/DanaRExecutionService.java similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/danar/services/DanaRExecutionService.java rename to pump/danar/src/main/java/info/nightscout/androidaps/danar/services/DanaRExecutionService.java diff --git a/danar/src/main/java/info/nightscout/androidaps/utils/CRC.kt b/pump/danar/src/main/java/info/nightscout/androidaps/utils/CRC.kt similarity index 100% rename from danar/src/main/java/info/nightscout/androidaps/utils/CRC.kt rename to pump/danar/src/main/java/info/nightscout/androidaps/utils/CRC.kt diff --git a/danar/src/main/res/values-af-rZA/strings.xml b/pump/danar/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from danar/src/main/res/values-af-rZA/strings.xml rename to pump/danar/src/main/res/values-af-rZA/strings.xml diff --git a/danar/src/main/res/values-bg-rBG/strings.xml b/pump/danar/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from danar/src/main/res/values-bg-rBG/strings.xml rename to pump/danar/src/main/res/values-bg-rBG/strings.xml diff --git a/danar/src/main/res/values-ca-rES/strings.xml b/pump/danar/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from danar/src/main/res/values-ca-rES/strings.xml rename to pump/danar/src/main/res/values-ca-rES/strings.xml diff --git a/danar/src/main/res/values-cs-rCZ/strings.xml b/pump/danar/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from danar/src/main/res/values-cs-rCZ/strings.xml rename to pump/danar/src/main/res/values-cs-rCZ/strings.xml diff --git a/danar/src/main/res/values-da-rDK/strings.xml b/pump/danar/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from danar/src/main/res/values-da-rDK/strings.xml rename to pump/danar/src/main/res/values-da-rDK/strings.xml diff --git a/danar/src/main/res/values-de-rDE/strings.xml b/pump/danar/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from danar/src/main/res/values-de-rDE/strings.xml rename to pump/danar/src/main/res/values-de-rDE/strings.xml diff --git a/danar/src/main/res/values-el-rGR/strings.xml b/pump/danar/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from danar/src/main/res/values-el-rGR/strings.xml rename to pump/danar/src/main/res/values-el-rGR/strings.xml diff --git a/danar/src/main/res/values-es-rES/strings.xml b/pump/danar/src/main/res/values-es-rES/strings.xml similarity index 100% rename from danar/src/main/res/values-es-rES/strings.xml rename to pump/danar/src/main/res/values-es-rES/strings.xml diff --git a/danar/src/main/res/values-fr-rFR/strings.xml b/pump/danar/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from danar/src/main/res/values-fr-rFR/strings.xml rename to pump/danar/src/main/res/values-fr-rFR/strings.xml diff --git a/danar/src/main/res/values-ga-rIE/strings.xml b/pump/danar/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from danar/src/main/res/values-ga-rIE/strings.xml rename to pump/danar/src/main/res/values-ga-rIE/strings.xml diff --git a/danar/src/main/res/values-hr-rHR/strings.xml b/pump/danar/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from danar/src/main/res/values-hr-rHR/strings.xml rename to pump/danar/src/main/res/values-hr-rHR/strings.xml diff --git a/danar/src/main/res/values-hu-rHU/strings.xml b/pump/danar/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from danar/src/main/res/values-hu-rHU/strings.xml rename to pump/danar/src/main/res/values-hu-rHU/strings.xml diff --git a/danar/src/main/res/values-it-rIT/strings.xml b/pump/danar/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from danar/src/main/res/values-it-rIT/strings.xml rename to pump/danar/src/main/res/values-it-rIT/strings.xml diff --git a/danar/src/main/res/values-iw-rIL/strings.xml b/pump/danar/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from danar/src/main/res/values-iw-rIL/strings.xml rename to pump/danar/src/main/res/values-iw-rIL/strings.xml diff --git a/danar/src/main/res/values-ko-rKR/strings.xml b/pump/danar/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from danar/src/main/res/values-ko-rKR/strings.xml rename to pump/danar/src/main/res/values-ko-rKR/strings.xml diff --git a/danar/src/main/res/values-lt-rLT/strings.xml b/pump/danar/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from danar/src/main/res/values-lt-rLT/strings.xml rename to pump/danar/src/main/res/values-lt-rLT/strings.xml diff --git a/danar/src/main/res/values-nl-rNL/strings.xml b/pump/danar/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from danar/src/main/res/values-nl-rNL/strings.xml rename to pump/danar/src/main/res/values-nl-rNL/strings.xml diff --git a/danar/src/main/res/values-no-rNO/strings.xml b/pump/danar/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from danar/src/main/res/values-no-rNO/strings.xml rename to pump/danar/src/main/res/values-no-rNO/strings.xml diff --git a/danar/src/main/res/values-pl-rPL/strings.xml b/pump/danar/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from danar/src/main/res/values-pl-rPL/strings.xml rename to pump/danar/src/main/res/values-pl-rPL/strings.xml diff --git a/danar/src/main/res/values-pt-rBR/strings.xml b/pump/danar/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from danar/src/main/res/values-pt-rBR/strings.xml rename to pump/danar/src/main/res/values-pt-rBR/strings.xml diff --git a/danar/src/main/res/values-pt-rPT/strings.xml b/pump/danar/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from danar/src/main/res/values-pt-rPT/strings.xml rename to pump/danar/src/main/res/values-pt-rPT/strings.xml diff --git a/danar/src/main/res/values-ro-rRO/strings.xml b/pump/danar/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from danar/src/main/res/values-ro-rRO/strings.xml rename to pump/danar/src/main/res/values-ro-rRO/strings.xml diff --git a/danar/src/main/res/values-ru-rRU/strings.xml b/pump/danar/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from danar/src/main/res/values-ru-rRU/strings.xml rename to pump/danar/src/main/res/values-ru-rRU/strings.xml diff --git a/danar/src/main/res/values-sk-rSK/strings.xml b/pump/danar/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from danar/src/main/res/values-sk-rSK/strings.xml rename to pump/danar/src/main/res/values-sk-rSK/strings.xml diff --git a/danar/src/main/res/values-sr-rCS/strings.xml b/pump/danar/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from danar/src/main/res/values-sr-rCS/strings.xml rename to pump/danar/src/main/res/values-sr-rCS/strings.xml diff --git a/danar/src/main/res/values-sv-rSE/strings.xml b/pump/danar/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from danar/src/main/res/values-sv-rSE/strings.xml rename to pump/danar/src/main/res/values-sv-rSE/strings.xml diff --git a/danar/src/main/res/values-tr-rTR/strings.xml b/pump/danar/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from danar/src/main/res/values-tr-rTR/strings.xml rename to pump/danar/src/main/res/values-tr-rTR/strings.xml diff --git a/danar/src/main/res/values-zh-rCN/strings.xml b/pump/danar/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from danar/src/main/res/values-zh-rCN/strings.xml rename to pump/danar/src/main/res/values-zh-rCN/strings.xml diff --git a/danar/src/main/res/values/strings.xml b/pump/danar/src/main/res/values/strings.xml similarity index 100% rename from danar/src/main/res/values/strings.xml rename to pump/danar/src/main/res/values/strings.xml diff --git a/danar/src/main/res/xml/pref_danar.xml b/pump/danar/src/main/res/xml/pref_danar.xml similarity index 100% rename from danar/src/main/res/xml/pref_danar.xml rename to pump/danar/src/main/res/xml/pref_danar.xml diff --git a/danar/src/main/res/xml/pref_danarkorean.xml b/pump/danar/src/main/res/xml/pref_danarkorean.xml similarity index 100% rename from danar/src/main/res/xml/pref_danarkorean.xml rename to pump/danar/src/main/res/xml/pref_danarkorean.xml diff --git a/danar/src/main/res/xml/pref_danarv2.xml b/pump/danar/src/main/res/xml/pref_danarv2.xml similarity index 100% rename from danar/src/main/res/xml/pref_danarv2.xml rename to pump/danar/src/main/res/xml/pref_danarv2.xml diff --git a/danar/src/test/java/info/nightscout/androidaps/TestBase.kt b/pump/danar/src/test/java/info/nightscout/androidaps/TestBase.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/TestBase.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/TestBase.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt b/pump/danar/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/pump/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageHashTableRTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageHashTableRTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageHashTableRTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageHashTableRTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageOriginalNamesTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageOriginalNamesTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageOriginalNamesTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MessageOriginalNamesTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusProgressTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusProgressTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusProgressTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusProgressTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStopTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStopTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStopTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgBolusStopTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgCheckValueTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgCheckValueTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgCheckValueTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgCheckValueTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgErrorTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgErrorTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgErrorTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgErrorTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAlarmTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAlarmTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAlarmTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAlarmTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllDoneTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllDoneTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllDoneTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllDoneTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryAllTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBasalHourTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBasalHourTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBasalHourTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBasalHourTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBolusTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBolusTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBolusTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryBolusTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryCarboTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryCarboTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryCarboTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryCarboTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDailyInsulinTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDailyInsulinTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDailyInsulinTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDailyInsulinTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDoneTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDoneTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDoneTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryDoneTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryErrorTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryErrorTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryErrorTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryErrorTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryGlucoseTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryGlucoseTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryGlucoseTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryGlucoseTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewDoneTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewDoneTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewDoneTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewDoneTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryNewTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryRefillTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryRefillTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryRefillTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistoryRefillTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistorySuspendTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistorySuspendTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistorySuspendTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgHistorySuspendTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBasicTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBasicTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBasicTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBasicTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBolusTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBolusTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBolusTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusBolusTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusOptionTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusOptionTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusOptionTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusOptionTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusTimeTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusTimeTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusTimeTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgInitConnStatusTimeTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStartTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStartTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStartTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStartTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStopTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStopTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStopTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgPCCommStopTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetActivateBasalProfileTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetActivateBasalProfileTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetActivateBasalProfileTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetActivateBasalProfileTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetBasalProfileTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetBasalProfileTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetBasalProfileTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetBasalProfileTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetCarbsEntryTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetCarbsEntryTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetCarbsEntryTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetCarbsEntryTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStopTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStopTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStopTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetExtendedBolusStopTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetSingleBasalProfileTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetSingleBasalProfileTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetSingleBasalProfileTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetSingleBasalProfileTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTempBasalStartTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTempBasalStartTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTempBasalStartTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTempBasalStartTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTimeTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTimeTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTimeTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetTimeTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetUserOptionsTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetUserOptionsTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetUserOptionsTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSetUserOptionsTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingActiveProfileTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingActiveProfileTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingActiveProfileTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingActiveProfileTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalProfileAllTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalProfileAllTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalProfileAllTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalProfileAllTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingBasalTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingGlucoseTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingGlucoseTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingGlucoseTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingGlucoseTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMaxValuesTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMaxValuesTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMaxValuesTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMaxValuesTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMealTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMealTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMealTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingMealTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosAllTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosAllTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosAllTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosAllTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingProfileRatiosTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingShippingInfoTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingShippingInfoTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingShippingInfoTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingShippingInfoTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingUserOptionsTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingUserOptionsTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingUserOptionsTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingUserOptionsTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBasicTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBasicTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBasicTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBasicTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBolusExtendedTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBolusExtendedTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBolusExtendedTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusBolusExtendedTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusProfileTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusProfileTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusProfileTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusProfileTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTempBasalTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTempBasalTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTempBasalTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTempBasalTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgStatusTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/RecordTypesTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/RecordTypesTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/RecordTypesTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/RecordTypesTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MessageHashTableRv2Test.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MessageHashTableRv2Test.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MessageHashTableRv2Test.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MessageHashTableRv2Test.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgCheckValueRv2Test.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgCheckValueRv2Test.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgCheckValueRv2Test.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgCheckValueRv2Test.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgHistoryEventsRv2Test.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgHistoryEventsRv2Test.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgHistoryEventsRv2Test.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgHistoryEventsRv2Test.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetAPSTempBasalStartRv2Test.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetAPSTempBasalStartRv2Test.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetAPSTempBasalStartRv2Test.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetAPSTempBasalStartRv2Test.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetHistoryEntryRv2Test.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetHistoryEntryRv2Test.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetHistoryEntryRv2Test.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgSetHistoryEntryRv2Test.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgStatusAPSRv2Test.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgStatusAPSRv2Test.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgStatusAPSRv2Test.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/comm/MsgStatusAPSRv2Test.kt diff --git a/danar/src/test/java/info/nightscout/androidaps/utils/CRCTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/utils/CRCTest.kt similarity index 100% rename from danar/src/test/java/info/nightscout/androidaps/utils/CRCTest.kt rename to pump/danar/src/test/java/info/nightscout/androidaps/utils/CRCTest.kt diff --git a/danars/.gitignore b/pump/danars/.gitignore similarity index 100% rename from danars/.gitignore rename to pump/danars/.gitignore diff --git a/danars/build.gradle b/pump/danars/build.gradle similarity index 94% rename from danars/build.gradle rename to pump/danars/build.gradle index 2f0b2a46a4..58e9e39714 100644 --- a/danars/build.gradle +++ b/pump/danars/build.gradle @@ -23,6 +23,6 @@ android { dependencies { implementation project(':core') - implementation project(':dana') + implementation project(':pump:dana') implementation project(':shared') } \ No newline at end of file diff --git a/danars/consumer-rules.pro b/pump/danars/consumer-rules.pro similarity index 100% rename from danars/consumer-rules.pro rename to pump/danars/consumer-rules.pro diff --git a/danars/proguard-rules.pro b/pump/danars/proguard-rules.pro similarity index 100% rename from danars/proguard-rules.pro rename to pump/danars/proguard-rules.pro diff --git a/danars/src/main/AndroidManifest.xml b/pump/danars/src/main/AndroidManifest.xml similarity index 100% rename from danars/src/main/AndroidManifest.xml rename to pump/danars/src/main/AndroidManifest.xml diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/activities/BLEScanActivity.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/activities/BLEScanActivity.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/activities/BLEScanActivity.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/activities/BLEScanActivity.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/activities/EnterPinActivity.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/activities/EnterPinActivity.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/activities/EnterPinActivity.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/activities/EnterPinActivity.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/activities/PairingHelperActivity.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/activities/PairingHelperActivity.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/activities/PairingHelperActivity.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/activities/PairingHelperActivity.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacket.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacket.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacket.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacket.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSBasalSetTemporaryBasal.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSBasalSetTemporaryBasal.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSBasalSetTemporaryBasal.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSBasalSetTemporaryBasal.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSHistoryEvents.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSHistoryEvents.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSHistoryEvents.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSHistoryEvents.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSSetEventHistory.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSSetEventHistory.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSSetEventHistory.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketAPSSetEventHistory.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetBasalRate.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetBasalRate.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetBasalRate.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetBasalRate.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetProfileNumber.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetProfileNumber.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetProfileNumber.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalGetProfileNumber.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetCancelTemporaryBasal.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetCancelTemporaryBasal.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetCancelTemporaryBasal.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetCancelTemporaryBasal.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileBasalRate.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileBasalRate.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileBasalRate.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileBasalRate.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileNumber.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileNumber.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileNumber.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetProfileNumber.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOff.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOff.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOff.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOff.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOn.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOn.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOn.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetSuspendOn.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasal.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasal.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasal.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasal.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGet24CIRCFArray.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGet24CIRCFArray.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGet24CIRCFArray.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGet24CIRCFArray.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetBolusOption.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetBolusOption.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetBolusOption.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetBolusOption.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCIRCFArray.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCIRCFArray.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCIRCFArray.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCIRCFArray.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCalculationInformation.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCalculationInformation.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCalculationInformation.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetCalculationInformation.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetStepBolusInformation.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetStepBolusInformation.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetStepBolusInformation.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusGetStepBolusInformation.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSet24CIRCFArray.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSet24CIRCFArray.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSet24CIRCFArray.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSet24CIRCFArray.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetBolusOption.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetBolusOption.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetBolusOption.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetBolusOption.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolus.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolus.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolus.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolus.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolusCancel.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolusCancel.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolusCancel.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetExtendedBolusCancel.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStop.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStop.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStop.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStop.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcKeepConnection.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcKeepConnection.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcKeepConnection.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcKeepConnection.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcSetHistorySave.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcSetHistorySave.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcSetHistorySave.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketEtcSetHistorySave.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetPumpCheck.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetPumpCheck.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetPumpCheck.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetPumpCheck.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingInformation.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingInformation.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingInformation.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingInformation.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingVersion.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingVersion.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingVersion.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetShippingVersion.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetUserTimeChangeFlag.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetUserTimeChangeFlag.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetUserTimeChangeFlag.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralGetUserTimeChangeFlag.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralInitialScreenInformation.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralInitialScreenInformation.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralInitialScreenInformation.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralInitialScreenInformation.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetHistoryUploadMode.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetHistoryUploadMode.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetHistoryUploadMode.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetHistoryUploadMode.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetUserTimeChangeFlagClear.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetUserTimeChangeFlagClear.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetUserTimeChangeFlagClear.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketGeneralSetUserTimeChangeFlagClear.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistory.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistory.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistory.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistory.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarm.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarm.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarm.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarm.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAllHistory.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAllHistory.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAllHistory.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAllHistory.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBasal.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBasal.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBasal.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBasal.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBloodGlucose.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBloodGlucose.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBloodGlucose.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBloodGlucose.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBolus.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBolus.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBolus.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryBolus.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryCarbohydrate.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryCarbohydrate.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryCarbohydrate.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryCarbohydrate.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryDaily.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryDaily.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryDaily.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryDaily.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryPrime.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryPrime.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryPrime.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryPrime.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryRefill.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryRefill.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryRefill.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryRefill.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistorySuspend.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistorySuspend.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistorySuspend.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistorySuspend.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryTemporary.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryTemporary.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryTemporary.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryTemporary.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyAlarm.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyAlarm.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyAlarm.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyAlarm.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryComplete.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryComplete.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryComplete.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryComplete.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryRateDisplay.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryRateDisplay.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryRateDisplay.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryRateDisplay.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyMissedBolusAlarm.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyMissedBolusAlarm.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyMissedBolusAlarm.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyMissedBolusAlarm.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpTime.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpTime.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpTime.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpTime.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpUTCAndTimeZone.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpUTCAndTimeZone.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpUTCAndTimeZone.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetPumpUTCAndTimeZone.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetUserOption.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetUserOption.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetUserOption.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionGetUserOption.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpTime.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpTime.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpTime.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpTime.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpUTCAndTimeZone.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpUTCAndTimeZone.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpUTCAndTimeZone.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetPumpUTCAndTimeZone.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOption.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOption.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOption.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOption.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewBolusAvg.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewBolusAvg.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewBolusAvg.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewBolusAvg.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewGetPumpDecRatio.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewGetPumpDecRatio.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewGetPumpDecRatio.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketReviewGetPumpDecRatio.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSActivitiesModule.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSActivitiesModule.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSActivitiesModule.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSActivitiesModule.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSModule.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSModule.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSModule.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSModule.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSServicesModule.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSServicesModule.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSServicesModule.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSServicesModule.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/dialogs/PairingProgressDialog.java b/pump/danars/src/main/java/info/nightscout/androidaps/danars/dialogs/PairingProgressDialog.java similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/dialogs/PairingProgressDialog.java rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/dialogs/PairingProgressDialog.java diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java b/pump/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/encryption/EncryptionType.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/encryption/EncryptionType.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/encryption/EncryptionType.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/encryption/EncryptionType.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSDeviceChange.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSDeviceChange.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSDeviceChange.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSDeviceChange.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSPairingSuccess.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSPairingSuccess.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSPairingSuccess.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/events/EventDanaRSPairingSuccess.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt similarity index 100% rename from danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt rename to pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt diff --git a/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so b/pump/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so similarity index 100% rename from danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so rename to pump/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so diff --git a/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so b/pump/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so similarity index 100% rename from danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so rename to pump/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so diff --git a/danars/src/main/jniLibs/x86/libBleEncryption.so b/pump/danars/src/main/jniLibs/x86/libBleEncryption.so similarity index 100% rename from danars/src/main/jniLibs/x86/libBleEncryption.so rename to pump/danars/src/main/jniLibs/x86/libBleEncryption.so diff --git a/danars/src/main/jniLibs/x86_64/libBleEncryption.so b/pump/danars/src/main/jniLibs/x86_64/libBleEncryption.so similarity index 100% rename from danars/src/main/jniLibs/x86_64/libBleEncryption.so rename to pump/danars/src/main/jniLibs/x86_64/libBleEncryption.so diff --git a/danars/src/main/res/layout/danars_blescanner_activity.xml b/pump/danars/src/main/res/layout/danars_blescanner_activity.xml similarity index 100% rename from danars/src/main/res/layout/danars_blescanner_activity.xml rename to pump/danars/src/main/res/layout/danars_blescanner_activity.xml diff --git a/danars/src/main/res/layout/danars_blescanner_item.xml b/pump/danars/src/main/res/layout/danars_blescanner_item.xml similarity index 100% rename from danars/src/main/res/layout/danars_blescanner_item.xml rename to pump/danars/src/main/res/layout/danars_blescanner_item.xml diff --git a/danars/src/main/res/layout/danars_enter_pin_activity.xml b/pump/danars/src/main/res/layout/danars_enter_pin_activity.xml similarity index 100% rename from danars/src/main/res/layout/danars_enter_pin_activity.xml rename to pump/danars/src/main/res/layout/danars_enter_pin_activity.xml diff --git a/danars/src/main/res/layout/danars_pairing_progress_dialog.xml b/pump/danars/src/main/res/layout/danars_pairing_progress_dialog.xml similarity index 100% rename from danars/src/main/res/layout/danars_pairing_progress_dialog.xml rename to pump/danars/src/main/res/layout/danars_pairing_progress_dialog.xml diff --git a/danars/src/main/res/xml/pref_danars.xml b/pump/danars/src/main/res/xml/pref_danars.xml similarity index 100% rename from danars/src/main/res/xml/pref_danars.xml rename to pump/danars/src/main/res/xml/pref_danars.xml diff --git a/danars/src/test/java/info/nightscout/androidaps/TestBase.kt b/pump/danars/src/test/java/info/nightscout/androidaps/TestBase.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/TestBase.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/TestBase.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt b/pump/danars/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSTestBase.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSTestBase.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/DanaRSTestBase.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSTestBase.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasalTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasalTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasalTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBasalSetTemporaryBasalTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarmTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarmTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarmTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketHistoryAlarmTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryCompleteTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryCompleteTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryCompleteTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketNotifyDeliveryCompleteTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOptionTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOptionTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOptionTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSPacketOptionSetUserOptionTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSTestBase.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSTestBase.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSTestBase.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRSTestBase.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsBasalSetTemporaryBasalTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsBasalSetTemporaryBasalTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsBasalSetTemporaryBasalTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsBasalSetTemporaryBasalTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsHistoryEventsTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsHistoryEventsTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsHistoryEventsTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsHistoryEventsTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsSetEventHistoryTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsSetEventHistoryTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsSetEventHistoryTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketApsSetEventHistoryTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetBasalRateTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetBasalRateTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetBasalRateTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetBasalRateTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetProfileNumberTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetProfileNumberTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetProfileNumberTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalGetProfileNumberTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetCancelTemporaryBasalTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetCancelTemporaryBasalTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetCancelTemporaryBasalTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetCancelTemporaryBasalTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileBasalRateTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileBasalRateTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileBasalRateTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileBasalRateTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileNumberTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileNumberTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileNumberTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetProfileNumberTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOffTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOffTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOffTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOffTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOnTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOnTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOnTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBasalSetSuspendOnTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetBolusOptionTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetBolusOptionTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetBolusOptionTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetBolusOptionTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCalculationInformationTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCalculationInformationTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCalculationInformationTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCalculationInformationTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCirCfArrayTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCirCfArrayTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCirCfArrayTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetCirCfArrayTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetStepBolusInformationTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetStepBolusInformationTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetStepBolusInformationTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusGetStepBolusInformationTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetBolusOptionTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetBolusOptionTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetBolusOptionTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetBolusOptionTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusCancelTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusCancelTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusCancelTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusCancelTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetExtendedBolusTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStopTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStopTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStopTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStopTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcKeepConnectionTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcKeepConnectionTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcKeepConnectionTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcKeepConnectionTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcSetHistorySaveTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcSetHistorySaveTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcSetHistorySaveTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketEtcSetHistorySaveTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetPumpCheckTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetPumpCheckTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetPumpCheckTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetPumpCheckTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingInformationTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingInformationTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingInformationTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingInformationTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingVerisonTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingVerisonTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingVerisonTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetShippingVerisonTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetUserTimeChangeFlagTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetUserTimeChangeFlagTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetUserTimeChangeFlagTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralGetUserTimeChangeFlagTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralInitialScreenInformationTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralInitialScreenInformationTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralInitialScreenInformationTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralInitialScreenInformationTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetHistoryUploadModeTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetHistoryUploadModeTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetHistoryUploadModeTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetHistoryUploadModeTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetUserTimeChangeFlagClearTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetUserTimeChangeFlagClearTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetUserTimeChangeFlagClearTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketGeneralSetUserTimeChangeFlagClearTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryAllHistoryTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryAllHistoryTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryAllHistoryTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryAllHistoryTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBasalTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBasalTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBasalTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBasalTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBloodGlucoseTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBloodGlucoseTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBloodGlucoseTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBloodGlucoseTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBolusTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBolusTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBolusTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryBolusTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryCarbohydrateTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryCarbohydrateTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryCarbohydrateTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryCarbohydrateTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryDailyTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryDailyTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryDailyTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryDailyTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryPrimeTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryPrimeTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryPrimeTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryPrimeTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryRefillTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryRefillTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryRefillTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryRefillTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistorySuspendTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistorySuspendTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistorySuspendTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistorySuspendTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryTemporaryTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryTemporaryTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryTemporaryTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketHistoryTemporaryTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyAlarmTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyAlarmTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyAlarmTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyAlarmTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyMissedBolusAlarmTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyMissedBolusAlarmTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyMissedBolusAlarmTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyMissedBolusAlarmTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetPumpTimeTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetPumpTimeTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetPumpTimeTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetPumpTimeTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetUserOptionTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetUserOptionTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetUserOptionTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionGetUserOptionTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionSetPumpTimeTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionSetPumpTimeTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionSetPumpTimeTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketOptionSetPumpTimeTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewBolusAvgTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewBolusAvgTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewBolusAvgTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewBolusAvgTest.kt diff --git a/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewGetPumpDecRatioTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewGetPumpDecRatioTest.kt similarity index 100% rename from danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewGetPumpDecRatioTest.kt rename to pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketReviewGetPumpDecRatioTest.kt diff --git a/diaconn/build.gradle b/pump/diaconn/build.gradle similarity index 100% rename from diaconn/build.gradle rename to pump/diaconn/build.gradle diff --git a/diaconn/consumer-rules.pro b/pump/diaconn/consumer-rules.pro similarity index 100% rename from diaconn/consumer-rules.pro rename to pump/diaconn/consumer-rules.pro diff --git a/diaconn/proguard-rules.pro b/pump/diaconn/proguard-rules.pro similarity index 100% rename from diaconn/proguard-rules.pro rename to pump/diaconn/proguard-rules.pro diff --git a/diaconn/schemas/info.nightscout.androidaps.diaconn.database.DiaconnHistoryDatabase/1.json b/pump/diaconn/schemas/info.nightscout.androidaps.diaconn.database.DiaconnHistoryDatabase/1.json similarity index 100% rename from diaconn/schemas/info.nightscout.androidaps.diaconn.database.DiaconnHistoryDatabase/1.json rename to pump/diaconn/schemas/info.nightscout.androidaps.diaconn.database.DiaconnHistoryDatabase/1.json diff --git a/diaconn/src/main/AndroidManifest.xml b/pump/diaconn/src/main/AndroidManifest.xml similarity index 100% rename from diaconn/src/main/AndroidManifest.xml rename to pump/diaconn/src/main/AndroidManifest.xml diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Pump.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Pump.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Pump.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Pump.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8BLEScanActivity.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8BLEScanActivity.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8BLEScanActivity.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8BLEScanActivity.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8HistoryActivity.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8HistoryActivity.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8HistoryActivity.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8HistoryActivity.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiResponse.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiResponse.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiResponse.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiResponse.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiService.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiService.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiService.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnApiService.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnLogUploader.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnLogUploader.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnLogUploader.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/api/DiaconnLogUploader.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/common/RecordTypes.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/common/RecordTypes.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/common/RecordTypes.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/common/RecordTypes.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryDatabase.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryDatabase.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryDatabase.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryDatabase.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecord.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecord.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecord.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecord.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecordDao.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecordDao.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecordDao.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/database/DiaconnHistoryRecordDao.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ActivitiesModule.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ActivitiesModule.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ActivitiesModule.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ActivitiesModule.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8Module.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8Module.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8Module.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8Module.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8PacketModule.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8PacketModule.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8PacketModule.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8PacketModule.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ServiceModule.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ServiceModule.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ServiceModule.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnG8ServiceModule.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnHistoryModule.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnHistoryModule.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnHistoryModule.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnHistoryModule.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnLogUploaderModule.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnLogUploaderModule.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnLogUploaderModule.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/di/DiaconnLogUploaderModule.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8DeviceChange.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8DeviceChange.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8DeviceChange.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8DeviceChange.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8NewStatus.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8NewStatus.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8NewStatus.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8NewStatus.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8PumpLogReset.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8PumpLogReset.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8PumpLogReset.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/events/EventDiaconnG8PumpLogReset.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppCancelSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/AppConfirmSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalLimitInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalPauseSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BasalSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BatteryWarningReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BatteryWarningReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BatteryWarningReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BatteryWarningReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigAPSMainInfoInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigLogInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BigMainInfoInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/BolusSpeedSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/ConfirmReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/ConfirmReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/ConfirmReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/ConfirmReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8Packet.java b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8Packet.java similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8Packet.java rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8Packet.java diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8ResponseMessageHashTable.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8ResponseMessageHashTable.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8ResponseMessageHashTable.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8ResponseMessageHashTable.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8SettingResponseMessageHashTable.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8SettingResponseMessageHashTable.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8SettingResponseMessageHashTable.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DiaconnG8SettingResponseMessageHashTable.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/DisplayTimeoutSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/IncarnationInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBasalSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBlockReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBlockReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBlockReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionBlockReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionCancelSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusResultReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusResultReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusResultReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusResultReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionExtendedBolusSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionMealSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackResultReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackResultReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackResultReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackResultReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InjectionSnackSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InsulinLackReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InsulinLackReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InsulinLackReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/InsulinLackReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LanguageSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/LogStatusInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/RejectReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/RejectReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/RejectReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/RejectReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SerialNumInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SneckLimitInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/SoundSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TempBasalSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquirePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquirePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquirePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquirePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquireResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquireResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquireResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeInquireResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeReportPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeReportPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeReportPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeReportPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingPacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingPacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingPacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingPacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingResponsePacket.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingResponsePacket.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingResponsePacket.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/packet/TimeSettingResponsePacket.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BATTERY.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BATTERY.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BATTERY.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BATTERY.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BLOCK.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BLOCK.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BLOCK.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_BLOCK.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_SHORTAGE.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_SHORTAGE.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_SHORTAGE.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_ALARM_SHORTAGE.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_INJECTOR_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_INJECTOR_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_INJECTOR_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_INJECTOR_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_NEEDLE_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_NEEDLE_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_NEEDLE_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_NEEDLE_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_TUBE_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_TUBE_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_TUBE_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_CHANGE_TUBE_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY_BASAL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY_BASAL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY_BASAL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1DAY_BASAL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1HOUR_BASAL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1HOUR_BASAL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1HOUR_BASAL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_1HOUR_BASAL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_DUAL_NORMAL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_DUAL_NORMAL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_DUAL_NORMAL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECTION_DUAL_NORMAL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_FAIL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_FAIL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_FAIL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_FAIL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_DUAL_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_FAIL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_FAIL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_FAIL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_FAIL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_MEAL_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_FAIL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_FAIL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_FAIL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_FAIL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_NORMAL_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_FAIL.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_FAIL.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_FAIL.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_FAIL.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_SUCCESS.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_SUCCESS.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_SUCCESS.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_INJECT_SQUARE_SUCCESS.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_RESET_SYS_V3.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_RESET_SYS_V3.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_RESET_SYS_V3.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_RESET_SYS_V3.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_DUAL_INJECTION.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_DUAL_INJECTION.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_DUAL_INJECTION.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_DUAL_INJECTION.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_SQUARE_INJECTION.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_SQUARE_INJECTION.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_SQUARE_INJECTION.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SET_SQUARE_INJECTION.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_RELEASE_V2.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_RELEASE_V2.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_RELEASE_V2.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_RELEASE_V2.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_V2.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_V2.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_V2.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_SUSPEND_V2.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_START_V3.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_START_V3.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_START_V3.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_START_V3.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_STOP_V3.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_STOP_V3.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_STOP_V3.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/LOG_TB_STOP_V3.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/PumplogUtil.java b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/PumplogUtil.java similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/PumplogUtil.java rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/pumplog/PumplogUtil.java diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt diff --git a/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt similarity index 100% rename from diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt rename to pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt diff --git a/diaconn/src/main/res/layout/diaconn_g8_blescanner_activity.xml b/pump/diaconn/src/main/res/layout/diaconn_g8_blescanner_activity.xml similarity index 100% rename from diaconn/src/main/res/layout/diaconn_g8_blescanner_activity.xml rename to pump/diaconn/src/main/res/layout/diaconn_g8_blescanner_activity.xml diff --git a/diaconn/src/main/res/layout/diaconn_g8_blescanner_item.xml b/pump/diaconn/src/main/res/layout/diaconn_g8_blescanner_item.xml similarity index 100% rename from diaconn/src/main/res/layout/diaconn_g8_blescanner_item.xml rename to pump/diaconn/src/main/res/layout/diaconn_g8_blescanner_item.xml diff --git a/diaconn/src/main/res/layout/diaconn_g8_fragment.xml b/pump/diaconn/src/main/res/layout/diaconn_g8_fragment.xml similarity index 100% rename from diaconn/src/main/res/layout/diaconn_g8_fragment.xml rename to pump/diaconn/src/main/res/layout/diaconn_g8_fragment.xml diff --git a/diaconn/src/main/res/layout/diaconn_g8_history_activity.xml b/pump/diaconn/src/main/res/layout/diaconn_g8_history_activity.xml similarity index 100% rename from diaconn/src/main/res/layout/diaconn_g8_history_activity.xml rename to pump/diaconn/src/main/res/layout/diaconn_g8_history_activity.xml diff --git a/diaconn/src/main/res/layout/diaconn_g8_history_item.xml b/pump/diaconn/src/main/res/layout/diaconn_g8_history_item.xml similarity index 100% rename from diaconn/src/main/res/layout/diaconn_g8_history_item.xml rename to pump/diaconn/src/main/res/layout/diaconn_g8_history_item.xml diff --git a/diaconn/src/main/res/layout/diaconn_g8_user_options_activity.xml b/pump/diaconn/src/main/res/layout/diaconn_g8_user_options_activity.xml similarity index 100% rename from diaconn/src/main/res/layout/diaconn_g8_user_options_activity.xml rename to pump/diaconn/src/main/res/layout/diaconn_g8_user_options_activity.xml diff --git a/diaconn/src/main/res/values-af-rZA/strings.xml b/pump/diaconn/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from diaconn/src/main/res/values-af-rZA/strings.xml rename to pump/diaconn/src/main/res/values-af-rZA/strings.xml diff --git a/diaconn/src/main/res/values-bg-rBG/strings.xml b/pump/diaconn/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from diaconn/src/main/res/values-bg-rBG/strings.xml rename to pump/diaconn/src/main/res/values-bg-rBG/strings.xml diff --git a/diaconn/src/main/res/values-ca-rES/strings.xml b/pump/diaconn/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from diaconn/src/main/res/values-ca-rES/strings.xml rename to pump/diaconn/src/main/res/values-ca-rES/strings.xml diff --git a/diaconn/src/main/res/values-cs-rCZ/strings.xml b/pump/diaconn/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from diaconn/src/main/res/values-cs-rCZ/strings.xml rename to pump/diaconn/src/main/res/values-cs-rCZ/strings.xml diff --git a/diaconn/src/main/res/values-da-rDK/strings.xml b/pump/diaconn/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from diaconn/src/main/res/values-da-rDK/strings.xml rename to pump/diaconn/src/main/res/values-da-rDK/strings.xml diff --git a/diaconn/src/main/res/values-de-rDE/strings.xml b/pump/diaconn/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from diaconn/src/main/res/values-de-rDE/strings.xml rename to pump/diaconn/src/main/res/values-de-rDE/strings.xml diff --git a/diaconn/src/main/res/values-el-rGR/strings.xml b/pump/diaconn/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from diaconn/src/main/res/values-el-rGR/strings.xml rename to pump/diaconn/src/main/res/values-el-rGR/strings.xml diff --git a/diaconn/src/main/res/values-es-rES/strings.xml b/pump/diaconn/src/main/res/values-es-rES/strings.xml similarity index 100% rename from diaconn/src/main/res/values-es-rES/strings.xml rename to pump/diaconn/src/main/res/values-es-rES/strings.xml diff --git a/diaconn/src/main/res/values-fr-rFR/strings.xml b/pump/diaconn/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from diaconn/src/main/res/values-fr-rFR/strings.xml rename to pump/diaconn/src/main/res/values-fr-rFR/strings.xml diff --git a/diaconn/src/main/res/values-ga-rIE/strings.xml b/pump/diaconn/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from diaconn/src/main/res/values-ga-rIE/strings.xml rename to pump/diaconn/src/main/res/values-ga-rIE/strings.xml diff --git a/diaconn/src/main/res/values-hr-rHR/strings.xml b/pump/diaconn/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from diaconn/src/main/res/values-hr-rHR/strings.xml rename to pump/diaconn/src/main/res/values-hr-rHR/strings.xml diff --git a/diaconn/src/main/res/values-hu-rHU/strings.xml b/pump/diaconn/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from diaconn/src/main/res/values-hu-rHU/strings.xml rename to pump/diaconn/src/main/res/values-hu-rHU/strings.xml diff --git a/diaconn/src/main/res/values-it-rIT/strings.xml b/pump/diaconn/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from diaconn/src/main/res/values-it-rIT/strings.xml rename to pump/diaconn/src/main/res/values-it-rIT/strings.xml diff --git a/diaconn/src/main/res/values-iw-rIL/strings.xml b/pump/diaconn/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from diaconn/src/main/res/values-iw-rIL/strings.xml rename to pump/diaconn/src/main/res/values-iw-rIL/strings.xml diff --git a/diaconn/src/main/res/values-ko-rKR/strings.xml b/pump/diaconn/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from diaconn/src/main/res/values-ko-rKR/strings.xml rename to pump/diaconn/src/main/res/values-ko-rKR/strings.xml diff --git a/diaconn/src/main/res/values-lt-rLT/strings.xml b/pump/diaconn/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from diaconn/src/main/res/values-lt-rLT/strings.xml rename to pump/diaconn/src/main/res/values-lt-rLT/strings.xml diff --git a/diaconn/src/main/res/values-nl-rNL/strings.xml b/pump/diaconn/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from diaconn/src/main/res/values-nl-rNL/strings.xml rename to pump/diaconn/src/main/res/values-nl-rNL/strings.xml diff --git a/diaconn/src/main/res/values-no-rNO/strings.xml b/pump/diaconn/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from diaconn/src/main/res/values-no-rNO/strings.xml rename to pump/diaconn/src/main/res/values-no-rNO/strings.xml diff --git a/diaconn/src/main/res/values-pl-rPL/strings.xml b/pump/diaconn/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from diaconn/src/main/res/values-pl-rPL/strings.xml rename to pump/diaconn/src/main/res/values-pl-rPL/strings.xml diff --git a/diaconn/src/main/res/values-pt-rBR/strings.xml b/pump/diaconn/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from diaconn/src/main/res/values-pt-rBR/strings.xml rename to pump/diaconn/src/main/res/values-pt-rBR/strings.xml diff --git a/diaconn/src/main/res/values-pt-rPT/strings.xml b/pump/diaconn/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from diaconn/src/main/res/values-pt-rPT/strings.xml rename to pump/diaconn/src/main/res/values-pt-rPT/strings.xml diff --git a/diaconn/src/main/res/values-ro-rRO/strings.xml b/pump/diaconn/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from diaconn/src/main/res/values-ro-rRO/strings.xml rename to pump/diaconn/src/main/res/values-ro-rRO/strings.xml diff --git a/diaconn/src/main/res/values-ru-rRU/strings.xml b/pump/diaconn/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from diaconn/src/main/res/values-ru-rRU/strings.xml rename to pump/diaconn/src/main/res/values-ru-rRU/strings.xml diff --git a/diaconn/src/main/res/values-sk-rSK/strings.xml b/pump/diaconn/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from diaconn/src/main/res/values-sk-rSK/strings.xml rename to pump/diaconn/src/main/res/values-sk-rSK/strings.xml diff --git a/diaconn/src/main/res/values-sl-rSI/strings.xml b/pump/diaconn/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from diaconn/src/main/res/values-sl-rSI/strings.xml rename to pump/diaconn/src/main/res/values-sl-rSI/strings.xml diff --git a/diaconn/src/main/res/values-sr-rCS/strings.xml b/pump/diaconn/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from diaconn/src/main/res/values-sr-rCS/strings.xml rename to pump/diaconn/src/main/res/values-sr-rCS/strings.xml diff --git a/diaconn/src/main/res/values-sv-rSE/strings.xml b/pump/diaconn/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from diaconn/src/main/res/values-sv-rSE/strings.xml rename to pump/diaconn/src/main/res/values-sv-rSE/strings.xml diff --git a/diaconn/src/main/res/values-ta-rIN/strings.xml b/pump/diaconn/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from diaconn/src/main/res/values-ta-rIN/strings.xml rename to pump/diaconn/src/main/res/values-ta-rIN/strings.xml diff --git a/diaconn/src/main/res/values-tr-rTR/strings.xml b/pump/diaconn/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from diaconn/src/main/res/values-tr-rTR/strings.xml rename to pump/diaconn/src/main/res/values-tr-rTR/strings.xml diff --git a/diaconn/src/main/res/values-zh-rCN/strings.xml b/pump/diaconn/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from diaconn/src/main/res/values-zh-rCN/strings.xml rename to pump/diaconn/src/main/res/values-zh-rCN/strings.xml diff --git a/diaconn/src/main/res/values/arrays.xml b/pump/diaconn/src/main/res/values/arrays.xml similarity index 100% rename from diaconn/src/main/res/values/arrays.xml rename to pump/diaconn/src/main/res/values/arrays.xml diff --git a/diaconn/src/main/res/values/colors.xml b/pump/diaconn/src/main/res/values/colors.xml similarity index 100% rename from diaconn/src/main/res/values/colors.xml rename to pump/diaconn/src/main/res/values/colors.xml diff --git a/diaconn/src/main/res/values/ids.xml b/pump/diaconn/src/main/res/values/ids.xml similarity index 100% rename from diaconn/src/main/res/values/ids.xml rename to pump/diaconn/src/main/res/values/ids.xml diff --git a/diaconn/src/main/res/values/strings.xml b/pump/diaconn/src/main/res/values/strings.xml similarity index 100% rename from diaconn/src/main/res/values/strings.xml rename to pump/diaconn/src/main/res/values/strings.xml diff --git a/diaconn/src/main/res/xml/pref_diaconn.xml b/pump/diaconn/src/main/res/xml/pref_diaconn.xml similarity index 100% rename from diaconn/src/main/res/xml/pref_diaconn.xml rename to pump/diaconn/src/main/res/xml/pref_diaconn.xml diff --git a/medtronic/.gitignore b/pump/medtronic/.gitignore similarity index 100% rename from medtronic/.gitignore rename to pump/medtronic/.gitignore diff --git a/medtronic/Changelog.txt b/pump/medtronic/Changelog.txt similarity index 100% rename from medtronic/Changelog.txt rename to pump/medtronic/Changelog.txt diff --git a/medtronic/build.gradle b/pump/medtronic/build.gradle similarity index 87% rename from medtronic/build.gradle rename to pump/medtronic/build.gradle index 525dd93b52..9d8ba7a41d 100644 --- a/medtronic/build.gradle +++ b/pump/medtronic/build.gradle @@ -14,8 +14,8 @@ android { dependencies { implementation project(':libraries') - implementation project(':core') - implementation project(':pump-common') - implementation project(':rileylink') implementation project(':shared') + implementation project(':core') + implementation project(':pump:pump-common') + implementation project(':pump:rileylink') } diff --git a/medtronic/consumer-rules.pro b/pump/medtronic/consumer-rules.pro similarity index 100% rename from medtronic/consumer-rules.pro rename to pump/medtronic/consumer-rules.pro diff --git a/medtronic/proguard-rules.pro b/pump/medtronic/proguard-rules.pro similarity index 100% rename from medtronic/proguard-rules.pro rename to pump/medtronic/proguard-rules.pro diff --git a/medtronic/src/main/AndroidManifest.xml b/pump/medtronic/src/main/AndroidManifest.xml similarity index 100% rename from medtronic/src/main/AndroidManifest.xml rename to pump/medtronic/src/main/AndroidManifest.xml diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverter.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverter.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverter.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverter.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoder.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoder.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoder.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoder.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoderInterface.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoderInterface.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoderInterface.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryDecoderInterface.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntryInterface.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntryInterface.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntryInterface.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntryInterface.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RawHistoryPage.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RawHistoryPage.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RawHistoryPage.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RawHistoryPage.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RecordDecodeStatus.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RecordDecodeStatus.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RecordDecodeStatus.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/RecordDecodeStatus.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntryType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntryType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntryType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntryType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryResult.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryResult.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryResult.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryResult.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkLongMessageBody.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkLongMessageBody.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkLongMessageBody.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkLongMessageBody.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkShortMessageBody.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkShortMessageBody.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkShortMessageBody.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/CarelinkShortMessageBody.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/GetHistoryPageCarelinkMessageBody.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/GetHistoryPageCarelinkMessageBody.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/GetHistoryPageCarelinkMessageBody.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/GetHistoryPageCarelinkMessageBody.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/MessageBody.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/MessageBody.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/MessageBody.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/MessageBody.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PacketType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PacketType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PacketType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PacketType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpAckMessageBody.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpAckMessageBody.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpAckMessageBody.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpAckMessageBody.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpMessage.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpMessage.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpMessage.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/PumpMessage.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/UnknownMessageBody.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/UnknownMessageBody.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/UnknownMessageBody.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/message/UnknownMessageBody.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIComm.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIComm.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIComm.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIComm.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIPostprocessor.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIPostprocessor.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIPostprocessor.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUIPostprocessor.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUITask.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUITask.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUITask.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/ui/MedtronicUITask.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfile.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfile.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfile.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfile.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileEntry.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileEntry.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileEntry.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileEntry.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BatteryStatusDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BatteryStatusDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BatteryStatusDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BatteryStatusDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusWizardDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusWizardDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusWizardDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BolusWizardDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/ClockDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/ClockDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/ClockDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/ClockDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/DailyTotalsDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/DailyTotalsDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/DailyTotalsDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/DailyTotalsDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpSettingDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpSettingDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpSettingDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpSettingDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpTimeStampedRecord.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpTimeStampedRecord.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpTimeStampedRecord.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/PumpTimeStampedRecord.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/RLHistoryItemMedtronic.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/RLHistoryItemMedtronic.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/RLHistoryItemMedtronic.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/RLHistoryItemMedtronic.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BasalProfileStatus.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BasalProfileStatus.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BasalProfileStatus.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BasalProfileStatus.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BatteryType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BatteryType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BatteryType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/BatteryType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCommandType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCommandType.kt old mode 100755 new mode 100644 similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCommandType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCommandType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCustomActionType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCustomActionType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCustomActionType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicCustomActionType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicDeviceType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicDeviceType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicDeviceType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicDeviceType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicNotificationType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicNotificationType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicNotificationType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicNotificationType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicStatusRefreshType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicStatusRefreshType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicStatusRefreshType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicStatusRefreshType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicUIResponseType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicUIResponseType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicUIResponseType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/MedtronicUIResponseType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpBolusType.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpBolusType.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpBolusType.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpBolusType.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpConfigurationGroup.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpConfigurationGroup.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpConfigurationGroup.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/defs/PumpConfigurationGroup.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/di/MedtronicModule.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/di/MedtronicModule.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/di/MedtronicModule.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/di/MedtronicModule.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpConfigurationChanged.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpConfigurationChanged.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpConfigurationChanged.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpConfigurationChanged.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpValuesChanged.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpValuesChanged.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpValuesChanged.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/events/EventMedtronicPumpValuesChanged.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicConst.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicConst.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicConst.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicConst.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.kt similarity index 100% rename from medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.kt rename to pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.kt diff --git a/medtronic/src/main/res/drawable/ic_medtronic_veo.xml b/pump/medtronic/src/main/res/drawable/ic_medtronic_veo.xml similarity index 100% rename from medtronic/src/main/res/drawable/ic_medtronic_veo.xml rename to pump/medtronic/src/main/res/drawable/ic_medtronic_veo.xml diff --git a/medtronic/src/main/res/layout/medtronic_fragment.xml b/pump/medtronic/src/main/res/layout/medtronic_fragment.xml similarity index 100% rename from medtronic/src/main/res/layout/medtronic_fragment.xml rename to pump/medtronic/src/main/res/layout/medtronic_fragment.xml diff --git a/medtronic/src/main/res/layout/medtronic_history_activity.xml b/pump/medtronic/src/main/res/layout/medtronic_history_activity.xml similarity index 100% rename from medtronic/src/main/res/layout/medtronic_history_activity.xml rename to pump/medtronic/src/main/res/layout/medtronic_history_activity.xml diff --git a/medtronic/src/main/res/layout/medtronic_history_item.xml b/pump/medtronic/src/main/res/layout/medtronic_history_item.xml similarity index 100% rename from medtronic/src/main/res/layout/medtronic_history_item.xml rename to pump/medtronic/src/main/res/layout/medtronic_history_item.xml diff --git a/medtronic/src/main/res/values-af-rZA/strings.xml b/pump/medtronic/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from medtronic/src/main/res/values-af-rZA/strings.xml rename to pump/medtronic/src/main/res/values-af-rZA/strings.xml diff --git a/medtronic/src/main/res/values-ar-rSA/strings.xml b/pump/medtronic/src/main/res/values-ar-rSA/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ar-rSA/strings.xml rename to pump/medtronic/src/main/res/values-ar-rSA/strings.xml diff --git a/medtronic/src/main/res/values-bg-rBG/strings.xml b/pump/medtronic/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from medtronic/src/main/res/values-bg-rBG/strings.xml rename to pump/medtronic/src/main/res/values-bg-rBG/strings.xml diff --git a/medtronic/src/main/res/values-ca-rES/strings.xml b/pump/medtronic/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ca-rES/strings.xml rename to pump/medtronic/src/main/res/values-ca-rES/strings.xml diff --git a/medtronic/src/main/res/values-cs-rCZ/strings.xml b/pump/medtronic/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from medtronic/src/main/res/values-cs-rCZ/strings.xml rename to pump/medtronic/src/main/res/values-cs-rCZ/strings.xml diff --git a/medtronic/src/main/res/values-cy-rGB/strings.xml b/pump/medtronic/src/main/res/values-cy-rGB/strings.xml similarity index 100% rename from medtronic/src/main/res/values-cy-rGB/strings.xml rename to pump/medtronic/src/main/res/values-cy-rGB/strings.xml diff --git a/medtronic/src/main/res/values-da-rDK/strings.xml b/pump/medtronic/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from medtronic/src/main/res/values-da-rDK/strings.xml rename to pump/medtronic/src/main/res/values-da-rDK/strings.xml diff --git a/medtronic/src/main/res/values-de-rDE/strings.xml b/pump/medtronic/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from medtronic/src/main/res/values-de-rDE/strings.xml rename to pump/medtronic/src/main/res/values-de-rDE/strings.xml diff --git a/medtronic/src/main/res/values-el-rGR/strings.xml b/pump/medtronic/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from medtronic/src/main/res/values-el-rGR/strings.xml rename to pump/medtronic/src/main/res/values-el-rGR/strings.xml diff --git a/medtronic/src/main/res/values-es-rES/strings.xml b/pump/medtronic/src/main/res/values-es-rES/strings.xml similarity index 100% rename from medtronic/src/main/res/values-es-rES/strings.xml rename to pump/medtronic/src/main/res/values-es-rES/strings.xml diff --git a/medtronic/src/main/res/values-fi-rFI/strings.xml b/pump/medtronic/src/main/res/values-fi-rFI/strings.xml similarity index 100% rename from medtronic/src/main/res/values-fi-rFI/strings.xml rename to pump/medtronic/src/main/res/values-fi-rFI/strings.xml diff --git a/medtronic/src/main/res/values-fr-rFR/strings.xml b/pump/medtronic/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from medtronic/src/main/res/values-fr-rFR/strings.xml rename to pump/medtronic/src/main/res/values-fr-rFR/strings.xml diff --git a/medtronic/src/main/res/values-ga-rIE/strings.xml b/pump/medtronic/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ga-rIE/strings.xml rename to pump/medtronic/src/main/res/values-ga-rIE/strings.xml diff --git a/medtronic/src/main/res/values-hr-rHR/strings.xml b/pump/medtronic/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from medtronic/src/main/res/values-hr-rHR/strings.xml rename to pump/medtronic/src/main/res/values-hr-rHR/strings.xml diff --git a/medtronic/src/main/res/values-hu-rHU/strings.xml b/pump/medtronic/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from medtronic/src/main/res/values-hu-rHU/strings.xml rename to pump/medtronic/src/main/res/values-hu-rHU/strings.xml diff --git a/medtronic/src/main/res/values-it-rIT/strings.xml b/pump/medtronic/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from medtronic/src/main/res/values-it-rIT/strings.xml rename to pump/medtronic/src/main/res/values-it-rIT/strings.xml diff --git a/medtronic/src/main/res/values-iw-rIL/strings.xml b/pump/medtronic/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from medtronic/src/main/res/values-iw-rIL/strings.xml rename to pump/medtronic/src/main/res/values-iw-rIL/strings.xml diff --git a/medtronic/src/main/res/values-ko-rKR/strings.xml b/pump/medtronic/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ko-rKR/strings.xml rename to pump/medtronic/src/main/res/values-ko-rKR/strings.xml diff --git a/medtronic/src/main/res/values-lt-rLT/strings.xml b/pump/medtronic/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from medtronic/src/main/res/values-lt-rLT/strings.xml rename to pump/medtronic/src/main/res/values-lt-rLT/strings.xml diff --git a/medtronic/src/main/res/values-nl-rNL/strings.xml b/pump/medtronic/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from medtronic/src/main/res/values-nl-rNL/strings.xml rename to pump/medtronic/src/main/res/values-nl-rNL/strings.xml diff --git a/medtronic/src/main/res/values-no-rNO/strings.xml b/pump/medtronic/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from medtronic/src/main/res/values-no-rNO/strings.xml rename to pump/medtronic/src/main/res/values-no-rNO/strings.xml diff --git a/medtronic/src/main/res/values-pl-rPL/strings.xml b/pump/medtronic/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from medtronic/src/main/res/values-pl-rPL/strings.xml rename to pump/medtronic/src/main/res/values-pl-rPL/strings.xml diff --git a/medtronic/src/main/res/values-pt-rBR/strings.xml b/pump/medtronic/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from medtronic/src/main/res/values-pt-rBR/strings.xml rename to pump/medtronic/src/main/res/values-pt-rBR/strings.xml diff --git a/medtronic/src/main/res/values-pt-rPT/strings.xml b/pump/medtronic/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from medtronic/src/main/res/values-pt-rPT/strings.xml rename to pump/medtronic/src/main/res/values-pt-rPT/strings.xml diff --git a/medtronic/src/main/res/values-ro-rRO/strings.xml b/pump/medtronic/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ro-rRO/strings.xml rename to pump/medtronic/src/main/res/values-ro-rRO/strings.xml diff --git a/medtronic/src/main/res/values-ru-rRU/strings.xml b/pump/medtronic/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ru-rRU/strings.xml rename to pump/medtronic/src/main/res/values-ru-rRU/strings.xml diff --git a/medtronic/src/main/res/values-sk-rSK/strings.xml b/pump/medtronic/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from medtronic/src/main/res/values-sk-rSK/strings.xml rename to pump/medtronic/src/main/res/values-sk-rSK/strings.xml diff --git a/medtronic/src/main/res/values-sl-rSI/strings.xml b/pump/medtronic/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from medtronic/src/main/res/values-sl-rSI/strings.xml rename to pump/medtronic/src/main/res/values-sl-rSI/strings.xml diff --git a/medtronic/src/main/res/values-sr-rCS/strings.xml b/pump/medtronic/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from medtronic/src/main/res/values-sr-rCS/strings.xml rename to pump/medtronic/src/main/res/values-sr-rCS/strings.xml diff --git a/medtronic/src/main/res/values-sv-rSE/strings.xml b/pump/medtronic/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from medtronic/src/main/res/values-sv-rSE/strings.xml rename to pump/medtronic/src/main/res/values-sv-rSE/strings.xml diff --git a/medtronic/src/main/res/values-ta-rIN/strings.xml b/pump/medtronic/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from medtronic/src/main/res/values-ta-rIN/strings.xml rename to pump/medtronic/src/main/res/values-ta-rIN/strings.xml diff --git a/medtronic/src/main/res/values-tr-rTR/strings.xml b/pump/medtronic/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from medtronic/src/main/res/values-tr-rTR/strings.xml rename to pump/medtronic/src/main/res/values-tr-rTR/strings.xml diff --git a/medtronic/src/main/res/values-zh-rCN/strings.xml b/pump/medtronic/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from medtronic/src/main/res/values-zh-rCN/strings.xml rename to pump/medtronic/src/main/res/values-zh-rCN/strings.xml diff --git a/medtronic/src/main/res/values/arrays.xml b/pump/medtronic/src/main/res/values/arrays.xml similarity index 100% rename from medtronic/src/main/res/values/arrays.xml rename to pump/medtronic/src/main/res/values/arrays.xml diff --git a/medtronic/src/main/res/values/strings.xml b/pump/medtronic/src/main/res/values/strings.xml similarity index 100% rename from medtronic/src/main/res/values/strings.xml rename to pump/medtronic/src/main/res/values/strings.xml diff --git a/medtronic/src/main/res/xml/pref_medtronic.xml b/pump/medtronic/src/main/res/xml/pref_medtronic.xml similarity index 100% rename from medtronic/src/main/res/xml/pref_medtronic.xml rename to pump/medtronic/src/main/res/xml/pref_medtronic.xml diff --git a/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt b/pump/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt rename to pump/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverterUTest.java b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverterUTest.java similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverterUTest.java rename to pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicConverterUTest.java diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt rename to pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt rename to pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryUTest.java b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryUTest.java similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryUTest.java rename to pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntryUTest.java diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt rename to pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileUTest.java b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileUTest.java similarity index 100% rename from medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileUTest.java rename to pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/BasalProfileUTest.java diff --git a/medtronic/src/test/resources/tbr_1724.json b/pump/medtronic/src/test/resources/tbr_1724.json similarity index 100% rename from medtronic/src/test/resources/tbr_1724.json rename to pump/medtronic/src/test/resources/tbr_1724.json diff --git a/medtronic/src/test/resources/tbr_data.json b/pump/medtronic/src/test/resources/tbr_data.json similarity index 100% rename from medtronic/src/test/resources/tbr_data.json rename to pump/medtronic/src/test/resources/tbr_data.json diff --git a/medtronic/src/test/resources/tbr_data_special.json b/pump/medtronic/src/test/resources/tbr_data_special.json similarity index 100% rename from medtronic/src/test/resources/tbr_data_special.json rename to pump/medtronic/src/test/resources/tbr_data_special.json diff --git a/omnipod-common/.gitignore b/pump/omnipod-common/.gitignore similarity index 100% rename from omnipod-common/.gitignore rename to pump/omnipod-common/.gitignore diff --git a/omnipod-common/build.gradle b/pump/omnipod-common/build.gradle similarity index 100% rename from omnipod-common/build.gradle rename to pump/omnipod-common/build.gradle diff --git a/omnipod-common/consumer-rules.pro b/pump/omnipod-common/consumer-rules.pro similarity index 100% rename from omnipod-common/consumer-rules.pro rename to pump/omnipod-common/consumer-rules.pro diff --git a/omnipod-common/proguard-rules.pro b/pump/omnipod-common/proguard-rules.pro similarity index 100% rename from omnipod-common/proguard-rules.pro rename to pump/omnipod-common/proguard-rules.pro diff --git a/omnipod-common/src/main/AndroidManifest.xml b/pump/omnipod-common/src/main/AndroidManifest.xml similarity index 100% rename from omnipod-common/src/main/AndroidManifest.xml rename to pump/omnipod-common/src/main/AndroidManifest.xml diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/definition/OmnipodCommandType.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/definition/OmnipodCommandType.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/definition/OmnipodCommandType.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/definition/OmnipodCommandType.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodInjectHelpers.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodInjectHelpers.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodInjectHelpers.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodInjectHelpers.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodWizardModule.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodWizardModule.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodWizardModule.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/di/OmnipodWizardModule.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDeactivatePod.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDeactivatePod.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDeactivatePod.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDeactivatePod.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDisableSuspendAlerts.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDisableSuspendAlerts.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDisableSuspendAlerts.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandDisableSuspendAlerts.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandHandleTimeChange.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandHandleTimeChange.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandHandleTimeChange.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandHandleTimeChange.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandPlayTestBeep.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandPlayTestBeep.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandPlayTestBeep.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandPlayTestBeep.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandResumeDelivery.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandResumeDelivery.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandResumeDelivery.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandResumeDelivery.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSilenceAlerts.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSilenceAlerts.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSilenceAlerts.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSilenceAlerts.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSuspendDelivery.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSuspendDelivery.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSuspendDelivery.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandSuspendDelivery.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandUpdateAlertConfiguration.java b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandUpdateAlertConfiguration.java similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandUpdateAlertConfiguration.java rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/queue/command/CommandUpdateAlertConfiguration.java diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/PodActivationWizardActivity.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/PodActivationWizardActivity.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/PodActivationWizardActivity.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/PodActivationWizardActivity.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InitializePodFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InitializePodFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InitializePodFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InitializePodFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InsertCannulaFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InsertCannulaFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InsertCannulaFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/InsertCannulaFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/PodActivationActionFragmentBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/PodActivationActionFragmentBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/PodActivationActionFragmentBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/action/PodActivationActionFragmentBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/AttachPodFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/AttachPodFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/AttachPodFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/AttachPodFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/PodActivatedFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/PodActivatedFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/PodActivatedFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/PodActivatedFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/StartPodActivationFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/StartPodActivationFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/StartPodActivationFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/fragment/info/StartPodActivationFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InitializePodViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InitializePodViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InitializePodViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InitializePodViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InsertCannulaViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InsertCannulaViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InsertCannulaViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/InsertCannulaViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/PodActivationActionViewModelBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/PodActivationActionViewModelBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/PodActivationActionViewModelBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/action/PodActivationActionViewModelBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/AttachPodViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/AttachPodViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/AttachPodViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/AttachPodViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/PodActivatedViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/PodActivatedViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/PodActivatedViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/PodActivatedViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/StartPodActivationViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/StartPodActivationViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/StartPodActivationViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/activation/viewmodel/info/StartPodActivationViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/activity/OmnipodWizardActivityBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/activity/OmnipodWizardActivityBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/activity/OmnipodWizardActivityBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/activity/OmnipodWizardActivityBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/ActionFragmentBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/ActionFragmentBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/ActionFragmentBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/ActionFragmentBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/InfoFragmentBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/InfoFragmentBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/InfoFragmentBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/InfoFragmentBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/WizardFragmentBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/WizardFragmentBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/WizardFragmentBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/fragment/WizardFragmentBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ActionViewModelBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ActionViewModelBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ActionViewModelBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ActionViewModelBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ViewModelBase.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ViewModelBase.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ViewModelBase.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/common/viewmodel/ViewModelBase.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/PodDeactivationWizardActivity.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/PodDeactivationWizardActivity.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/PodDeactivationWizardActivity.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/PodDeactivationWizardActivity.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDeactivatedFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDeactivatedFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDeactivatedFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDeactivatedFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDiscardedFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDiscardedFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDiscardedFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/PodDiscardedFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/StartPodDeactivationFragment.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/StartPodDeactivationFragment.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/StartPodDeactivationFragment.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/info/StartPodDeactivationFragment.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/action/DeactivatePodViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/action/DeactivatePodViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/action/DeactivatePodViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/action/DeactivatePodViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDeactivatedViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDeactivatedViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDeactivatedViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDeactivatedViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDiscardedViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDiscardedViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDiscardedViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/PodDiscardedViewModel.kt diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/StartPodDeactivationViewModel.kt b/pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/StartPodDeactivationViewModel.kt similarity index 100% rename from omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/StartPodDeactivationViewModel.kt rename to pump/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/viewmodel/info/StartPodDeactivationViewModel.kt diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_overview_pod_management.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_pod_management.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_overview_pod_management.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_pod_management.xml diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_overview_refresh_pod_status.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_refresh_pod_status.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_overview_refresh_pod_status.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_refresh_pod_status.xml diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_overview_resume_delivery.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_resume_delivery.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_overview_resume_delivery.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_resume_delivery.xml diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_overview_set_time.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_set_time.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_overview_set_time.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_set_time.xml diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_overview_silence_alerts.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_silence_alerts.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_overview_silence_alerts.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_silence_alerts.xml diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_overview_suspend_delivery.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_suspend_delivery.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_overview_suspend_delivery.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_overview_suspend_delivery.xml diff --git a/omnipod-common/src/main/res/drawable/ic_omnipod_wizard_success.xml b/pump/omnipod-common/src/main/res/drawable/ic_omnipod_wizard_success.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_omnipod_wizard_success.xml rename to pump/omnipod-common/src/main/res/drawable/ic_omnipod_wizard_success.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod_management_activate_pod.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod_management_activate_pod.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod_management_activate_pod.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod_management_activate_pod.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod_management_deactivate_pod.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod_management_deactivate_pod.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod_management_deactivate_pod.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod_management_deactivate_pod.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod_management_discard_pod.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod_management_discard_pod.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod_management_discard_pod.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod_management_discard_pod.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod_management_play_test_beep.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod_management_play_test_beep.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod_management_play_test_beep.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod_management_play_test_beep.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod_management_pod_history.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod_management_pod_history.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod_management_pod_history.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod_management_pod_history.xml diff --git a/omnipod-common/src/main/res/drawable/ic_pod_management_pulse_log.xml b/pump/omnipod-common/src/main/res/drawable/ic_pod_management_pulse_log.xml similarity index 100% rename from omnipod-common/src/main/res/drawable/ic_pod_management_pulse_log.xml rename to pump/omnipod-common/src/main/res/drawable/ic_pod_management_pulse_log.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_overview_buttons.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_overview_buttons.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_overview_buttons.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_overview_buttons.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_overview_pod_info.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_overview_pod_info.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_overview_pod_info.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_overview_pod_info.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_pod_activation_wizard_activity.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_pod_activation_wizard_activity.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_pod_activation_wizard_activity.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_pod_activation_wizard_activity.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_pod_deactivation_wizard_activity.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_pod_deactivation_wizard_activity.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_pod_deactivation_wizard_activity.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_pod_deactivation_wizard_activity.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_wizard_action_page_fragment.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_action_page_fragment.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_wizard_action_page_fragment.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_action_page_fragment.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_wizard_base_fragment.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_base_fragment.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_wizard_base_fragment.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_base_fragment.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_wizard_info_page_fragment.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_info_page_fragment.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_wizard_info_page_fragment.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_info_page_fragment.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_wizard_nav_buttons.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_nav_buttons.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_wizard_nav_buttons.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_nav_buttons.xml diff --git a/omnipod-common/src/main/res/layout/omnipod_common_wizard_progress_indication.xml b/pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_progress_indication.xml similarity index 100% rename from omnipod-common/src/main/res/layout/omnipod_common_wizard_progress_indication.xml rename to pump/omnipod-common/src/main/res/layout/omnipod_common_wizard_progress_indication.xml diff --git a/omnipod-common/src/main/res/navigation/omnipod_common_pod_activation_wizard_navigation_graph.xml b/pump/omnipod-common/src/main/res/navigation/omnipod_common_pod_activation_wizard_navigation_graph.xml similarity index 100% rename from omnipod-common/src/main/res/navigation/omnipod_common_pod_activation_wizard_navigation_graph.xml rename to pump/omnipod-common/src/main/res/navigation/omnipod_common_pod_activation_wizard_navigation_graph.xml diff --git a/omnipod-common/src/main/res/navigation/omnipod_common_pod_deactivation_wizard_navigation_graph.xml b/pump/omnipod-common/src/main/res/navigation/omnipod_common_pod_deactivation_wizard_navigation_graph.xml similarity index 100% rename from omnipod-common/src/main/res/navigation/omnipod_common_pod_deactivation_wizard_navigation_graph.xml rename to pump/omnipod-common/src/main/res/navigation/omnipod_common_pod_deactivation_wizard_navigation_graph.xml diff --git a/omnipod-common/src/main/res/values-af-rZA/strings.xml b/pump/omnipod-common/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-af-rZA/strings.xml rename to pump/omnipod-common/src/main/res/values-af-rZA/strings.xml diff --git a/omnipod-common/src/main/res/values-bg-rBG/strings.xml b/pump/omnipod-common/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-bg-rBG/strings.xml rename to pump/omnipod-common/src/main/res/values-bg-rBG/strings.xml diff --git a/omnipod-common/src/main/res/values-ca-rES/strings.xml b/pump/omnipod-common/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-ca-rES/strings.xml rename to pump/omnipod-common/src/main/res/values-ca-rES/strings.xml diff --git a/omnipod-common/src/main/res/values-cs-rCZ/strings.xml b/pump/omnipod-common/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-cs-rCZ/strings.xml rename to pump/omnipod-common/src/main/res/values-cs-rCZ/strings.xml diff --git a/omnipod-common/src/main/res/values-da-rDK/strings.xml b/pump/omnipod-common/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-da-rDK/strings.xml rename to pump/omnipod-common/src/main/res/values-da-rDK/strings.xml diff --git a/omnipod-common/src/main/res/values-de-rDE/strings.xml b/pump/omnipod-common/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-de-rDE/strings.xml rename to pump/omnipod-common/src/main/res/values-de-rDE/strings.xml diff --git a/omnipod-common/src/main/res/values-el-rGR/strings.xml b/pump/omnipod-common/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-el-rGR/strings.xml rename to pump/omnipod-common/src/main/res/values-el-rGR/strings.xml diff --git a/omnipod-common/src/main/res/values-es-rES/strings.xml b/pump/omnipod-common/src/main/res/values-es-rES/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-es-rES/strings.xml rename to pump/omnipod-common/src/main/res/values-es-rES/strings.xml diff --git a/omnipod-common/src/main/res/values-fr-rFR/strings.xml b/pump/omnipod-common/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-fr-rFR/strings.xml rename to pump/omnipod-common/src/main/res/values-fr-rFR/strings.xml diff --git a/omnipod-common/src/main/res/values-ga-rIE/strings.xml b/pump/omnipod-common/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-ga-rIE/strings.xml rename to pump/omnipod-common/src/main/res/values-ga-rIE/strings.xml diff --git a/omnipod-common/src/main/res/values-hr-rHR/strings.xml b/pump/omnipod-common/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-hr-rHR/strings.xml rename to pump/omnipod-common/src/main/res/values-hr-rHR/strings.xml diff --git a/omnipod-common/src/main/res/values-hu-rHU/strings.xml b/pump/omnipod-common/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-hu-rHU/strings.xml rename to pump/omnipod-common/src/main/res/values-hu-rHU/strings.xml diff --git a/omnipod-common/src/main/res/values-it-rIT/strings.xml b/pump/omnipod-common/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-it-rIT/strings.xml rename to pump/omnipod-common/src/main/res/values-it-rIT/strings.xml diff --git a/omnipod-common/src/main/res/values-iw-rIL/strings.xml b/pump/omnipod-common/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-iw-rIL/strings.xml rename to pump/omnipod-common/src/main/res/values-iw-rIL/strings.xml diff --git a/omnipod-common/src/main/res/values-ko-rKR/strings.xml b/pump/omnipod-common/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-ko-rKR/strings.xml rename to pump/omnipod-common/src/main/res/values-ko-rKR/strings.xml diff --git a/omnipod-common/src/main/res/values-lt-rLT/strings.xml b/pump/omnipod-common/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-lt-rLT/strings.xml rename to pump/omnipod-common/src/main/res/values-lt-rLT/strings.xml diff --git a/omnipod-common/src/main/res/values-nl-rNL/strings.xml b/pump/omnipod-common/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-nl-rNL/strings.xml rename to pump/omnipod-common/src/main/res/values-nl-rNL/strings.xml diff --git a/omnipod-common/src/main/res/values-no-rNO/strings.xml b/pump/omnipod-common/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-no-rNO/strings.xml rename to pump/omnipod-common/src/main/res/values-no-rNO/strings.xml diff --git a/omnipod-common/src/main/res/values-pl-rPL/strings.xml b/pump/omnipod-common/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-pl-rPL/strings.xml rename to pump/omnipod-common/src/main/res/values-pl-rPL/strings.xml diff --git a/omnipod-common/src/main/res/values-pt-rBR/strings.xml b/pump/omnipod-common/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-pt-rBR/strings.xml rename to pump/omnipod-common/src/main/res/values-pt-rBR/strings.xml diff --git a/omnipod-common/src/main/res/values-pt-rPT/strings.xml b/pump/omnipod-common/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-pt-rPT/strings.xml rename to pump/omnipod-common/src/main/res/values-pt-rPT/strings.xml diff --git a/omnipod-common/src/main/res/values-ro-rRO/strings.xml b/pump/omnipod-common/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-ro-rRO/strings.xml rename to pump/omnipod-common/src/main/res/values-ro-rRO/strings.xml diff --git a/omnipod-common/src/main/res/values-ru-rRU/strings.xml b/pump/omnipod-common/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-ru-rRU/strings.xml rename to pump/omnipod-common/src/main/res/values-ru-rRU/strings.xml diff --git a/omnipod-common/src/main/res/values-sk-rSK/strings.xml b/pump/omnipod-common/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-sk-rSK/strings.xml rename to pump/omnipod-common/src/main/res/values-sk-rSK/strings.xml diff --git a/omnipod-common/src/main/res/values-sl-rSI/strings.xml b/pump/omnipod-common/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-sl-rSI/strings.xml rename to pump/omnipod-common/src/main/res/values-sl-rSI/strings.xml diff --git a/omnipod-common/src/main/res/values-sr-rCS/strings.xml b/pump/omnipod-common/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-sr-rCS/strings.xml rename to pump/omnipod-common/src/main/res/values-sr-rCS/strings.xml diff --git a/omnipod-common/src/main/res/values-sv-rSE/strings.xml b/pump/omnipod-common/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-sv-rSE/strings.xml rename to pump/omnipod-common/src/main/res/values-sv-rSE/strings.xml diff --git a/omnipod-common/src/main/res/values-ta-rIN/strings.xml b/pump/omnipod-common/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-ta-rIN/strings.xml rename to pump/omnipod-common/src/main/res/values-ta-rIN/strings.xml diff --git a/omnipod-common/src/main/res/values-tr-rTR/strings.xml b/pump/omnipod-common/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-tr-rTR/strings.xml rename to pump/omnipod-common/src/main/res/values-tr-rTR/strings.xml diff --git a/omnipod-common/src/main/res/values-zh-rCN/strings.xml b/pump/omnipod-common/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values-zh-rCN/strings.xml rename to pump/omnipod-common/src/main/res/values-zh-rCN/strings.xml diff --git a/omnipod-common/src/main/res/values/dimens.xml b/pump/omnipod-common/src/main/res/values/dimens.xml similarity index 100% rename from omnipod-common/src/main/res/values/dimens.xml rename to pump/omnipod-common/src/main/res/values/dimens.xml diff --git a/omnipod-common/src/main/res/values/strings.xml b/pump/omnipod-common/src/main/res/values/strings.xml similarity index 100% rename from omnipod-common/src/main/res/values/strings.xml rename to pump/omnipod-common/src/main/res/values/strings.xml diff --git a/omnipod-common/src/main/res/values/styles.xml b/pump/omnipod-common/src/main/res/values/styles.xml similarity index 100% rename from omnipod-common/src/main/res/values/styles.xml rename to pump/omnipod-common/src/main/res/values/styles.xml diff --git a/omnipod-dash/.gitignore b/pump/omnipod-dash/.gitignore similarity index 100% rename from omnipod-dash/.gitignore rename to pump/omnipod-dash/.gitignore diff --git a/omnipod-dash/build.gradle b/pump/omnipod-dash/build.gradle similarity index 94% rename from omnipod-dash/build.gradle rename to pump/omnipod-dash/build.gradle index 04d92e3880..2f8de56b0e 100644 --- a/omnipod-dash/build.gradle +++ b/pump/omnipod-dash/build.gradle @@ -30,12 +30,12 @@ android { } dependencies { - implementation project(':libraries') - implementation project(':core') - implementation project(':pump-common') - implementation project(':omnipod-common') implementation project(':database') implementation project(':shared') + implementation project(':libraries') + implementation project(':core') + implementation project(':pump:pump-common') + implementation project(':pump:omnipod-common') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/omnipod-dash/consumer-rules.pro b/pump/omnipod-dash/consumer-rules.pro similarity index 100% rename from omnipod-dash/consumer-rules.pro rename to pump/omnipod-dash/consumer-rules.pro diff --git a/omnipod-dash/detekt-config.yml b/pump/omnipod-dash/detekt-config.yml similarity index 100% rename from omnipod-dash/detekt-config.yml rename to pump/omnipod-dash/detekt-config.yml diff --git a/omnipod-dash/proguard-rules.pro b/pump/omnipod-dash/proguard-rules.pro similarity index 100% rename from omnipod-dash/proguard-rules.pro rename to pump/omnipod-dash/proguard-rules.pro diff --git a/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt b/pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt similarity index 100% rename from omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt rename to pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt diff --git a/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt b/pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt similarity index 100% rename from omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt rename to pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt diff --git a/omnipod-dash/src/main/AndroidManifest.xml b/pump/omnipod-dash/src/main/AndroidManifest.xml similarity index 100% rename from omnipod-dash/src/main/AndroidManifest.xml rename to pump/omnipod-dash/src/main/AndroidManifest.xml diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/EventOmnipodDashPumpValuesChanged.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/EventOmnipodDashPumpValuesChanged.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/EventOmnipodDashPumpValuesChanged.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/EventOmnipodDashPumpValuesChanged.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashHistoryModule.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashHistoryModule.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashHistoryModule.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashHistoryModule.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashModule.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashModule.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashModule.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashModule.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashWizardViewModelsModule.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashWizardViewModelsModule.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashWizardViewModelsModule.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/di/OmnipodDashWizardViewModelsModule.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/WriteConfirmation.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/WriteConfirmation.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/WriteConfirmation.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/WriteConfirmation.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/Nonce.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/Nonce.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/Nonce.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/Nonce.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BusyException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BusyException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BusyException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BusyException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ConnectException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ConnectException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ConnectException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ConnectException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseMessageException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseMessageException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseMessageException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseMessageException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseResponseException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseResponseException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseResponseException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotParseResponseException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendCommandException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendCommandException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendCommandException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendCommandException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/MessageIOException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/MessageIOException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/MessageIOException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/MessageIOException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/NotConnectedException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/NotConnectedException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/NotConnectedException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/NotConnectedException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/PairingException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/PairingException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/PairingException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/PairingException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/SessionEstablishmentException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/SessionEstablishmentException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/SessionEstablishmentException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/SessionEstablishmentException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CharacteristicType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CharacteristicType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CharacteristicType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CharacteristicType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CmdBleIO.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CmdBleIO.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CmdBleIO.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/CmdBleIO.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/DataBleIO.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/DataBleIO.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/DataBleIO.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/DataBleIO.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IncomingPackets.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IncomingPackets.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IncomingPackets.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IncomingPackets.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/CrcMismatchException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/CrcMismatchException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/CrcMismatchException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/CrcMismatchException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/IncorrectPacketException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/IncorrectPacketException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/IncorrectPacketException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/IncorrectPacketException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacket.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacket.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacket.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacket.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncoding.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncoding.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncoding.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncoding.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadSplitter.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadSplitter.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadSplitter.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadSplitter.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchange.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchange.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchange.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchange.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairMessage.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairMessage.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairMessage.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairMessage.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/DiscoveredInvalidPodException.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/DiscoveredInvalidPodException.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/DiscoveredInvalidPodException.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/DiscoveredInvalidPodException.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ConnectionStateChangeHandler.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ConnectionStateChangeHandler.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ConnectionStateChangeHandler.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ConnectionStateChangeHandler.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/DisconnectHandler.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/DisconnectHandler.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/DisconnectHandler.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/DisconnectHandler.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapAkaAttribute.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapAkaAttribute.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapAkaAttribute.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapAkaAttribute.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapSqn.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapSqn.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapSqn.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapSqn.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Milenage.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Milenage.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Milenage.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Milenage.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ResponseUtil.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ResponseUtil.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ResponseUtil.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/ResponseUtil.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionKeys.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionKeys.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionKeys.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionKeys.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramInsulinCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramInsulinCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramInsulinCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramInsulinCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/CommandType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/CommandType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/CommandType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/CommandType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/NonceEnabledCommand.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/NonceEnabledCommand.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/NonceEnabledCommand.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/NonceEnabledCommand.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/CommandBuilder.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/CommandBuilder.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/CommandBuilder.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/CommandBuilder.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/HeaderEnabledCommandBuilder.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/HeaderEnabledCommandBuilder.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/HeaderEnabledCommandBuilder.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/HeaderEnabledCommandBuilder.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/NonceEnabledCommandBuilder.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/NonceEnabledCommandBuilder.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/NonceEnabledCommandBuilder.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/builder/NonceEnabledCommandBuilder.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalInsulinProgramElement.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalInsulinProgramElement.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalInsulinProgramElement.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalInsulinProgramElement.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalShortInsulinProgramElement.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalShortInsulinProgramElement.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalShortInsulinProgramElement.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BasalShortInsulinProgramElement.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BolusShortInsulinProgramElement.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BolusShortInsulinProgramElement.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BolusShortInsulinProgramElement.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/BolusShortInsulinProgramElement.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentBasalInsulinProgramElement.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentBasalInsulinProgramElement.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentBasalInsulinProgramElement.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentBasalInsulinProgramElement.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentSlot.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentSlot.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentSlot.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/CurrentSlot.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/ShortInsulinProgramElement.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/ShortInsulinProgramElement.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/ShortInsulinProgramElement.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/ShortInsulinProgramElement.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/TempBasalInsulinProgramElement.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/TempBasalInsulinProgramElement.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/TempBasalInsulinProgramElement.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/TempBasalInsulinProgramElement.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramBasalUtil.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramBasalUtil.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramBasalUtil.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramBasalUtil.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramTempBasalUtil.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramTempBasalUtil.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramTempBasalUtil.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/insulin/program/util/ProgramTempBasalUtil.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ActivationProgress.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ActivationProgress.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ActivationProgress.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ActivationProgress.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlarmType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlarmType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlarmType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlarmType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertConfiguration.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertConfiguration.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertConfiguration.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertConfiguration.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertTrigger.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertTrigger.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertTrigger.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertTrigger.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/AlertType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepRepetitionType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepRepetitionType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepRepetitionType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepRepetitionType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BeepType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/DeliveryStatus.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/DeliveryStatus.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/DeliveryStatus.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/DeliveryStatus.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/Encodable.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/Encodable.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/Encodable.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/Encodable.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/NakErrorType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/NakErrorType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/NakErrorType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/NakErrorType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodStatus.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodStatus.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodStatus.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodStatus.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/SoftwareVersion.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/SoftwareVersion.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/SoftwareVersion.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/SoftwareVersion.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ActivationResponseBase.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ActivationResponseBase.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ActivationResponseBase.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ActivationResponseBase.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AdditionalStatusResponseBase.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AdditionalStatusResponseBase.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AdditionalStatusResponseBase.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AdditionalStatusResponseBase.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponse.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponse.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponse.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponse.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponse.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponse.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponse.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponse.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponse.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/Response.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/Response.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/Response.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/Response.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseBase.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseBase.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseBase.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseBase.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseType.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseType.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseType.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/ResponseType.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponse.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponse.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponse.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponse.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponse.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponse.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/AlertUtil.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/AlertUtil.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/AlertUtil.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/AlertUtil.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/HasValue.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/HasValue.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/HasValue.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/HasValue.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/MessageUtil.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/MessageUtil.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/MessageUtil.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/MessageUtil.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/RandomByteGenerator.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/RandomByteGenerator.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/RandomByteGenerator.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/RandomByteGenerator.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/X25519KeyGenerator.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/X25519KeyGenerator.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/X25519KeyGenerator.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/util/X25519KeyGenerator.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodHistoryActivity.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodHistoryActivity.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodHistoryActivity.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodHistoryActivity.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/DashPodActivationWizardActivity.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/DashPodActivationWizardActivity.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/DashPodActivationWizardActivity.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/DashPodActivationWizardActivity.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInitializePodViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInitializePodViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInitializePodViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInitializePodViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInsertCannulaViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInsertCannulaViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInsertCannulaViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/action/DashInsertCannulaViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashAttachPodViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashAttachPodViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashAttachPodViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashAttachPodViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashPodActivatedViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashPodActivatedViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashPodActivatedViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashPodActivatedViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashStartPodActivationViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashStartPodActivationViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashStartPodActivationViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/activation/viewmodel/info/DashStartPodActivationViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/DashPodDeactivationWizardActivity.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/DashPodDeactivationWizardActivity.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/DashPodDeactivationWizardActivity.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/DashPodDeactivationWizardActivity.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/action/DashDeactivatePodViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/action/DashDeactivatePodViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/action/DashDeactivatePodViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/action/DashDeactivatePodViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDeactivatedViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDeactivatedViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDeactivatedViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDeactivatedViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDiscardedViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDiscardedViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDiscardedViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashPodDiscardedViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashStartPodDeactivationViewModel.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashStartPodDeactivationViewModel.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashStartPodDeactivationViewModel.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/wizard/deactivation/viewmodel/info/DashStartPodDeactivationViewModel.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Constants.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Constants.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Constants.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Constants.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Flag.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Flag.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Flag.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Flag.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Functions.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Functions.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Functions.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/Functions.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/I8n.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/I8n.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/I8n.kt rename to pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/I8n.kt diff --git a/omnipod-dash/src/main/res/layout/omnipod_dash_overview.xml b/pump/omnipod-dash/src/main/res/layout/omnipod_dash_overview.xml similarity index 100% rename from omnipod-dash/src/main/res/layout/omnipod_dash_overview.xml rename to pump/omnipod-dash/src/main/res/layout/omnipod_dash_overview.xml diff --git a/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml b/pump/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml similarity index 100% rename from omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml rename to pump/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml diff --git a/omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_activity.xml b/pump/omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_activity.xml similarity index 100% rename from omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_activity.xml rename to pump/omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_activity.xml diff --git a/omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_item.xml b/pump/omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_item.xml similarity index 100% rename from omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_item.xml rename to pump/omnipod-dash/src/main/res/layout/omnipod_dash_pod_history_item.xml diff --git a/omnipod-dash/src/main/res/layout/omnipod_dash_pod_management.xml b/pump/omnipod-dash/src/main/res/layout/omnipod_dash_pod_management.xml similarity index 100% rename from omnipod-dash/src/main/res/layout/omnipod_dash_pod_management.xml rename to pump/omnipod-dash/src/main/res/layout/omnipod_dash_pod_management.xml diff --git a/omnipod-dash/src/main/res/values-af-rZA/strings.xml b/pump/omnipod-dash/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-af-rZA/strings.xml rename to pump/omnipod-dash/src/main/res/values-af-rZA/strings.xml diff --git a/omnipod-dash/src/main/res/values-bg-rBG/strings.xml b/pump/omnipod-dash/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-bg-rBG/strings.xml rename to pump/omnipod-dash/src/main/res/values-bg-rBG/strings.xml diff --git a/omnipod-dash/src/main/res/values-ca-rES/strings.xml b/pump/omnipod-dash/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-ca-rES/strings.xml rename to pump/omnipod-dash/src/main/res/values-ca-rES/strings.xml diff --git a/omnipod-dash/src/main/res/values-cs-rCZ/strings.xml b/pump/omnipod-dash/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-cs-rCZ/strings.xml rename to pump/omnipod-dash/src/main/res/values-cs-rCZ/strings.xml diff --git a/omnipod-dash/src/main/res/values-da-rDK/strings.xml b/pump/omnipod-dash/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-da-rDK/strings.xml rename to pump/omnipod-dash/src/main/res/values-da-rDK/strings.xml diff --git a/omnipod-dash/src/main/res/values-de-rDE/strings.xml b/pump/omnipod-dash/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-de-rDE/strings.xml rename to pump/omnipod-dash/src/main/res/values-de-rDE/strings.xml diff --git a/omnipod-dash/src/main/res/values-el-rGR/strings.xml b/pump/omnipod-dash/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-el-rGR/strings.xml rename to pump/omnipod-dash/src/main/res/values-el-rGR/strings.xml diff --git a/omnipod-dash/src/main/res/values-es-rES/strings.xml b/pump/omnipod-dash/src/main/res/values-es-rES/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-es-rES/strings.xml rename to pump/omnipod-dash/src/main/res/values-es-rES/strings.xml diff --git a/omnipod-dash/src/main/res/values-fr-rFR/strings.xml b/pump/omnipod-dash/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-fr-rFR/strings.xml rename to pump/omnipod-dash/src/main/res/values-fr-rFR/strings.xml diff --git a/omnipod-dash/src/main/res/values-ga-rIE/strings.xml b/pump/omnipod-dash/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-ga-rIE/strings.xml rename to pump/omnipod-dash/src/main/res/values-ga-rIE/strings.xml diff --git a/omnipod-dash/src/main/res/values-hr-rHR/strings.xml b/pump/omnipod-dash/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-hr-rHR/strings.xml rename to pump/omnipod-dash/src/main/res/values-hr-rHR/strings.xml diff --git a/omnipod-dash/src/main/res/values-hu-rHU/strings.xml b/pump/omnipod-dash/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-hu-rHU/strings.xml rename to pump/omnipod-dash/src/main/res/values-hu-rHU/strings.xml diff --git a/omnipod-dash/src/main/res/values-it-rIT/strings.xml b/pump/omnipod-dash/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-it-rIT/strings.xml rename to pump/omnipod-dash/src/main/res/values-it-rIT/strings.xml diff --git a/omnipod-dash/src/main/res/values-iw-rIL/strings.xml b/pump/omnipod-dash/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-iw-rIL/strings.xml rename to pump/omnipod-dash/src/main/res/values-iw-rIL/strings.xml diff --git a/omnipod-dash/src/main/res/values-ko-rKR/strings.xml b/pump/omnipod-dash/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-ko-rKR/strings.xml rename to pump/omnipod-dash/src/main/res/values-ko-rKR/strings.xml diff --git a/omnipod-dash/src/main/res/values-lt-rLT/strings.xml b/pump/omnipod-dash/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-lt-rLT/strings.xml rename to pump/omnipod-dash/src/main/res/values-lt-rLT/strings.xml diff --git a/omnipod-dash/src/main/res/values-nl-rNL/strings.xml b/pump/omnipod-dash/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-nl-rNL/strings.xml rename to pump/omnipod-dash/src/main/res/values-nl-rNL/strings.xml diff --git a/omnipod-dash/src/main/res/values-no-rNO/strings.xml b/pump/omnipod-dash/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-no-rNO/strings.xml rename to pump/omnipod-dash/src/main/res/values-no-rNO/strings.xml diff --git a/omnipod-dash/src/main/res/values-pl-rPL/strings.xml b/pump/omnipod-dash/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-pl-rPL/strings.xml rename to pump/omnipod-dash/src/main/res/values-pl-rPL/strings.xml diff --git a/omnipod-dash/src/main/res/values-pt-rBR/strings.xml b/pump/omnipod-dash/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-pt-rBR/strings.xml rename to pump/omnipod-dash/src/main/res/values-pt-rBR/strings.xml diff --git a/omnipod-dash/src/main/res/values-pt-rPT/strings.xml b/pump/omnipod-dash/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-pt-rPT/strings.xml rename to pump/omnipod-dash/src/main/res/values-pt-rPT/strings.xml diff --git a/omnipod-dash/src/main/res/values-ro-rRO/strings.xml b/pump/omnipod-dash/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-ro-rRO/strings.xml rename to pump/omnipod-dash/src/main/res/values-ro-rRO/strings.xml diff --git a/omnipod-dash/src/main/res/values-ru-rRU/strings.xml b/pump/omnipod-dash/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-ru-rRU/strings.xml rename to pump/omnipod-dash/src/main/res/values-ru-rRU/strings.xml diff --git a/omnipod-dash/src/main/res/values-sk-rSK/strings.xml b/pump/omnipod-dash/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-sk-rSK/strings.xml rename to pump/omnipod-dash/src/main/res/values-sk-rSK/strings.xml diff --git a/omnipod-dash/src/main/res/values-sl-rSI/strings.xml b/pump/omnipod-dash/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-sl-rSI/strings.xml rename to pump/omnipod-dash/src/main/res/values-sl-rSI/strings.xml diff --git a/omnipod-dash/src/main/res/values-sr-rCS/strings.xml b/pump/omnipod-dash/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-sr-rCS/strings.xml rename to pump/omnipod-dash/src/main/res/values-sr-rCS/strings.xml diff --git a/omnipod-dash/src/main/res/values-sv-rSE/strings.xml b/pump/omnipod-dash/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-sv-rSE/strings.xml rename to pump/omnipod-dash/src/main/res/values-sv-rSE/strings.xml diff --git a/omnipod-dash/src/main/res/values-ta-rIN/strings.xml b/pump/omnipod-dash/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-ta-rIN/strings.xml rename to pump/omnipod-dash/src/main/res/values-ta-rIN/strings.xml diff --git a/omnipod-dash/src/main/res/values-tr-rTR/strings.xml b/pump/omnipod-dash/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-tr-rTR/strings.xml rename to pump/omnipod-dash/src/main/res/values-tr-rTR/strings.xml diff --git a/omnipod-dash/src/main/res/values-zh-rCN/strings.xml b/pump/omnipod-dash/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values-zh-rCN/strings.xml rename to pump/omnipod-dash/src/main/res/values-zh-rCN/strings.xml diff --git a/omnipod-dash/src/main/res/values/strings.xml b/pump/omnipod-dash/src/main/res/values/strings.xml similarity index 100% rename from omnipod-dash/src/main/res/values/strings.xml rename to pump/omnipod-dash/src/main/res/values/strings.xml diff --git a/omnipod-dash/src/main/res/xml/omnipod_dash_preferences.xml b/pump/omnipod-dash/src/main/res/xml/omnipod_dash_preferences.xml similarity index 100% rename from omnipod-dash/src/main/res/xml/omnipod_dash_preferences.xml rename to pump/omnipod-dash/src/main/res/xml/omnipod_dash_preferences.xml diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncodingTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncodingTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncodingTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/StringLengthPrefixEncodingTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetStatusCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBeepsCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBolusCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramTempBasalCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommandTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommandTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommandTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SuspendDeliveryCommandTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponseTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponseTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponseTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/AlarmStatusResponseTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponseTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponseTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponseTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/NakResponseTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponseTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponseTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponseTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/SetUniqueIdResponseTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponseTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponseTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponseTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/VersionResponseTest.kt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/FunctionsTest.kt b/pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/FunctionsTest.kt similarity index 100% rename from omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/FunctionsTest.kt rename to pump/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/util/FunctionsTest.kt diff --git a/omnipod-eros/.gitignore b/pump/omnipod-eros/.gitignore similarity index 100% rename from omnipod-eros/.gitignore rename to pump/omnipod-eros/.gitignore diff --git a/omnipod-eros/build.gradle b/pump/omnipod-eros/build.gradle similarity index 89% rename from omnipod-eros/build.gradle rename to pump/omnipod-eros/build.gradle index 5e5fa44f0f..6b3756e762 100644 --- a/omnipod-eros/build.gradle +++ b/pump/omnipod-eros/build.gradle @@ -23,13 +23,13 @@ android { } dependencies { - implementation project(':libraries') - implementation project(':core') - implementation project(':pump-common') - implementation project(':omnipod-common') - implementation project(':rileylink') implementation project(':database') implementation project(':shared') + implementation project(':libraries') + implementation project(':core') + implementation project(':pump:pump-common') + implementation project(':pump:rileylink') + implementation project(':pump:omnipod-common') api "androidx.room:room-ktx:$room_version" api "androidx.room:room-runtime:$room_version" diff --git a/omnipod-eros/consumer-rules.pro b/pump/omnipod-eros/consumer-rules.pro similarity index 100% rename from omnipod-eros/consumer-rules.pro rename to pump/omnipod-eros/consumer-rules.pro diff --git a/omnipod-eros/proguard-rules.pro b/pump/omnipod-eros/proguard-rules.pro similarity index 100% rename from omnipod-eros/proguard-rules.pro rename to pump/omnipod-eros/proguard-rules.pro diff --git a/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt b/pump/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt similarity index 100% rename from omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt rename to pump/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt diff --git a/omnipod-eros/src/main/AndroidManifest.xml b/pump/omnipod-eros/src/main/AndroidManifest.xml similarity index 100% rename from omnipod-eros/src/main/AndroidManifest.xml rename to pump/omnipod-eros/src/main/AndroidManifest.xml diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/ActiveBolus.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/ActiveBolus.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/ActiveBolus.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/ActiveBolus.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/RLHistoryItemOmnipod.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/RLHistoryItemOmnipod.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/RLHistoryItemOmnipod.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/data/RLHistoryItemOmnipod.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/OmnipodErosStorageKeys.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/OmnipodErosStorageKeys.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/OmnipodErosStorageKeys.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/OmnipodErosStorageKeys.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/PodHistoryEntryType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/PodHistoryEntryType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/PodHistoryEntryType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/definition/PodHistoryEntryType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosHistoryModule.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosHistoryModule.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosHistoryModule.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosHistoryModule.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosModule.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosModule.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosModule.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosModule.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosWizardViewModelsModule.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosWizardViewModelsModule.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosWizardViewModelsModule.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/di/OmnipodErosWizardViewModelsModule.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AcknowledgeAlertsAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AcknowledgeAlertsAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AcknowledgeAlertsAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AcknowledgeAlertsAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AssignAddressAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AssignAddressAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AssignAddressAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/AssignAddressAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/BolusAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/BolusAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/BolusAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/BolusAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/CancelDeliveryAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/CancelDeliveryAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/CancelDeliveryAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/CancelDeliveryAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureAlertsAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureAlertsAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureAlertsAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureAlertsAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureBeepAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureBeepAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureBeepAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/ConfigureBeepAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/DeactivatePodAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/DeactivatePodAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/DeactivatePodAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/DeactivatePodAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetPodInfoAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetPodInfoAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetPodInfoAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetPodInfoAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetStatusAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetStatusAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetStatusAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/GetStatusAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/InsertCannulaAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/InsertCannulaAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/InsertCannulaAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/InsertCannulaAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/OmnipodAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/OmnipodAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/OmnipodAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/OmnipodAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/PrimeAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/PrimeAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/PrimeAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/PrimeAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetBasalScheduleAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetBasalScheduleAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetBasalScheduleAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetBasalScheduleAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetTempBasalAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetTempBasalAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetTempBasalAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetTempBasalAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetupPodAction.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetupPodAction.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetupPodAction.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/SetupPodAction.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/ExpirationReminderBuilder.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/ExpirationReminderBuilder.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/ExpirationReminderBuilder.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/ExpirationReminderBuilder.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/PrimeService.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/PrimeService.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/PrimeService.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/action/service/PrimeService.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/IRawRepresentable.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/IRawRepresentable.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/IRawRepresentable.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/IRawRepresentable.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/MessageBlock.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/MessageBlock.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/MessageBlock.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/MessageBlock.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/NonceResyncableMessageBlock.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/NonceResyncableMessageBlock.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/NonceResyncableMessageBlock.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/NonceResyncableMessageBlock.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodMessage.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodMessage.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodMessage.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodMessage.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodPacket.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodPacket.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodPacket.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/OmnipodPacket.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommand.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommand.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommand.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommand.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponse.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponse.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponse.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponse.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponse.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponse.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponse.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponse.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusUpdatableResponse.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusUpdatableResponse.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusUpdatableResponse.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusUpdatableResponse.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponse.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponse.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponse.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponse.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfo.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfo.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfo.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfo.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLog.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLog.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLog.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLog.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponse.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponse.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponse.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponse.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ActivationProgress.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ActivationProgress.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ActivationProgress.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ActivationProgress.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertConfiguration.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertConfiguration.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertConfiguration.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertConfiguration.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSet.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSet.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSet.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSet.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSlot.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSlot.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSlot.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSlot.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertTrigger.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertTrigger.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertTrigger.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertTrigger.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepConfigType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepConfigType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepConfigType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepConfigType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepRepeat.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepRepeat.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepRepeat.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepRepeat.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/BeepType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryStatus.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryStatus.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryStatus.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryStatus.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/DeliveryType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ErrorEventInfo.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ErrorEventInfo.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ErrorEventInfo.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/ErrorEventInfo.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FaultEventCode.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FaultEventCode.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FaultEventCode.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FaultEventCode.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FirmwareVersion.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FirmwareVersion.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FirmwareVersion.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/FirmwareVersion.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/MessageBlockType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/MessageBlockType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/MessageBlockType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/MessageBlockType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodConstants.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodConstants.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodConstants.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodConstants.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodCrc.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodCrc.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodCrc.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/OmnipodCrc.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PacketType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PacketType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PacketType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PacketType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodInfoType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodInfoType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodInfoType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodInfoType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodProgressStatus.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodProgressStatus.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodProgressStatus.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/PodProgressStatus.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/TimerAlertTrigger.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/TimerAlertTrigger.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/TimerAlertTrigger.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/TimerAlertTrigger.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/UnitsRemainingAlertTrigger.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/UnitsRemainingAlertTrigger.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/UnitsRemainingAlertTrigger.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/UnitsRemainingAlertTrigger.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliverySchedule.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliverySchedule.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliverySchedule.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliverySchedule.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliveryTable.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliveryTable.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliveryTable.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalDeliveryTable.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalSchedule.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalSchedule.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalSchedule.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalSchedule.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleEntry.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleEntry.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleEntry.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleEntry.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalTableEntry.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalTableEntry.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalTableEntry.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalTableEntry.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BolusDeliverySchedule.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BolusDeliverySchedule.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BolusDeliverySchedule.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BolusDeliverySchedule.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/DeliverySchedule.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/DeliverySchedule.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/DeliverySchedule.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/DeliverySchedule.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/InsulinScheduleType.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/InsulinScheduleType.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/InsulinScheduleType.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/InsulinScheduleType.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/RateEntry.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/RateEntry.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/RateEntry.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/RateEntry.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/TempBasalDeliverySchedule.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/TempBasalDeliverySchedule.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/TempBasalDeliverySchedule.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/TempBasalDeliverySchedule.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/ActivationTimeExceededException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/ActivationTimeExceededException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/ActivationTimeExceededException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/ActivationTimeExceededException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CrcMismatchException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CrcMismatchException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CrcMismatchException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/CrcMismatchException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalActivationProgressException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalActivationProgressException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalActivationProgressException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalActivationProgressException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalDeliveryStatusException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalDeliveryStatusException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalDeliveryStatusException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalDeliveryStatusException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageAddressException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageAddressException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageAddressException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageAddressException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageSequenceNumberException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageSequenceNumberException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageSequenceNumberException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalMessageSequenceNumberException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPacketTypeException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPacketTypeException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPacketTypeException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPacketTypeException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPodProgressException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPodProgressException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPodProgressException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalPodProgressException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalResponseException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalResponseException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalResponseException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalResponseException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalVersionResponseTypeException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalVersionResponseTypeException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalVersionResponseTypeException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/IllegalVersionResponseTypeException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/MessageDecodingException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/MessageDecodingException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/MessageDecodingException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/MessageDecodingException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceOutOfSyncException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceOutOfSyncException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceOutOfSyncException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceOutOfSyncException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceResyncException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceResyncException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceResyncException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NonceResyncException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NotEnoughDataException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NotEnoughDataException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NotEnoughDataException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/NotEnoughDataException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/OmnipodException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/OmnipodException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/OmnipodException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/OmnipodException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodFaultException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodFaultException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodFaultException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodFaultException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodProgressStatusVerificationFailedException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodProgressStatusVerificationFailedException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodProgressStatusVerificationFailedException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodProgressStatusVerificationFailedException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodReturnedErrorResponseException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodReturnedErrorResponseException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodReturnedErrorResponseException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PodReturnedErrorResponseException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PrecedingCommandFailedUncertainlyException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PrecedingCommandFailedUncertainlyException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PrecedingCommandFailedUncertainlyException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/PrecedingCommandFailedUncertainlyException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkInterruptedException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkInterruptedException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkInterruptedException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkInterruptedException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkTimeoutException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkTimeoutException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkTimeoutException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkTimeoutException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnexpectedException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnexpectedException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnexpectedException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnexpectedException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnreachableException.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnreachableException.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnreachableException.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/exception/RileyLinkUnreachableException.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/ErosPodStateManager.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/ErosPodStateManager.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/ErosPodStateManager.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/ErosPodStateManager.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/OmnipodManager.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/OmnipodManager.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/OmnipodManager.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/manager/OmnipodManager.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/AlertConfigurationUtil.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/AlertConfigurationUtil.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/AlertConfigurationUtil.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/AlertConfigurationUtil.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtil.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtil.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtil.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtil.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosActiveAlertsChanged.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosActiveAlertsChanged.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosActiveAlertsChanged.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosActiveAlertsChanged.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosFaultEventChanged.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosFaultEventChanged.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosFaultEventChanged.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosFaultEventChanged.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosPumpValuesChanged.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosPumpValuesChanged.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosPumpValuesChanged.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosPumpValuesChanged.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosTbrChanged.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosTbrChanged.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosTbrChanged.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosTbrChanged.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosUncertainTbrRecovered.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosUncertainTbrRecovered.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosUncertainTbrRecovered.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/event/EventOmnipodErosUncertainTbrRecovered.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistory.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistory.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistory.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistory.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryDatabase.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryDatabase.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryDatabase.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryDatabase.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordDao.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordDao.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordDao.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordDao.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordEntity.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordEntity.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordEntity.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/database/ErosHistoryRecordEntity.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManager.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManager.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManager.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManager.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandGetPodStatus.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandGetPodStatus.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandGetPodStatus.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandGetPodStatus.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandReadPulseLog.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandReadPulseLog.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandReadPulseLog.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/queue/command/CommandReadPulseLog.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/manager/OmnipodRileyLinkCommunicationManager.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/manager/OmnipodRileyLinkCommunicationManager.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/manager/OmnipodRileyLinkCommunicationManager.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/manager/OmnipodRileyLinkCommunicationManager.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/ErosPodActivationWizardActivity.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/ErosPodActivationWizardActivity.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/ErosPodActivationWizardActivity.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/ErosPodActivationWizardActivity.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInitializePodViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInitializePodViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInitializePodViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInitializePodViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInsertCannulaViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInsertCannulaViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInsertCannulaViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/action/ErosInsertCannulaViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosAttachPodViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosAttachPodViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosAttachPodViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosAttachPodViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosPodActivatedViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosPodActivatedViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosPodActivatedViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosPodActivatedViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosStartPodActivationViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosStartPodActivationViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosStartPodActivationViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/activation/viewmodel/info/ErosStartPodActivationViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/ErosPodDeactivationWizardActivity.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/ErosPodDeactivationWizardActivity.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/ErosPodDeactivationWizardActivity.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/ErosPodDeactivationWizardActivity.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/action/ErosDeactivatePodViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/action/ErosDeactivatePodViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/action/ErosDeactivatePodViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/action/ErosDeactivatePodViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDeactivatedViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDeactivatedViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDeactivatedViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDeactivatedViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDiscardedViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDiscardedViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDiscardedViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosPodDiscardedViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosStartPodDeactivationViewModel.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosStartPodDeactivationViewModel.kt similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosStartPodDeactivationViewModel.kt rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/wizard/deactivation/viewmodel/info/ErosStartPodDeactivationViewModel.kt diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/AapsOmnipodUtil.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/AapsOmnipodUtil.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/AapsOmnipodUtil.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/AapsOmnipodUtil.java diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/OmnipodAlertUtil.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/OmnipodAlertUtil.java similarity index 100% rename from omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/OmnipodAlertUtil.java rename to pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/util/OmnipodAlertUtil.java diff --git a/omnipod-eros/src/main/res/drawable/ic_pod_activity_reset_rileylink_config.xml b/pump/omnipod-eros/src/main/res/drawable/ic_pod_activity_reset_rileylink_config.xml similarity index 100% rename from omnipod-eros/src/main/res/drawable/ic_pod_activity_reset_rileylink_config.xml rename to pump/omnipod-eros/src/main/res/drawable/ic_pod_activity_reset_rileylink_config.xml diff --git a/omnipod-eros/src/main/res/drawable/ic_pod_management_rl_stats.xml b/pump/omnipod-eros/src/main/res/drawable/ic_pod_management_rl_stats.xml similarity index 100% rename from omnipod-eros/src/main/res/drawable/ic_pod_management_rl_stats.xml rename to pump/omnipod-eros/src/main/res/drawable/ic_pod_management_rl_stats.xml diff --git a/omnipod-eros/src/main/res/layout/omnipod_eros_overview.xml b/pump/omnipod-eros/src/main/res/layout/omnipod_eros_overview.xml similarity index 100% rename from omnipod-eros/src/main/res/layout/omnipod_eros_overview.xml rename to pump/omnipod-eros/src/main/res/layout/omnipod_eros_overview.xml diff --git a/omnipod-eros/src/main/res/layout/omnipod_eros_overview_riley_link_status.xml b/pump/omnipod-eros/src/main/res/layout/omnipod_eros_overview_riley_link_status.xml similarity index 100% rename from omnipod-eros/src/main/res/layout/omnipod_eros_overview_riley_link_status.xml rename to pump/omnipod-eros/src/main/res/layout/omnipod_eros_overview_riley_link_status.xml diff --git a/omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_activity.xml b/pump/omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_activity.xml similarity index 100% rename from omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_activity.xml rename to pump/omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_activity.xml diff --git a/omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_item.xml b/pump/omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_item.xml similarity index 100% rename from omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_item.xml rename to pump/omnipod-eros/src/main/res/layout/omnipod_eros_pod_history_item.xml diff --git a/omnipod-eros/src/main/res/layout/omnipod_eros_pod_management.xml b/pump/omnipod-eros/src/main/res/layout/omnipod_eros_pod_management.xml similarity index 100% rename from omnipod-eros/src/main/res/layout/omnipod_eros_pod_management.xml rename to pump/omnipod-eros/src/main/res/layout/omnipod_eros_pod_management.xml diff --git a/omnipod-eros/src/main/res/values-af-rZA/strings.xml b/pump/omnipod-eros/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-af-rZA/strings.xml rename to pump/omnipod-eros/src/main/res/values-af-rZA/strings.xml diff --git a/omnipod-eros/src/main/res/values-bg-rBG/strings.xml b/pump/omnipod-eros/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-bg-rBG/strings.xml rename to pump/omnipod-eros/src/main/res/values-bg-rBG/strings.xml diff --git a/omnipod-eros/src/main/res/values-ca-rES/strings.xml b/pump/omnipod-eros/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-ca-rES/strings.xml rename to pump/omnipod-eros/src/main/res/values-ca-rES/strings.xml diff --git a/omnipod-eros/src/main/res/values-cs-rCZ/strings.xml b/pump/omnipod-eros/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-cs-rCZ/strings.xml rename to pump/omnipod-eros/src/main/res/values-cs-rCZ/strings.xml diff --git a/omnipod-eros/src/main/res/values-da-rDK/strings.xml b/pump/omnipod-eros/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-da-rDK/strings.xml rename to pump/omnipod-eros/src/main/res/values-da-rDK/strings.xml diff --git a/omnipod-eros/src/main/res/values-de-rDE/strings.xml b/pump/omnipod-eros/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-de-rDE/strings.xml rename to pump/omnipod-eros/src/main/res/values-de-rDE/strings.xml diff --git a/omnipod-eros/src/main/res/values-el-rGR/strings.xml b/pump/omnipod-eros/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-el-rGR/strings.xml rename to pump/omnipod-eros/src/main/res/values-el-rGR/strings.xml diff --git a/omnipod-eros/src/main/res/values-es-rES/strings.xml b/pump/omnipod-eros/src/main/res/values-es-rES/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-es-rES/strings.xml rename to pump/omnipod-eros/src/main/res/values-es-rES/strings.xml diff --git a/omnipod-eros/src/main/res/values-fr-rFR/strings.xml b/pump/omnipod-eros/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-fr-rFR/strings.xml rename to pump/omnipod-eros/src/main/res/values-fr-rFR/strings.xml diff --git a/omnipod-eros/src/main/res/values-ga-rIE/strings.xml b/pump/omnipod-eros/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-ga-rIE/strings.xml rename to pump/omnipod-eros/src/main/res/values-ga-rIE/strings.xml diff --git a/omnipod-eros/src/main/res/values-hr-rHR/strings.xml b/pump/omnipod-eros/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-hr-rHR/strings.xml rename to pump/omnipod-eros/src/main/res/values-hr-rHR/strings.xml diff --git a/omnipod-eros/src/main/res/values-hu-rHU/strings.xml b/pump/omnipod-eros/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-hu-rHU/strings.xml rename to pump/omnipod-eros/src/main/res/values-hu-rHU/strings.xml diff --git a/omnipod-eros/src/main/res/values-it-rIT/strings.xml b/pump/omnipod-eros/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-it-rIT/strings.xml rename to pump/omnipod-eros/src/main/res/values-it-rIT/strings.xml diff --git a/omnipod-eros/src/main/res/values-iw-rIL/strings.xml b/pump/omnipod-eros/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-iw-rIL/strings.xml rename to pump/omnipod-eros/src/main/res/values-iw-rIL/strings.xml diff --git a/omnipod-eros/src/main/res/values-ko-rKR/strings.xml b/pump/omnipod-eros/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-ko-rKR/strings.xml rename to pump/omnipod-eros/src/main/res/values-ko-rKR/strings.xml diff --git a/omnipod-eros/src/main/res/values-lt-rLT/strings.xml b/pump/omnipod-eros/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-lt-rLT/strings.xml rename to pump/omnipod-eros/src/main/res/values-lt-rLT/strings.xml diff --git a/omnipod-eros/src/main/res/values-nl-rNL/strings.xml b/pump/omnipod-eros/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-nl-rNL/strings.xml rename to pump/omnipod-eros/src/main/res/values-nl-rNL/strings.xml diff --git a/omnipod-eros/src/main/res/values-no-rNO/strings.xml b/pump/omnipod-eros/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-no-rNO/strings.xml rename to pump/omnipod-eros/src/main/res/values-no-rNO/strings.xml diff --git a/omnipod-eros/src/main/res/values-pl-rPL/strings.xml b/pump/omnipod-eros/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-pl-rPL/strings.xml rename to pump/omnipod-eros/src/main/res/values-pl-rPL/strings.xml diff --git a/omnipod-eros/src/main/res/values-pt-rBR/strings.xml b/pump/omnipod-eros/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-pt-rBR/strings.xml rename to pump/omnipod-eros/src/main/res/values-pt-rBR/strings.xml diff --git a/omnipod-eros/src/main/res/values-pt-rPT/strings.xml b/pump/omnipod-eros/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-pt-rPT/strings.xml rename to pump/omnipod-eros/src/main/res/values-pt-rPT/strings.xml diff --git a/omnipod-eros/src/main/res/values-ro-rRO/strings.xml b/pump/omnipod-eros/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-ro-rRO/strings.xml rename to pump/omnipod-eros/src/main/res/values-ro-rRO/strings.xml diff --git a/omnipod-eros/src/main/res/values-ru-rRU/strings.xml b/pump/omnipod-eros/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-ru-rRU/strings.xml rename to pump/omnipod-eros/src/main/res/values-ru-rRU/strings.xml diff --git a/omnipod-eros/src/main/res/values-sk-rSK/strings.xml b/pump/omnipod-eros/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-sk-rSK/strings.xml rename to pump/omnipod-eros/src/main/res/values-sk-rSK/strings.xml diff --git a/omnipod-eros/src/main/res/values-sl-rSI/strings.xml b/pump/omnipod-eros/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-sl-rSI/strings.xml rename to pump/omnipod-eros/src/main/res/values-sl-rSI/strings.xml diff --git a/omnipod-eros/src/main/res/values-sr-rCS/strings.xml b/pump/omnipod-eros/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-sr-rCS/strings.xml rename to pump/omnipod-eros/src/main/res/values-sr-rCS/strings.xml diff --git a/omnipod-eros/src/main/res/values-sv-rSE/strings.xml b/pump/omnipod-eros/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-sv-rSE/strings.xml rename to pump/omnipod-eros/src/main/res/values-sv-rSE/strings.xml diff --git a/omnipod-eros/src/main/res/values-ta-rIN/strings.xml b/pump/omnipod-eros/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-ta-rIN/strings.xml rename to pump/omnipod-eros/src/main/res/values-ta-rIN/strings.xml diff --git a/omnipod-eros/src/main/res/values-tr-rTR/strings.xml b/pump/omnipod-eros/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-tr-rTR/strings.xml rename to pump/omnipod-eros/src/main/res/values-tr-rTR/strings.xml diff --git a/omnipod-eros/src/main/res/values-zh-rCN/strings.xml b/pump/omnipod-eros/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values-zh-rCN/strings.xml rename to pump/omnipod-eros/src/main/res/values-zh-rCN/strings.xml diff --git a/omnipod-eros/src/main/res/values/strings.xml b/pump/omnipod-eros/src/main/res/values/strings.xml similarity index 100% rename from omnipod-eros/src/main/res/values/strings.xml rename to pump/omnipod-eros/src/main/res/values/strings.xml diff --git a/omnipod-eros/src/main/res/xml/omnipod_eros_preferences.xml b/pump/omnipod-eros/src/main/res/xml/omnipod_eros_preferences.xml similarity index 100% rename from omnipod-eros/src/main/res/xml/omnipod_eros_preferences.xml rename to pump/omnipod-eros/src/main/res/xml/omnipod_eros_preferences.xml diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/TestBase.kt b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/TestBase.kt similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/TestBase.kt rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/TestBase.kt diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/AapsOmnipodErosManagerTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/AapsOmnipodErosManagerTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/AapsOmnipodErosManagerTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/AapsOmnipodErosManagerTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AcknowledgeAlertsCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/AssignAddressCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BasalScheduleExtraCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BeepConfigCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/BolusExtraCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/CancelDeliveryCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/ConfigureAlertsCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/DeactivatePodCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/FaultConfigCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/GetStatusCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetInsulinScheduleCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/SetupPodCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommandTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommandTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommandTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/command/TempBasalExtraCommandTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponseTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponseTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponseTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/ErrorResponseTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponseTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponseTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponseTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/StatusResponseTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponseTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponseTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponseTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/VersionResponseTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlertsTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlertsTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlertsTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoActiveAlertsTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLogTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLogTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLogTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDataLogTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTimeTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTimeTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTimeTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTimeTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLogTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLogTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLogTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoOlderPulseLogTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLogTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLogTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLogTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoRecentPulseLogTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSetTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSetTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSetTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/AlertSetTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/definition/schedule/BasalScheduleTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtilTest.java b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtilTest.java similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtilTest.java rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/util/TimeUtilTest.java diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt similarity index 100% rename from omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt rename to pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt diff --git a/pump-common/.gitignore b/pump/pump-common/.gitignore similarity index 100% rename from pump-common/.gitignore rename to pump/pump-common/.gitignore diff --git a/pump-common/build.gradle b/pump/pump-common/build.gradle similarity index 100% rename from pump-common/build.gradle rename to pump/pump-common/build.gradle diff --git a/pump-common/consumer-rules.pro b/pump/pump-common/consumer-rules.pro similarity index 100% rename from pump-common/consumer-rules.pro rename to pump/pump-common/consumer-rules.pro diff --git a/pump-common/proguard-rules.pro b/pump/pump-common/proguard-rules.pro similarity index 100% rename from pump-common/proguard-rules.pro rename to pump/pump-common/proguard-rules.pro diff --git a/pump-common/src/main/AndroidManifest.xml b/pump/pump-common/src/main/AndroidManifest.xml similarity index 100% rename from pump-common/src/main/AndroidManifest.xml rename to pump/pump-common/src/main/AndroidManifest.xml diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDeviceState.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDeviceState.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDeviceState.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDeviceState.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpStatusType.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpStatusType.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpStatusType.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpStatusType.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/TempBasalPair.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/TempBasalPair.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/TempBasalPair.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/TempBasalPair.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/PumpCommonModule.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/PumpCommonModule.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/PumpCommonModule.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/PumpCommonModule.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpDbEntry.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpDbEntry.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpDbEntry.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpDbEntry.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncEntriesCreator.java b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncEntriesCreator.java similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncEntriesCreator.java rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncEntriesCreator.java diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncStorage.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncStorage.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncStorage.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/sync/PumpSyncStorage.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ByteUtil.java b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ByteUtil.java similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ByteUtil.java rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ByteUtil.java diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ProfileUtil.kt b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ProfileUtil.kt similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ProfileUtil.kt rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ProfileUtil.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/StringUtil.java b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/StringUtil.java similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/StringUtil.java rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/StringUtil.java diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ThreadUtil.java b/pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ThreadUtil.java similarity index 100% rename from pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ThreadUtil.java rename to pump/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/ThreadUtil.java diff --git a/pump-common/src/main/res/layout/pump_ble_config_activity.xml b/pump/pump-common/src/main/res/layout/pump_ble_config_activity.xml old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/res/layout/pump_ble_config_activity.xml rename to pump/pump-common/src/main/res/layout/pump_ble_config_activity.xml diff --git a/pump-common/src/main/res/layout/pump_ble_config_scan_item.xml b/pump/pump-common/src/main/res/layout/pump_ble_config_scan_item.xml old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/res/layout/pump_ble_config_scan_item.xml rename to pump/pump-common/src/main/res/layout/pump_ble_config_scan_item.xml diff --git a/pump-common/src/main/res/layout/pump_history_activity.xml b/pump/pump-common/src/main/res/layout/pump_history_activity.xml old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/res/layout/pump_history_activity.xml rename to pump/pump-common/src/main/res/layout/pump_history_activity.xml diff --git a/pump-common/src/main/res/layout/pump_history_item.xml b/pump/pump-common/src/main/res/layout/pump_history_item.xml old mode 100755 new mode 100644 similarity index 100% rename from pump-common/src/main/res/layout/pump_history_item.xml rename to pump/pump-common/src/main/res/layout/pump_history_item.xml diff --git a/pump-common/src/main/res/values-af-rZA/strings.xml b/pump/pump-common/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from pump-common/src/main/res/values-af-rZA/strings.xml rename to pump/pump-common/src/main/res/values-af-rZA/strings.xml diff --git a/pump-common/src/main/res/values-bg-rBG/strings.xml b/pump/pump-common/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from pump-common/src/main/res/values-bg-rBG/strings.xml rename to pump/pump-common/src/main/res/values-bg-rBG/strings.xml diff --git a/pump-common/src/main/res/values-ca-rES/strings.xml b/pump/pump-common/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from pump-common/src/main/res/values-ca-rES/strings.xml rename to pump/pump-common/src/main/res/values-ca-rES/strings.xml diff --git a/pump-common/src/main/res/values-cs-rCZ/strings.xml b/pump/pump-common/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from pump-common/src/main/res/values-cs-rCZ/strings.xml rename to pump/pump-common/src/main/res/values-cs-rCZ/strings.xml diff --git a/pump-common/src/main/res/values-da-rDK/strings.xml b/pump/pump-common/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from pump-common/src/main/res/values-da-rDK/strings.xml rename to pump/pump-common/src/main/res/values-da-rDK/strings.xml diff --git a/pump-common/src/main/res/values-de-rDE/strings.xml b/pump/pump-common/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from pump-common/src/main/res/values-de-rDE/strings.xml rename to pump/pump-common/src/main/res/values-de-rDE/strings.xml diff --git a/pump-common/src/main/res/values-el-rGR/strings.xml b/pump/pump-common/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from pump-common/src/main/res/values-el-rGR/strings.xml rename to pump/pump-common/src/main/res/values-el-rGR/strings.xml diff --git a/pump-common/src/main/res/values-es-rES/strings.xml b/pump/pump-common/src/main/res/values-es-rES/strings.xml similarity index 100% rename from pump-common/src/main/res/values-es-rES/strings.xml rename to pump/pump-common/src/main/res/values-es-rES/strings.xml diff --git a/pump-common/src/main/res/values-fr-rFR/strings.xml b/pump/pump-common/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from pump-common/src/main/res/values-fr-rFR/strings.xml rename to pump/pump-common/src/main/res/values-fr-rFR/strings.xml diff --git a/pump-common/src/main/res/values-ga-rIE/strings.xml b/pump/pump-common/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from pump-common/src/main/res/values-ga-rIE/strings.xml rename to pump/pump-common/src/main/res/values-ga-rIE/strings.xml diff --git a/pump-common/src/main/res/values-hr-rHR/strings.xml b/pump/pump-common/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from pump-common/src/main/res/values-hr-rHR/strings.xml rename to pump/pump-common/src/main/res/values-hr-rHR/strings.xml diff --git a/pump-common/src/main/res/values-hu-rHU/strings.xml b/pump/pump-common/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from pump-common/src/main/res/values-hu-rHU/strings.xml rename to pump/pump-common/src/main/res/values-hu-rHU/strings.xml diff --git a/pump-common/src/main/res/values-it-rIT/strings.xml b/pump/pump-common/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from pump-common/src/main/res/values-it-rIT/strings.xml rename to pump/pump-common/src/main/res/values-it-rIT/strings.xml diff --git a/pump-common/src/main/res/values-iw-rIL/strings.xml b/pump/pump-common/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from pump-common/src/main/res/values-iw-rIL/strings.xml rename to pump/pump-common/src/main/res/values-iw-rIL/strings.xml diff --git a/pump-common/src/main/res/values-ko-rKR/strings.xml b/pump/pump-common/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from pump-common/src/main/res/values-ko-rKR/strings.xml rename to pump/pump-common/src/main/res/values-ko-rKR/strings.xml diff --git a/pump-common/src/main/res/values-lt-rLT/strings.xml b/pump/pump-common/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from pump-common/src/main/res/values-lt-rLT/strings.xml rename to pump/pump-common/src/main/res/values-lt-rLT/strings.xml diff --git a/pump-common/src/main/res/values-nl-rNL/strings.xml b/pump/pump-common/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from pump-common/src/main/res/values-nl-rNL/strings.xml rename to pump/pump-common/src/main/res/values-nl-rNL/strings.xml diff --git a/pump-common/src/main/res/values-no-rNO/strings.xml b/pump/pump-common/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from pump-common/src/main/res/values-no-rNO/strings.xml rename to pump/pump-common/src/main/res/values-no-rNO/strings.xml diff --git a/pump-common/src/main/res/values-pl-rPL/strings.xml b/pump/pump-common/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from pump-common/src/main/res/values-pl-rPL/strings.xml rename to pump/pump-common/src/main/res/values-pl-rPL/strings.xml diff --git a/pump-common/src/main/res/values-pt-rBR/strings.xml b/pump/pump-common/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from pump-common/src/main/res/values-pt-rBR/strings.xml rename to pump/pump-common/src/main/res/values-pt-rBR/strings.xml diff --git a/pump-common/src/main/res/values-pt-rPT/strings.xml b/pump/pump-common/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from pump-common/src/main/res/values-pt-rPT/strings.xml rename to pump/pump-common/src/main/res/values-pt-rPT/strings.xml diff --git a/pump-common/src/main/res/values-ro-rRO/strings.xml b/pump/pump-common/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from pump-common/src/main/res/values-ro-rRO/strings.xml rename to pump/pump-common/src/main/res/values-ro-rRO/strings.xml diff --git a/pump-common/src/main/res/values-ru-rRU/strings.xml b/pump/pump-common/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from pump-common/src/main/res/values-ru-rRU/strings.xml rename to pump/pump-common/src/main/res/values-ru-rRU/strings.xml diff --git a/pump-common/src/main/res/values-sk-rSK/strings.xml b/pump/pump-common/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from pump-common/src/main/res/values-sk-rSK/strings.xml rename to pump/pump-common/src/main/res/values-sk-rSK/strings.xml diff --git a/pump-common/src/main/res/values-sr-rCS/strings.xml b/pump/pump-common/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from pump-common/src/main/res/values-sr-rCS/strings.xml rename to pump/pump-common/src/main/res/values-sr-rCS/strings.xml diff --git a/pump-common/src/main/res/values-sv-rSE/strings.xml b/pump/pump-common/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from pump-common/src/main/res/values-sv-rSE/strings.xml rename to pump/pump-common/src/main/res/values-sv-rSE/strings.xml diff --git a/pump-common/src/main/res/values-tr-rTR/strings.xml b/pump/pump-common/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from pump-common/src/main/res/values-tr-rTR/strings.xml rename to pump/pump-common/src/main/res/values-tr-rTR/strings.xml diff --git a/pump-common/src/main/res/values-zh-rCN/strings.xml b/pump/pump-common/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from pump-common/src/main/res/values-zh-rCN/strings.xml rename to pump/pump-common/src/main/res/values-zh-rCN/strings.xml diff --git a/pump-common/src/main/res/values/strings.xml b/pump/pump-common/src/main/res/values/strings.xml similarity index 100% rename from pump-common/src/main/res/values/strings.xml rename to pump/pump-common/src/main/res/values/strings.xml diff --git a/rileylink/.gitignore b/pump/rileylink/.gitignore similarity index 100% rename from rileylink/.gitignore rename to pump/rileylink/.gitignore diff --git a/rileylink/build.gradle b/pump/rileylink/build.gradle similarity index 92% rename from rileylink/build.gradle rename to pump/rileylink/build.gradle index 24ac3125e8..33c437bb34 100644 --- a/rileylink/build.gradle +++ b/pump/rileylink/build.gradle @@ -13,7 +13,7 @@ android { } dependencies { - implementation project(':core') - implementation project(':pump-common') implementation project(':shared') + implementation project(':core') + implementation project(':pump:pump-common') } diff --git a/rileylink/consumer-rules.pro b/pump/rileylink/consumer-rules.pro similarity index 100% rename from rileylink/consumer-rules.pro rename to pump/rileylink/consumer-rules.pro diff --git a/rileylink/proguard-rules.pro b/pump/rileylink/proguard-rules.pro similarity index 100% rename from rileylink/proguard-rules.pro rename to pump/rileylink/proguard-rules.pro diff --git a/rileylink/src/main/AndroidManifest.xml b/pump/rileylink/src/main/AndroidManifest.xml similarity index 100% rename from rileylink/src/main/AndroidManifest.xml rename to pump/rileylink/src/main/AndroidManifest.xml diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/RileyLinkModule.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/RileyLinkModule.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/RileyLinkModule.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/di/RileyLinkModule.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/dialog/RileyLinkBLEConfigActivity.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/dialog/RileyLinkBLEConfigActivity.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/dialog/RileyLinkBLEConfigActivity.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/dialog/RileyLinkBLEConfigActivity.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkConst.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkConst.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkConst.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkConst.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkBLE.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkBLE.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkBLE.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkBLE.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkCommunicationException.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkCommunicationException.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkCommunicationException.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RileyLinkCommunicationException.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/GetVersion.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/GetVersion.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/GetVersion.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/GetVersion.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/Reset.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/Reset.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/Reset.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/Reset.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/ResetRadioConfig.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/ResetRadioConfig.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/ResetRadioConfig.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/ResetRadioConfig.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/RileyLinkCommand.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/RileyLinkCommand.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/RileyLinkCommand.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/RileyLinkCommand.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SendAndListen.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SendAndListen.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SendAndListen.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SendAndListen.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetHardwareEncoding.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetHardwareEncoding.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetHardwareEncoding.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetHardwareEncoding.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/UpdateRegister.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/UpdateRegister.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/UpdateRegister.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/UpdateRegister.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyScanResults.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyScanResults.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyScanResults.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyScanResults.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyTrial.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyTrial.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyTrial.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/FrequencyTrial.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/GattAttributes.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/GattAttributes.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/GattAttributes.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/GattAttributes.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RFSpyResponse.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RFSpyResponse.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RFSpyResponse.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RFSpyResponse.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessage.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessage.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessage.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessage.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessageType.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessageType.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessageType.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RLMessageType.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioPacket.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioPacket.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioPacket.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioPacket.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioResponse.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioResponse.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioResponse.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/RadioResponse.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6b.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6b.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6b.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6b.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bAbstract.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bAbstract.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bAbstract.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bAbstract.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bGeoff.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bGeoff.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bGeoff.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/data/encoding/Encoding4b6bGeoff.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/CC111XRegister.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/CC111XRegister.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/CC111XRegister.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/CC111XRegister.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyCommand.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyCommand.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyCommand.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyCommand.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyRLResponse.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyRLResponse.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyRLResponse.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RFSpyRLResponse.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkBLEError.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkBLEError.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkBLEError.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkBLEError.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkCommandType.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkCommandType.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkCommandType.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkCommandType.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkEncodingType.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkEncodingType.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkEncodingType.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkEncodingType.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersion.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersion.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersion.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersion.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/device/OrangeLinkImpl.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/device/OrangeLinkImpl.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/device/OrangeLinkImpl.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/device/OrangeLinkImpl.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperation.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperation.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperation.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperation.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperationResult.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperationResult.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperationResult.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/BLECommOperationResult.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicReadOperation.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicReadOperation.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicReadOperation.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicReadOperation.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicWriteOperation.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicWriteOperation.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicWriteOperation.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/CharacteristicWriteOperation.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/DescriptorWriteOperation.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/DescriptorWriteOperation.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/DescriptorWriteOperation.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/operations/DescriptorWriteOperation.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/BleAdvertisedData.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/BleAdvertisedData.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/BleAdvertisedData.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/BleAdvertisedData.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/CommandValueDefinition.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/CommandValueDefinition.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/CommandValueDefinition.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/CommandValueDefinition.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/RLHistoryItem.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/RLHistoryItem.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/RLHistoryItem.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/data/RLHistoryItem.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionRLType.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionRLType.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionRLType.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionRLType.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionType.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionType.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionType.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/CommandValueDefinitionType.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkError.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkError.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkError.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkError.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpDevice.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpDevice.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpDevice.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpDevice.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpInfo.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpInfo.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpInfo.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkPumpInfo.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkServiceState.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkServiceState.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkServiceState.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkServiceState.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkTargetDevice.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkTargetDevice.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkTargetDevice.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/defs/RileyLinkTargetDevice.java diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusActivity.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusActivity.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusActivity.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusActivity.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusHistoryFragment.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusHistoryFragment.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusHistoryFragment.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusHistoryFragment.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBluetoothStateReceiver.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBluetoothStateReceiver.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBluetoothStateReceiver.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBluetoothStateReceiver.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/DiscoverGattServicesTask.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/DiscoverGattServicesTask.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/DiscoverGattServicesTask.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/DiscoverGattServicesTask.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/PumpTask.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/PumpTask.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/PumpTask.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/PumpTask.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ResetRileyLinkConfigurationTask.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ResetRileyLinkConfigurationTask.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ResetRileyLinkConfigurationTask.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ResetRileyLinkConfigurationTask.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTask.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTask.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTask.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTask.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTaskExecutor.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTaskExecutor.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTaskExecutor.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/ServiceTaskExecutor.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/WakeAndTuneTask.kt b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/WakeAndTuneTask.kt similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/WakeAndTuneTask.kt rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/WakeAndTuneTask.kt diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/CRC.java b/pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/CRC.java similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/CRC.java rename to pump/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/CRC.java diff --git a/rileylink/src/main/res/layout/riley_link_ble_config_activity.xml b/pump/rileylink/src/main/res/layout/riley_link_ble_config_activity.xml similarity index 100% rename from rileylink/src/main/res/layout/riley_link_ble_config_activity.xml rename to pump/rileylink/src/main/res/layout/riley_link_ble_config_activity.xml diff --git a/rileylink/src/main/res/layout/riley_link_ble_config_scan_item.xml b/pump/rileylink/src/main/res/layout/riley_link_ble_config_scan_item.xml similarity index 100% rename from rileylink/src/main/res/layout/riley_link_ble_config_scan_item.xml rename to pump/rileylink/src/main/res/layout/riley_link_ble_config_scan_item.xml diff --git a/rileylink/src/main/res/layout/rileylink_status.xml b/pump/rileylink/src/main/res/layout/rileylink_status.xml similarity index 100% rename from rileylink/src/main/res/layout/rileylink_status.xml rename to pump/rileylink/src/main/res/layout/rileylink_status.xml diff --git a/rileylink/src/main/res/layout/rileylink_status_device_item.xml b/pump/rileylink/src/main/res/layout/rileylink_status_device_item.xml similarity index 100% rename from rileylink/src/main/res/layout/rileylink_status_device_item.xml rename to pump/rileylink/src/main/res/layout/rileylink_status_device_item.xml diff --git a/rileylink/src/main/res/layout/rileylink_status_general.xml b/pump/rileylink/src/main/res/layout/rileylink_status_general.xml similarity index 100% rename from rileylink/src/main/res/layout/rileylink_status_general.xml rename to pump/rileylink/src/main/res/layout/rileylink_status_general.xml diff --git a/rileylink/src/main/res/layout/rileylink_status_history.xml b/pump/rileylink/src/main/res/layout/rileylink_status_history.xml similarity index 100% rename from rileylink/src/main/res/layout/rileylink_status_history.xml rename to pump/rileylink/src/main/res/layout/rileylink_status_history.xml diff --git a/rileylink/src/main/res/layout/rileylink_status_history_item.xml b/pump/rileylink/src/main/res/layout/rileylink_status_history_item.xml similarity index 100% rename from rileylink/src/main/res/layout/rileylink_status_history_item.xml rename to pump/rileylink/src/main/res/layout/rileylink_status_history_item.xml diff --git a/rileylink/src/main/res/menu/menu_rileylink_ble_scan.xml b/pump/rileylink/src/main/res/menu/menu_rileylink_ble_scan.xml similarity index 100% rename from rileylink/src/main/res/menu/menu_rileylink_ble_scan.xml rename to pump/rileylink/src/main/res/menu/menu_rileylink_ble_scan.xml diff --git a/rileylink/src/main/res/values-af-rZA/strings.xml b/pump/rileylink/src/main/res/values-af-rZA/strings.xml similarity index 100% rename from rileylink/src/main/res/values-af-rZA/strings.xml rename to pump/rileylink/src/main/res/values-af-rZA/strings.xml diff --git a/rileylink/src/main/res/values-ar-rSA/strings.xml b/pump/rileylink/src/main/res/values-ar-rSA/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ar-rSA/strings.xml rename to pump/rileylink/src/main/res/values-ar-rSA/strings.xml diff --git a/rileylink/src/main/res/values-bg-rBG/strings.xml b/pump/rileylink/src/main/res/values-bg-rBG/strings.xml similarity index 100% rename from rileylink/src/main/res/values-bg-rBG/strings.xml rename to pump/rileylink/src/main/res/values-bg-rBG/strings.xml diff --git a/rileylink/src/main/res/values-ca-rES/strings.xml b/pump/rileylink/src/main/res/values-ca-rES/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ca-rES/strings.xml rename to pump/rileylink/src/main/res/values-ca-rES/strings.xml diff --git a/rileylink/src/main/res/values-cs-rCZ/strings.xml b/pump/rileylink/src/main/res/values-cs-rCZ/strings.xml similarity index 100% rename from rileylink/src/main/res/values-cs-rCZ/strings.xml rename to pump/rileylink/src/main/res/values-cs-rCZ/strings.xml diff --git a/rileylink/src/main/res/values-cy-rGB/strings.xml b/pump/rileylink/src/main/res/values-cy-rGB/strings.xml similarity index 100% rename from rileylink/src/main/res/values-cy-rGB/strings.xml rename to pump/rileylink/src/main/res/values-cy-rGB/strings.xml diff --git a/rileylink/src/main/res/values-da-rDK/strings.xml b/pump/rileylink/src/main/res/values-da-rDK/strings.xml similarity index 100% rename from rileylink/src/main/res/values-da-rDK/strings.xml rename to pump/rileylink/src/main/res/values-da-rDK/strings.xml diff --git a/rileylink/src/main/res/values-de-rDE/strings.xml b/pump/rileylink/src/main/res/values-de-rDE/strings.xml similarity index 100% rename from rileylink/src/main/res/values-de-rDE/strings.xml rename to pump/rileylink/src/main/res/values-de-rDE/strings.xml diff --git a/rileylink/src/main/res/values-el-rGR/strings.xml b/pump/rileylink/src/main/res/values-el-rGR/strings.xml similarity index 100% rename from rileylink/src/main/res/values-el-rGR/strings.xml rename to pump/rileylink/src/main/res/values-el-rGR/strings.xml diff --git a/rileylink/src/main/res/values-es-rES/strings.xml b/pump/rileylink/src/main/res/values-es-rES/strings.xml similarity index 100% rename from rileylink/src/main/res/values-es-rES/strings.xml rename to pump/rileylink/src/main/res/values-es-rES/strings.xml diff --git a/rileylink/src/main/res/values-fi-rFI/strings.xml b/pump/rileylink/src/main/res/values-fi-rFI/strings.xml similarity index 100% rename from rileylink/src/main/res/values-fi-rFI/strings.xml rename to pump/rileylink/src/main/res/values-fi-rFI/strings.xml diff --git a/rileylink/src/main/res/values-fr-rFR/strings.xml b/pump/rileylink/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from rileylink/src/main/res/values-fr-rFR/strings.xml rename to pump/rileylink/src/main/res/values-fr-rFR/strings.xml diff --git a/rileylink/src/main/res/values-ga-rIE/strings.xml b/pump/rileylink/src/main/res/values-ga-rIE/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ga-rIE/strings.xml rename to pump/rileylink/src/main/res/values-ga-rIE/strings.xml diff --git a/rileylink/src/main/res/values-hr-rHR/strings.xml b/pump/rileylink/src/main/res/values-hr-rHR/strings.xml similarity index 100% rename from rileylink/src/main/res/values-hr-rHR/strings.xml rename to pump/rileylink/src/main/res/values-hr-rHR/strings.xml diff --git a/rileylink/src/main/res/values-hu-rHU/strings.xml b/pump/rileylink/src/main/res/values-hu-rHU/strings.xml similarity index 100% rename from rileylink/src/main/res/values-hu-rHU/strings.xml rename to pump/rileylink/src/main/res/values-hu-rHU/strings.xml diff --git a/rileylink/src/main/res/values-it-rIT/strings.xml b/pump/rileylink/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from rileylink/src/main/res/values-it-rIT/strings.xml rename to pump/rileylink/src/main/res/values-it-rIT/strings.xml diff --git a/rileylink/src/main/res/values-iw-rIL/strings.xml b/pump/rileylink/src/main/res/values-iw-rIL/strings.xml similarity index 100% rename from rileylink/src/main/res/values-iw-rIL/strings.xml rename to pump/rileylink/src/main/res/values-iw-rIL/strings.xml diff --git a/rileylink/src/main/res/values-ko-rKR/strings.xml b/pump/rileylink/src/main/res/values-ko-rKR/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ko-rKR/strings.xml rename to pump/rileylink/src/main/res/values-ko-rKR/strings.xml diff --git a/rileylink/src/main/res/values-lt-rLT/strings.xml b/pump/rileylink/src/main/res/values-lt-rLT/strings.xml similarity index 100% rename from rileylink/src/main/res/values-lt-rLT/strings.xml rename to pump/rileylink/src/main/res/values-lt-rLT/strings.xml diff --git a/rileylink/src/main/res/values-nl-rNL/strings.xml b/pump/rileylink/src/main/res/values-nl-rNL/strings.xml similarity index 100% rename from rileylink/src/main/res/values-nl-rNL/strings.xml rename to pump/rileylink/src/main/res/values-nl-rNL/strings.xml diff --git a/rileylink/src/main/res/values-no-rNO/strings.xml b/pump/rileylink/src/main/res/values-no-rNO/strings.xml similarity index 100% rename from rileylink/src/main/res/values-no-rNO/strings.xml rename to pump/rileylink/src/main/res/values-no-rNO/strings.xml diff --git a/rileylink/src/main/res/values-pl-rPL/strings.xml b/pump/rileylink/src/main/res/values-pl-rPL/strings.xml similarity index 100% rename from rileylink/src/main/res/values-pl-rPL/strings.xml rename to pump/rileylink/src/main/res/values-pl-rPL/strings.xml diff --git a/rileylink/src/main/res/values-pt-rBR/strings.xml b/pump/rileylink/src/main/res/values-pt-rBR/strings.xml similarity index 100% rename from rileylink/src/main/res/values-pt-rBR/strings.xml rename to pump/rileylink/src/main/res/values-pt-rBR/strings.xml diff --git a/rileylink/src/main/res/values-pt-rPT/strings.xml b/pump/rileylink/src/main/res/values-pt-rPT/strings.xml similarity index 100% rename from rileylink/src/main/res/values-pt-rPT/strings.xml rename to pump/rileylink/src/main/res/values-pt-rPT/strings.xml diff --git a/rileylink/src/main/res/values-ro-rRO/strings.xml b/pump/rileylink/src/main/res/values-ro-rRO/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ro-rRO/strings.xml rename to pump/rileylink/src/main/res/values-ro-rRO/strings.xml diff --git a/rileylink/src/main/res/values-ru-rRU/strings.xml b/pump/rileylink/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ru-rRU/strings.xml rename to pump/rileylink/src/main/res/values-ru-rRU/strings.xml diff --git a/rileylink/src/main/res/values-sk-rSK/strings.xml b/pump/rileylink/src/main/res/values-sk-rSK/strings.xml similarity index 100% rename from rileylink/src/main/res/values-sk-rSK/strings.xml rename to pump/rileylink/src/main/res/values-sk-rSK/strings.xml diff --git a/rileylink/src/main/res/values-sl-rSI/strings.xml b/pump/rileylink/src/main/res/values-sl-rSI/strings.xml similarity index 100% rename from rileylink/src/main/res/values-sl-rSI/strings.xml rename to pump/rileylink/src/main/res/values-sl-rSI/strings.xml diff --git a/rileylink/src/main/res/values-sr-rCS/strings.xml b/pump/rileylink/src/main/res/values-sr-rCS/strings.xml similarity index 100% rename from rileylink/src/main/res/values-sr-rCS/strings.xml rename to pump/rileylink/src/main/res/values-sr-rCS/strings.xml diff --git a/rileylink/src/main/res/values-sv-rSE/strings.xml b/pump/rileylink/src/main/res/values-sv-rSE/strings.xml similarity index 100% rename from rileylink/src/main/res/values-sv-rSE/strings.xml rename to pump/rileylink/src/main/res/values-sv-rSE/strings.xml diff --git a/rileylink/src/main/res/values-ta-rIN/strings.xml b/pump/rileylink/src/main/res/values-ta-rIN/strings.xml similarity index 100% rename from rileylink/src/main/res/values-ta-rIN/strings.xml rename to pump/rileylink/src/main/res/values-ta-rIN/strings.xml diff --git a/rileylink/src/main/res/values-tr-rTR/strings.xml b/pump/rileylink/src/main/res/values-tr-rTR/strings.xml similarity index 100% rename from rileylink/src/main/res/values-tr-rTR/strings.xml rename to pump/rileylink/src/main/res/values-tr-rTR/strings.xml diff --git a/rileylink/src/main/res/values-zh-rCN/strings.xml b/pump/rileylink/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from rileylink/src/main/res/values-zh-rCN/strings.xml rename to pump/rileylink/src/main/res/values-zh-rCN/strings.xml diff --git a/rileylink/src/main/res/values/strings.xml b/pump/rileylink/src/main/res/values/strings.xml similarity index 100% rename from rileylink/src/main/res/values/strings.xml rename to pump/rileylink/src/main/res/values/strings.xml diff --git a/rileylink/src/test/java/info/nightscout/androidaps/TestBase.kt b/pump/rileylink/src/test/java/info/nightscout/androidaps/TestBase.kt similarity index 100% rename from rileylink/src/test/java/info/nightscout/androidaps/TestBase.kt rename to pump/rileylink/src/test/java/info/nightscout/androidaps/TestBase.kt diff --git a/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyTest.kt b/pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyTest.kt similarity index 100% rename from rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyTest.kt rename to pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyTest.kt diff --git a/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsParametrizedUTest.java b/pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsParametrizedUTest.java similarity index 100% rename from rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsParametrizedUTest.java rename to pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsParametrizedUTest.java diff --git a/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsUTest.java b/pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsUTest.java similarity index 100% rename from rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsUTest.java rename to pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFToolsUTest.java diff --git a/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersionTest.java b/pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersionTest.java similarity index 100% rename from rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersionTest.java rename to pump/rileylink/src/test/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkFirmwareVersionTest.java diff --git a/settings.gradle b/settings.gradle index 04c5fb7e1b..f770757e60 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,24 +1,24 @@ -include ':automation' -include ':insight' include ':app' include ':wear' include ':database' include ':core' -include ':combo' -include ':dana' -include ':danar' -include ':danars' -include ':pump-common' -include ':rileylink' -include ':medtronic' -include ':omnipod-common' -include ':omnipod-eros' -include ':omnipod-dash' -include ':diaconn' -include ':openhumans' include ':shared' include ':graphview' include ':libraries' include ':ui' include ':implementation' include ':plugins' +include ':pump:combo' +include ':pump:dana' +include ':pump:danar' +include ':pump:danars' +include ':pump:diaconn' +include ':insight' +include ':pump:medtronic' +include ':pump:omnipod-common' +include ':pump:omnipod-eros' +include ':pump:omnipod-dash' +include ':pump:pump-common' +include ':pump:rileylink' +include ':openhumans' +include ':automation' From 8e2a17335cdd1c2c394213cb2af6fa8a2cc0a907 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 13:18:19 +0100 Subject: [PATCH 59/77] Update Crowdin configuration file --- crowdin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin.yml b/crowdin.yml index 8badd8004e..5599cdf679 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -16,7 +16,7 @@ files: - source: /shared/src/main/res/values/strings.xml translation: /shared/src/main/res/values-%android_code%/strings.xml - source: /pump/combo/src/main/res/values/strings.xml - translation: /pump//combo/src/main/res/values-%android_code%/strings.xml + translation: /pump/combo/src/main/res/values-%android_code%/strings.xml - source: /pump/dana/src/main/res/values/strings.xml translation: /pump/dana/src/main/res/values-%android_code%/strings.xml - source: /pump/danar/src/main/res/values/strings.xml From befd4253b5be0f21ed20223fbc6aee87ec998579 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 14:02:09 +0100 Subject: [PATCH 60/77] Diaconn: do not translate key --- pump/diaconn/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pump/diaconn/src/main/res/values/strings.xml b/pump/diaconn/src/main/res/values/strings.xml index ea014d7ef3..cf4d6041b9 100644 --- a/pump/diaconn/src/main/res/values/strings.xml +++ b/pump/diaconn/src/main/res/values/strings.xml @@ -11,6 +11,7 @@ diaconn_g8_loginsulinchange diaconn_g8_logneedlechange diaconn_g8_cloudsend + diaconn_g8_appuid Reset Pairing No Device available @@ -169,5 +170,4 @@ Tempbasal stop is rejected when tempbasal is not running Send pump logs to the Diaconn Cloud. Diaconn Cloud Sync - diaconn_g8_appuid From 2f85abbc8400c15816301e316cac48223425232c Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 14:05:50 +0100 Subject: [PATCH 61/77] Insulin -> plugins module --- .../activities/MyPreferenceFragment.kt | 2 +- .../nightscout/androidaps/di/AppComponent.kt | 4 +++- .../androidaps/di/FragmentsModule.kt | 2 -- .../nightscout/androidaps/di/PluginsModule.kt | 8 +++---- .../main/res/layout/localprofile_fragment.xml | 2 +- .../res/layout/smscommunicator_fragment.xml | 13 ++++++++++++ app/src/main/res/values/strings.xml | 18 ---------------- .../nightscout/plugins/di/InsulinModule.kt | 12 +++++++++++ .../activities/SmsCommunicatorOtpActivity.kt | 6 +++--- .../plugins/insulin/ActivityGraph.kt | 2 +- .../plugins/insulin/InsulinFragment.kt | 6 +++--- .../plugins/insulin/InsulinLyumjevPlugin.kt | 4 ++-- .../plugins/insulin/InsulinOrefBasePlugin.kt | 4 ++-- .../insulin/InsulinOrefFreePeakPlugin.kt | 4 ++-- .../insulin/InsulinOrefRapidActingPlugin.kt | 8 +++---- .../InsulinOrefUltraRapidActingPlugin.kt | 8 +++---- .../src/main/res/layout/insulin_fragment.xml | 4 ++-- ...p.xml => smscommunicator_activity_otp.xml} | 2 +- plugins/src/main/res/values/strings.xml | 21 +++++++++++++++++++ .../main/res/xml/pref_insulinoreffreepeak.xml | 0 .../insulin/InsulinLyumjevPluginTest.kt | 4 ++-- .../insulin/InsulinOrefBasePluginTest.kt | 5 +---- .../insulin/InsulinOrefFreePeakPluginTest.kt | 6 +++--- .../InsulinOrefRapidActingPluginTest.kt | 4 ++-- .../InsulinOrefUltraRapidActingPluginTest.kt | 4 ++-- 25 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 app/src/main/res/layout/smscommunicator_fragment.xml create mode 100644 plugins/src/main/java/info/nightscout/plugins/di/InsulinModule.kt rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/ActivityGraph.kt (97%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/InsulinFragment.kt (89%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/InsulinLyumjevPlugin.kt (94%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/InsulinOrefBasePlugin.kt (97%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/InsulinOrefFreePeakPlugin.kt (95%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/InsulinOrefRapidActingPlugin.kt (94%) rename {app/src/main/java/info/nightscout/androidaps => plugins/src/main/java/info/nightscout}/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt (94%) rename {app => plugins}/src/main/res/layout/insulin_fragment.xml (90%) rename plugins/src/main/res/layout/{activity_smscommunicator_otp.xml => smscommunicator_activity_otp.xml} (97%) rename {app => plugins}/src/main/res/xml/pref_insulinoreffreepeak.xml (100%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/insulin/InsulinLyumjevPluginTest.kt (95%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/insulin/InsulinOrefBasePluginTest.kt (95%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/insulin/InsulinOrefFreePeakPluginTest.kt (93%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/insulin/InsulinOrefRapidActingPluginTest.kt (95%) rename {app/src/test/java/info/nightscout/androidaps => plugins/src/test/java/info/nightscout}/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt (95%) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt index bbfe01a0e6..ce1552c575 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt @@ -36,7 +36,7 @@ import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin import info.nightscout.androidaps.plugins.general.wear.WearPlugin import info.nightscout.androidaps.plugins.general.xdripStatusline.StatusLinePlugin -import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin +import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt index 642088131c..e33bcec641 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt @@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule import info.nightscout.androidaps.plugins.pump.omnipod.dash.di.OmnipodDashModule import info.nightscout.androidaps.plugins.pump.omnipod.eros.di.OmnipodErosModule import info.nightscout.implementation.di.CommandQueueModule +import info.nightscout.plugins.di.InsulinModule import info.nightscout.plugins.di.SMSCommunicatorModule import info.nightscout.shared.di.SharedModule import info.nightscout.ui.di.UiModule @@ -69,7 +70,8 @@ import javax.inject.Singleton DiaconnG8Module::class, OpenHumansModule::class, SharedModule::class, - UiModule::class + UiModule::class, + InsulinModule::class ] ) interface AppComponent : AndroidInjector { diff --git a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt index 9b63bce462..e272765167 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt @@ -43,7 +43,6 @@ import info.nightscout.androidaps.plugins.general.overview.OverviewFragment import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment import info.nightscout.androidaps.plugins.general.wear.WearFragment -import info.nightscout.androidaps.plugins.insulin.InsulinFragment import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment import info.nightscout.androidaps.plugins.source.BGSourceFragment @@ -63,7 +62,6 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment @ContributesAndroidInjector abstract fun contributesFoodFragment(): FoodFragment - @ContributesAndroidInjector abstract fun contributesInsulinFragment(): InsulinFragment @ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): LocalProfileFragment @ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment @ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment diff --git a/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt index 9e5077d1fb..cf02ad8bf9 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt @@ -37,10 +37,10 @@ import info.nightscout.androidaps.plugins.general.themes.ThemeSwitcherPlugin import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin import info.nightscout.androidaps.plugins.general.wear.WearPlugin import info.nightscout.androidaps.plugins.general.xdripStatusline.StatusLinePlugin -import info.nightscout.androidaps.plugins.insulin.InsulinLyumjevPlugin -import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin -import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin -import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin +import info.nightscout.plugins.insulin.InsulinLyumjevPlugin +import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin +import info.nightscout.plugins.insulin.InsulinOrefRapidActingPlugin +import info.nightscout.plugins.insulin.InsulinOrefUltraRapidActingPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml index ff453c53e0..f07eaa4184 100644 --- a/app/src/main/res/layout/localprofile_fragment.xml +++ b/app/src/main/res/layout/localprofile_fragment.xml @@ -198,7 +198,7 @@ - + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ee1afa804..9b42467f8d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,7 +32,6 @@ smscommunicator protection absorption_category_settings - insulin_oref_peak_settings ns_temporary_target_last_sync temporary_target_new_data_id ns_glucose_value_last_sync @@ -70,10 +69,6 @@ Used for configuring the active plugins Learning program Displays the food presets defined in Nightscout - Insulin preset for Humalog and NovoRapid / NovoLog - Insulin preset for Fiasp - Insulin preset for Lyumjev - Allows you to define the peak of the insulin activity and should only be used by advanced users Activate or deactivate the implementation triggering the loop. Synchronizes your data with Nightscout State of the algorithm in 2017 @@ -225,7 +220,6 @@ Button 3 Units: Units - DIA Range for Visualization High and low mark for the charts in Overview and Smartwatch LOW mark @@ -335,9 +329,6 @@ Log app start to NS Exiting application to apply settings. Which type of insulin are you using? - Novorapid, Novolog, Humalog - Fiasp - INS key_usersuperbolus Enable superbolus in wizard Enable superbolus functionality in wizard. Do not enable until you learn what it really does. IT MAY CAUSE INSULIN OVERDOSE IF USED BLINDLY! @@ -437,15 +428,6 @@ Enable SMB Use Super Micro Boluses instead of temp basal for faster action Detection of Unannounced meals - insulin_oref_peak - IOB Curve Peak Time - Peak Time [min] - Peak - Free-Peak Oref - Rapid-Acting Oref - Ultra-Rapid Oref - Lyumjev - DIA of %1$f too short - using %2$f instead! Activate profile INVALID wizard_include_cob diff --git a/plugins/src/main/java/info/nightscout/plugins/di/InsulinModule.kt b/plugins/src/main/java/info/nightscout/plugins/di/InsulinModule.kt new file mode 100644 index 0000000000..42cce3d1f1 --- /dev/null +++ b/plugins/src/main/java/info/nightscout/plugins/di/InsulinModule.kt @@ -0,0 +1,12 @@ +package info.nightscout.plugins.di + +import dagger.Module +import dagger.android.ContributesAndroidInjector +import info.nightscout.plugins.insulin.InsulinFragment + +@Module +@Suppress("unused") +abstract class InsulinModule { + + @ContributesAndroidInjector abstract fun contributesInsulinFragment(): InsulinFragment +} \ No newline at end of file diff --git a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt index 6236eabbf9..a1bea14b29 100644 --- a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/activities/SmsCommunicatorOtpActivity.kt @@ -21,7 +21,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.plugins.R -import info.nightscout.plugins.databinding.ActivitySmscommunicatorOtpBinding +import info.nightscout.plugins.databinding.SmscommunicatorActivityOtpBinding import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import net.glxn.qrgen.android.QRCode @@ -34,13 +34,13 @@ class SmsCommunicatorOtpActivity : NoSplashAppCompatActivity() { @Inject lateinit var otp: OneTimePassword @Inject lateinit var uel: UserEntryLogger - private lateinit var binding: ActivitySmscommunicatorOtpBinding + private lateinit var binding: SmscommunicatorActivityOtpBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) - binding = ActivitySmscommunicatorOtpBinding.inflate(layoutInflater) + binding = SmscommunicatorActivityOtpBinding.inflate(layoutInflater) setContentView(binding.root) binding.otpVerifyEdit.addTextChangedListener(object : TextWatcher { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/ActivityGraph.kt similarity index 97% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/ActivityGraph.kt index 7662100e49..05cb3b1556 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/ActivityGraph.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import android.content.Context import android.graphics.Color diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinFragment.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/InsulinFragment.kt index 3302f21a51..15bbe3320d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinFragment.kt @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import dagger.android.support.DaggerFragment -import info.nightscout.androidaps.R -import info.nightscout.androidaps.databinding.InsulinFragmentBinding import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.plugins.R +import info.nightscout.plugins.databinding.InsulinFragmentBinding import javax.inject.Inject class InsulinFragment : DaggerFragment() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinLyumjevPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinLyumjevPlugin.kt similarity index 94% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinLyumjevPlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/InsulinLyumjevPlugin.kt index e13bb47b6f..c297f74233 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinLyumjevPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinLyumjevPlugin.kt @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction @@ -9,6 +8,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefBasePlugin.kt similarity index 97% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefBasePlugin.kt index f84d23f531..e6756ca712 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefBasePlugin.kt @@ -1,7 +1,7 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R +import info.nightscout.plugins.R import info.nightscout.androidaps.data.Iob import info.nightscout.androidaps.database.embedments.InsulinConfiguration import info.nightscout.androidaps.database.entities.Bolus diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefFreePeakPlugin.kt similarity index 95% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefFreePeakPlugin.kt index 3b3150cca7..e14a2c8522 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefFreePeakPlugin.kt @@ -1,7 +1,7 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R +import info.nightscout.plugins.R import info.nightscout.androidaps.extensions.putInt import info.nightscout.androidaps.extensions.storeInt import info.nightscout.androidaps.interfaces.Config diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefRapidActingPlugin.kt similarity index 94% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefRapidActingPlugin.kt index 76bceef9f2..999d52610d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefRapidActingPlugin.kt @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R +import info.nightscout.shared.logging.AAPSLogger import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt similarity index 94% rename from app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt index 631d495943..93ca0c175e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R +import info.nightscout.shared.logging.AAPSLogger import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/main/res/layout/insulin_fragment.xml b/plugins/src/main/res/layout/insulin_fragment.xml similarity index 90% rename from app/src/main/res/layout/insulin_fragment.xml rename to plugins/src/main/res/layout/insulin_fragment.xml index ef70d617c9..7733829b41 100644 --- a/app/src/main/res/layout/insulin_fragment.xml +++ b/plugins/src/main/res/layout/insulin_fragment.xml @@ -2,7 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="info.nightscout.androidaps.plugins.insulin.InsulinFragment"> + tools:context=".insulin.InsulinFragment"> - + tools:context=".general.smsCommunicator.activities.SmsCommunicatorOtpActivity"> TBR duration must be a multiple of %1$d minutes and greater than 0. QR Code for setup one time password + + insulin_oref_peak + insulin_oref_peak_settings + + DIA + Lyumjev + Insulin preset for Humalog and NovoRapid / NovoLog + Insulin preset for Fiasp + Insulin preset for Lyumjev + Allows you to define the peak of the insulin activity and should only be used by advanced users + INS + IOB Curve Peak Time + Peak Time [min] + Peak + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + DIA of %1$f too short - using %2$f instead! + Novorapid, Novolog, Humalog + Fiasp + \ No newline at end of file diff --git a/app/src/main/res/xml/pref_insulinoreffreepeak.xml b/plugins/src/main/res/xml/pref_insulinoreffreepeak.xml similarity index 100% rename from app/src/main/res/xml/pref_insulinoreffreepeak.xml rename to plugins/src/main/res/xml/pref_insulinoreffreepeak.xml diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinLyumjevPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinLyumjevPluginTest.kt similarity index 95% rename from app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinLyumjevPluginTest.kt rename to plugins/src/test/java/info/nightscout/plugins/insulin/InsulinLyumjevPluginTest.kt index 27f3b16011..409ac5c3eb 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinLyumjevPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinLyumjevPluginTest.kt @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R import info.nightscout.shared.logging.AAPSLogger import org.junit.Assert.assertEquals import org.junit.Before diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefBasePluginTest.kt similarity index 95% rename from app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePluginTest.kt rename to plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefBasePluginTest.kt index 254974283b..16801b1c5e 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefBasePluginTest.kt @@ -1,11 +1,9 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.data.Iob import info.nightscout.androidaps.database.entities.Bolus -import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction @@ -65,7 +63,6 @@ class InsulinOrefBasePluginTest { @Mock lateinit var profileFunction: ProfileFunction @Mock lateinit var rxBus: RxBus @Mock lateinit var aapsLogger: AAPSLogger - @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var config: Config @Mock lateinit var hardLimits: HardLimits diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefFreePeakPluginTest.kt similarity index 93% rename from app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt rename to plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefFreePeakPluginTest.kt index 75d996285d..d2877bc236 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefFreePeakPluginTest.kt @@ -1,8 +1,7 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin @@ -10,6 +9,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert.assertEquals import org.junit.Before @@ -25,7 +25,7 @@ import org.mockito.Mockito.`when` class InsulinOrefFreePeakPluginTest : TestBase() { - lateinit var sut: InsulinOrefFreePeakPlugin + private lateinit var sut: InsulinOrefFreePeakPlugin @Mock lateinit var sp: SP @Mock lateinit var rh: ResourceHelper diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefRapidActingPluginTest.kt similarity index 95% rename from app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPluginTest.kt rename to plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefRapidActingPluginTest.kt index 317ccabf5f..ea33cc534e 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefRapidActingPluginTest.kt @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R import info.nightscout.shared.logging.AAPSLogger import org.junit.Assert.assertEquals import org.junit.Before diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt similarity index 95% rename from app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt rename to plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt index 1944d0a0f0..704254f041 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/insulin/InsulinOrefUltraRapidActingPluginTest.kt @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.insulin +package info.nightscout.plugins.insulin import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Insulin import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.plugins.R import info.nightscout.shared.logging.AAPSLogger import org.junit.Assert.assertEquals import org.junit.Before From df3c18c3c1bcd2a0a7b238cc59b4e227236d9ac6 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 14:06:57 +0100 Subject: [PATCH 62/77] fail crowdin --- crowdin.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 5599cdf679..a02249dec5 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -18,19 +18,19 @@ files: - source: /pump/combo/src/main/res/values/strings.xml translation: /pump/combo/src/main/res/values-%android_code%/strings.xml - source: /pump/dana/src/main/res/values/strings.xml - translation: /pump/dana/src/main/res/values-%android_code%/strings.xml + translation: /pump//dana/src/main/res/values-%android_code%/strings.xml - source: /pump/danar/src/main/res/values/strings.xml - translation: /pump/danar/src/main/res/values-%android_code%/strings.xml + translation: /pump//danar/src/main/res/values-%android_code%/strings.xml - source: /pump/medtronic/src/main/res/values/strings.xml - translation: /pump/medtronic/src/main/res/values-%android_code%/strings.xml + translation: /pump//medtronic/src/main/res/values-%android_code%/strings.xml - source: /pump/omnipod-common/src/main/res/values/strings.xml - translation: /pump/omnipod-common/src/main/res/values-%android_code%/strings.xml + translation: /pump//omnipod-common/src/main/res/values-%android_code%/strings.xml - source: /pump/omnipod-dash/src/main/res/values/strings.xml - translation: /pump/omnipod-dash/src/main/res/values-%android_code%/strings.xml + translation: /pump//omnipod-dash/src/main/res/values-%android_code%/strings.xml - source: /pump/omnipod-eros/src/main/res/values/strings.xml - translation: /pump/omnipod-eros/src/main/res/values-%android_code%/strings.xml + translation: /pump//omnipod-eros/src/main/res/values-%android_code%/strings.xml - source: /pump/rileylink/src/main/res/values/strings.xml - translation: /pump/rileylink/src/main/res/values-%android_code%/strings.xml + translation: /pump//rileylink/src/main/res/values-%android_code%/strings.xml - source: /insight/src/main/res/values/strings.xml translation: /insight/src/main/res/values-%android_code%/strings.xml - source: /insight/src/main/res/values/alert_codes.xml @@ -44,9 +44,9 @@ files: - source: /automation/src/main/res/values/strings.xml translation: /automation/src/main/res/values-%android_code%/strings.xml - source: /pump/diaconn/src/main/res/values/strings.xml - translation: /pump/diaconn/src/main/res/values-%android_code%/strings.xml + translation: /pump//diaconn/src/main/res/values-%android_code%/strings.xml - source: /pump/pump-common/src/main/res/values/strings.xml - translation: /pump/pump-common/src/main/res/values-%android_code%/strings.xml + translation: /pump//pump-common/src/main/res/values-%android_code%/strings.xml - source: /openhumans/src/main/res/values/strings.xml translation: /openhumans/src/main/res/values-%android_code%/strings.xml - source: /implementation/src/main/res/values/strings.xml From 1d5b1e8c8f327e7bbe7636c3004c7dca5fd75cc3 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 14:19:41 +0100 Subject: [PATCH 63/77] Update Crowdin configuration file --- crowdin.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index a02249dec5..5599cdf679 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -18,19 +18,19 @@ files: - source: /pump/combo/src/main/res/values/strings.xml translation: /pump/combo/src/main/res/values-%android_code%/strings.xml - source: /pump/dana/src/main/res/values/strings.xml - translation: /pump//dana/src/main/res/values-%android_code%/strings.xml + translation: /pump/dana/src/main/res/values-%android_code%/strings.xml - source: /pump/danar/src/main/res/values/strings.xml - translation: /pump//danar/src/main/res/values-%android_code%/strings.xml + translation: /pump/danar/src/main/res/values-%android_code%/strings.xml - source: /pump/medtronic/src/main/res/values/strings.xml - translation: /pump//medtronic/src/main/res/values-%android_code%/strings.xml + translation: /pump/medtronic/src/main/res/values-%android_code%/strings.xml - source: /pump/omnipod-common/src/main/res/values/strings.xml - translation: /pump//omnipod-common/src/main/res/values-%android_code%/strings.xml + translation: /pump/omnipod-common/src/main/res/values-%android_code%/strings.xml - source: /pump/omnipod-dash/src/main/res/values/strings.xml - translation: /pump//omnipod-dash/src/main/res/values-%android_code%/strings.xml + translation: /pump/omnipod-dash/src/main/res/values-%android_code%/strings.xml - source: /pump/omnipod-eros/src/main/res/values/strings.xml - translation: /pump//omnipod-eros/src/main/res/values-%android_code%/strings.xml + translation: /pump/omnipod-eros/src/main/res/values-%android_code%/strings.xml - source: /pump/rileylink/src/main/res/values/strings.xml - translation: /pump//rileylink/src/main/res/values-%android_code%/strings.xml + translation: /pump/rileylink/src/main/res/values-%android_code%/strings.xml - source: /insight/src/main/res/values/strings.xml translation: /insight/src/main/res/values-%android_code%/strings.xml - source: /insight/src/main/res/values/alert_codes.xml @@ -44,9 +44,9 @@ files: - source: /automation/src/main/res/values/strings.xml translation: /automation/src/main/res/values-%android_code%/strings.xml - source: /pump/diaconn/src/main/res/values/strings.xml - translation: /pump//diaconn/src/main/res/values-%android_code%/strings.xml + translation: /pump/diaconn/src/main/res/values-%android_code%/strings.xml - source: /pump/pump-common/src/main/res/values/strings.xml - translation: /pump//pump-common/src/main/res/values-%android_code%/strings.xml + translation: /pump/pump-common/src/main/res/values-%android_code%/strings.xml - source: /openhumans/src/main/res/values/strings.xml translation: /openhumans/src/main/res/values-%android_code%/strings.xml - source: /implementation/src/main/res/values/strings.xml From 8b72f434c063c37404ea7c17fa4a8d21fe7e309b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 14:36:21 +0100 Subject: [PATCH 64/77] fix tests --- app/src/main/res/values/strings.xml | 2 -- .../src/main/res/drawable-nodpi/widget_preview.png | Bin .../src/main/res/drawable-v21/widget_background.xml | 0 .../drawable-v21/widget_inner_view_background.xml | 0 {app => ui}/src/main/res/values-v21/styles.xml | 0 {app => ui}/src/main/res/values/attrs.xml | 0 ui/src/main/res/values/strings.xml | 4 ++++ {app => ui}/src/main/res/xml/widget_info.xml | 0 8 files changed, 4 insertions(+), 2 deletions(-) rename {app => ui}/src/main/res/drawable-nodpi/widget_preview.png (100%) rename {app => ui}/src/main/res/drawable-v21/widget_background.xml (100%) rename {app => ui}/src/main/res/drawable-v21/widget_inner_view_background.xml (100%) rename {app => ui}/src/main/res/values-v21/styles.xml (100%) rename {app => ui}/src/main/res/values/attrs.xml (100%) rename {app => ui}/src/main/res/xml/widget_info.xml (100%) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9b42467f8d..14422b30e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1032,8 +1032,6 @@ Above Show loop records Hide loop records - AAPS widget - Configure opacity Loop status Graph scale Profile 1 diff --git a/app/src/main/res/drawable-nodpi/widget_preview.png b/ui/src/main/res/drawable-nodpi/widget_preview.png similarity index 100% rename from app/src/main/res/drawable-nodpi/widget_preview.png rename to ui/src/main/res/drawable-nodpi/widget_preview.png diff --git a/app/src/main/res/drawable-v21/widget_background.xml b/ui/src/main/res/drawable-v21/widget_background.xml similarity index 100% rename from app/src/main/res/drawable-v21/widget_background.xml rename to ui/src/main/res/drawable-v21/widget_background.xml diff --git a/app/src/main/res/drawable-v21/widget_inner_view_background.xml b/ui/src/main/res/drawable-v21/widget_inner_view_background.xml similarity index 100% rename from app/src/main/res/drawable-v21/widget_inner_view_background.xml rename to ui/src/main/res/drawable-v21/widget_inner_view_background.xml diff --git a/app/src/main/res/values-v21/styles.xml b/ui/src/main/res/values-v21/styles.xml similarity index 100% rename from app/src/main/res/values-v21/styles.xml rename to ui/src/main/res/values-v21/styles.xml diff --git a/app/src/main/res/values/attrs.xml b/ui/src/main/res/values/attrs.xml similarity index 100% rename from app/src/main/res/values/attrs.xml rename to ui/src/main/res/values/attrs.xml diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 24db1dbc2a..df3b9b9155 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -15,4 +15,8 @@ set reminder + + Configure opacity + AAPS widget + diff --git a/app/src/main/res/xml/widget_info.xml b/ui/src/main/res/xml/widget_info.xml similarity index 100% rename from app/src/main/res/xml/widget_info.xml rename to ui/src/main/res/xml/widget_info.xml From daae1653bd8fd7e25bb5f6dcbe05d03ead892bc5 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 14:51:41 +0100 Subject: [PATCH 65/77] try to remove old files from crowdin --- crowdin.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crowdin.yml b/crowdin.yml index 5599cdf679..0cfefc83f0 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,4 +55,6 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml + - source: /pump-common/src/main/res/values/strings.xml + translation: /pump-common/src/main/res/values-%android_code%/strings.xml translate_attributes: 0 From b137b84a274a5b2d2dd790073f7d222054c515c2 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 15:06:01 +0100 Subject: [PATCH 66/77] Update Crowdin configuration file --- crowdin.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 0cfefc83f0..1776a78fd2 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,6 +55,3 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml - - source: /pump-common/src/main/res/values/strings.xml - translation: /pump-common/src/main/res/values-%android_code%/strings.xml - translate_attributes: 0 From 689e66843bac4868c338a4bc69cc170fa8dfc082 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 15:59:18 +0100 Subject: [PATCH 67/77] try to remove old files from crowdin --- crowdin.yml | 2 ++ pump-common/src/main/res/values/strings.xml | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 pump-common/src/main/res/values/strings.xml diff --git a/crowdin.yml b/crowdin.yml index 1776a78fd2..9c62a1adb9 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,3 +55,5 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml + - source: /pump-common/src/main/res/values/strings.xml + translation: /pump-common/src/main/res/values-%android_code%/strings.xml diff --git a/pump-common/src/main/res/values/strings.xml b/pump-common/src/main/res/values/strings.xml new file mode 100644 index 0000000000..045e125f3d --- /dev/null +++ b/pump-common/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + + From 526556b0bd38bb02d36f0d9c173e8f12ad2fef9d Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 16:44:10 +0100 Subject: [PATCH 68/77] try to remove old files from crowdin --- crowdin.yml | 4 ++-- rileylink/src/main/res/values/strings.xml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 rileylink/src/main/res/values/strings.xml diff --git a/crowdin.yml b/crowdin.yml index 9c62a1adb9..5af2c50692 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,5 +55,5 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml - - source: /pump-common/src/main/res/values/strings.xml - translation: /pump-common/src/main/res/values-%android_code%/strings.xml + - source: /rileylink/src/main/res/values/strings.xml + translation: /rileylink/src/main/res/values-%android_code%/strings.xml diff --git a/rileylink/src/main/res/values/strings.xml b/rileylink/src/main/res/values/strings.xml new file mode 100644 index 0000000000..045e125f3d --- /dev/null +++ b/rileylink/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + + From f651b718b9fd498895cf533b2b55579e9753ad87 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 17:06:44 +0100 Subject: [PATCH 69/77] try to remove old files from crowdin --- crowdin.yml | 4 ++-- {rileylink => dana}/src/main/res/values/strings.xml | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename {rileylink => dana}/src/main/res/values/strings.xml (100%) diff --git a/crowdin.yml b/crowdin.yml index 5af2c50692..9055dc205b 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,5 +55,5 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml - - source: /rileylink/src/main/res/values/strings.xml - translation: /rileylink/src/main/res/values-%android_code%/strings.xml + - source: /dana/src/main/res/values/strings.xml + translation: /dana/src/main/res/values-%android_code%/strings.xml diff --git a/rileylink/src/main/res/values/strings.xml b/dana/src/main/res/values/strings.xml similarity index 100% rename from rileylink/src/main/res/values/strings.xml rename to dana/src/main/res/values/strings.xml From 2760cdd6eaaaf712a8423fb9f499815931ff28bd Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 19:18:32 +0100 Subject: [PATCH 70/77] try to remove old files from crowdin --- crowdin.yml | 14 ++++++++++++-- dana/src/main/res/values/strings.xml | 3 --- 2 files changed, 12 insertions(+), 5 deletions(-) delete mode 100644 dana/src/main/res/values/strings.xml diff --git a/crowdin.yml b/crowdin.yml index 9055dc205b..b7695c40b3 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,5 +55,15 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml - - source: /dana/src/main/res/values/strings.xml - translation: /dana/src/main/res/values-%android_code%/strings.xml + - source: /danar/src/main/res/values/strings.xml + translation: /danar/src/main/res/values-%android_code%/strings.xml + - source: /diaconn/src/main/res/values/strings.xml + translation: /diaconn/src/main/res/values-%android_code%/strings.xml + - source: /medtronic/src/main/res/values/strings.xml + translation: /medtronic/src/main/res/values-%android_code%/strings.xml + - source: /omnipod-common/src/main/res/values/strings.xml + translation: /omnipod-common/src/main/res/values-%android_code%/strings.xml + - source: /omnipod-eros/src/main/res/values/strings.xml + translation: /omnipod-eros/src/main/res/values-%android_code%/strings.xml + - source: /omnipod-dash/src/main/res/values/strings.xml + translation: /omnipod-dash/src/main/res/values-%android_code%/strings.xml diff --git a/dana/src/main/res/values/strings.xml b/dana/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/dana/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - From 917f06374ebc1e6f5d5bb0965a4734c68b988f17 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 20:24:47 +0100 Subject: [PATCH 71/77] try to remove old files from crowdin --- crowdin.yml | 14 ++++++++++++-- {dana => danar}/src/main/res/values/strings.xml | 0 .../src/main/res/values/strings.xml | 0 medtronic/src/main/res/values/strings.xml | 3 +++ omnipod-common/src/main/res/values/strings.xml | 3 +++ omnipod-dash/src/main/res/values/strings.xml | 3 +++ omnipod-eros/src/main/res/values/strings.xml | 3 +++ 7 files changed, 24 insertions(+), 2 deletions(-) rename {dana => danar}/src/main/res/values/strings.xml (100%) rename {pump-common => diaconn}/src/main/res/values/strings.xml (100%) create mode 100644 medtronic/src/main/res/values/strings.xml create mode 100644 omnipod-common/src/main/res/values/strings.xml create mode 100644 omnipod-dash/src/main/res/values/strings.xml create mode 100644 omnipod-eros/src/main/res/values/strings.xml diff --git a/crowdin.yml b/crowdin.yml index 9055dc205b..b7695c40b3 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,5 +55,15 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml - - source: /dana/src/main/res/values/strings.xml - translation: /dana/src/main/res/values-%android_code%/strings.xml + - source: /danar/src/main/res/values/strings.xml + translation: /danar/src/main/res/values-%android_code%/strings.xml + - source: /diaconn/src/main/res/values/strings.xml + translation: /diaconn/src/main/res/values-%android_code%/strings.xml + - source: /medtronic/src/main/res/values/strings.xml + translation: /medtronic/src/main/res/values-%android_code%/strings.xml + - source: /omnipod-common/src/main/res/values/strings.xml + translation: /omnipod-common/src/main/res/values-%android_code%/strings.xml + - source: /omnipod-eros/src/main/res/values/strings.xml + translation: /omnipod-eros/src/main/res/values-%android_code%/strings.xml + - source: /omnipod-dash/src/main/res/values/strings.xml + translation: /omnipod-dash/src/main/res/values-%android_code%/strings.xml diff --git a/dana/src/main/res/values/strings.xml b/danar/src/main/res/values/strings.xml similarity index 100% rename from dana/src/main/res/values/strings.xml rename to danar/src/main/res/values/strings.xml diff --git a/pump-common/src/main/res/values/strings.xml b/diaconn/src/main/res/values/strings.xml similarity index 100% rename from pump-common/src/main/res/values/strings.xml rename to diaconn/src/main/res/values/strings.xml diff --git a/medtronic/src/main/res/values/strings.xml b/medtronic/src/main/res/values/strings.xml new file mode 100644 index 0000000000..045e125f3d --- /dev/null +++ b/medtronic/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + + diff --git a/omnipod-common/src/main/res/values/strings.xml b/omnipod-common/src/main/res/values/strings.xml new file mode 100644 index 0000000000..045e125f3d --- /dev/null +++ b/omnipod-common/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + + diff --git a/omnipod-dash/src/main/res/values/strings.xml b/omnipod-dash/src/main/res/values/strings.xml new file mode 100644 index 0000000000..045e125f3d --- /dev/null +++ b/omnipod-dash/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + + diff --git a/omnipod-eros/src/main/res/values/strings.xml b/omnipod-eros/src/main/res/values/strings.xml new file mode 100644 index 0000000000..045e125f3d --- /dev/null +++ b/omnipod-eros/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + + From 7ec10492760584689a78d4f9a66bec9df5c4a03a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 20:58:09 +0100 Subject: [PATCH 72/77] crowdin final cleanup --- crowdin.yml | 12 ------------ danar/src/main/res/values/strings.xml | 3 --- diaconn/src/main/res/values/strings.xml | 3 --- medtronic/src/main/res/values/strings.xml | 3 --- omnipod-common/src/main/res/values/strings.xml | 3 --- omnipod-dash/src/main/res/values/strings.xml | 3 --- omnipod-eros/src/main/res/values/strings.xml | 3 --- 7 files changed, 30 deletions(-) delete mode 100644 danar/src/main/res/values/strings.xml delete mode 100644 diaconn/src/main/res/values/strings.xml delete mode 100644 medtronic/src/main/res/values/strings.xml delete mode 100644 omnipod-common/src/main/res/values/strings.xml delete mode 100644 omnipod-dash/src/main/res/values/strings.xml delete mode 100644 omnipod-eros/src/main/res/values/strings.xml diff --git a/crowdin.yml b/crowdin.yml index b7695c40b3..1776a78fd2 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -55,15 +55,3 @@ files: translation: /ui/src/main/res/values-%android_code%/strings.xml - source: /plugins/src/main/res/values/strings.xml translation: /plugins/src/main/res/values-%android_code%/strings.xml - - source: /danar/src/main/res/values/strings.xml - translation: /danar/src/main/res/values-%android_code%/strings.xml - - source: /diaconn/src/main/res/values/strings.xml - translation: /diaconn/src/main/res/values-%android_code%/strings.xml - - source: /medtronic/src/main/res/values/strings.xml - translation: /medtronic/src/main/res/values-%android_code%/strings.xml - - source: /omnipod-common/src/main/res/values/strings.xml - translation: /omnipod-common/src/main/res/values-%android_code%/strings.xml - - source: /omnipod-eros/src/main/res/values/strings.xml - translation: /omnipod-eros/src/main/res/values-%android_code%/strings.xml - - source: /omnipod-dash/src/main/res/values/strings.xml - translation: /omnipod-dash/src/main/res/values-%android_code%/strings.xml diff --git a/danar/src/main/res/values/strings.xml b/danar/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/danar/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/diaconn/src/main/res/values/strings.xml b/diaconn/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/diaconn/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/medtronic/src/main/res/values/strings.xml b/medtronic/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/medtronic/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/omnipod-common/src/main/res/values/strings.xml b/omnipod-common/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/omnipod-common/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/omnipod-dash/src/main/res/values/strings.xml b/omnipod-dash/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/omnipod-dash/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/omnipod-eros/src/main/res/values/strings.xml b/omnipod-eros/src/main/res/values/strings.xml deleted file mode 100644 index 045e125f3d..0000000000 --- a/omnipod-eros/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - From bf14292b980686ab83069db96ebb7ec1fdf48a1f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 21:49:44 +0100 Subject: [PATCH 73/77] remove database -> shared dependency --- database/build.gradle | 5 +---- .../androidaps/annotations/DbOpenForTesting.kt | 15 +++++++++++++++ .../androidaps/database/AppRepository.kt | 4 ++-- .../androidaps/annotations/DbOpenForTesting.kt | 8 ++++++++ 4 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 database/src/debug/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt create mode 100644 database/src/release/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt diff --git a/database/build.gradle b/database/build.gradle index d67b86c464..0bd96c99ff 100644 --- a/database/build.gradle +++ b/database/build.gradle @@ -20,9 +20,6 @@ android { } dependencies { - // shared needed for OpenForTesting - implementation project(':shared') - api "androidx.core:core-ktx:$core_version" api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" @@ -48,5 +45,5 @@ dependencies { allOpen { // allows mocking for classes w/o directly opening them for release builds - annotation 'info.nightscout.androidaps.annotations.OpenForTesting' + annotation 'info.nightscout.androidaps.annotations.DbOpenForTesting' } \ No newline at end of file diff --git a/database/src/debug/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt b/database/src/debug/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt new file mode 100644 index 0000000000..deca64872c --- /dev/null +++ b/database/src/debug/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.annotations + +/** + * This is the actual annotation that makes the class open. Don't use it directly, only through [DbOpenForTesting] + * which has a NOOP replacement in production. + */ +@Target(AnnotationTarget.ANNOTATION_CLASS) +annotation class DbOpenClass + +/** + * Annotate a class with [DbOpenForTesting] if it should be extendable for testing. + */ +@DbOpenClass +@Target(AnnotationTarget.CLASS) +annotation class DbOpenForTesting \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt index dd2d33806d..1019581b80 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt @@ -1,6 +1,6 @@ package info.nightscout.androidaps.database -import info.nightscout.androidaps.annotations.OpenForTesting +import info.nightscout.androidaps.annotations.DbOpenForTesting import info.nightscout.androidaps.database.data.NewEntries import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.entities.* @@ -19,7 +19,7 @@ import javax.inject.Inject import javax.inject.Singleton import kotlin.math.roundToInt -@OpenForTesting +@DbOpenForTesting @Singleton class AppRepository @Inject internal constructor( internal val database: AppDatabase ) { diff --git a/database/src/release/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt b/database/src/release/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt new file mode 100644 index 0000000000..66704666fe --- /dev/null +++ b/database/src/release/java/info/nightscout/androidaps/annotations/DbOpenForTesting.kt @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.annotations + +/** + * Annotate a class with [DbOpenForTesting] if it should be extendable for testing. + * In production the class remains final. + */ +@Target(AnnotationTarget.CLASS) +annotation class DbOpenForTesting \ No newline at end of file From 724587ad461b700086618df305e8b2acf15f3434 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 23:43:25 +0100 Subject: [PATCH 74/77] Run all tests configuration --- .run/Run all tests.run.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .run/Run all tests.run.xml diff --git a/.run/Run all tests.run.xml b/.run/Run all tests.run.xml new file mode 100644 index 0000000000..16e5767ada --- /dev/null +++ b/.run/Run all tests.run.xml @@ -0,0 +1,23 @@ + + + + + + + false + true + false + + + \ No newline at end of file From fbeb03f322c88bd576ca13de759121b022e48276 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 2 Nov 2022 23:44:53 +0100 Subject: [PATCH 75/77] move activities to ui module --- .../androidaps/dialogs/ExtendedBolusDialog.kt | 15 ++-- .../androidaps/dialogs/FillDialog.kt | 17 ++-- .../androidaps/dialogs/InsulinDialog.kt | 8 +- .../androidaps/dialogs/LoopDialog.kt | 21 +++-- .../androidaps/dialogs/TempBasalDialog.kt | 13 ++- .../androidaps/dialogs/TreatmentDialog.kt | 17 ++-- .../implementations/ActivityNamesImpl.kt | 25 ++++++ .../androidaps/plugins/aps/loop/LoopPlugin.kt | 13 +-- .../general/actions/ActionsFragment.kt | 32 ++++--- .../androidaps/utils/wizard/BolusWizard.kt | 39 ++++++--- .../plugins/aps/loop/LoopPluginTest.kt | 15 +++- core/src/main/AndroidManifest.xml | 14 --- .../androidaps/di/CoreFragmentsModule.kt | 7 -- .../androidaps/dialogs/BolusProgressDialog.kt | 6 +- .../androidaps/dialogs/ErrorDialog.kt | 4 +- .../androidaps/interfaces/ActivityNames.kt | 20 +++++ .../androidaps/services/AlarmSoundService.kt | 9 +- .../services/AlarmSoundServiceHelper.kt | 3 +- .../queue/CommandQueueImplementation.kt | 12 +-- .../queue/CommandQueueImplementationTest.kt | 20 +++-- .../implementation/queue/QueueThreadTest.kt | 4 +- .../androidaps/dana/DanaFragment.kt | 5 +- .../activities/DanaUserOptionsActivity.kt | 6 +- .../services/DanaRv2ExecutionService.java | 16 ++-- .../danars/services/DanaRSService.kt | 16 ++-- .../androidaps/diaconn/DiaconnG8Fragment.kt | 7 +- .../DiaconnG8UserOptionsActivity.kt | 7 +- .../diaconn/service/BLECommonService.kt | 30 +++++-- .../diaconn/service/DiaconnG8Service.kt | 37 ++++++-- .../pump/medtronic/MedtronicPumpPlugin.kt | 6 +- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 36 ++++++-- .../dash/ui/DashPodManagementActivity.kt | 5 +- .../dash/ui/OmnipodDashOverviewFragment.kt | 10 +-- .../omnipod/eros/OmnipodErosPumpPlugin.java | 37 ++++---- .../eros/manager/AapsOmnipodErosManager.java | 15 ++-- .../eros/ui/ErosPodManagementActivity.kt | 37 +++++--- .../eros/ui/OmnipodErosOverviewFragment.kt | 85 +++++++++++-------- .../omnipod/eros/OmnipodErosPumpPluginTest.kt | 11 ++- ui/src/main/AndroidManifest.xml | 15 +++- .../activities/BolusProgressHelperActivity.kt | 3 +- .../ui}/activities/ErrorHelperActivity.kt | 28 ++---- .../ui}/activities/TDDStatsActivity.kt | 12 +-- .../java/info/nightscout/ui/di/UiModule.kt | 8 ++ .../info/nightscout/ui/dialogs/CarbsDialog.kt | 26 ++++-- .../main/res/layout/activity_tdd_stats.xml | 2 +- 45 files changed, 479 insertions(+), 295 deletions(-) rename {core/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/activities/BolusProgressHelperActivity.kt (82%) rename {core/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/activities/ErrorHelperActivity.kt (58%) rename {core/src/main/java/info/nightscout/androidaps => ui/src/main/java/info/nightscout/ui}/activities/TDDStatsActivity.kt (98%) rename {core => ui}/src/main/res/layout/activity_tdd_stats.xml (99%) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt index 4e5e82d903..8df008ed23 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt @@ -7,25 +7,25 @@ import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity -import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources +import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.databinding.DialogExtendedbolusBinding +import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.shared.SafeParse -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.SafeParse import info.nightscout.shared.logging.LTag import java.text.DecimalFormat import java.util.* @@ -41,6 +41,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var uel: UserEntryLogger @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames private var queryingProtection = false private var _binding: DialogExtendedbolusBinding? = null @@ -103,7 +104,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { commandQueue.extendedBolus(insulinAfterConstraint, durationInMinutes, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index 3699e70352..e9820377d9 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -7,31 +7,31 @@ import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources +import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampTherapyEventTransaction import info.nightscout.androidaps.databinding.DialogFillBinding +import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.shared.SafeParse -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.SafeParse +import info.nightscout.shared.logging.LTag import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.util.* @@ -48,6 +48,7 @@ class FillDialog : DialogFragmentWithDate() { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames private var queryingProtection = false private val disposable = CompositeDisposable() @@ -194,7 +195,7 @@ class FillDialog : DialogFragmentWithDate() { commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 2e28e6a0d9..d25fff10ed 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -9,7 +9,6 @@ import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.TemporaryTarget @@ -21,7 +20,6 @@ import info.nightscout.androidaps.databinding.DialogInsulinBinding import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.interfaces.* -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.queue.Callback @@ -30,9 +28,8 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.toSignedString import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper -import info.nightscout.androidaps.interfaces.BolusTimer import info.nightscout.shared.SafeParse +import info.nightscout.shared.logging.LTag import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.text.DecimalFormat @@ -56,6 +53,7 @@ class InsulinDialog : DialogFragmentWithDate() { @Inject lateinit var bolusTimer: BolusTimer @Inject lateinit var uel: UserEntryLogger @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames companion object { @@ -243,7 +241,7 @@ class InsulinDialog : DialogFragmentWithDate() { commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else { bolusTimer.removeAutomationEventBolusReminder() } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt index 88a400f82c..4820917e38 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt @@ -12,7 +12,6 @@ import android.view.WindowManager import androidx.fragment.app.FragmentManager import dagger.android.support.DaggerDialogFragment import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.OfflineEvent import info.nightscout.androidaps.database.entities.UserEntry.Action @@ -25,9 +24,17 @@ import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventRefreshOverview import info.nightscout.androidaps.extensions.runOnUiThread import info.nightscout.androidaps.extensions.toVisibility -import info.nightscout.androidaps.interfaces.* -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.ConfigBuilder +import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker @@ -40,7 +47,8 @@ import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -65,6 +73,7 @@ class LoopDialog : DaggerDialogFragment() { @Inject lateinit var repository: AppRepository @Inject lateinit var objectivePlugin: ObjectivesPlugin @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames private var queryingProtection = false private var showOkCancel: Boolean = true @@ -345,7 +354,7 @@ class LoopDialog : DaggerDialogFragment() { commandQueue.cancelTempBasal(true, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt index c22b3653fb..c44370bad9 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt @@ -7,23 +7,21 @@ import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity -import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources +import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.databinding.DialogTempbasalBinding +import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.shared.SafeParse -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.SafeParse import info.nightscout.shared.logging.LTag import java.text.DecimalFormat import java.util.* @@ -40,6 +38,7 @@ class TempBasalDialog : DialogFragmentWithDate() { @Inject lateinit var ctx: Context @Inject lateinit var uel: UserEntryLogger @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames private var queryingProtection = false private var isPercentPump = true @@ -125,7 +124,7 @@ class TempBasalDialog : DialogFragmentWithDate() { val callback: Callback = object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index de5a2a5457..2f01d661f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -8,31 +8,31 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner -import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources +import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.databinding.DialogTreatmentBinding +import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Constraint -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.shared.SafeParse import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.SafeParse +import info.nightscout.shared.logging.LTag import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.text.DecimalFormat @@ -51,6 +51,7 @@ class TreatmentDialog : DialogFragmentWithDate() { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames private var queryingProtection = false private val disposable = CompositeDisposable() @@ -179,7 +180,7 @@ class TreatmentDialog : DialogFragmentWithDate() { commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt b/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt index 7e78556ef4..579c0ce8ba 100644 --- a/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt +++ b/app/src/main/java/info/nightscout/androidaps/implementations/ActivityNamesImpl.kt @@ -1,11 +1,36 @@ package info.nightscout.androidaps.implementations +import android.content.Context +import android.content.Intent +import androidx.annotation.RawRes import info.nightscout.androidaps.MainActivity import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.services.AlarmSoundService +import info.nightscout.ui.activities.BolusProgressHelperActivity +import info.nightscout.ui.activities.ErrorHelperActivity +import info.nightscout.ui.activities.TDDStatsActivity import javax.inject.Inject class ActivityNamesImpl @Inject constructor() : ActivityNames { override val mainActivityClass: Class<*> get() = MainActivity::class.java + + override val tddStatsActivity: Class<*> + get() = TDDStatsActivity::class.java + + override val errorHelperActivity: Class<*> + get() = ErrorHelperActivity::class.java + + override val bolusProgressHelperActivity: Class<*> + get() = BolusProgressHelperActivity::class.java + + override fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int) { + val i = Intent(ctx, errorHelperActivity) + i.putExtra(AlarmSoundService.SOUND_ID, soundId) + i.putExtra(AlarmSoundService.STATUS, status) + i.putExtra(AlarmSoundService.TITLE, title) + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ctx.startActivity(i) + } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt index f2bcfc92f4..bf57ff5d7b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt @@ -16,7 +16,6 @@ import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.Constants import info.nightscout.androidaps.MainActivity import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.PumpEnactResult @@ -36,6 +35,7 @@ import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.convertedToPercent import info.nightscout.androidaps.extensions.plannedRemainingMinutes import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Constraint @@ -100,7 +100,8 @@ class LoopPlugin @Inject constructor( private val dateUtil: DateUtil, private val uel: UserEntryLogger, private val repository: AppRepository, - private val runningConfiguration: RunningConfiguration + private val runningConfiguration: RunningConfiguration, + private val activityNames: ActivityNames ) : PluginBase( PluginDescription() .mainType(PluginType.LOOP) @@ -678,7 +679,7 @@ class LoopPlugin @Inject constructor( commandQueue.tempBasalAbsolute(0.0, durationInMinutes, true, profile, PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) @@ -686,7 +687,7 @@ class LoopPlugin @Inject constructor( commandQueue.tempBasalPercent(0, durationInMinutes, true, profile, PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) @@ -695,7 +696,7 @@ class LoopPlugin @Inject constructor( commandQueue.cancelExtended(object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.extendedbolusdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.extendedbolusdeliveryerror), R.raw.boluserror) } } }) @@ -713,7 +714,7 @@ class LoopPlugin @Inject constructor( commandQueue.cancelTempBasal(true, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt index ff3fc89a4a..ac03112388 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt @@ -11,15 +11,18 @@ import android.widget.LinearLayout import androidx.core.content.ContextCompat import dagger.android.support.DaggerFragment import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.HistoryBrowseActivity -import info.nightscout.androidaps.activities.TDDStatsActivity import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.databinding.ActionsFragmentBinding -import info.nightscout.androidaps.dialogs.* +import info.nightscout.androidaps.dialogs.CareDialog +import info.nightscout.androidaps.dialogs.ExtendedBolusDialog +import info.nightscout.androidaps.dialogs.FillDialog +import info.nightscout.androidaps.dialogs.ProfileSwitchDialog +import info.nightscout.androidaps.dialogs.TempBasalDialog +import info.nightscout.androidaps.dialogs.TempTargetDialog import info.nightscout.androidaps.events.EventCustomActionsChanged import info.nightscout.androidaps.events.EventExtendedBolusChange import info.nightscout.androidaps.events.EventInitializationChanged @@ -28,8 +31,15 @@ import info.nightscout.androidaps.events.EventTherapyEventChange import info.nightscout.androidaps.extensions.toStringMedium import info.nightscout.androidaps.extensions.toStringShort import info.nightscout.androidaps.extensions.toVisibility -import info.nightscout.androidaps.interfaces.* -import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.BuildHelper +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction @@ -39,16 +49,15 @@ import info.nightscout.androidaps.skins.SkinProvider import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.ProtectionCheck -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers -import info.nightscout.shared.sharedPreferences.SP import info.nightscout.androidaps.utils.ui.SingleClickButton import info.nightscout.androidaps.utils.ui.UIRunnable +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.ui.activities.TDDStatsActivity import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign -import java.util.* import javax.inject.Inject class ActionsFragment : DaggerFragment() { @@ -73,6 +82,7 @@ class ActionsFragment : DaggerFragment() { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository @Inject lateinit var loop: Loop + @Inject lateinit var activityNames: ActivityNames private var disposable: CompositeDisposable = CompositeDisposable() @@ -137,7 +147,7 @@ class ActionsFragment : DaggerFragment() { commandQueue.cancelExtended(object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.extendedbolusdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.extendedbolusdeliveryerror), R.raw.boluserror) } } }) @@ -157,7 +167,7 @@ class ActionsFragment : DaggerFragment() { commandQueue.cancelTempBasal(true, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt index e0d66a5cb7..3ca74ce899 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt @@ -5,7 +5,6 @@ import android.text.Spanned import com.google.common.base.Joiner import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.BolusCalculatorResult @@ -19,23 +18,38 @@ import info.nightscout.androidaps.events.EventRefreshOverview import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.extensions.highValueToUnitsToString import info.nightscout.androidaps.extensions.lowValueToUnitsToString -import info.nightscout.androidaps.interfaces.* -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.BolusTimer +import info.nightscout.androidaps.interfaces.CarbTimer +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.Loop +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.queue.Callback -import info.nightscout.androidaps.utils.* +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.HtmlHelper +import info.nightscout.androidaps.utils.Round +import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.interfaces.ResourceHelper -import info.nightscout.androidaps.interfaces.BolusTimer +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign -import java.util.* +import java.util.LinkedList import javax.inject.Inject import kotlin.math.abs import kotlin.math.max @@ -62,6 +76,7 @@ class BolusWizard @Inject constructor( @Inject lateinit var bolusTimer: BolusTimer @Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider @Inject lateinit var repository: AppRepository + @Inject lateinit var activityNames: ActivityNames private val disposable = CompositeDisposable() @@ -388,7 +403,7 @@ class BolusWizard @Inject constructor( commandQueue.bolus(this, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else carbTimer.scheduleAutomationEventEatReminder() } @@ -435,7 +450,7 @@ class BolusWizard @Inject constructor( commandQueue.tempBasalAbsolute(0.0, 120, true, profile, PumpSync.TemporaryBasalType.NORMAL, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) @@ -443,7 +458,7 @@ class BolusWizard @Inject constructor( commandQueue.tempBasalPercent(0, 120, true, profile, PumpSync.TemporaryBasalType.NORMAL, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror) } } }) @@ -474,7 +489,7 @@ class BolusWizard @Inject constructor( commandQueue.bolus(this, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } } }) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt index ceb9141b7b..6914c34e49 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt @@ -7,7 +7,15 @@ import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Config +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker @@ -16,7 +24,6 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before @@ -44,6 +51,7 @@ class LoopPluginTest : TestBase() { @Mock lateinit var dateUtil: DateUtil @Mock lateinit var runningConfiguration: RunningConfiguration @Mock lateinit var config: Config + @Mock lateinit var activityNames: ActivityNames private lateinit var loopPlugin: LoopPlugin @@ -51,7 +59,8 @@ class LoopPluginTest : TestBase() { @Before fun prepareMock() { loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, config, - constraintChecker, rh, profileFunction, context, commandQueue, activePlugin, virtualPumpPlugin, iobCobCalculator, receiverStatusStore, fabricPrivacy, dateUtil, uel, repository, runningConfiguration) + constraintChecker, rh, profileFunction, context, commandQueue, activePlugin, virtualPumpPlugin, iobCobCalculator, receiverStatusStore, fabricPrivacy, dateUtil, uel, + repository, runningConfiguration, activityNames) `when`(activePlugin.activePump).thenReturn(virtualPumpPlugin) `when`(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager) } diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 083c7f30cf..4395bb15a5 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -10,18 +10,4 @@ - - - - - - diff --git a/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt b/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt index c51a379622..acdb351b18 100644 --- a/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt +++ b/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt @@ -2,9 +2,6 @@ package info.nightscout.androidaps.di import dagger.Module import dagger.android.ContributesAndroidInjector -import info.nightscout.androidaps.activities.BolusProgressHelperActivity -import info.nightscout.androidaps.activities.ErrorHelperActivity -import info.nightscout.androidaps.activities.TDDStatsActivity import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.dialogs.ErrorDialog import info.nightscout.androidaps.dialogs.ProfileViewerDialog @@ -16,10 +13,6 @@ import info.nightscout.androidaps.utils.ui.SingleClickButton abstract class CoreFragmentsModule { @ContributesAndroidInjector abstract fun contributesPrefImportListActivity(): PrefImportListActivity - @ContributesAndroidInjector abstract fun contributesTDDStatsActivity(): TDDStatsActivity - @ContributesAndroidInjector abstract fun contributeBolusProgressHelperActivity(): BolusProgressHelperActivity - @ContributesAndroidInjector abstract fun contributeErrorHelperActivity(): ErrorHelperActivity - @ContributesAndroidInjector abstract fun contributesBolusProgressDialog(): BolusProgressDialog @ContributesAndroidInjector abstract fun contributesErrorDialog(): ErrorDialog @ContributesAndroidInjector abstract fun contributesProfileViewerDialog(): ProfileViewerDialog diff --git a/core/src/main/java/info/nightscout/androidaps/dialogs/BolusProgressDialog.kt b/core/src/main/java/info/nightscout/androidaps/dialogs/BolusProgressDialog.kt index fd677e751c..fb820c7dae 100644 --- a/core/src/main/java/info/nightscout/androidaps/dialogs/BolusProgressDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/dialogs/BolusProgressDialog.kt @@ -8,7 +8,7 @@ import android.view.ViewGroup import android.view.Window import android.view.WindowManager import dagger.android.support.DaggerDialogFragment -import info.nightscout.androidaps.activities.BolusProgressHelperActivity +import info.nightscout.androidaps.activities.DialogAppCompatActivity import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.databinding.DialogBolusprogressBinding import info.nightscout.androidaps.database.entities.UserEntry.Action @@ -50,7 +50,7 @@ class BolusProgressDialog : DaggerDialogFragment() { private var amount = 0.0 var id: Long = 0L private var state: String? = null - private var helpActivity: BolusProgressHelperActivity? = null + private var helpActivity: DialogAppCompatActivity? = null fun setId(id: Long): BolusProgressDialog { this.id = id @@ -63,7 +63,7 @@ class BolusProgressDialog : DaggerDialogFragment() { return this } - fun setHelperActivity(activity: BolusProgressHelperActivity): BolusProgressDialog { + fun setHelperActivity(activity: DialogAppCompatActivity): BolusProgressDialog { helpActivity = activity return this } diff --git a/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt b/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt index 541f67a873..cd637d921e 100644 --- a/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt @@ -11,7 +11,7 @@ import android.view.ViewGroup import android.view.Window import android.view.WindowManager import dagger.android.support.DaggerDialogFragment -import info.nightscout.androidaps.activities.ErrorHelperActivity +import info.nightscout.androidaps.activities.DialogAppCompatActivity import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.databinding.DialogErrorBinding import info.nightscout.androidaps.database.entities.UserEntry.Action @@ -29,7 +29,7 @@ class ErrorDialog : DaggerDialogFragment() { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var ctx: Context - var helperActivity: ErrorHelperActivity? = null + var helperActivity: DialogAppCompatActivity? = null var status: String = "" var title: String = "" var sound: Int = 0 diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt index 80f7f61049..de52ed8f1d 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/ActivityNames.kt @@ -1,5 +1,25 @@ package info.nightscout.androidaps.interfaces +import android.content.Context +import androidx.annotation.RawRes + +/** + * Interface to use activities located in different modules + * usage: startActivity(Intent(context, activityNames.xxxx)) + */ interface ActivityNames { + val mainActivityClass: Class<*> + val tddStatsActivity: Class<*> + val errorHelperActivity: Class<*> + val bolusProgressHelperActivity: Class<*> + + /** + * Show ErrorHelperActivity and start alarm + * @param ctx Context + * @param status message inside dialog + * @param title title of dialog + * @param soundId sound resource. if == 0 alarm is not started + */ + fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int = 0) } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt index 8b10cb6a97..07e79a59ef 100644 --- a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt +++ b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt @@ -9,12 +9,11 @@ import android.os.Handler import android.os.IBinder import android.os.Looper import dagger.android.DaggerService -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.core.R import info.nightscout.androidaps.interfaces.NotificationHolder +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject import kotlin.math.ln @@ -32,6 +31,10 @@ class AlarmSoundService : DaggerService() { companion object { + const val SOUND_ID = "soundId" + const val STATUS = "status" + const val TITLE = "title" + private const val VOLUME_INCREASE_STEPS = 40 // Total number of steps to increase volume with private const val VOLUME_INCREASE_INITIAL_SILENT_TIME_MILLIS = 3_000L // Number of milliseconds that the notification should initially be silent private const val VOLUME_INCREASE_BASE_DELAY_MILLIS = 15_000 // Base delay between volume increments @@ -71,7 +74,7 @@ class AlarmSoundService : DaggerService() { player?.let { if (it.isPlaying) it.stop() } - if (intent?.hasExtra(ErrorHelperActivity.SOUND_ID) == true) resourceId = intent.getIntExtra(ErrorHelperActivity.SOUND_ID, R.raw.error) + if (intent?.hasExtra(AlarmSoundService.SOUND_ID) == true) resourceId = intent.getIntExtra(AlarmSoundService.SOUND_ID, R.raw.error) player = MediaPlayer() try { val afd = rh.openRawResourceFd(resourceId) ?: return START_NOT_STICKY diff --git a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt index 9f5e32a9b6..9d47b78572 100644 --- a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt @@ -5,7 +5,6 @@ import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.IBinder -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.interfaces.NotificationHolder import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -70,7 +69,7 @@ class AlarmSoundServiceHelper @Inject constructor( private fun getServiceIntent(context: Context, sound: Int): Intent { val alarm = Intent(context, AlarmSoundService::class.java) - alarm.putExtra(ErrorHelperActivity.SOUND_ID, sound) + alarm.putExtra(AlarmSoundService.SOUND_ID, sound) return alarm } } \ No newline at end of file diff --git a/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt index e4cbcc9253..65177e94b9 100644 --- a/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt @@ -6,8 +6,6 @@ import android.os.SystemClock import android.text.Spanned import androidx.appcompat.app.AppCompatActivity import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.activities.BolusProgressHelperActivity -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.ProfileSealed @@ -22,6 +20,7 @@ import info.nightscout.androidaps.events.EventMobileToWear import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.extensions.getCustomizedName import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.AndroidPermission import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.CommandQueue @@ -93,7 +92,8 @@ class CommandQueueImplementation @Inject constructor( private val repository: AppRepository, private val fabricPrivacy: FabricPrivacy, private val config: Config, - private val androidPermission: AndroidPermission + private val androidPermission: AndroidPermission, + private val activityNames: ActivityNames ) : CommandQueue { private val disposable = CompositeDisposable() @@ -117,7 +117,7 @@ class CommandQueueImplementation @Inject constructor( setProfile(ProfileSealed.PS(it), it.interfaceIDs.nightscoutId != null, object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.failedupdatebasalprofile), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.failedupdatebasalprofile), R.raw.boluserror) } else { val nonCustomized = ProfileSealed.PS(it).convertToNonCustomizedProfile(dateUtil) EffectiveProfileSwitch( @@ -229,7 +229,7 @@ class CommandQueueImplementation @Inject constructor( val tempCommandQueue = CommandQueueImplementation( injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, activePlugin, context, sp, - buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission + buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission, activityNames ) tempCommandQueue.readStatus(reason, callback) tempCommandQueue.disposable.clear() @@ -631,7 +631,7 @@ class CommandQueueImplementation @Inject constructor( val i = Intent() i.putExtra("insulin", detailedBolusInfo.insulin) i.putExtra("id", detailedBolusInfo.id) - i.setClass(context, BolusProgressHelperActivity::class.java) + i.setClass(context, activityNames.bolusProgressHelperActivity) i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(i) } diff --git a/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt index 0113dc3f62..5324fdf01b 100644 --- a/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt @@ -4,7 +4,6 @@ import android.content.Context import android.os.PowerManager import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.implementation.R import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.data.DetailedBolusInfo @@ -13,6 +12,7 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.AndroidPermission import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config @@ -22,12 +22,13 @@ import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker -import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import info.nightscout.androidaps.queue.Callback -import info.nightscout.androidaps.queue.commands.* +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.androidaps.queue.commands.CustomCommand import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.implementation.R import info.nightscout.implementation.queue.commands.CommandBolus import info.nightscout.implementation.queue.commands.CommandCustomCommand import info.nightscout.implementation.queue.commands.CommandExtendedBolus @@ -42,7 +43,7 @@ import org.junit.Test import org.mockito.Mock import org.mockito.Mockito.anyLong import org.mockito.Mockito.`when` -import java.util.* +import java.util.Calendar class CommandQueueImplementationTest : TestBaseWithProfile() { @@ -51,7 +52,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { @Mock lateinit var sp: SP @Mock lateinit var powerManager: PowerManager @Mock lateinit var repository: AppRepository - @Mock lateinit var fileListProvider: PrefFileListProvider + @Mock lateinit var activityNames: ActivityNames @Mock lateinit var buildHelper: BuildHelper @Mock lateinit var androidPermission: AndroidPermission @@ -71,10 +72,11 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { repository: AppRepository, fabricPrivacy: FabricPrivacy, config: Config, - androidPermission: AndroidPermission + androidPermission: AndroidPermission, + activityNames: ActivityNames ) : CommandQueueImplementation( injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, - activePlugin, context, sp, buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission + activePlugin, context, sp, buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission, activityNames ) { override fun notifyAboutNewCommand() {} @@ -119,7 +121,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { constraintChecker, profileFunction, activePlugin, context, sp, buildHelper, dateUtil, repository, - fabricPrivacy, config, androidPermission + fabricPrivacy, config, androidPermission, activityNames ) testPumpPlugin = TestPumpPlugin(injector) @@ -158,7 +160,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { constraintChecker, profileFunction, activePlugin, context, sp, buildHelper, dateUtil, repository, - fabricPrivacy, config, androidPermission + fabricPrivacy, config, androidPermission, activityNames ) // start with empty queue Assert.assertEquals(0, commandQueue.size()) diff --git a/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt index cb34c49793..7329abdfcd 100644 --- a/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt @@ -8,6 +8,7 @@ import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.AndroidPermission import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Constraint @@ -34,6 +35,7 @@ class QueueThreadTest : TestBaseWithProfile() { @Mock lateinit var repository: AppRepository @Mock lateinit var buildHelper: BuildHelper @Mock lateinit var androidPermission: AndroidPermission + @Mock lateinit var activityNames: ActivityNames val injector = HasAndroidInjector { AndroidInjector { @@ -58,7 +60,7 @@ class QueueThreadTest : TestBaseWithProfile() { commandQueue = CommandQueueImplementation( injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, activePlugin, context, sp, - buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission + buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission, activityNames ) val pumpDescription = PumpDescription() diff --git a/pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt index 6f3f374774..010dbb445a 100644 --- a/pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt +++ b/pump/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt @@ -10,7 +10,6 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import dagger.android.support.DaggerFragment -import info.nightscout.androidaps.activities.TDDStatsActivity import info.nightscout.androidaps.dana.activities.DanaHistoryActivity import info.nightscout.androidaps.dana.activities.DanaUserOptionsActivity import info.nightscout.androidaps.dana.databinding.DanarFragmentBinding @@ -37,6 +36,7 @@ import info.nightscout.androidaps.utils.userEntry.UserEntryMapper.Sources import info.nightscout.androidaps.utils.WarnColors import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.extensions.toVisibility +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers @@ -59,6 +59,7 @@ class DanaFragment : DaggerFragment() { @Inject lateinit var dateUtil: DateUtil @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var activityNames: ActivityNames private var disposable: CompositeDisposable = CompositeDisposable() @@ -107,7 +108,7 @@ class DanaFragment : DaggerFragment() { }.show(childFragmentManager, "ProfileViewDialog") } - binding.stats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) } + binding.stats.setOnClickListener { startActivity(Intent(context, activityNames.tddStatsActivity)) } binding.userOptions.setOnClickListener { startActivity(Intent(context, DanaUserOptionsActivity::class.java)) } binding.btConnectionLayout.setOnClickListener { aapsLogger.debug(LTag.PUMP, "Clicked connect to pump") diff --git a/pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt b/pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt index fed75385ff..2e217293d2 100644 --- a/pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt +++ b/pump/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt @@ -3,15 +3,14 @@ package info.nightscout.androidaps.dana.activities import android.content.Context import android.os.Bundle import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.dana.R import info.nightscout.androidaps.dana.databinding.DanarUserOptionsActivityBinding import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.FabricPrivacy @@ -32,6 +31,7 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var aapsSchedulers: AapsSchedulers + @Inject lateinit var activityNames: ActivityNames private val disposable = CompositeDisposable() @@ -152,7 +152,7 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { commandQueue.setUserOptions(object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.pumperror), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.pumperror), R.raw.boluserror) } } }) diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java index ac134cbf4a..6970322926 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/services/DanaRv2ExecutionService.java @@ -11,7 +11,6 @@ import javax.inject.Inject; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.activities.ErrorHelperActivity; import info.nightscout.androidaps.dana.DanaPump; import info.nightscout.androidaps.dana.events.EventDanaRNewStatus; import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin; @@ -50,19 +49,19 @@ import info.nightscout.androidaps.danar.comm.MsgStatusBasic; import info.nightscout.androidaps.danar.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; -import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.dialogs.BolusProgressDialog; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventProfileSwitchChanged; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.interfaces.ActivePlugin; +import info.nightscout.androidaps.interfaces.ActivityNames; import info.nightscout.androidaps.interfaces.CommandQueue; +import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.interfaces.Pump; import info.nightscout.androidaps.interfaces.PumpSync; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; @@ -72,7 +71,8 @@ import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.T; -import info.nightscout.androidaps.interfaces.ResourceHelper; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { @@ -91,6 +91,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { @Inject PumpSync pumpSync; @Inject SP sp; @Inject DateUtil dateUtil; + @Inject ActivityNames activityNames; public DanaRv2ExecutionService() { } @@ -194,7 +195,8 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { if (Math.abs(timeDiff) > 60 * 60 * 1.5) { aapsLogger.debug(LTag.PUMP, "Pump time difference: " + timeDiff + " seconds - large difference"); //If time-diff is very large, warn user until we can synchronize history readings properly - ErrorHelperActivity.Companion.runAlarm(context, rh.gs(R.string.largetimediff), rh.gs(R.string.largetimedifftitle), R.raw.error); + activityNames.runAlarm(context, rh.gs(R.string.largetimediff), + rh.gs(R.string.largetimedifftitle), R.raw.error); //deinitialize pump danaPump.reset(); @@ -350,7 +352,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { mSerialIOThread.sendMessage(msgSetHistoryEntry_v2); danaPump.lastHistoryFetched = Math.min(danaPump.lastHistoryFetched, carbtime - T.Companion.mins(1).msecs()); if (!msgSetHistoryEntry_v2.isReceived() || msgSetHistoryEntry_v2.getFailed()) - ErrorHelperActivity.Companion.runAlarm(context, rh.gs(R.string.carbs_store_error) + activityNames.runAlarm(context, rh.gs(R.string.carbs_store_error) , rh.gs(R.string.error), R.raw.boluserror); } diff --git a/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt index 7510b9f7a3..994a56b43e 100644 --- a/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt +++ b/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt @@ -9,7 +9,6 @@ import android.os.SystemClock import dagger.android.DaggerService import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.dana.comm.RecordTypes import info.nightscout.androidaps.dana.events.EventDanaRNewStatus @@ -23,25 +22,25 @@ import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.general.overview.notifications.Notification -import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -65,10 +64,9 @@ class DanaRSService : DaggerService() { @Inject lateinit var context: Context @Inject lateinit var danaRSPlugin: DanaRSPlugin @Inject lateinit var danaPump: DanaPump - @Inject lateinit var danaRSMessageHashTable: DanaRSMessageHashTable @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var constraintChecker: ConstraintChecker - @Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage + @Inject lateinit var activityNames: ActivityNames @Inject lateinit var bleComm: BLEComm @Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var pumpSync: PumpSync @@ -162,7 +160,7 @@ class DanaRSService : DaggerService() { if (abs(timeDiff) > 60 * 60 * 1.5) { aapsLogger.debug(LTag.PUMPCOMM, "Pump time difference: $timeDiff seconds - large difference") //If time-diff is very large, warn user until we can synchronize history readings properly - ErrorHelperActivity.runAlarm(context, rh.gs(R.string.largetimediff), rh.gs(R.string.largetimedifftitle), R.raw.error) + activityNames.runAlarm(context, rh.gs(R.string.largetimediff), rh.gs(R.string.largetimedifftitle), R.raw.error) //de-initialize pump danaPump.reset() @@ -272,7 +270,7 @@ class DanaRSService : DaggerService() { sendMessage(msgSetHistoryEntryV2) danaPump.lastHistoryFetched = min(danaPump.lastHistoryFetched, carbTime - T.mins(1).msecs()) if (!msgSetHistoryEntryV2.isReceived || msgSetHistoryEntryV2.failed) - ErrorHelperActivity.runAlarm(context, rh.gs(R.string.carbs_store_error), rh.gs(R.string.error), R.raw.boluserror) + activityNames.runAlarm(context, rh.gs(R.string.carbs_store_error), rh.gs(R.string.error), R.raw.boluserror) } val bolusStart = System.currentTimeMillis() if (insulin > 0) { diff --git a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt index 5a503a2247..1552ca7170 100644 --- a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt +++ b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Fragment.kt @@ -9,7 +9,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import dagger.android.support.DaggerFragment -import info.nightscout.androidaps.activities.TDDStatsActivity import info.nightscout.androidaps.diaconn.activities.DiaconnG8HistoryActivity import info.nightscout.androidaps.diaconn.activities.DiaconnG8UserOptionsActivity import info.nightscout.androidaps.diaconn.databinding.DiaconnG8FragmentBinding @@ -19,15 +18,16 @@ import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.events.EventTempBasalChange import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Pump +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.WarnColors -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -49,6 +49,7 @@ class DiaconnG8Fragment : DaggerFragment() { @Inject lateinit var warnColors: WarnColors @Inject lateinit var dateUtil: DateUtil @Inject lateinit var aapsSchedulers: AapsSchedulers + @Inject lateinit var activityNames: ActivityNames private var disposable: CompositeDisposable = CompositeDisposable() @@ -77,7 +78,7 @@ class DiaconnG8Fragment : DaggerFragment() { super.onViewCreated(view, savedInstanceState) binding.history.setOnClickListener { startActivity(Intent(context, DiaconnG8HistoryActivity::class.java)) } - binding.stats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) } + binding.stats.setOnClickListener { startActivity(Intent(context, activityNames.tddStatsActivity)) } binding.userOptions.setOnClickListener { startActivity(Intent(context, DiaconnG8UserOptionsActivity::class.java)) } binding.btconnection.setOnClickListener { aapsLogger.debug(LTag.PUMP, "Clicked connect to pump") diff --git a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt index a1e62c4d5d..adb92d9317 100644 --- a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt +++ b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/activities/DiaconnG8UserOptionsActivity.kt @@ -1,19 +1,17 @@ package info.nightscout.androidaps.diaconn.activities import android.content.Context -import android.content.Intent import android.os.Bundle import android.view.View import android.widget.AdapterView import android.widget.ArrayAdapter -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.diaconn.DiaconnG8Pump import info.nightscout.androidaps.diaconn.R import info.nightscout.androidaps.diaconn.databinding.DiaconnG8UserOptionsActivityBinding import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.ToastUtils @@ -31,6 +29,7 @@ class DiaconnG8UserOptionsActivity : NoSplashAppCompatActivity() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var sp: SP + @Inject lateinit var activityNames: ActivityNames private val disposable = CompositeDisposable() @@ -152,7 +151,7 @@ class DiaconnG8UserOptionsActivity : NoSplashAppCompatActivity() { commandQueue.setUserOptions(object : Callback() { override fun run() { if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, rh.gs(R.string.pumperror), R.raw.boluserror) + activityNames.runAlarm(context, result.comment, rh.gs(R.string.pumperror), R.raw.boluserror) } } }) diff --git a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt index 556e8dc38f..61165a6f60 100644 --- a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt +++ b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/BLECommonService.kt @@ -2,26 +2,39 @@ package info.nightscout.androidaps.diaconn.service import android.Manifest import android.annotation.SuppressLint -import android.bluetooth.* +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothGattCallback +import android.bluetooth.BluetoothGattCharacteristic +import android.bluetooth.BluetoothGattDescriptor +import android.bluetooth.BluetoothGattService +import android.bluetooth.BluetoothManager +import android.bluetooth.BluetoothProfile import android.content.Context import android.content.pm.PackageManager import android.os.Build import android.os.SystemClock import androidx.core.app.ActivityCompat import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.diaconn.DiaconnG8Pump import info.nightscout.androidaps.diaconn.R -import info.nightscout.androidaps.diaconn.packet.* +import info.nightscout.androidaps.diaconn.packet.BatteryWarningReportPacket +import info.nightscout.androidaps.diaconn.packet.BigLogInquireResponsePacket +import info.nightscout.androidaps.diaconn.packet.DiaconnG8Packet +import info.nightscout.androidaps.diaconn.packet.DiaconnG8ResponseMessageHashTable +import info.nightscout.androidaps.diaconn.packet.DiaconnG8SettingResponseMessageHashTable +import info.nightscout.androidaps.diaconn.packet.InjectionBlockReportPacket +import info.nightscout.androidaps.diaconn.packet.InsulinLackReportPacket import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.extensions.notify import info.nightscout.androidaps.extensions.waitMillis +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag -import java.util.* +import java.util.UUID import java.util.concurrent.ScheduledFuture import javax.inject.Inject import javax.inject.Singleton @@ -36,6 +49,7 @@ class BLECommonService @Inject internal constructor( private val diaconnG8ResponseMessageHashTable: DiaconnG8ResponseMessageHashTable, private val diaconnG8SettingResponseMessageHashTable: DiaconnG8SettingResponseMessageHashTable, private val diaconnG8Pump: DiaconnG8Pump, + private val activityNames: ActivityNames ) { companion object { @@ -274,7 +288,7 @@ class BLECommonService @Inject internal constructor( processedMessageByte = bytes if (bluetoothGatt == null) { - aapsLogger.debug(LTag.PUMPBTCOMM, ">>>>> IGNORING (NOT CONNECTED) " + message.friendlyName ) + aapsLogger.debug(LTag.PUMPBTCOMM, ">>>>> IGNORING (NOT CONNECTED) " + message.friendlyName) return } @@ -324,20 +338,20 @@ class BLECommonService @Inject internal constructor( if (message is InjectionBlockReportPacket) { message.handleMessage(data) diaconnG8Pump.bolusBlocked = true - ErrorHelperActivity.runAlarm(context, rh.gs(R.string.injectionblocked), rh.gs(R.string.injectionblocked), R.raw.boluserror) + activityNames.runAlarm(context, rh.gs(R.string.injectionblocked), rh.gs(R.string.injectionblocked), R.raw.boluserror) return } // battery warning report if (message is BatteryWarningReportPacket) { message.handleMessage(data) - ErrorHelperActivity.runAlarm(context, rh.gs(R.string.needbatteryreplace), rh.gs(R.string.batterywarning), R.raw.boluserror) + activityNames.runAlarm(context, rh.gs(R.string.needbatteryreplace), rh.gs(R.string.batterywarning), R.raw.boluserror) return } // insulin lack warning report if (message is InsulinLackReportPacket) { message.handleMessage(data) - ErrorHelperActivity.runAlarm(context, rh.gs(R.string.needinsullinreplace), rh.gs(R.string.insulinlackwarning), R.raw.boluserror) + activityNames.runAlarm(context, rh.gs(R.string.needinsullinreplace), rh.gs(R.string.insulinlackwarning), R.raw.boluserror) return } diff --git a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt index 160c4f64a3..1dd284d41c 100644 --- a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt +++ b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt @@ -9,7 +9,6 @@ import android.os.SystemClock import dagger.android.DaggerService import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.diaconn.DiaconnG8Plugin import info.nightscout.androidaps.diaconn.DiaconnG8Pump @@ -18,7 +17,34 @@ import info.nightscout.androidaps.diaconn.api.DiaconnApiService import info.nightscout.androidaps.diaconn.api.DiaconnLogUploader import info.nightscout.androidaps.diaconn.database.DiaconnHistoryRecordDao import info.nightscout.androidaps.diaconn.events.EventDiaconnG8NewStatus -import info.nightscout.androidaps.diaconn.packet.* +import info.nightscout.androidaps.diaconn.packet.AppConfirmSettingPacket +import info.nightscout.androidaps.diaconn.packet.BasalLimitInquirePacket +import info.nightscout.androidaps.diaconn.packet.BasalSettingPacket +import info.nightscout.androidaps.diaconn.packet.BigAPSMainInfoInquirePacket +import info.nightscout.androidaps.diaconn.packet.BigLogInquirePacket +import info.nightscout.androidaps.diaconn.packet.BigMainInfoInquirePacket +import info.nightscout.androidaps.diaconn.packet.BolusSpeedInquirePacket +import info.nightscout.androidaps.diaconn.packet.BolusSpeedSettingPacket +import info.nightscout.androidaps.diaconn.packet.DiaconnG8Packet +import info.nightscout.androidaps.diaconn.packet.DisplayTimeInquirePacket +import info.nightscout.androidaps.diaconn.packet.DisplayTimeoutSettingPacket +import info.nightscout.androidaps.diaconn.packet.IncarnationInquirePacket +import info.nightscout.androidaps.diaconn.packet.InjectionBasalSettingPacket +import info.nightscout.androidaps.diaconn.packet.InjectionCancelSettingPacket +import info.nightscout.androidaps.diaconn.packet.InjectionExtendedBolusSettingPacket +import info.nightscout.androidaps.diaconn.packet.InjectionSnackInquirePacket +import info.nightscout.androidaps.diaconn.packet.InjectionSnackSettingPacket +import info.nightscout.androidaps.diaconn.packet.LanguageInquirePacket +import info.nightscout.androidaps.diaconn.packet.LanguageSettingPacket +import info.nightscout.androidaps.diaconn.packet.LogStatusInquirePacket +import info.nightscout.androidaps.diaconn.packet.SerialNumInquirePacket +import info.nightscout.androidaps.diaconn.packet.SneckLimitInquirePacket +import info.nightscout.androidaps.diaconn.packet.SoundInquirePacket +import info.nightscout.androidaps.diaconn.packet.SoundSettingPacket +import info.nightscout.androidaps.diaconn.packet.TempBasalInquirePacket +import info.nightscout.androidaps.diaconn.packet.TempBasalSettingPacket +import info.nightscout.androidaps.diaconn.packet.TimeInquirePacket +import info.nightscout.androidaps.diaconn.packet.TimeSettingPacket import info.nightscout.androidaps.diaconn.pumplog.PumplogUtil import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.events.EventAppExit @@ -26,10 +52,12 @@ import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification @@ -41,7 +69,6 @@ import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -68,7 +95,6 @@ class DiaconnG8Service : DaggerService() { @Inject lateinit var context: Context @Inject lateinit var diaconnG8Plugin: DiaconnG8Plugin @Inject lateinit var diaconnG8Pump: DiaconnG8Pump - @Inject lateinit var diaconnG8ResponseMessageHashTable: DiaconnG8ResponseMessageHashTable @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var constraintChecker: ConstraintChecker @Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @@ -79,6 +105,7 @@ class DiaconnG8Service : DaggerService() { @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var diaconnLogUploader: DiaconnLogUploader @Inject lateinit var diaconnHistoryRecordDao: DiaconnHistoryRecordDao + @Inject lateinit var activityNames: ActivityNames private val disposable = CompositeDisposable() private val mBinder: IBinder = LocalBinder() @@ -190,7 +217,7 @@ class DiaconnG8Service : DaggerService() { if (abs(timeDiff) > 60 * 60 * 1.5) { aapsLogger.debug(LTag.PUMPCOMM, "Pump time difference: $timeDiff seconds - large difference") //If time-diff is very large, warn user until we can synchronize history readings properly - ErrorHelperActivity.runAlarm(context, rh.gs(R.string.largetimediff), rh.gs(R.string.largetimedifftitle), R.raw.error) + activityNames.runAlarm(context, rh.gs(R.string.largetimediff), rh.gs(R.string.largetimedifftitle), R.raw.error) //de-initialize pump diaconnG8Pump.reset() diff --git a/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index 551a06f862..1aa1bfa19e 100644 --- a/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/pump/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -7,7 +7,6 @@ import android.os.IBinder import android.os.SystemClock import androidx.preference.Preference import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.activities.ErrorHelperActivity.Companion.runAlarm import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.events.EventRefreshOverview @@ -88,6 +87,7 @@ class MedtronicPumpPlugin @Inject constructor( private val medtronicHistoryData: MedtronicHistoryData, private val rileyLinkServiceData: RileyLinkServiceData, private val serviceTaskExecutor: ServiceTaskExecutor, + private val activityNames: ActivityNames, dateUtil: DateUtil, aapsSchedulers: AapsSchedulers, pumpSync: PumpSync, @@ -626,7 +626,7 @@ class MedtronicPumpPlugin @Inject constructor( // LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled after Bolus started."); Thread { SystemClock.sleep(2000) - runAlarm(context, rh.gs(R.string.medtronic_cmd_cancel_bolus_not_supported), rh.gs(R.string.medtronic_warning), R.raw.boluserror) + activityNames.runAlarm(context, rh.gs(R.string.medtronic_cmd_cancel_bolus_not_supported), rh.gs(R.string.medtronic_warning), R.raw.boluserror) }.start() } val now = System.currentTimeMillis() @@ -1182,7 +1182,7 @@ class MedtronicPumpPlugin @Inject constructor( if (rileyLinkMedtronicService?.verifyConfiguration() == true) { serviceTaskExecutor.startTask(WakeAndTuneTask(injector)) } else { - runAlarm(context, rh.gs(R.string.medtronic_error_operation_not_possible_no_configuration), rh.gs(R.string.medtronic_warning), R.raw.boluserror) + activityNames.runAlarm(context, rh.gs(R.string.medtronic_error_operation_not_possible_no_configuration), rh.gs(R.string.medtronic_warning), R.raw.boluserror) } } diff --git a/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt index 2ef6ee79eb..6c9b453bcb 100644 --- a/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt +++ b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt @@ -5,7 +5,6 @@ import android.os.Handler import android.os.HandlerThread import android.text.format.DateFormat import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.activities.ErrorHelperActivity.Companion.runAlarm import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.events.EventPreferenceChange @@ -15,7 +14,17 @@ import info.nightscout.androidaps.events.EventTempBasalChange import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.plannedRemainingMinutes import info.nightscout.androidaps.extensions.toStringFull -import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.PluginDescription +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.Pump +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.PumpPluginBase +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction @@ -27,9 +36,22 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType -import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.* +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDeactivatePod +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDisableSuspendAlerts +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandPlayTestBeep +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandResumeDelivery +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSilenceAlerts +import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandUpdateAlertConfiguration import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.* +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertTrigger +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepRepetitionType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodConstants import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmed import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager @@ -61,7 +83,7 @@ import io.reactivex.rxjava3.kotlin.plusAssign import org.json.JSONObject import java.time.Duration import java.time.ZonedDateTime -import java.util.* +import java.util.Date import java.util.concurrent.CountDownLatch import javax.inject.Inject import javax.inject.Singleton @@ -81,7 +103,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private val aapsSchedulers: AapsSchedulers, private val fabricPrivacy: FabricPrivacy, private val dateUtil: DateUtil, - + private val activityNames: ActivityNames, injector: HasAndroidInjector, aapsLogger: AAPSLogger, rh: ResourceHelper, @@ -1478,7 +1500,7 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun showErrorDialog(message: String, sound: Int) { - runAlarm(context, message, rh.gs(R.string.error), sound) + activityNames.runAlarm(context, message, rh.gs(R.string.error), sound) } private fun showNotification(id: Int, message: String, urgency: Int, sound: Int?) { diff --git a/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt index cb253cae21..82c0d2b802 100644 --- a/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt +++ b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/DashPodManagementActivity.kt @@ -4,9 +4,9 @@ import android.content.Context import android.content.Intent import android.os.Bundle import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.extensions.toVisibility +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandPlayTestBeep import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.PodActivationWizardActivity @@ -33,6 +33,7 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() { @Inject lateinit var context: Context @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var podStateManager: OmnipodDashPodStateManager + @Inject lateinit var activityNames: ActivityNames private var disposables: CompositeDisposable = CompositeDisposable() @@ -147,7 +148,7 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() { private fun displayErrorDialog(title: String, message: String, @Suppress("SameParameterValue") withSound: Boolean) { context.let { - ErrorHelperActivity.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) + activityNames.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) } } } diff --git a/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt index 9d28dc6485..9c90531efb 100644 --- a/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt +++ b/pump/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt @@ -10,12 +10,11 @@ import android.view.View import android.view.ViewGroup import dagger.android.support.DaggerFragment import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventPumpStatusChanged +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.CommandQueue -import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification @@ -49,7 +48,8 @@ import io.reactivex.rxjava3.kotlin.plusAssign import org.apache.commons.lang3.StringUtils import java.time.Duration import java.time.ZonedDateTime -import java.util.* +import java.util.Date +import java.util.TimeZone import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -66,7 +66,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var dateUtil: DateUtil @Inject lateinit var aapsSchedulers: AapsSchedulers - @Inject lateinit var pumpSync: PumpSync + @Inject lateinit var activityNames: ActivityNames @Inject lateinit var buildHelper: BuildHelper companion object { @@ -677,7 +677,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { private fun displayErrorDialog(title: String, message: String, withSound: Boolean) { context?.let { - ErrorHelperActivity.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) + activityNames.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) } } diff --git a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java index eec5d61dd9..2a72613ba8 100644 --- a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java +++ b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java @@ -1,5 +1,10 @@ package info.nightscout.androidaps.plugins.pump.omnipod.eros; +import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.convertedToAbsolute; +import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.getPlannedRemainingMinutes; +import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.toStringFull; +import static info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.OmnipodConstants.BASAL_STEP_DURATION; + import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -29,7 +34,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import dagger.android.HasAndroidInjector; -import info.nightscout.androidaps.activities.ErrorHelperActivity; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventAppExit; @@ -37,6 +41,7 @@ import info.nightscout.androidaps.events.EventAppInitialized; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.ActivePlugin; +import info.nightscout.androidaps.interfaces.ActivityNames; import info.nightscout.androidaps.interfaces.CommandQueue; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; @@ -46,9 +51,7 @@ import info.nightscout.androidaps.interfaces.Pump; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpPluginBase; import info.nightscout.androidaps.interfaces.PumpSync; -import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.schedule.BasalSchedule; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.common.ManufacturerType; import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType; @@ -81,6 +84,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.Al import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.BeepConfigType; import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.manager.ErosPodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.util.TimeUtil; import info.nightscout.androidaps.plugins.pump.omnipod.eros.event.EventOmnipodErosActiveAlertsChanged; @@ -98,22 +102,19 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.util.AapsOmnipodUtil import info.nightscout.androidaps.plugins.pump.omnipod.eros.util.OmnipodAlertUtil; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.commands.CustomCommand; +import info.nightscout.androidaps.services.AlarmSoundService; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.Round; import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.TimeChangeType; -import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.utils.rx.AapsSchedulers; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; import io.reactivex.rxjava3.disposables.CompositeDisposable; -import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.convertedToAbsolute; -import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.getPlannedRemainingMinutes; -import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.toStringFull; -import static info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.OmnipodConstants.BASAL_STEP_DURATION; - /** * Created by andy on 23.04.18. * @@ -129,7 +130,6 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley private final ErosPodStateManager podStateManager; private final RileyLinkServiceData rileyLinkServiceData; private final AapsOmnipodErosManager aapsOmnipodErosManager; - private final ErosHistory erosHistory; private final AapsOmnipodUtil aapsOmnipodUtil; private final RileyLinkUtil rileyLinkUtil; private final OmnipodAlertUtil omnipodAlertUtil; @@ -147,6 +147,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley private final ServiceConnection serviceConnection; private final PumpType pumpType = PumpType.OMNIPOD_EROS; private final PumpSync pumpSync; + private final ActivityNames activityNames; private final CompositeDisposable disposable = new CompositeDisposable(); @@ -176,7 +177,6 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley ActivePlugin activePlugin, SP sp, ErosPodStateManager podStateManager, - ErosHistory erosHistory, AapsOmnipodErosManager aapsOmnipodErosManager, CommandQueue commandQueue, FabricPrivacy fabricPrivacy, @@ -186,7 +186,8 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley RileyLinkUtil rileyLinkUtil, OmnipodAlertUtil omnipodAlertUtil, ProfileFunction profileFunction, - PumpSync pumpSync + PumpSync pumpSync, + ActivityNames activityNames ) { super(new PluginDescription() // .mainType(PluginType.PUMP) // @@ -209,12 +210,12 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley this.podStateManager = podStateManager; this.rileyLinkServiceData = rileyLinkServiceData; this.aapsOmnipodErosManager = aapsOmnipodErosManager; - this.erosHistory = erosHistory; this.aapsOmnipodUtil = aapsOmnipodUtil; this.rileyLinkUtil = rileyLinkUtil; this.omnipodAlertUtil = omnipodAlertUtil; this.profileFunction = profileFunction; this.pumpSync = pumpSync; + this.activityNames = activityNames; pumpDescription = new PumpDescription(pumpType); @@ -896,10 +897,10 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(aapsOmnipodErosManager.translateException(ex)); } - Intent i = new Intent(context, ErrorHelperActivity.class); - i.putExtra(ErrorHelperActivity.SOUND_ID, 0); - i.putExtra(ErrorHelperActivity.STATUS, rh.gs(R.string.omnipod_eros_pod_management_pulse_log_value) + ":\n" + result.toString()); - i.putExtra(ErrorHelperActivity.TITLE, rh.gs(R.string.omnipod_eros_pod_management_pulse_log)); + Intent i = new Intent(context, activityNames.getErrorHelperActivity()); + i.putExtra(AlarmSoundService.SOUND_ID, 0); + i.putExtra(AlarmSoundService.STATUS, rh.gs(R.string.omnipod_eros_pod_management_pulse_log_value) + ":\n" + result.toString()); + i.putExtra(AlarmSoundService.TITLE, rh.gs(R.string.omnipod_eros_pod_management_pulse_log)); i.putExtra("clipboardContent", result.toString()); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); diff --git a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java index d017a7e7d2..2cba6243c3 100644 --- a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java +++ b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java @@ -14,16 +14,15 @@ import javax.inject.Inject; import javax.inject.Singleton; import dagger.android.HasAndroidInjector; -import info.nightscout.androidaps.activities.ErrorHelperActivity; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.extensions.PumpStateExtensionKt; +import info.nightscout.androidaps.interfaces.ActivityNames; import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.interfaces.PumpSync; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; @@ -79,8 +78,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.rileylink.manager.Om import info.nightscout.androidaps.plugins.pump.omnipod.eros.util.AapsOmnipodUtil; import info.nightscout.androidaps.plugins.pump.omnipod.eros.util.OmnipodAlertUtil; import info.nightscout.androidaps.utils.T; -import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.utils.rx.AapsSchedulers; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; import io.reactivex.rxjava3.subjects.SingleSubject; @@ -99,6 +99,7 @@ public class AapsOmnipodErosManager { private final OmnipodAlertUtil omnipodAlertUtil; private final Context context; private final PumpSync pumpSync; + private final ActivityNames activityNames; private boolean basalBeepsEnabled; private boolean bolusBeepsEnabled; @@ -128,7 +129,8 @@ public class AapsOmnipodErosManager { HasAndroidInjector injector, OmnipodAlertUtil omnipodAlertUtil, Context context, - PumpSync pumpSync) { + PumpSync pumpSync, + ActivityNames activityNames) { this.podStateManager = podStateManager; this.erosHistory = erosHistory; @@ -141,6 +143,7 @@ public class AapsOmnipodErosManager { this.omnipodAlertUtil = omnipodAlertUtil; this.context = context; this.pumpSync = pumpSync; + this.activityNames = activityNames; delegate = new OmnipodManager(aapsLogger, aapsSchedulers, communicationService, podStateManager); @@ -965,7 +968,7 @@ public class AapsOmnipodErosManager { } private void showErrorDialog(String message, Integer sound) { - ErrorHelperActivity.Companion.runAlarm(context, message, rh.gs(R.string.error), sound); + activityNames.runAlarm(context, message, rh.gs(R.string.error), sound); } private void showPodFaultNotification(FaultEventCode faultEventCode) { diff --git a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt index 5e55c7d612..3893b36eea 100644 --- a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt +++ b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodManagementActivity.kt @@ -6,10 +6,11 @@ import android.os.Bundle import android.os.Handler import android.os.HandlerThread import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.NoSplashAppCompatActivity +import info.nightscout.androidaps.extensions.toVisibility +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.CommandQueue -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData @@ -31,8 +32,6 @@ import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.extensions.toVisibility -import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.ui.UIRunnable import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -55,6 +54,7 @@ class ErosPodManagementActivity : NoSplashAppCompatActivity() { @Inject lateinit var serviceTaskExecutor: ServiceTaskExecutor @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var buildHelper: BuildHelper + @Inject lateinit var activityNames: ActivityNames private var disposables: CompositeDisposable = CompositeDisposable() private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) @@ -69,7 +69,8 @@ class ErosPodManagementActivity : NoSplashAppCompatActivity() { binding.buttonActivatePod.setOnClickListener { val type: PodActivationWizardActivity.Type = if (podStateManager.isPodInitialized - and podStateManager.activationProgress.isAtLeast(ActivationProgress.PRIMING_COMPLETED)) { + and podStateManager.activationProgress.isAtLeast(ActivationProgress.PRIMING_COMPLETED) + ) { PodActivationWizardActivity.Type.SHORT } else { PodActivationWizardActivity.Type.LONG @@ -86,9 +87,9 @@ class ErosPodManagementActivity : NoSplashAppCompatActivity() { binding.buttonDiscardPod.setOnClickListener { OKDialog.showConfirmation(this, - rh.gs(R.string.omnipod_common_pod_management_discard_pod_confirmation), Thread { - aapsOmnipodManager.discardPodState() - }) + rh.gs(R.string.omnipod_common_pod_management_discard_pod_confirmation), Thread { + aapsOmnipodManager.discardPodState() + }) } binding.buttonRileylinkStats.setOnClickListener { @@ -111,7 +112,11 @@ class ErosPodManagementActivity : NoSplashAppCompatActivity() { commandQueue.customCommand(CommandPlayTestBeep(), object : Callback() { override fun run() { if (!result.success) { - displayErrorDialog(rh.gs(R.string.omnipod_common_warning), rh.gs(R.string.omnipod_common_two_strings_concatenated_by_colon, rh.gs(R.string.omnipod_common_error_failed_to_play_test_beep), result.comment), false) + displayErrorDialog( + rh.gs(R.string.omnipod_common_warning), + rh.gs(R.string.omnipod_common_two_strings_concatenated_by_colon, rh.gs(R.string.omnipod_common_error_failed_to_play_test_beep), result.comment), + false + ) } } }) @@ -124,7 +129,11 @@ class ErosPodManagementActivity : NoSplashAppCompatActivity() { commandQueue.customCommand(CommandReadPulseLog(), object : Callback() { override fun run() { if (!result.success) { - displayErrorDialog(rh.gs(R.string.omnipod_common_warning), rh.gs(R.string.omnipod_common_two_strings_concatenated_by_colon, rh.gs(R.string.omnipod_eros_error_failed_to_read_pulse_log), result.comment), false) + displayErrorDialog( + rh.gs(R.string.omnipod_common_warning), + rh.gs(R.string.omnipod_common_two_strings_concatenated_by_colon, rh.gs(R.string.omnipod_eros_error_failed_to_read_pulse_log), result.comment), + false + ) } } }) @@ -224,15 +233,17 @@ class ErosPodManagementActivity : NoSplashAppCompatActivity() { private fun displayErrorDialog(title: String, message: String, @Suppress("SameParameterValue") withSound: Boolean) { context.let { - ErrorHelperActivity.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) + activityNames.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) } } private fun displayNotConfiguredDialog() { context.let { UIRunnable { - OKDialog.show(it, rh.gs(R.string.omnipod_common_warning), - rh.gs(R.string.omnipod_eros_error_operation_not_possible_no_configuration), null) + OKDialog.show( + it, rh.gs(R.string.omnipod_common_warning), + rh.gs(R.string.omnipod_eros_error_operation_not_possible_no_configuration), null + ) }.run() } } diff --git a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt index e26bb0dfb0..f62e5c044c 100644 --- a/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt +++ b/pump/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/OmnipodErosOverviewFragment.kt @@ -10,9 +10,9 @@ import android.view.View import android.view.ViewGroup import dagger.android.support.DaggerFragment import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus @@ -56,7 +56,7 @@ import io.reactivex.rxjava3.kotlin.plusAssign import org.apache.commons.lang3.StringUtils import org.joda.time.DateTime import org.joda.time.Duration -import java.util.* +import java.util.TimeZone import javax.inject.Inject class OmnipodErosOverviewFragment : DaggerFragment() { @@ -81,6 +81,7 @@ class OmnipodErosOverviewFragment : DaggerFragment() { @Inject lateinit var omnipodManager: AapsOmnipodErosManager @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var aapsSchedulers: AapsSchedulers + @Inject lateinit var activityNames: ActivityNames private var disposables: CompositeDisposable = CompositeDisposable() @@ -243,7 +244,7 @@ class OmnipodErosOverviewFragment : DaggerFragment() { rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + rh.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.Omnipod)) else -> "{fa-bluetooth-b} " + rh.gs(resourceId) } - rileyLinkStatusBinding.rileyLinkStatus.setTextColor( rh.gac(context, if (rileyLinkServiceState.isError || rileyLinkError != null) R.attr.warningColor else R.attr.defaultTextColor)) + rileyLinkStatusBinding.rileyLinkStatus.setTextColor(rh.gac(context, if (rileyLinkServiceState.isError || rileyLinkError != null) R.attr.warningColor else R.attr.defaultTextColor)) } private fun updateOmnipodStatus() { @@ -285,12 +286,14 @@ class OmnipodErosOverviewFragment : DaggerFragment() { podInfoBinding.timeOnPod.text = readableZonedTime(podStateManager.time) podInfoBinding.timeOnPod.setTextColor( - rh.gac(context, - if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) { - R.attr.warningColor - } else { - R.attr.defaultTextColor - }) + rh.gac( + context, + if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) { + R.attr.warningColor + } else { + R.attr.defaultTextColor + } + ) ) val expiresAt = podStateManager.expiresAt if (expiresAt == null) { @@ -299,13 +302,15 @@ class OmnipodErosOverviewFragment : DaggerFragment() { } else { podInfoBinding.podExpiryDate.text = readableZonedTime(expiresAt) podInfoBinding.podExpiryDate.setTextColor( - rh.gac(context, - if (DateTime.now().isAfter(expiresAt)) { - R.attr.warningColor - } else { - R.attr.defaultTextColor - } - )) + rh.gac( + context, + if (DateTime.now().isAfter(expiresAt)) { + R.attr.warningColor + } else { + R.attr.defaultTextColor + } + ) + ) } if (podStateManager.isPodFaulted) { @@ -338,12 +343,14 @@ class OmnipodErosOverviewFragment : DaggerFragment() { podInfoBinding.reservoir.text = rh.gs(R.string.omnipod_common_overview_reservoir_value, podStateManager.reservoirLevel) podInfoBinding.reservoir.setTextColor( - rh.gac(context, - if (podStateManager.reservoirLevel < lowReservoirThreshold) { - R.attr.warningColor - } else { - R.attr.defaultTextColor - }) + rh.gac( + context, + if (podStateManager.reservoirLevel < lowReservoirThreshold) { + R.attr.warningColor + } else { + R.attr.defaultTextColor + } + ) ) } @@ -367,12 +374,14 @@ class OmnipodErosOverviewFragment : DaggerFragment() { if (podStateManager.isPodInitialized && podStateManager.lastSuccessfulCommunication != null) { podInfoBinding.lastConnection.text = readableDuration(podStateManager.lastSuccessfulCommunication) val lastConnectionColor = - rh.gac(context, - if (omnipodErosPumpPlugin.isUnreachableAlertTimeoutExceeded(getPumpUnreachableTimeout().millis)) { - R.attr.warningColor - } else { - R.attr.defaultTextColor - }) + rh.gac( + context, + if (omnipodErosPumpPlugin.isUnreachableAlertTimeoutExceeded(getPumpUnreachableTimeout().millis)) { + R.attr.warningColor + } else { + R.attr.defaultTextColor + } + ) podInfoBinding.lastConnection.setTextColor(lastConnectionColor) } else { podInfoBinding.lastConnection.setTextColor(rh.gac(context, R.attr.defaultTextColor)) @@ -420,12 +429,14 @@ class OmnipodErosOverviewFragment : DaggerFragment() { } val podStatusColor = - rh.gac( context, - if (!podStateManager.isPodActivationCompleted || podStateManager.isPodDead || podStateManager.isSuspended || (podStateManager.isPodRunning && !podStateManager.isBasalCertain)) { - R.attr.warningColor - } else { - R.attr.defaultTextColor - }) + rh.gac( + context, + if (!podStateManager.isPodActivationCompleted || podStateManager.isPodDead || podStateManager.isSuspended || (podStateManager.isPodRunning && !podStateManager.isBasalCertain)) { + R.attr.warningColor + } else { + R.attr.defaultTextColor + } + ) podInfoBinding.podStatus.setTextColor(podStatusColor) } @@ -473,9 +484,9 @@ class OmnipodErosOverviewFragment : DaggerFragment() { val textColor: Int text = rh.gs(R.string.omnipod_common_overview_temp_basal_value, amount, dateUtil.timeString(startTime.millis), minutesRunning, duration.standardMinutes) if (podStateManager.isTempBasalCertain) { - textColor = rh.gac(context, R.attr.defaultTextColor) + textColor = rh.gac(context, R.attr.defaultTextColor) } else { - textColor = rh.gac(context, R.attr.warningColor) + textColor = rh.gac(context, R.attr.warningColor) text += " (" + rh.gs(R.string.omnipod_eros_uncertain) + ")" } @@ -581,7 +592,7 @@ class OmnipodErosOverviewFragment : DaggerFragment() { private fun displayErrorDialog(title: String, message: String, withSound: Boolean) { context?.let { - ErrorHelperActivity.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) + activityNames.runAlarm(it, message, title, if (withSound) R.raw.boluserror else 0) } } diff --git a/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt index 1940baeb14..46ce682b2b 100644 --- a/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt +++ b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt @@ -5,16 +5,16 @@ import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil -import info.nightscout.androidaps.plugins.pump.omnipod.eros.history.ErosHistory import info.nightscout.androidaps.plugins.pump.omnipod.eros.manager.AapsOmnipodErosManager -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.TestAapsSchedulers import org.joda.time.DateTimeZone import org.joda.time.tz.UTCProvider @@ -27,7 +27,6 @@ import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.`when` import org.mockito.invocation.InvocationOnMock -import java.util.* class OmnipodErosPumpPluginTest : TestBase() { @@ -35,7 +34,7 @@ class OmnipodErosPumpPluginTest : TestBase() { @Mock lateinit var rh: ResourceHelper @Mock(answer = Answers.RETURNS_DEEP_STUBS) lateinit var activePlugin: ActivePlugin @Mock lateinit var aapsOmnipodErosManager: AapsOmnipodErosManager - @Mock lateinit var erosHistory: ErosHistory + @Mock lateinit var activityNames: ActivityNames @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var rileyLinkUtil: RileyLinkUtil @Mock lateinit var pumpSync: PumpSync @@ -53,9 +52,9 @@ class OmnipodErosPumpPluginTest : TestBase() { // mock all the things val plugin = OmnipodErosPumpPlugin( injector, aapsLogger, TestAapsSchedulers(), rxBusWrapper, null, - rh, activePlugin, null, null, erosHistory, aapsOmnipodErosManager, commandQueue, + rh, activePlugin, null, null, aapsOmnipodErosManager, commandQueue, null, null, null, null, - rileyLinkUtil, null, null, pumpSync + rileyLinkUtil, null, null, pumpSync, activityNames ) val pumpState = PumpSync.PumpState(null, null, null, null, "") `when`(pumpSync.expectedPumpState()).thenReturn(pumpState) diff --git a/ui/src/main/AndroidManifest.xml b/ui/src/main/AndroidManifest.xml index 3e2b647f2e..29f4af7a96 100644 --- a/ui/src/main/AndroidManifest.xml +++ b/ui/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ - + + + + + + \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/activities/BolusProgressHelperActivity.kt b/ui/src/main/java/info/nightscout/ui/activities/BolusProgressHelperActivity.kt similarity index 82% rename from core/src/main/java/info/nightscout/androidaps/activities/BolusProgressHelperActivity.kt rename to ui/src/main/java/info/nightscout/ui/activities/BolusProgressHelperActivity.kt index 9849f642b9..e58ca33420 100644 --- a/core/src/main/java/info/nightscout/androidaps/activities/BolusProgressHelperActivity.kt +++ b/ui/src/main/java/info/nightscout/ui/activities/BolusProgressHelperActivity.kt @@ -1,6 +1,7 @@ -package info.nightscout.androidaps.activities +package info.nightscout.ui.activities import android.os.Bundle +import info.nightscout.androidaps.activities.DialogAppCompatActivity import info.nightscout.androidaps.dialogs.BolusProgressDialog class BolusProgressHelperActivity : DialogAppCompatActivity() { diff --git a/core/src/main/java/info/nightscout/androidaps/activities/ErrorHelperActivity.kt b/ui/src/main/java/info/nightscout/ui/activities/ErrorHelperActivity.kt similarity index 58% rename from core/src/main/java/info/nightscout/androidaps/activities/ErrorHelperActivity.kt rename to ui/src/main/java/info/nightscout/ui/activities/ErrorHelperActivity.kt index b5dec651c9..4acf51ae66 100644 --- a/core/src/main/java/info/nightscout/androidaps/activities/ErrorHelperActivity.kt +++ b/ui/src/main/java/info/nightscout/ui/activities/ErrorHelperActivity.kt @@ -1,13 +1,15 @@ -package info.nightscout.androidaps.activities +package info.nightscout.ui.activities import android.content.Context import android.content.Intent import android.os.Bundle import androidx.annotation.RawRes +import info.nightscout.androidaps.activities.DialogAppCompatActivity import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction import info.nightscout.androidaps.dialogs.ErrorDialog +import info.nightscout.androidaps.services.AlarmSoundService import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -25,28 +27,12 @@ class ErrorHelperActivity : DialogAppCompatActivity() { super.onCreate(savedInstanceState) val errorDialog = ErrorDialog() errorDialog.helperActivity = this - errorDialog.status = intent.getStringExtra(STATUS) ?: "" - errorDialog.sound = intent.getIntExtra(SOUND_ID, R.raw.error) - errorDialog.title = intent.getStringExtra(TITLE)?: "" + errorDialog.status = intent.getStringExtra(AlarmSoundService.STATUS) ?: "" + errorDialog.sound = intent.getIntExtra(AlarmSoundService.SOUND_ID, R.raw.error) + errorDialog.title = intent.getStringExtra(AlarmSoundService.TITLE) ?: "" errorDialog.show(supportFragmentManager, "Error") if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) - disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(intent.getStringExtra(STATUS) ?: "")).subscribe() - } - - companion object { - - const val SOUND_ID = "soundId" - const val STATUS = "status" - const val TITLE = "title" - - fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int = 0) { - val i = Intent(ctx, ErrorHelperActivity::class.java) - i.putExtra(SOUND_ID, soundId) - i.putExtra(STATUS, status) - i.putExtra(TITLE, title) - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ctx.startActivity(i) - } + disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(intent.getStringExtra(AlarmSoundService.STATUS) ?: "")).subscribe() } } diff --git a/core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt b/ui/src/main/java/info/nightscout/ui/activities/TDDStatsActivity.kt similarity index 98% rename from core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt rename to ui/src/main/java/info/nightscout/ui/activities/TDDStatsActivity.kt index b07f66f893..1bc7133edf 100644 --- a/core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt +++ b/ui/src/main/java/info/nightscout/ui/activities/TDDStatsActivity.kt @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.activities +package info.nightscout.ui.activities import android.annotation.SuppressLint -import android.graphics.Color import android.graphics.Rect import android.os.Bundle import android.text.TextUtils @@ -15,8 +14,8 @@ import android.widget.EditText import android.widget.TableLayout import android.widget.TableRow import android.widget.TextView +import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.core.R -import info.nightscout.androidaps.core.databinding.ActivityTddStatsBinding import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.TotalDailyDose import info.nightscout.androidaps.events.EventDanaRSyncStatus @@ -25,7 +24,6 @@ import info.nightscout.androidaps.extensions.total import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.FabricPrivacy @@ -33,11 +31,13 @@ import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.SafeParse import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.ui.databinding.ActivityTddStatsBinding import io.reactivex.rxjava3.disposables.CompositeDisposable import java.text.DateFormat import java.text.DecimalFormat import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale import javax.inject.Inject import kotlin.math.min import kotlin.math.roundToInt @@ -55,7 +55,7 @@ class TDDStatsActivity : NoSplashAppCompatActivity() { private lateinit var binding: ActivityTddStatsBinding private val disposable = CompositeDisposable() - lateinit var tbb: String + private lateinit var tbb: String private var magicNumber = 0.0 private var decimalFormat: DecimalFormat = DecimalFormat("0.000") private var historyList: MutableList = mutableListOf() diff --git a/ui/src/main/java/info/nightscout/ui/di/UiModule.kt b/ui/src/main/java/info/nightscout/ui/di/UiModule.kt index f2c4c70594..2afc10c402 100644 --- a/ui/src/main/java/info/nightscout/ui/di/UiModule.kt +++ b/ui/src/main/java/info/nightscout/ui/di/UiModule.kt @@ -2,6 +2,9 @@ package info.nightscout.ui.di import dagger.Module import dagger.android.ContributesAndroidInjector +import info.nightscout.ui.activities.BolusProgressHelperActivity +import info.nightscout.ui.activities.ErrorHelperActivity +import info.nightscout.ui.activities.TDDStatsActivity import info.nightscout.ui.dialogs.CalibrationDialog import info.nightscout.ui.dialogs.CarbsDialog @@ -11,4 +14,9 @@ abstract class UiModule { @ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog @ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog + + @ContributesAndroidInjector abstract fun contributesTDDStatsActivity(): TDDStatsActivity + @ContributesAndroidInjector abstract fun contributeBolusProgressHelperActivity(): BolusProgressHelperActivity + @ContributesAndroidInjector abstract fun contributeErrorHelperActivity(): ErrorHelperActivity + } \ No newline at end of file diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt index 93dbe027c9..2bae95c60c 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt @@ -8,7 +8,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.TemporaryTarget @@ -18,23 +17,35 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.extensions.formatColor -import info.nightscout.androidaps.interfaces.* -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ActivityNames +import info.nightscout.androidaps.interfaces.BolusTimer +import info.nightscout.androidaps.interfaces.CarbTimer +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.GlucoseUnit +import info.nightscout.androidaps.interfaces.IobCobCalculator +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.queue.Callback -import info.nightscout.androidaps.utils.* +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.DefaultValueHelper +import info.nightscout.androidaps.utils.HtmlHelper +import info.nightscout.androidaps.utils.T +import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.LTag import info.nightscout.ui.R import info.nightscout.ui.databinding.DialogCarbsBinding import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.text.DecimalFormat -import java.util.* +import java.util.LinkedList import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.max @@ -54,6 +65,7 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var repository: AppRepository @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames companion object { @@ -367,7 +379,7 @@ class CarbsDialog : DialogFragmentWithDate() { override fun run() { carbTimer.removeAutomationEventEatReminder() if (!result.success) { - ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else if (sp.getBoolean(R.string.key_usebolusreminder, false) && remindBolus) bolusTimer.scheduleAutomationEventBolusReminder() } diff --git a/core/src/main/res/layout/activity_tdd_stats.xml b/ui/src/main/res/layout/activity_tdd_stats.xml similarity index 99% rename from core/src/main/res/layout/activity_tdd_stats.xml rename to ui/src/main/res/layout/activity_tdd_stats.xml index e73f296e22..21ea646795 100644 --- a/core/src/main/res/layout/activity_tdd_stats.xml +++ b/ui/src/main/res/layout/activity_tdd_stats.xml @@ -6,7 +6,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" - tools:context="info.nightscout.androidaps.activities.TDDStatsActivity"> + tools:context="info.nightscout.ui.activities.TDDStatsActivity"> Date: Wed, 2 Nov 2022 23:45:19 +0100 Subject: [PATCH 76/77] New Crowdin updates (#2156) * New translations strings.xml (Romanian) * New translations exam.xml (Bulgarian) * New translations exam.xml (Norwegian) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Greek) * New translations strings.xml (Hebrew) * New translations strings.xml (Italian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Bulgarian) * New translations objectives.xml (Norwegian) * New translations strings.xml (Norwegian) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Turkish) * New translations strings.xml (French) * New translations strings.xml (Bulgarian) * New translations strings.xml (Czech) * New translations strings.xml (Hebrew) * New translations strings.xml (Italian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Russian) * New translations strings.xml (German) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Danish) * New translations strings.xml (Czech) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Bulgarian) * New translations strings.xml (French) * New translations strings.xml (Bulgarian) * New translations strings.xml (Norwegian) * New translations strings.xml (Spanish) * New translations strings.xml (French) * New translations strings.xml (Romanian) * New translations strings.xml (Russian) * New translations strings.xml (Norwegian) * New translations strings.xml (Turkish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Romanian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Serbian (Latin)) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Catalan) * New translations strings.xml (Dutch) * New translations strings.xml (Lithuanian) * New translations strings.xml (Korean) * New translations strings.xml (Italian) * New translations strings.xml (Hungarian) * New translations strings.xml (Hebrew) * New translations strings.xml (Irish) * New translations strings.xml (Greek) * New translations strings.xml (German) * New translations strings.xml (Danish) * New translations strings.xml (Czech) * New translations strings.xml (Bulgarian) * New translations strings.xml (Afrikaans) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Greek) * New translations strings.xml (Irish) * New translations strings.xml (Hungarian) * New translations strings.xml (Romanian) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Serbian (Latin)) * New translations strings.xml (Afrikaans) * New translations strings.xml (Korean) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Czech) * New translations strings.xml (Danish) * New translations strings.xml (German) * New translations strings.xml (Greek) * New translations strings.xml (Irish) * New translations strings.xml (Hebrew) * New translations strings.xml (Hungarian) * New translations strings.xml (Italian) * New translations strings.xml (Lithuanian) * New translations strings.xml (Croatian) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Slovak) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Turkish) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Turkish) * New translations strings.xml (Croatian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Greek) * New translations strings.xml (Russian) * New translations strings.xml (Irish) * New translations strings.xml (Hungarian) * New translations strings.xml (Norwegian) * New translations strings.xml (Portuguese) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Catalan) * New translations strings.xml (Greek) * New translations strings.xml (Lithuanian) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Romanian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Korean) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Greek) * New translations strings.xml (Irish) * New translations strings.xml (Hungarian) * New translations strings.xml (Hungarian) * New translations strings.xml (Hungarian) * New translations strings.xml (Korean) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Greek) * New translations strings.xml (Korean) * New translations strings.xml (Russian) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Serbian (Latin)) * New translations strings.xml (Afrikaans) * New translations strings.xml (Catalan) * New translations strings.xml (Catalan) * New translations strings.xml (Lithuanian) * New translations strings.xml (Greek) * New translations strings.xml (Hungarian) * New translations strings.xml (Korean) * New translations strings.xml (Bulgarian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Swedish) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Catalan) * New translations strings.xml (Afrikaans) * New translations strings.xml (Greek) * New translations strings.xml (Hungarian) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Romanian) * New translations strings.xml (Greek) * New translations strings.xml (Romanian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Bulgarian) * New translations strings.xml (Catalan) * New translations strings.xml (Danish) * New translations strings.xml (Irish) * New translations strings.xml (Croatian) * New translations strings.xml (Hungarian) * New translations strings.xml (Korean) * New translations strings.xml (Lithuanian) * New translations strings.xml (Dutch) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Serbian (Latin)) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Hungarian) * New translations strings.xml (Afrikaans) * New translations strings.xml (Catalan) * New translations strings.xml (Greek) * New translations strings.xml (Irish) * New translations strings.xml (Norwegian) * New translations strings.xml (Portuguese) * New translations strings.xml (Swedish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Croatian) * New translations strings.xml (Serbian (Latin)) --- app/src/main/res/values-af-rZA/strings.xml | 13 -- app/src/main/res/values-bg-rBG/exam.xml | 2 + app/src/main/res/values-bg-rBG/strings.xml | 54 ++++-- app/src/main/res/values-ca-rES/strings.xml | 7 - app/src/main/res/values-cs-rCZ/strings.xml | 34 ---- app/src/main/res/values-da-rDK/strings.xml | 33 ---- app/src/main/res/values-de-rDE/strings.xml | 33 ---- app/src/main/res/values-el-rGR/strings.xml | 13 -- app/src/main/res/values-es-rES/strings.xml | 34 ---- app/src/main/res/values-fr-rFR/strings.xml | 34 ---- app/src/main/res/values-it-rIT/strings.xml | 34 ---- app/src/main/res/values-iw-rIL/strings.xml | 33 ---- app/src/main/res/values-ko-rKR/strings.xml | 19 -- app/src/main/res/values-lt-rLT/strings.xml | 19 -- app/src/main/res/values-nl-rNL/strings.xml | 33 ---- app/src/main/res/values-no-rNO/exam.xml | 33 ++++ app/src/main/res/values-no-rNO/objectives.xml | 2 + app/src/main/res/values-no-rNO/strings.xml | 48 ++--- app/src/main/res/values-pl-rPL/strings.xml | 19 -- app/src/main/res/values-pt-rBR/strings.xml | 30 --- app/src/main/res/values-pt-rPT/strings.xml | 19 -- app/src/main/res/values-ro-rRO/strings.xml | 19 -- app/src/main/res/values-ru-rRU/strings.xml | 35 +--- app/src/main/res/values-sk-rSK/strings.xml | 34 ---- app/src/main/res/values-sv-rSE/strings.xml | 31 --- app/src/main/res/values-tr-rTR/strings.xml | 34 ---- app/src/main/res/values-zh-rCN/strings.xml | 32 ---- .../src/main/res/values-cs-rCZ/strings.xml | 1 - .../src/main/res/values-da-rDK/strings.xml | 1 - .../src/main/res/values-de-rDE/strings.xml | 1 - .../src/main/res/values-es-rES/strings.xml | 1 - .../src/main/res/values-fr-rFR/strings.xml | 1 - .../src/main/res/values-it-rIT/strings.xml | 1 - .../src/main/res/values-iw-rIL/strings.xml | 1 - .../src/main/res/values-nl-rNL/strings.xml | 1 - .../src/main/res/values-no-rNO/strings.xml | 1 - .../src/main/res/values-ru-rRU/strings.xml | 1 - .../src/main/res/values-sk-rSK/strings.xml | 1 - .../src/main/res/values-sv-rSE/strings.xml | 1 - .../src/main/res/values-tr-rTR/strings.xml | 1 - .../src/main/res/values-zh-rCN/strings.xml | 1 - core/src/main/res/values-bg-rBG/strings.xml | 12 ++ core/src/main/res/values-cs-rCZ/strings.xml | 16 ++ core/src/main/res/values-fr-rFR/strings.xml | 17 ++ core/src/main/res/values-no-rNO/strings.xml | 22 +++ core/src/main/res/values-ru-rRU/strings.xml | 21 +++ core/src/main/res/values-sk-rSK/strings.xml | 16 ++ core/src/main/res/values-tr-rTR/strings.xml | 16 ++ .../src/main/res/values-bg-rBG/strings.xml | 13 ++ .../src/main/res/values-fr-rFR/strings.xml | 6 + .../src/main/res/values-no-rNO/strings.xml | 14 ++ .../src/main/res/values-ru-rRU/strings.xml | 14 ++ .../src/main/res/values-bg-rBG/strings.xml | 8 + .../src/main/res/values-no-rNO/strings.xml | 1 + .../src/main/res/values-af-rZA/strings.xml | 14 ++ .../src/main/res/values-bg-rBG/strings.xml | 30 +++ .../src/main/res/values-ca-rES/strings.xml | 16 ++ .../src/main/res/values-cs-rCZ/strings.xml | 17 ++ .../src/main/res/values-da-rDK/strings.xml | 17 ++ .../src/main/res/values-de-rDE/strings.xml | 17 ++ .../src/main/res/values-el-rGR/strings.xml | 14 ++ .../src/main/res/values-es-rES/strings.xml | 17 ++ .../src/main/res/values-fr-rFR/strings.xml | 30 +++ .../src/main/res/values-ga-rIE/strings.xml | 8 + .../src/main/res/values-hr-rHR/strings.xml | 1 + .../src/main/res/values-hu-rHU/strings.xml | 6 + .../src/main/res/values-it-rIT/strings.xml | 17 ++ .../src/main/res/values-iw-rIL/strings.xml | 17 ++ .../src/main/res/values-ko-rKR/strings.xml | 16 ++ .../src/main/res/values-lt-rLT/strings.xml | 16 ++ .../src/main/res/values-nl-rNL/strings.xml | 17 ++ .../src/main/res/values-no-rNO/strings.xml | 32 ++++ .../src/main/res/values-pl-rPL/strings.xml | 17 ++ .../src/main/res/values-pt-rBR/strings.xml | 17 ++ .../src/main/res/values-pt-rPT/strings.xml | 16 ++ .../src/main/res/values-ro-rRO/strings.xml | 16 ++ .../src/main/res/values-ru-rRU/strings.xml | 30 +++ .../src/main/res/values-sk-rSK/strings.xml | 17 ++ .../src/main/res/values-sr-rCS/strings.xml | 5 + .../src/main/res/values-sv-rSE/strings.xml | 16 ++ .../src/main/res/values-tr-rTR/strings.xml | 30 +++ .../src/main/res/values-zh-rCN/strings.xml | 16 ++ .../src/main/res/values-af-rZA/strings.xml | 2 + .../src/main/res/values-bg-rBG/strings.xml | 6 + .../src/main/res/values-ca-rES/strings.xml | 1 + .../src/main/res/values-cs-rCZ/strings.xml | 2 +- .../src/main/res/values-el-rGR/strings.xml | 1 + .../src/main/res/values-ga-rIE/strings.xml | 30 ++- .../src/main/res/values-hr-rHR/strings.xml | 2 + .../src/main/res/values-hu-rHU/strings.xml | 40 +++- .../src/main/res/values-ko-rKR/strings.xml | 2 + .../src/main/res/values-lt-rLT/strings.xml | 6 + .../src/main/res/values-no-rNO/strings.xml | 12 +- .../src/main/res/values-pl-rPL/strings.xml | 1 + .../src/main/res/values-pt-rPT/strings.xml | 1 + .../src/main/res/values-ro-rRO/strings.xml | 1 + .../src/main/res/values-ru-rRU/strings.xml | 8 +- .../src/main/res/values-tr-rTR/strings.xml | 22 +-- .../src/main/res/values-af-rZA/strings.xml | 96 +++++++++- .../src/main/res/values-bg-rBG/strings.xml | 1 + .../src/main/res/values-ca-rES/strings.xml | 116 +++++++++++- .../src/main/res/values-el-rGR/strings.xml | 92 ++++++++- .../src/main/res/values-ga-rIE/strings.xml | 26 ++- .../src/main/res/values-hr-rHR/strings.xml | 10 +- .../src/main/res/values-hu-rHU/strings.xml | 9 +- .../src/main/res/values-no-rNO/strings.xml | 10 +- .../src/main/res/values-pt-rBR/strings.xml | 24 +++ .../src/main/res/values-pt-rPT/strings.xml | 2 + .../src/main/res/values-ru-rRU/strings.xml | 22 +-- .../src/main/res/values-tr-rTR/strings.xml | 20 +- .../src/main/res/values-no-rNO/strings.xml | 2 +- .../src/main/res/values-pl-rPL/strings.xml | 4 +- .../src/main/res/values-pt-rBR/strings.xml | 4 +- .../src/main/res/values-af-rZA/strings.xml | 24 +++ .../src/main/res/values-ca-rES/strings.xml | 28 +++ .../src/main/res/values-el-rGR/strings.xml | 26 +++ .../src/main/res/values-ga-rIE/strings.xml | 5 +- .../src/main/res/values-hr-rHR/strings.xml | 10 +- .../src/main/res/values-hu-rHU/strings.xml | 10 +- .../src/main/res/values-no-rNO/strings.xml | 2 +- .../src/main/res/values-pt-rBR/strings.xml | 126 +++++++++++++ .../src/main/res/values-pt-rPT/strings.xml | 28 +++ .../src/main/res/values-sr-rCS/strings.xml | 4 +- .../src/main/res/values-af-rZA/strings.xml | 8 + .../src/main/res/values-bg-rBG/strings.xml | 2 + .../src/main/res/values-ca-rES/strings.xml | 76 ++++++++ .../src/main/res/values-el-rGR/strings.xml | 9 + .../src/main/res/values-ga-rIE/strings.xml | 5 + .../src/main/res/values-hr-rHR/strings.xml | 53 ++++++ .../src/main/res/values-hu-rHU/strings.xml | 75 ++++++++ .../src/main/res/values-ko-rKR/strings.xml | 1 + .../src/main/res/values-lt-rLT/strings.xml | 2 + .../src/main/res/values-pl-rPL/strings.xml | 2 + .../src/main/res/values-pt-rBR/strings.xml | 19 ++ .../src/main/res/values-pt-rPT/strings.xml | 2 + .../src/main/res/values-ro-rRO/strings.xml | 2 + .../src/main/res/values-ru-rRU/strings.xml | 4 +- .../src/main/res/values-sv-rSE/strings.xml | 2 + .../src/main/res/values-tr-rTR/strings.xml | 2 +- .../src/main/res/values-af-rZA/strings.xml | 31 +++ .../src/main/res/values-ca-rES/strings.xml | 176 +++++++++++++++++ .../src/main/res/values-el-rGR/strings.xml | 32 ++++ .../src/main/res/values-hr-rHR/strings.xml | 7 + .../src/main/res/values-hu-rHU/strings.xml | 25 +++ .../src/main/res/values-ko-rKR/strings.xml | 3 + .../src/main/res/values-pt-rBR/strings.xml | 177 ++++++++++++++++++ .../src/main/res/values-ru-rRU/strings.xml | 4 +- .../src/main/res/values-sr-rCS/strings.xml | 2 + .../src/main/res/values-af-rZA/strings.xml | 3 + .../src/main/res/values-ca-rES/strings.xml | 13 ++ .../src/main/res/values-el-rGR/strings.xml | 4 + .../src/main/res/values-hr-rHR/strings.xml | 1 + .../src/main/res/values-hu-rHU/strings.xml | 2 + .../src/main/res/values-ko-rKR/strings.xml | 12 ++ .../src/main/res/values-pt-rBR/strings.xml | 32 ++++ .../src/main/res/values-af-rZA/strings.xml | 5 + .../src/main/res/values-ca-rES/strings.xml | 59 ++++++ .../src/main/res/values-el-rGR/strings.xml | 6 + .../src/main/res/values-hr-rHR/strings.xml | 2 + .../src/main/res/values-hu-rHU/strings.xml | 3 + .../src/main/res/values-pt-rBR/strings.xml | 55 ++++++ .../src/main/res/values-af-rZA/strings.xml | 43 +++++ .../src/main/res/values-bg-rBG/strings.xml | 21 +++ .../src/main/res/values-ca-rES/strings.xml | 22 +++ .../src/main/res/values-da-rDK/strings.xml | 1 + .../src/main/res/values-el-rGR/strings.xml | 43 +++++ .../src/main/res/values-ga-rIE/strings.xml | 7 + .../src/main/res/values-hr-rHR/strings.xml | 45 +++++ .../src/main/res/values-hu-rHU/strings.xml | 21 +++ .../src/main/res/values-ko-rKR/strings.xml | 39 ++++ .../src/main/res/values-lt-rLT/strings.xml | 21 +++ .../src/main/res/values-nl-rNL/strings.xml | 59 ++++++ .../src/main/res/values-pl-rPL/strings.xml | 41 ++++ .../src/main/res/values-pt-rBR/strings.xml | 79 ++++++++ .../src/main/res/values-pt-rPT/strings.xml | 21 +++ .../src/main/res/values-ro-rRO/strings.xml | 21 +++ .../src/main/res/values-sr-rCS/strings.xml | 1 + .../src/main/res/values-sv-rSE/strings.xml | 21 +++ .../src/main/res/values-zh-rCN/strings.xml | 76 ++++++++ .../src/main/res/values-af-rZA/strings.xml | 28 +++ .../src/main/res/values-bg-rBG/strings.xml | 1 + .../src/main/res/values-ca-rES/strings.xml | 68 +++++++ .../src/main/res/values-el-rGR/strings.xml | 28 +++ .../src/main/res/values-hr-rHR/strings.xml | 14 ++ .../src/main/res/values-hu-rHU/strings.xml | 70 +++++++ .../src/main/res/values-ko-rKR/strings.xml | 1 + .../src/main/res/values-lt-rLT/strings.xml | 1 + .../src/main/res/values-pl-rPL/strings.xml | 1 + .../src/main/res/values-pt-rBR/strings.xml | 46 +++++ .../src/main/res/values-pt-rPT/strings.xml | 1 + .../src/main/res/values-ro-rRO/strings.xml | 1 + .../src/main/res/values-sv-rSE/strings.xml | 1 + ui/src/main/res/values-af-rZA/strings.xml | 1 + ui/src/main/res/values-bg-rBG/strings.xml | 5 + ui/src/main/res/values-ca-rES/strings.xml | 1 + ui/src/main/res/values-cs-rCZ/strings.xml | 3 + ui/src/main/res/values-da-rDK/strings.xml | 2 + ui/src/main/res/values-de-rDE/strings.xml | 1 + ui/src/main/res/values-el-rGR/strings.xml | 1 + ui/src/main/res/values-es-rES/strings.xml | 2 + ui/src/main/res/values-fr-rFR/strings.xml | 3 + ui/src/main/res/values-ga-rIE/strings.xml | 1 + ui/src/main/res/values-hr-rHR/strings.xml | 4 +- ui/src/main/res/values-hu-rHU/strings.xml | 4 +- ui/src/main/res/values-it-rIT/strings.xml | 2 + ui/src/main/res/values-iw-rIL/strings.xml | 1 + ui/src/main/res/values-ko-rKR/strings.xml | 1 + ui/src/main/res/values-lt-rLT/strings.xml | 1 + ui/src/main/res/values-nl-rNL/strings.xml | 1 + ui/src/main/res/values-no-rNO/strings.xml | 7 + ui/src/main/res/values-pl-rPL/strings.xml | 1 + ui/src/main/res/values-pt-rBR/strings.xml | 2 + ui/src/main/res/values-pt-rPT/strings.xml | 1 + ui/src/main/res/values-ro-rRO/strings.xml | 1 + ui/src/main/res/values-ru-rRU/strings.xml | 7 + ui/src/main/res/values-sk-rSK/strings.xml | 3 + ui/src/main/res/values-sr-rCS/strings.xml | 4 +- ui/src/main/res/values-sv-rSE/strings.xml | 1 + ui/src/main/res/values-tr-rTR/strings.xml | 2 + ui/src/main/res/values-zh-rCN/strings.xml | 1 + wear/src/main/res/values-bg-rBG/strings.xml | 31 +++ 221 files changed, 3368 insertions(+), 729 deletions(-) diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index d3371fa980..cff20bb7ab 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -15,9 +15,6 @@ Gebruik vir die aktiewe plugins te konfigureer Onderrig program Vertoon kos-voorafinstellings soos omskryf in Nightscout - Insulien voorkeure vir Humalog en NovoRapid / NovoLog - Insulien voorkeure vir Fiasp - Laat jou toe om die piek van die insulien aktiwiteit definieer en behoort slegs gebruik te word deur gevorderde gebruikers Aktiveer of deaktiveer die implementering die lus wakker maak. Sinkroniseer jou data met Nightscout Status van die algoritme in 2017 @@ -212,9 +209,6 @@ Log app begin na NS Begin toepassing weer om instellings toe te pas. Watter tipe insulien gebruik jy? - Novorapid, Novolog, Humalog - Fiasp - INS Ontsper superbolus in Ghoeroe Ontsper superbolus funksionaliteit in Ghoeroe. Moenie aktiveer totdat jy leer wat dit werklik doen. DIT KAN \'n INSULIEN OORDOSIS VEROORSAAK AS BLINDELINGS GEBRUIK WORD! Wys status vlae op tuisskerm @@ -256,12 +250,6 @@ Aktiveer SMB Gebruik Super Mikro Boluses in plaas van of tydelike basale vir vinniger resultate Opsporing van Onaangekondigde etes - IAB kurwe piek tyd - Piek tyd [min] - Vry-piek Oref - Snelaksie Oref - Ultra-Snel Oref - DIA van %1$f is te kort - %2$f in stede gebruik! Aktiveer profiel ONGELDIG Persentasie @@ -399,7 +387,6 @@ Bolus sluimer dia divisor Maks daaglikse veiligheids vermenigvuldiger Huidige basale veiligheids vermenigvuldiger - nvt Virtuele Pomp Pomp definisie Bolus: Stap =%1$s\nVerlengde Bolus: [stap%2$s, duur = =%3$smin -%4$sh]\nBasal: stap =%5$s\nTBR: %6$s (deur %7$s), duur =%8$smin -%9$sh\n%10$s diff --git a/app/src/main/res/values-bg-rBG/exam.xml b/app/src/main/res/values-bg-rBG/exam.xml index e9ba5b5d94..357f888dc1 100644 --- a/app/src/main/res/values-bg-rBG/exam.xml +++ b/app/src/main/res/values-bg-rBG/exam.xml @@ -32,10 +32,12 @@ https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting https://www.facebook.com/groups/AndroidAPSUsers/ + https://discord.gg/4fQUWHZ4Mw Fiasp® https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#insulin Отбележете всички правилни отговори. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html + https://androidaps.readthedocs.io/en/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-to-carb-ratio-ic-g-u https://androidaps.readthedocs.io/en/latest/EN/Usage/Extended-Carbs.html https://androidaps.readthedocs.io/en/latest/EN/Children/Children.html diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index f8b1d3d8f1..a92d681ef1 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -16,14 +16,11 @@ За конфигурация на активните плъгини Разучаване на програмата Показва въведените в Nightscout храни - Действие на инсулините Humalog и NovoRapid / NovoLog - Действие на инсулин Fiasp - Действие на инсулин Lyumjev - Позволява да зададете сами пика на инсулиновата активност (не използвайте, ако сте нови потребители) Включва или изключва затворения кръг (loop). Синхронизира локалните данни с Nightscout Алгоритъма, какъвто е бил през 2017 Най-новият алгоритъм (само за напреднали потребители) + Най-новия алгоритм за напреднали потребители с динамичен/автоматичен ISF Показва текущото състояние на вашия APS и бутони за най-често използваните действия Показва известие с резюме на това, което прави вашия APS Този тип профил е достъпен в офлайн режим. @@ -141,6 +138,7 @@ Лицензионно споразумение с краен потребител НЕ ТРЯБВА ДА СЕ ИЗПОЛЗВА ЗА ВЗЕМАНЕ НА МЕДИЦИНСКИ РЕШЕНИЯ. НЯМА ГАРАНЦИЯ ЗА ПРОГРАМАТА, ДО СТЕПЕНТА, ПОЗВОЛЕНА ОТ ПРИЛОЖИМОТО ПРАВО. ОСВЕН КОГАТО Е ПОСОЧЕНО ДРУГО В ПИСМЕН ВИД, ПРИТЕЖАТЕЛИТЕ НА АВТОРСКОТО ПРАВО И/ИЛИ ДРУГИ СТРАНИ ПРЕДОСТАВЯТ ПРОГРАМАТА \"КАКТО Е\", БЕЗ ГАРАНЦИИ ОТ ВСЯКАКЪВ ВИД, ИЗРАЗЕНИ ИЛИ ПОДРАЗБИРАЩИ СЕ, ВКЛЮЧИТЕЛНО, НО НЕ САМО, ПОДРАЗБИРАЩИ СЕ ГАРАНЦИИ ЗА ПРОДАВАЕМОСТ И ПРИГОДНОСТ ЗА КОНКРЕТНА ЦЕЛ. ЦЕЛИЯ РИСК ПО ОТНОШЕНИЕ НА КАЧЕСТВОТО И ЕФЕКТИВНОСТТА НА ПРОГРАМАТА Е САМО ВАШ. АКО ПРОГРАМАТА НЕ СРАБОТИ, ВИЕ ПОЕМАТЕ ВСИЧКИ НЕОБХОДИМИ РАЗХОДИ ЗА ОБСЛУЖВАНЕ, РЕМОНТ ИЛИ КОРЕКЦИЯ. Разбирам и приемам + Съхрани Презареди профил Бърз болус Настройки за бърз болус @@ -163,7 +161,6 @@ Бутон 3 Единици: Единици - DIA Диапазон за визуализация Стойност на линиите за ниска и висока КЗ (mmol/l) за телефона и часовника Ниска КЗ под @@ -171,6 +168,7 @@ Часовник Изпрати отново всички дани Отвори настройките на часовника + Базал MM640g Текущи известия СТАРИ ДАННИ @@ -186,6 +184,7 @@ КОНФ ЦИК APS + Динамичен ISF ЛПр ОСН ВП @@ -230,7 +229,6 @@ Покажи подробен IOB Раздели IOB от болус и от базал на часовника неуспешно - моля проверете телефона - --- Тип пациент Дете Тийнейджър @@ -265,9 +263,6 @@ Записвай всяко стартиране на AndroidAPS в NS Рестартиране за да се приложат новите настройки. Кой тип на инсулин използвате? - Novorapid Novolog, Humalog - Fiasp - ИНС Разреши използването на Суперболус Разреши функцията суперболус в съветника. Не я разрешавайте докато не научите какво наистина прави. ТОВА МОЖЕ ДА СЪЗДАДЕ ОПАСНОСТ ОТ ПРЕДОЗИРАНЕ С ИНСУЛИН. Покажи статус светлини на началния екран @@ -289,6 +284,7 @@ БАЗА Откл АКТ + -BGI АБС ОТК.НАКЛ За приложението @@ -333,17 +329,11 @@ Стойностите не са запазени! Разреши локално предаване на данни OpenAPS SMB + Динамично ISF Разреши UAM Разреши SMB Използвай супер микро болуси вместо временен базал за по бързо действие Детекция на необявено хранене (UAM) - Пик на кривата на IOB - Време на пик [мин.] - Със свободен пик по Oref - Бързодействащ по Oref - Ултра бързодействащ по Oref - Lyumjev - DIA от %1$f е твърде кратка - използвай %2$f вместо това! Активирай профила НЕВАЛИДНО % от профила @@ -397,6 +387,7 @@ Само отрицателни Калкулиране на COB Калкулиране на временни цели + Процентно изчисление APS разрешен Избран APS NSClient има права за запис @@ -416,6 +407,8 @@ Активирайте SMB, когато има висока временна цел (опитайте с над 100 мг/дл или 5,5 ммол/л) Инсулин Бутони + Изпрати калибрация до xDrip+ или отвори BYODA калибрационнен диалог + Отваря xDrip+ или BYODA, бутон назад те връща в AAPS Количество въглехидрати за добавяне при натискане на бутона Количество инсулин за добавяне при натискане на бутона Не може да се стартира CGM приложението. Уверете се, че е инсталирано. @@ -423,7 +416,6 @@ Игнориране за 5 мин Игнориране за 15 мин Игнориране за 30 мин - нужн История Уведомяване при SMB Покажи SMB на часовника като стандартен болус. @@ -499,7 +491,6 @@ Каква част от DIA след болус да изчаква AAPS преди да направи нещо Макс. множител за най-големия базал за денонощието Макс. множител за настоящ базал - --- Виртуална помпа тип Описание на помпата Болус: Стъпка =%1$s\Удължен болус: [стъпка =%2$s, продължителност =%3$smin -%4$sh] \nБазал: стъпка =%5$s\ nTBR: %6$s (от %7$s), продължителност =%8$sмин -%9$sh\n%10$s @@ -528,6 +519,8 @@ Изминало време Poctech Получавай данни за КЗ от Poctech апликацията. + Глуново + Получавай данните от Glunowo апликацията Получавай КЗ от Tomato апликация (устройство МяоМяо) Високите временни цели да вдигат ли чувствителността? @@ -537,6 +530,10 @@ Когато се установи резистентност, намалява целевата глюкоза. Чувствителността увеличава целта Когато се установи чувствителност, повишаване на целевата глюкоза + Покажи невалидните + Скрий невалидните + Премахни артикули + Подреди артикули Открити са предишни настройки Данните за лечението не са пълни Настройки за поддръжка @@ -588,6 +585,8 @@ Прилагането изтече Има нова версия от най-малко %1$d дни! Ще спре подаването на инсулин след %2$d дни, цикълът ще бъде изключен след %3$d дни + BYODA + BYODA COB срещу IOB Ограничение на болус: от %1$.2f Е на %2$.2f Е !!!!! Бавна абсорбция на въглехидрати: %2$d%% от времето. Проверете въведените данни. Може да има голяма грешка !!!!!]]> @@ -618,6 +617,8 @@ Името на профила съдържа точка.\nТова не се поддържа от НС.\nПрофилът не е качен в НС. Ниската граница на диапазона (графика) Високата граница на диапазона (графика) + Възраст + Тегло Номер: Изпрати Най-често използван профил: @@ -626,6 +627,11 @@ Невалидна стойност в % Средно Време в границите + Дневен TIR + Нощен TIR + Детайлни 14 дена + SD: %1$s + HbA1c: Мониторинг на активност Искате да нулирате статистиката? Статистика @@ -645,6 +651,7 @@ Диапазон между временни базали Продължителност на временни базали Прогнозни КЗ + Лечения Наклон на отклонението Удостоверяването неуспешно Абсолютен инсулин @@ -676,11 +683,11 @@ Алармата, когато е време за хранене. Време за ядене!\nИзпълнете болус съветника и направете изчисления отново. Включи подсещането за болус + Използвай подсещане за болус по-късно със съветник (\"след-болус\") Качването на данни за проблеми е забранено!(Fabric) Графика Меню на графиката Премахни филтъра - Стрелка тенденция Канюла Потербителска настройка Използвай стойностите от вашето най-голямо хранен, с което обикновено се храните @@ -723,8 +730,17 @@ Рекалкулирани използвани данни КЗ близо до:\n%1$s\n%2$s Недостъпно + графика + инсулин + изтриване на текущия профил + % от профила + Много ниска + Ниска + Висока + Много висока Вход + Всички diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index a78386e5e9..dd7648510d 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -16,10 +16,6 @@ Utilitzat per configurar plugins actius Programa d\'aprenentatge Mostra els valors preestablerts per alimentació definits a Nightscout - Configuració preestablerta per insulina Humalog i NovoRapid/NovoLog - Configuració preestablerta per insulina Fiasp - Configuració preestablerta per insulina Lyumjev - Permet definir el pic d\'activitat de la insulina. A utilitzar només per usuaris avançats Activar o desactivar la implementació que activa el llaç. Sincronitza les vostres dades amb Nightscout Estat de l\'algoritme el 2017 @@ -197,9 +193,6 @@ Enregistrar l\'inici de l\'app a NS Sortint de l\'app per aplicar configuració. Quin tipus d\'insulina feu servir? - Novorapid, Novolog, Humalog - Fiasp - INS Activar superbolus a l\'assistent Activar funcionalitat superbolus a l\'assistent. No ho activeu fins que no hagueu après què fa realment. POT CAUSAR SOBREDOSI D\'INSULINA SI NO VIGILEU! Mostrar indicadors d\'estat a la pantalla d\'inici diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index cb38b7c04a..6aac270b37 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -17,10 +17,6 @@ Nastavení konfigurace (povolování součástí systému) Výukový program Zobrazení jídel definovaných v NS - Předvolba pro Novorapid - Předvolba pro Fiasp - Předvolba pro Lyumjev - Možnost definice vrcholu účinnosti inzulínu pro pokročilé uživatele Povolení nebo zakázání smyčky. Synchronizace dat s NS Stav algoritmu v roce 2017 @@ -171,7 +167,6 @@ Tlačítko 3 Jednotky: Jednotky - DIA Rozsah pro zobrazení Značka vysoké a nízké hodnoty v přehledu a na hodinkách Wear Dolní značka @@ -240,7 +235,6 @@ Zobrazit detailní IOB Rozepsat IOB do bolusového a bazálního na hodinkách neúspěšně - zkontrolujte mobil - n/a Typ pacienta Dítě Dospívající @@ -275,9 +269,6 @@ Zaznamenávat spuštění aplikace do NS Ukončuji aplikaci, aby se nastavení projevilo. Jaký druh inzulínu používáte? - Novorapid - Fiasp - INZ Povolit superbolus Povolení superbolusu v kalkulátoru. Nepovolujte, dokud se nenaučíte, co to opravdu dělá. MŮŽE ZPŮSOBIT PŘEDÁVKOVÁNÍ INZULÍNEM PŘI NESPRÁVNÉM POUŽITÍ! Zobrazit stavové indikátory na domovské obrazovce @@ -352,14 +343,6 @@ Povolit SMB Použít super mikro bolusy místo dočasných bazálů pro zrychlení účinku Detekce neoznámených jídel - Čas vrcholu IOB křivky - Vrchol křivky [min] - Vrchol - Volitelný vrchol - Oref - Rychle působící - Oref - Ultra rychlý - Oref - Lyumjev - DIA %1$f je příliš krátké - použito %2$f ! Aktivovat profil NEPLATNÝ % změna @@ -442,7 +425,6 @@ Ignorovat 5 m Ignorovat 15 m Ignorovat 30 m - pož. Prohlížeč historie Oznámení při SMB Ukazovat SMB na hodinkách jako normální bolus. @@ -523,7 +505,6 @@ Dělitel \"bolus snooze\" Max násobitel denního nejvyššího bazálu Max násobitel současného bazálu - --- Typ virtuální pumpy Definice pumpy Bolus: Krok =%1$s\nProdl. bolus: [Krok=%2$s, Délka=%3$smin-%4$sh]\nBazál: Krok=%5$s\nDoč. bazál: %6$s (%7$s), Délka=%8$smin-%9$sh\n%10$s @@ -731,7 +712,6 @@ Graf Možnosti grafu Vymazat filtr - Šipka trendu Kanyla Vstup uživatele Použijte hodnoty pro největší jídlo, jaké obvykle jíte\n @@ -788,18 +768,6 @@ správný výsledek v % správný výsledek s jednotkami Nedostupný - vysoká - v rozsahu - nízká - rychle klesající - klesající - pomalu klesající - stabilní - pomalu stoupající - stoupající - rychle stoupající - žádný - neznámý graf kvalita glykémií přepočítáno @@ -874,8 +842,6 @@ Nad Zobrazit záznamy smyčky Skrýt záznamy smyčky - Widget AAPS - Konfigurovat průhlednost Stav smyčky Měřítko grafu Profil 1 diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index 686ea11617..a67255da27 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -17,10 +17,6 @@ Bruges til at konfigurere de aktive plugins Oplæringsprogram Viser forudindstillede madvarer defineret i Nightscout - Insulin forudindstillet til Humalog og NovoRapid / NovoLog - Insulinforudindstilling til Fiasp - Insulin forudindstillet til Lyumjev - Giver dig mulighed for at definere spidsbelastningen af insulin-aktiviteten og bør kun bruges af avancerede brugere Aktiver eller deaktiver implementeringen som aktiverer Loop. Synkroniserer dine data med NightScout Status for algoritmen i 2017 @@ -166,7 +162,6 @@ Knap 3 Enheder: Enheder - DIA Område for Visualisering Højeste og laveste værdi for diagrammerne i Oversigt og Smartwatch LAV værdi @@ -235,7 +230,6 @@ Vis detaljeret IOB Bryd IOB ned i bolus og basal IOB på urskiven mislykkedes - tjek venligst telefonen - n/a Patienttype Barn Teeanger @@ -270,9 +264,6 @@ Log app-start til NS Afslutter applikationen for at anvende indstillinger. Hvilken type insulin bruger du? - Novorapid, Novolog, Humalog - Fiasp - INS Aktiver superbolus i guiden Aktiver superbolus funktionalitet i guiden. Aktiver ikke før du har lært, hvad det virkelig gør. DET KAN FORÅRSAGE INSULIN OVERDOSERING HVIS BRUGT I BLINDE! Vis statuslys på startskærm @@ -346,14 +337,6 @@ Aktiver SMB Brug Super Mikro Boluser i stedet for midlertidig basal for hurtigere handling Detektering af uanmeldte måltider - IOB Kurve Peak-Tid - Spidstidspunkt [min] - Top - Free-Peak Oref - Rapid-Acting Oref - Ultra-Rapid Oref - Lyumjev - DIA af %1$f for kort - bruger %2$f i stedet! Aktivér profil UGYLDIG Procent @@ -436,7 +419,6 @@ Ignorér 5m Ignorér 15m Ignorér 30m - krævet Historik browser Giv besked ved SMB Vis SMB på uret som en standard bolus. @@ -517,7 +499,6 @@ Bolus snooze DIA divisor Maks daglig basal multiplikator Nuværende basal sikkerheds multiplikator - ikke tilgængelig Virtuel pumpe type Pumpe Definition Bolus: Trin=%1$s\nForlænget Bolus: [Trin=%2$s, Varighed=%3$smin-%4$sh]\nBasal: Trin=%5$s\nTBR: %6$s (by %7$s), Varighed=%8$smin-%9$sh\n%10$s @@ -717,7 +698,6 @@ Graf Diagrammenu Nulstil filter - Trend pil Kanyle Bruger indtastning Brug værdien af den største mængde mad du plejer at indtage\n @@ -774,18 +754,6 @@ korrekt resultat med % korrekt resultat med enheder Ikke tilgængelig - høj - inden for området - lav - falder hurtigt - falder - falder langsomt - stabil - stiger langsomt - stiger - stiger hurtigt - ingen - ukendt graf blodglukose kvalitet genberegnet @@ -860,7 +828,6 @@ Over Vis loop poster Skjul loop poster - Indstil gennemsigtighed Loop status Graf skala Profil 1 diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 17ab38bf87..7a50160091 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -17,10 +17,6 @@ Dient zum Konfigurieren der aktiven Plugins Das Programm kennenlernen Zeigt die Essensvorlagen aus Nightscout an - Insulinprofil für Humalog und NovoRapid / NovoLog - Insulinprofil für Fiasp - Insulin-Voreinstellung für Lyumjev - Erlaubt dir, das Wirkmaximum der Insulinaktivität zu definieren, und sollte nur von erfahrenen Anwendern genutzt werden Aktiviere oder deaktiviere die Anwendung, die den Loop ausführt. Synchronisiert deine Daten mit Nightscout Stand des Algorithmus in 2017 @@ -166,7 +162,6 @@ Schaltfläche 3 Einheiten: Einheiten - DIA Zielbereich für die Grafikanzeige Hoch- und Niedrig-Werte für die Übersicht- und die Smartwatch-Anzeige Niedrig-Markierung @@ -235,7 +230,6 @@ Zeige detailliertes IOB Differenziere IOB in Bolus- und Basal-IOB auf dem Watchface Nicht erfolgreich - bitte Telefon prüfen - n/a Patiententyp Kind Teenager @@ -270,9 +264,6 @@ Logge App-Start in Nightscout App wird beendet, um neue Einstellungen zu laden. Welchen Insulin-Typ verwendest Du? - NovoRapid, NovoLog, Humalog - Fiasp - INS Aktiviere Superbolus im Bolus-Rechner Aktiviere die SuperBolus-Funktion im Bolus-Rechner. Nicht aktivieren, wenn Du nicht weißt, welche Auswirkungen dieser Bolus hat! ES KANN ZU EINER ÜBERDOSIERUNG AN INSULIN KOMMEN! Statusanzeige auf Homescreen @@ -346,14 +337,6 @@ Aktiviere SMB Benutze Super-Mikro-Boli anstelle von temporären Basalraten, um eine schnellere Wirkung zu erreichen. Erkennung von unangekündigten Mahlzeiten - Wirkungshoch der IOB-Kurve - Wirkungshoch [min] - Gipfel - Free-Peak Oref - Rapid-Acting Oref - Ultra-Rapid Oref - Lyumjev - DIA von %1$f ist zu kurz - AAPS nutzt stattdessen %2$f! Aktiviere Profil Ungültig Prozentsatz @@ -436,7 +419,6 @@ 5 Min. ignorieren 15 Min. ignorieren 30 Min. ignorieren - angef. Historie Bei SMB benachrichtigen Zeige SMB auf der Uhr wie einen normalen Bolus an. @@ -517,7 +499,6 @@ Bolus-Snooze-DIA-Divisor Sicherheitsmultiplikator des Basalhöchstwertes Sicherheitsmultiplikator der aktuellen Basalrate - N/A Typ der virtuellen Pumpe Pumpen-Definition Bolus: Schritt=%1$s\nVerzögerter Bolus: [Schritt=%2$s, Dauer=%3$smin-%4$sh]\nBasal: Schritt=%5$s\nTBR: %6$s (bei %7$s), Dauer=%8$smin-%9$sh\n%10$s @@ -718,7 +699,6 @@ Unerwartetes Verhalten. Diagramm Diagrammmenü Filter löschen - Trendpfeil Kanüle Benutzereingabe Verwende die Werte der größten Mahlzeit, die Du normalerweise zu Dir nimmst\n @@ -775,18 +755,6 @@ Unerwartetes Verhalten. korrektes Ergebnis mit % korrektes Ergebnis mit Einheiten Nicht verfügbar - hoch - im Zielbereich - niedrig - schnell fallend - fallend - langsam fallend - stabil - Langsamer Anstieg - steigend - schnell steigend - kein(e) - unbekannt Diagramm BZ-Qualität neu berechnet @@ -861,7 +829,6 @@ Unerwartetes Verhalten. Über Zeige Loop Datensätze Verberge Loop Datensätze - Deckkraft konfigurieren Loop Status Diagrammskala Profil 1 diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index 8215365801..eb819b0798 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -15,9 +15,6 @@ Χρησιμοποιείται για ρύθμιση ενεργών συνδέσεων Πρόγραμμα εκμάθησης Εμφανίζει τις επιλογές τροφίμων που ορίζεται στο Nightscout - Η ινσουλίνη που ορίζεται Humalog και NovoRapid / NovoLog - Η ινσουλίνη που ορίζεται για Fiasp - Σας επιτρέπει να ορίσετε το μέγιστο της δράσης της ινσουλίνης και πρέπει να χρησιμοποιείται μόνο από προχωρημένους χρήστες Ενεργοποιήστε ή απενεργοποιήστε την εφαρμογή που ενεργοποιεί το κύκλωμα. Συγχρονίζει τα δεδομένα σας με το Nightscout Κατάσταση του αλγόριθμου για το 2017 @@ -212,9 +209,6 @@ Η εφαρμογή καταγραφής ξεκινά από το NS Έξοδος από το application για την εφαρμογή των ρυθμίσεων Ποιο τύπο ινσουλίνης χρησιμοποιείτε; - Novorapid, Novolog, Humalog - Fiasp - INS Ενεργοποίηση superbolus στον σύντομο οδηγό Ενεργοποιήστε την λειτουργία superbolus στον σύντομο οδηγό. Μην το κάνετε μέχρι να μάθετε τι ακριβώς κάνει. ΜΠΟΡΕΙ ΝΑ ΕΓΧΥΣΕΙ ΠΑΡΑΠΑΝΩ ΔΟΣΕΙΣ ΙΝΣΟΥΛΙΝΗΣ ΑΝ ΧΡΗΣΙΜΟΠΟΙΗΘΕΙ ΛΑΝΘΑΣΜΕΝΑ! Εμφάνιση του φωτισμού κατάστασης στην αρχική οθόνη @@ -256,12 +250,6 @@ Ενεργοποίηση SMB Χρησιμοποιήστε Super Micro Boluses αντί προσωρινού ρυθμού για ταχύτερα αποτελέσματα Ανίχνευση απαρατήρητων γευμάτων - Μέγιστη τιμή καμπύλης IOB - Μέγιστο καμπύλης [λεπτά] - Προαιρετικά-αιχμή Oref - Γρήγορη δράση - Oref - Έξτρα Γρήγορη δράση - Oref - DIA για %1$f πολύ μικρή - χρησιμοποιήστε %2$f! Ενεργοποίηση προφίλ ΜΗ ΕΓΚΥΡΟ Ποσοστό @@ -399,7 +387,6 @@ Διαιρέτης Αναβολής bolus Μέγιστος ημερήσιος πολλαπλασιαστής ασφαλείας Τρέχων πολλαπλασιαστής ασφαλείας βασικού ρυθμού - n/a Τύπος εικονικής αντλίας Ορισμός Αντλίας Bolus: Άμεσο=%1$s\nΕκτεταμένο Bolus: [Άμεσο=%2$s, Διάρκεια=%3$smin-%4$sh]\nΒασικός: Άμεσο=%5$s\nTBR: %6$s (με %7$s), Διάρκεια=%8$smin-%9$sh\n%10$s diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 868dc35105..8455d268e3 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -17,10 +17,6 @@ Utilizado para configurar complementos activos Programa de aprendizaje Muestra los ajustes preestablecidos de alimentos definidos en Nightscout - Ajustes de insulina preestablecidos para Humalog y NovoRapid/NovoLog - Ajuste de insulina preestablecido para Fiasp - Ajuste de insulina preestablecido para Lyumjev - Permite personalizar el pico de acción máxima de la insulina. Debe ser utilizado únicamente por usuarios avanzados Activar o desactivar la posibilidad para activar el lazo. Sincroniza tus datos con Nightscout Estado del algoritmo en 2017 @@ -171,7 +167,6 @@ Botón 3 Unidades: Unidades - DIA Rango de visualización Establece los rangos de glucosa objetivos (hiper e hipo) en la pantalla inicio de AAPS y en la esfera del reloj Valor de hipoglucemia @@ -240,7 +235,6 @@ Mostrar detalles IOB Separar la insulina activa en bolos y basales en el reloj sin efecto - por favor verificar en móvil - n/a Tipo de paciente Menor de edad Adolescente @@ -275,9 +269,6 @@ Registrar el inicio de la aplicación en Nightscout Saliendo de la aplicación para aplicar los ajustes. ¿Qué tipo de insulina estás utilizando? - Novorapid, Novolog, Humalog - Fiasp - INS Activar superbolo en asistente Activar la función superbolo en el asistente. No lo actives hasta que hayas aprendido lo que realmente hace. ¡PUEDE CAUSAR SOBREDOSIS DE INSULINA si lo usas sin precaución! Mostrar luces de estado en la pantalla de inicio @@ -352,14 +343,6 @@ Activar SMB Usar microbolos en lugar de basales temporales, para corregir más rápidamente Detectar comidas no anunciadas (UAM) - Tiempo del pico máximo de la curva de IOB - Tiempo del pico máximo de acción de la insulina [min] - Pico - Personalizar Pico - Acción Rápida - Acción Ultra Rápida - Lyumjev - DIA de %1$f demasiado corto - usando %2$f! ACTIVAR PERFIL INVÁLIDO Porcentaje @@ -442,7 +425,6 @@ Ignorar 5m Ignorar 15m Ignorar 30m - req Historial Notificar SMB Mostrar SMB en el reloj como un bolo estándar @@ -523,7 +505,6 @@ DIA Divisor para suspensión de bolos Máximo multiplicador diario de seguridad Multiplicador basal de seguridad actual - n/a Bomba virtual Definición de la bomba Bolo: Paso =%1$s\nBolo Extendido: [paso =%2$s, Duración =%3$smin -%4$sh] \nBasal: Paso =%5$s\nTBR: %6$s ( %7$s), Duración =%8$sMin -%9$sh\n%10$s @@ -730,7 +711,6 @@ Gráfico Menú gráfico Borrar filtro - Flecha de tendencia Cánula Entrada de usuario Usa los valores de la comida más grande que sueles comer\n @@ -787,18 +767,6 @@ resultado correcto con % corregir resultado con unidades No disponible - alto - en rango - bajo - bajando rápido - bajando - bajando despacio - estable - subiendo despacio - subiendo - subiendo rápido - ninguno - desconocido gráfico calidad de glucosa en sangre recalculado @@ -873,8 +841,6 @@ Alto Mostrar registros del lazo Ocultar registros del lazo - Widget de AAPS - Configurar opacidad Estado del lazo Escala gráfica Perfil 1 diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 757c97b58d..f9f81b2a7d 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -17,10 +17,6 @@ Utilisé pour configurer les plugins actifs Programme d’apprentissage Affiche les aliments définis par défaut dans Nightscout - Réglages pour les insulines Humalog et NovoRapid / NovoLog - Réglages pour l\'insuline Fiasp - Réglages pour l\'insuline Lyumjev - Permet de définir le pic de l’activité de l’insuline et ne doit être utilisé que par les utilisateurs avancés Activer ou désactiver la mise en œuvre déclenchant la Boucle. Synchronise vos données avec Nightscout État de l’algorithme en 2017 @@ -172,7 +168,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Bouton 3 Unités : Unités - DAI Fourchette de visualisation Les repères hauts et bas sur les graphiques pour l\'aperçu et la montre Ligne BASSE @@ -241,7 +236,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Afficher l\'IA détaillée Sur la montre, décomposer l’IA en IA bolus et IA basal Sans succès - vérifiez votre téléphone - s/o Type de patient Enfant Adolescent @@ -276,9 +270,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Démarrage AAPS entré dans NS Sortir de l’application pour appliquer les nouveaux paramètres. Quel type d\'insuline utilisez-vous ? - Novorapid, Novolog, Humalog, Apidra - Fiasp - INS Activer les Superbolus dans l’Assistant Activer la fonctionnalité SuperBolus dans l’Assistant. Ne pas l’activer avant de bien comprendre comment cela fonctionne réellement. IL PEUT PROVOQUER UNE OVERDOSE D’INSULINE SI UTILISÉ AVEUGLÉMENT ! Afficher les voyants d\'état sur l\'écran d\'accueil @@ -353,14 +344,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Activer SMB Utiliser les Super Micro Bolus au lieu des débits de base temporaires pour une action rapide Détection des Repas Non Signalés - Durée du Pic de la Courbe IA - Temps du Pic [min] - Pic - Profil d\'insuline ajustable Oref - Insuline à Action Rapide Oref - Insuline Ultra Rapide Oref - Lyumjev - Durée d’Action pour %1$f trop courte - utiliser %2$f à la place ! Activer le profil INVALIDE Pourcentage @@ -443,7 +426,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Ignorer 5m Ignorer 15m Ignorer 30m - req Historique Notifier en SMB Afficher SMB sur la montre comme un bolus standard. @@ -524,7 +506,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Snooze bolus Diviseur de DAI Multiplicateur max quotidien de sécurité Multiplicateur de sécurité basale courante - ND Type de pompe virtuelle Définition de pompe Bolus : Étape =%1$s\nExtended Bolus : [Étape =%2$s, Durée =%3$smin -%4$sh]\nBasal : Étape =%5$s\nTBR : %6$s (par %7$s), Durée =%8$smin -%9$sh\n%10$s @@ -732,7 +713,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Graph Menu graphique Effacer le filtre - Flèche de tendance Canule Entrées utilisateur Utilisez les valeurs qui correspondent à vos plus gros repas\n @@ -789,18 +769,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S corriger le résultat avec le % corriger le résultat avec les unités Non disponible - haut - dans la plage - bas - en baisse rapide - en baisse - en baisse lente - stable - en hausse lente - en hausse - en hausse rapide - aucun - inconnu graphique qualité de la glycémie recalculé @@ -875,8 +843,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Au-dessus Afficher les entrées de la boucle Masquer les entrées de la boucle - Widget AAPS - Configurer l’opacité État de la boucle Échelle du graph. Profil 1 diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 8ad394a177..3d170e1c48 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -17,10 +17,6 @@ Usato per configurare i plugin attivi Programma di apprendimento Visualizza i preset dei cibi definiti in Nightscout - Preset per insulina Humalog e NovoRapid / NovoLog - Preset per insulina Fiasp - Preset per insulina Lyumjev - Ti consente di definire il picco di attività dell\'insulina e dovrebbe essere usato solo dagli utenti avanzati Attiva o disattiva l\'implementazione per la gestione del loop. Sincronizza i tuoi dati con Nightscout Stato dell\'algoritmo nel 2017 @@ -171,7 +167,6 @@ Tasto 3 Unità: Unità - DIA Intervallo di visualizzazione Limite alto e basso per i grafici nella sezione Panoramica e sullo smartwatch Limite BASSO @@ -240,7 +235,6 @@ Mostra IOB dettagliato Dividi IOB in bolo e basale sulla watchface non riuscito - controlla il telefono - n/a Tipo paziente Bambino Adolescente @@ -275,9 +269,6 @@ Registra l\'avvio dell\'app in NS Uscita dall\'applicazione per applicare le impostazioni. Quale tipo di insulina stai usando? - Novorapid, Novolog, Humalog - Fiasp - INS Abilita superbolo nel calcolatore Abilita la funzionalità superbolo nel calcolatore. Non abilitare fino a quando non impari ciò che realmente fa. PUÒ CAUSARE SOVRA-DOSAGGIO DI INSULINA SE USATO IMPROPRIAMENTE! Mostra indicatori di stato sulla home @@ -352,14 +343,6 @@ Abilita SMB Usa super-micro-boli al posto della basale temporanea per un\'azione più veloce Rilevamento dei pasti non annunciati - Tempo picco Curva IOB - Tempo del picco [min] - Picco - Free-Peak Oref - Rapid-Acting Oref - Ultra-Rapid Oref - Lyumjev - DIA di %1$f troppo breve - uso %2$f. Attiva profilo NON VALIDO Percentuale @@ -442,7 +425,6 @@ Ignora | 5m Ignora | 15m Ignora | 30m - ric Storico Notifica SMB Mostra SMB sullo smartwatch come un bolo standard. @@ -523,7 +505,6 @@ Bolus snooze - divisore DIA Moltiplicatore di sicurezza max basale giornaliera Moltiplicatore di sicurezza basale corrente - n/a Tipo micro virtuale Definizione micro Bolo: Step=%1$s\nBolo Esteso: [Step=%2$s, Durata=%3$smin-%4$sh]\nBasale: Step=%5$s\nTBR: %6$s (di %7$s), Durata=%8$smin-%9$sh\n%10$s @@ -730,7 +711,6 @@ Grafico Menu grafico Cancella filtro - Freccia trend Cannula Inserimento utente Usa i valori del cibo più abbondante che mangi di solito\n @@ -787,18 +767,6 @@ risultato corretto con % risultato corretto con unità Non disponibile - alto - in range - basso - discesa rapida - discesa - discesa lenta - stabile - salita lenta - salita - salita rapida - nessuno - sconosciuto grafico qualità glicemia ricalcolato @@ -873,8 +841,6 @@ Sopra Mostra record di loop Nascondi record di loop - AAPS widget - Configura opacità Stato loop Scala del grafico Profilo 1 diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index 37b74837a2..bc88b62aeb 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -17,10 +17,6 @@ משמש לקביעת תצורה של תוספים פעילים תוכנית הלימוד מציג את ההגדרות הקבועות מראש עבור מזון המוגדר ב-Nightscout - הגדרת אינסולין ל-Humalog ו- NovoRapid / Novolog - הגדרת אינסולין מסוג Fiasp - הגדרת אינסולין מסוג Lyumjev - מאפשר להגדיר את שיא פעילות האינסולין, לשימוש על ידי משתמשים מתקדמים בלבד הפעלת או השבתת הלולאה. מסנכרן את נתוניכם עם Nightscout הישאר עם האלגוריתם של 2017 @@ -166,7 +162,6 @@ כפתור 3 יחידות: יחידות - משך פעילות אינסולין טווח הצגה סימוני גבוה ונמוך בתרשים סקירה כללית ובשעון חכם סימון נמוך @@ -235,7 +230,6 @@ הצגת IOB מפורט לחלק את ה IOB לבולוס ובזאלי במסך השעון נכשל - נא לבדוק את הטלפון - לא זמין סוג המטופל\\ת ילד\\ה מתבגר\\ת @@ -270,9 +264,6 @@ רשום הפעלת AAPS ב-Nightscout יוצא מ-AAPS כדי להחיל הגדרות. באיזה סוג של אינסולין אתה משתמש? - Novorapid, Novolog, Humalog - Fiasp - אינסולין אפשר סופר בולוס באשף אפשר פונקציית סופר בולוס באשף. אין להפעיל לפני שאתם יודעים להשתמש בה, שימוש לא נכון עלול לגרום למתן מינון יתר של אינסולין! הצגת אורות חיווי במסך הבית @@ -346,14 +337,6 @@ אפשר SMB השתמש בסופר מיקרו בולוסים במקום בבזאלי זמני לפעילות מהירה יותר זיהוי של ארוחות לא מוכרזות - שעת שיא של עקומת IOB - זמן שיא [min] - שיא - Oref שיא חופשי - Oref אינסולין מהיר - Oref אינסולין אולטרה מהיר - Lyumjev - DIA במשך %1$f הוא קצר מדי - משתמש ב-%2$f במקום! הפעלת פרופיל לא חוקי אחוזים @@ -436,7 +419,6 @@ התעלם ל-5 דק\' התעלם ל-15 דק\' התעלם ל-30 דק\' - דרושים דפדפן היסטוריה דיווח על SMB הצג SMB על השעון כמו בולוס סטנדרטי. @@ -517,7 +499,6 @@ נמנום בולוס - מחלק משך פעילות אינסולין מכפלת בטיחות בזאלי יומי מרבי מכפלת בטיחות בזאלי נוכחי - לא זמין סוג משאבה וירטואלית הגדרת משאבה בולוס: צעד=%1$s\nבולוס ממושך: [צעד=%2$s, משך=%3$s מינ\'-%4$sש\']\nבזאלי: צעד=%5$s\nבזאלי זמני: %6$s (עם %7$s), משך=%8$s מינ\'-%9$sש\'\n%10$s @@ -719,7 +700,6 @@ גרף תפריט הגרף נקה סינון - חץ מגמה צינורית קלט המשתמש השתמשו בערכים הגבוהים ביותר של מזונות שאתם אוכלים בדרך כלל\n @@ -776,18 +756,6 @@ תיקון עם % תיקון עם יחידות לא זמין - גבוה - בטווח - נמוך - ירידה מהירה - ירידה - ירידה איטית - יציב - עלייה איטית - עלייה - עלייה מהירה - אין - לא ידוע גרף איכות נתוני סוכר חושב מחדש @@ -860,7 +828,6 @@ מעל הצג רשומות לולאה החבא רשומות לולאה - הגדרת אטימות סטטוס הלולאה קנה מידה של הגרף פרופיל 1 diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index ead8b36546..c22008c968 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -16,10 +16,6 @@ 활성화된 플러그인을 구성하는 데 사용됩니다. 프로그램 배우기 Nightscout에서 정의된 음식 설정을 표시합니다. - 휴마로그와 노보래피드에 대한 인슐린 설정 - 피아스프에 대한 인슐린 설정 - Lyumjev에 대한 인슐린 설정 - 인슐린활동의 피크를 직접 정의할 수 있습니다. 고급 사용자만 사용해야 합니다. Loop를 활성화 혹은 비활성화합니다. Nightscout과 데이터 동기화하기 2017년의 알고리즘 @@ -161,7 +157,6 @@ 버튼3 단위: 단위 - DIA 차트 표시 범위 홈화면/스마트워치의 차트에서 표시되는 고/저혈당 선 저혈당 선 @@ -227,7 +222,6 @@ IOB 자세하게 보여주기 워치페이스에 IOB를 Bolus IOB와 Basal IOB로 나누어서 보여줍니다. 성공하지 못했습니다. 폰을 확인하세요 - 사용불가 환자 유형 어린이 청소년 @@ -261,9 +255,6 @@ 앱시작을 NS에 기록하기 설정을 적용하기위해 앱을 종료합니다. 어떤 종류의 인슐린을 사용합니까? - 노보래피드, 휴마로그, 에피드라 - 피아스프(Fiasp) - INS 마법사에서 Superbolus 활성화하기 마법사에서 Superbolus 기능을 활성화합니다. 어떤 기능인지 확실히 알기전까지 활성화 하지 마세요. 제대로 알지 못하고 사용하면 일슐린이 과다 주입될 수 있습니다! 홈화면에 상태 표시등 보여주기 @@ -334,13 +325,6 @@ SMB 활성화하기 더 빠른 작용을 위해 임시Basal 대신 Super Micro Bolus 사용 알리지 않은 식사 감지 - IOB 커브 피크 시간 - 피크 시간 [min] - 사용자지정-피크 Oref - 초속효성 Oref - 초-초속효성 Oref - Lyumjev - DIA %1$f는 너무 짧습니다. 대신 %2$f을 사용하세요! 프로파일 활성화하기 유효하지 않음 퍼센트 @@ -419,7 +403,6 @@ 5분간 무시하기 5분간 무시하기 30분간 무시하기 - 필요량 이력 브라우저 SMB 알림 일반 Bolus처럼 워치에 SMB 표시 @@ -495,7 +478,6 @@ Bolus snooze DIA 나눗수 최대 일 안전 승수 현재 Basal 안전 승수 - 사용불가 가성펌프 종류 펌프 정의 Bolus: 스텝=%1$s\n확장Bolus: [Step=%2$s, 기간=%3$s분-%4$s시]\nBasal: 스텝=%5$s\n임시Basal: %6$s (by %7$s), 기간=%8$s분-%9$s시\n%10$s @@ -671,7 +653,6 @@ 그래프 차트 메뉴 필터 지우기 - 경향 화살표 캐뉼라 사용자 항목 평소 섭취하는 가장 많은 양의 탄수화물 값을 사용하세요.\n diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index 3387e4b49a..df5288e681 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -16,10 +16,6 @@ Naudojama aktyvių įskiepių konfigūravimui Mokymosi programa Rodyti maisto ruošinius iš Nightscout - Nustatymai Humalog ir NovoRapid / NovoLog insulinams - Nustatymai Fiasp insulinui - Nustatymai Lyumjev insulinui - Leidžia pasirinkti insulino veikimo piką ir turėtų būti naudojama tik patyrusių vartotojų Aktyvuoja arba deaktyvuoja Ciklo paleidimą. Sinchronizuoja duomenis su Nightscout 2017 m. algoritmas @@ -164,7 +160,6 @@ Mygtukas 3 Vienetai: Vienetai - IVT Vizualizacijos diapazonas Aukštoji ir žemoji riba Apžvalgos grafikuose bei išmaniuosiuose laikrodžiuose Žemoji riba @@ -231,7 +226,6 @@ Rodyti AIO detaliai Rodyti laikrodyje bazės ir bolusų AIO Bandymas nesėkmingas - pasitikrinkite telefoną - n/a Paciento tipas Vaikas Paauglys @@ -266,9 +260,6 @@ Siųsti programos paleidimo žymę į NS Uždarant aplikaciją, taikyti nustatymus. Kokio tipo insuliną naudojate? - Novorapid, Novolog, Humalog - Fiasp - INS Įgalinti superbolusus skaičiuoklėje Įgalina superbolusų naudojimą insulino skaičiuoklėje. Nenaudokite, kol nesuprantate, ką superbolus funkcija atlieka. NAUDODAMI AKLAI GALITE PERDOZUOTI INSULINO! Pradžios ekrane rodyti spalvotus indikatorius @@ -339,13 +330,6 @@ Įjungti SMB Naudoti Super Mikro Bolusus vietoj laikinos bazės greitesniam veikimui Nedeklaruoto maisto (NDM) aptikimas - AIO kreivės pikas - Piko laikas [min] - Oref be piko - Greito veikimo Oref - Staigaus veikimo Oref - Lyumjev - IVT %1$f per trumpa - bus naudojama %2$f! Aktyvuoti profilį KLAIDA Procentais @@ -427,7 +411,6 @@ Ignoruoti 5 min Ignoruoti 15 min Ignoruoti 30 min - reikal. Istorija Pranešti apie SMB Rodyti SMB laikrodyje kaip standartinį bolusą. @@ -503,7 +486,6 @@ Boluso snaudimo daliklis Maksimalus dienos bazės saugos daugiklis Dabartinės bazės saugos daugiklis - n/a Virtualios pompos tipas Pompos nustatymas Bolusas: Žingsnis=%1$s\nIštęstinis bolusas: [Žingsnis=%2$s, Trukmė=%3$smin-%4$sh]\nBazė: Žingsnis=%5$s\nLDB: %6$s (iš %7$s), Trukmė=%8$smin -%9$sh\n%10$s @@ -689,7 +671,6 @@ Grafikas Grafiko meniu Valyti filtrą - Tendencijos kryptis Kaniulė Naudotojo įrašas Naudokite gausiausio patiekalo, kurį paprastai valgote, reikšmes\n diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index cc0757af53..cc62eccaf9 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -17,10 +17,6 @@ Gebruikt om actieve plugins te configureren Leerprogramma Toon de instellingen voor Voeding in Nightscout - Insuline instelling voor Humalog en NovoRapid / NovoLog - Insuline instelling voor Fiasp - Insuline instelling voor Lyumjev - Hiermee kan je de piek van de insulineactiviteit definiëren, mag alleen worden gebruikt door gevorderde gebruikers Activeer of deactiveer de implementatie die de Loop triggert. Synchroniseert je data met Nightscout Het algoritme uit 2017 @@ -166,7 +162,6 @@ Knop 3 Eenheden: Eenheden - DIA Bereik voor visualisatie Hoge en lage grens voor grafieken op het Overzicht en op Wear LAAG grens @@ -235,7 +230,6 @@ Toon gedetailleerde IOB Splits IOB in bolus en basaal op de watchface Niet geslaagd - controleer de telefoon - n.v.t. Type patiënt Kind Tiener @@ -270,9 +264,6 @@ Log app start naar NS Sluiten van applicatie om instellingen bij te werken. Welk soort insuline gebruik je? - Novorapid, Novolog, Humalog - Fiasp - INS Activeer superbolus in de wizard Activeer de superbolus functie in de wizard. Activeer deze niet tot je begrijpt wat dit doet. OVERDOSIS IS MOGELIJK BIJ BLINDELINGS GEBRUIK! Toon statusindicatoren op startscherm @@ -346,14 +337,6 @@ Activeer SMB SMB in plaats van tijdelijke basalen voor snellere reactie Detectie van niet aangekondigde (UnAnnounced) Maaltijden - IOB curve piek tijd - Piek tijd [min] - Piek - Free-Peak Oref - Snel-werkende Oref - Ultra-Rapid Oref - Lyumjev - DIA van %1$f te kort - %2$f wordt inplaats gebruikt! Activeer profiel Ongeldig Percentage @@ -436,7 +419,6 @@ Negeer 5m Negeer 15m Negeer 30m - nodig Historiek venster Waarschuw bij SMB Toon SMB op horloge zoals gewone bolussen. @@ -517,7 +499,6 @@ Bolus snooze dia deler Maximale dagelijkse veiligheids vermeningvuldigings factor Huidige basaalstand veiligheids vermenigvuldigings factor - n/a Virtuele pomp Type Pomp definitie Bolus: Stap=%1$s\nExtended Bolus: [Stap=%2$s, Duur=%3$smin-%4$sh]\nBasaal: Stap=%5$s\nTBR: %6$s (by %7$s), Duur=%8$smin-%9$sh\n%10$s @@ -717,7 +698,6 @@ Grafiek Grafiek menu Verwijder filter - Trendpijl Canule Gebruikersinvoer Gebruik de waarden van je grootste maaltijd die je gewoonlijk eet\n @@ -774,18 +754,6 @@ corrigeer uitkomt met percentage corrigeer uitkomt met units Niet beschikbaar - hoog - binnen bereik - laag - snel dalend - dalend - langzaam dalend - stabiel - langzaam stijgend - stijgt - snel stijgend - geen - onbekend grafiek bloedglucose kwaliteit opnieuw berekend @@ -860,7 +828,6 @@ Boven Toon loop records Verberg loop records - Configureer transparantie Loop status Grafiek schaal Profiel 1 diff --git a/app/src/main/res/values-no-rNO/exam.xml b/app/src/main/res/values-no-rNO/exam.xml index c1b4ebc0b0..3c83437f79 100644 --- a/app/src/main/res/values-no-rNO/exam.xml +++ b/app/src/main/res/values-no-rNO/exam.xml @@ -5,10 +5,12 @@ Du skal sette verdien for DIA i profilen din. Minimum tillatt DIA verdi er 5 timer. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html?#insulin + Hvis du føler at DIA verdien som du benyttet i pumpen fungerte godt før du tok i bruk AndroidAPS, da er det ikke nødvendig å endre dette når du starter å loope. Du må selv bestemme hvilken verdi som passer for DIA. Hypo Temp-Target (TT) Hva er hovedgrunnen til å velge en hypo temp-target? For å korrigere følinger som er forårsaket av feil i dine basalinnstillinger. + For å forhindre at AAPS overkorrigerer for en blodglukoseøkning forårsaket av de hurtigvirkende karbohydratene som brukes til behandling av en hypo. For å korrigere for en føling som er et resultat av trening. For å forhindre at blodsukkeret blir lavt selv om basaldosen allerede er 0%. https://androidaps.readthedocs.io/en/latest/EN/Usage/temptarget.html @@ -16,10 +18,15 @@ Tema: Offline profil NS profil kan brukes, men ikke konfigureres. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#profile + Årsaker for å velge \"Koble fra pumpen\" i AndroidAPS Hva bør gjøres innen du kobler fra pumpen? Dette er unødvendig siden insulin ikke vil bli levert hvis pumpen er fysisk frakoblet. + Det hjelper AndroidAPS å forstå at ingen insulin ble levert mens pumpen var fysisk frakoblet Insulinleveransen vil ikke stoppes hvis pumpen er fortsatt tilkoblet. + Det vil sette AndroidAPS i åpen loop modus. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#other-settings + AAPS innstillinger + AAPS innstillinger Hva er beste metode for å ta backup av dine innstillinger? Du trenger ikke å eksportere dine innstillinger hvis du har skrevet dem ned. Eksporter dine innstillinger etter at du har avsluttet et læringsmål. @@ -33,6 +40,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#what-emergency-equipment-is-recommended-to-take-with-me Støy i CGM målinger Hva bør gjøres hvis CGM data har støy? + Gjør ingenting - AndroidAPS vil håndtere det. Deaktiver lukket loop for å unngå mulig over- eller underdosering. Bytt alltid ut støyete eller unøyaktige sensorer. Kontroller at din CGM app leverer glattede data. @@ -63,6 +71,7 @@ Når du har innstilt og validert verdiene vil de ikke endre seg over tid. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#androidaps-settings Forutsetninger + Hva er nødvendig for å sette opp og bruke AAPS? Validert profil informasjon (basal, IK, ISF, DIA). En computer hvor Android Studio er installert og konfigurert. En telefon som støttes. @@ -77,17 +86,25 @@ En smartklokke. En CGM som støttes. Forutsetninger + Hva er nødvendig for å sette opp og bruke AAPS? Validert informasjon for å konfigurere din profil (ISF, KH ratio, basal doser, DIA etc.). En kompatibel Android enhet (f.eks. mobiltelefon, full Android klokke, eller nettbrett). + AndroidAPS krever en internett forbindelse for å kunne kjøre lukket loop. En støttet CGM og passende app som mottar blodsukkerverdier på mobilen/enheten. https://androidaps.readthedocs.io/en/latest/EN/Module/module.html + Oppdatering av AAPS Kontroller alle riktige svar. Du må ha Git installert og konfigurert på din PC. + Når oppdateringer til AndroidAPS lanseres kan tidligere versjoner etter en tidsperiode få begrenset funksjonalitet. Du må lagre og notere lokasjonen for din keystore og benytte samme signeringsnøkkel for bygging av oppdateringen som forrige installasjon. Aldri oppdater hvis systemet fungerer bra. Hvis du har problemer med å bygge apk filen, kan du installere en apk som er bygget av en venn. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch Feilsøking + Hvor kan du be om hjelp for AndroidAPS? + Du kan be om råd i Facebookgruppen AAPS Users. + Du bør lese (og lese om igjen) AndroidAPS dokumentasjonen. + Du kan be om råd og stille tekniske problemer eller spørsmål på AAPS Discord. Du bør spørre din diabetesklinikk/endokrinolog. https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting https://www.facebook.com/groups/AndroidAPSUsers/ @@ -101,6 +118,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#insulin Sensitivitets plugin Kontroller alle riktige svar. + Sensitivitets plugin gjør det mulig for AAPS å gjøre midlertidige eller kortvarige justeringer av insulin sensitivitet (f. eks. hormonelle forandringer eller problemer med absorpsjon ved innstikkstedet). Sensitivitets plugin gir brukeren forslag til endringer i basaldoser, KH ratio og ISF som kan benyttes til å redigere profilen. Hvis du logger bytte av kanyle vil Autosens verdien tilbakestilles til 100%. Noen plugins har konfigurerbare tidsintervall som kan settes av brukeren. @@ -110,11 +128,14 @@ Hva skal du gjøre hvis du har gjort en feilaktig registrering av karbohydrater? Fjern den feilaktige registreringen i Behandlinger og legg inn riktig verdi for karbohydrater. Gi insulinbolus ved å bruke prime funksjonen for infusjonssettet. + Gjør ingenting - AndroidAPS vil gjøre nødvendige justeringer. Gi bolus ved hjelp av Insulin knappen på hjem/oversikts siden. Feil i insulin levering/registrering Hva ska du gjøre hvis du har fått mindre insulin enn hva pumpens historikk viser, f.eks. på grunn av okklusjon, feil med kanyle eller om du har glemt å koble på pumpen etter en dusj Fjern insulindata fra Nightscout slik at det slettes fra pumpens historikk. + Sammenlign verdiene i AndroidAPS og pumpehistorikken (hvis pumpen støtter dette). Gi en bolus med en del av det insulinet du mangler enten med penn eller ved å bruke prime funksjonen. + Ikke gjør noe og la AndroidAPS korrigere eventuelle høye blodsukkerverdier. Karbohydrater ombord (COB) Hvordan vil endring av ISF-verdi påvirke COB-beregning? Økning av ISF gjør at karbohydrater absorberes over lengre tid @@ -136,20 +157,28 @@ Karbohydrater og bolus Bare gram skal benyttes for å estimere og registrere spiste karbohydrater. Karbohydrater som konsumeres kan registreres ved hjelp av et passende byttesystem (f.eks. DAFNE \"CHO\" eller europeiske \"brødenheter\"). + AndroidAPS bruker en dynamisk modell til å beregne karbohydrat opptaket og beregne COB. Hvis blodsukkernivået er utenfor akseptable verdier (for lavt eller for høy), kan boluskalkulatoren brukes til å gi forslag til korreksjoner for karbohydrater eller insulin. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-to-carb-ratio-ic-g-u e-Karbo Hva kan du bruke e-karbohydrater (forlengede karbohydrater) til? For å angi karbohydrater i fremtiden og/eller fordele dem over et tidsintervall (tilsvarende en forlenget bolus over et intervall). + For å logge \"frie\" treningskarbohydrater som du vil skjule for AndroidAPS. + E-karbo som er registrert i fremtiden kan hjelpe AAPS å håndtere måltider som er fett/proteinrike. For å registrere karbohydrater som brukes til å korrigere lavt blodsukker https://androidaps.readthedocs.io/en/latest/EN/Usage/Extended-Carbs.html Fjernovervåking + Hvordan kan du overvåke AndroidAPS (for eksempel for ditt barn) på eksternt? + AAPSClient app, Nightscout app og Nightscout websiden gjør det mulig for deg å følge AAPS eksternt. Andre apper (f.eks. Dexcom follow, xDrip som kjører i følger modus) lar deg følge noen parametere (f.eks. blodsukker/sensor verdier) på avstand, men bruker forskjellige beregningsmetoder og kan derfor vise andre IOB eller COB verdier. + For å følge AAPS eksternt må begge enhetene ha Internett-tilgang (f.eks. via Wi-Fi eller mobildata). + AAPSClient som brukes som ekstern følger app vil både overvåke og gi full kontroll over AAPS. https://androidaps.readthedocs.io/en/latest/EN/Children/Children.html Insulin Sensitivitetsfaktor (ISF) Økte ISF-verdiene vil føre til levering av mer insulin for å dekke opp en viss mengde karbohydrater. Lavere ISF verdier fører til mer insulintilførsel for å korrigere blodsukker som ligger over målnivået. Å øke eller senke ISF har ingen effekt på tilførselen av insulin når blodsukkeret er lavere enn målverdien. + ISF skal angis i dine AndroidAPS innstillinger. Å endre ISF verdien i din profil er tilstrekkelig for å ta i bruk endringen. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html @@ -176,6 +205,7 @@ Blodsukkermålet vil være uforandret. ISF vil være 20% høyere. Profil bytte + Hvis du står opp 2 timer tidligere enn vanlig, hvordan forteller du AndroidAPS om endringen i døgnrytmen din? Gjør et profilbytte med en tidsforskyvning på 2 Gjør et profilbytte med en tidsforskyvning på -2 Angi et \"spise snart\" midlertidig temp target. @@ -183,6 +213,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html?highlight=profile%20switch#timeshift Endring av profil Basalrater, ISF, KH ratio, etc., bør defineres i profiler. + Aktivering av endringer i Nightscout profilen din krever at din AndroidAPS telefon er koblet til Internett. Å redigere verdier i profilen din er tilstrekkelig for å aktivere profilendringen. Flere profiler kan defineres og velges for å håndtere endringer i omstendigheter (f.eks. hormonelle endringer, skift arbeid, hverdager/helgedager). https://androidaps.readthedocs.io/en/latest/EN/Module/module.html#good-individual-dosage-algorithm-for-your-diabetes-therapy @@ -192,4 +223,6 @@ Google Facebook Annen medisinering. Vennligst les utsagnet nedenfor, og sjekk deretter boksen for å godta erklæringen. + AndroidAPS reduserer basaldoser eller utsetter insulindoser for å få en økning i blodsukkerverdier. Medisiner av typen SGLT2 hemmere (gliflozins) kan redusere eller hemme forventet økning i blodsukker og kan derfor føre til akutt og farlig høyt blodsukker ketoacidose (DKA). +\nVanlige medisinnavn er: Invokana®, Forxiga®, Jardiance®, Steglatro®, Suglat®, Apleway®, Deberza®, Synjardy®, Vokanamet®, Xigduo®.\n\nJeg lover å ikke ta slike medisiner mens jeg bruker AndroidAPS og vil deaktivere bruken av loop mens jeg bruker slik medisin. diff --git a/app/src/main/res/values-no-rNO/objectives.xml b/app/src/main/res/values-no-rNO/objectives.xml index 05dc75b154..8cdedfd9e8 100644 --- a/app/src/main/res/values-no-rNO/objectives.xml +++ b/app/src/main/res/values-no-rNO/objectives.xml @@ -25,6 +25,8 @@ Pumpe status tilgjengelig i NS Manuell kommando Utført: %1$s + Lær hvordan du kontrollerer AAPS + Utfør forskjellige handlinger i AAPS Angi profil 90% for 10 min (langt-trykk på profilnavn i Oversikt) Simuler dusjing. Frakoble pumpen i 1t (langt trykk på Åpen Loop) ... og koble til igjen på samme måte diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml index 521d66d07e..7e8e0b1cc1 100644 --- a/app/src/main/res/values-no-rNO/strings.xml +++ b/app/src/main/res/values-no-rNO/strings.xml @@ -17,10 +17,6 @@ Brukes for innstilling av aktive plugins Opplæringsprogram Viser forhåndsinnstillinger for mat fra Nightscout - Innstillinger for Humalog og NovoRapid / NovoLog - Innstillinger for Fiasp - Innstillinger for Lyumjev - Lar deg stille inn tidspunktet for toppen av insulinvirkningen. Bør bare benyttes av erfarne brukere Aktiver eller deaktiver hendelsen som trigger loop. Synkroniserer dine data med Nightscout Slik algoritmen var definert i 2017 @@ -39,6 +35,7 @@ Last ned BS-verdier fra Nightscout Motta BS-verdier fra xDrip+. Lagre data om alle behandlinger som er utført + Overvåke og kontrollere AAPS ved hjelp av WearOS-klokken. Vis informasjon om loop på din xDrip+ urskive. Insulin: Karbo: @@ -72,7 +69,9 @@ Behandlinger Virtuell pumpe Pumpe + Hvilken pumpe ønsker du å bruke med AAPS? Profil + Hvilken profil skal AAPS bruke? APS Hvilken algoritme skal APS benytte for behandlinger? Generelt @@ -80,6 +79,7 @@ Hvilke begrensninger brukes? Begrensninger Loop + Bruk denne for å aktivere AAPS\' loopintegrasjon. APS Etter behandling av begrensninger Temp basal satt av pumpen @@ -92,6 +92,7 @@ Kalkulator Endre dine inndata! BS-kilde + Hvor skal AAPS få sine data fra? xDrip+ APS modus Lukket Loop @@ -166,7 +167,6 @@ Knapp 3 Enheter: Enheter - DIA Område for visualisering Høy og lav verdi for grafen i Oversikt og smartklokke Lav verdi @@ -235,7 +235,6 @@ Vis detaljert IOB Splitt IOB til bolus- og basal-IOB på klokken feilet - sjekk telefonen - n/a Pasienttype Barn Tenåring @@ -270,9 +269,6 @@ Logg app-start til NS Avslutter appen for å aktivere innstillinger. Hvilken type insulin bruker du? - Novorapid, Novolog, Humalog - Fiasp - INS Aktiver superbolus i veiviser Aktiver superbolus-funksjonen i veiviseren. Ikke aktiver denne før du vet hvordan den fungerer. DEN KAN LEDE TIL EN OVERDOSERING AV INSULIN HVIS DEN BRUKES BLINDT! Vis statusindikatorer på hjem-skjermen @@ -337,6 +333,7 @@ Sensitivitet vektet middelverdi Ikke alle profiler ble lastet! Verdier ikke lagret! + Aktiver kringkasting av data til andre apper (som xDrip+). Ikke aktiver dette hvis du har mer enn én AAPS eller NSClient installert! Aktiver deling av data mellom apper på telefonen. OpenAPS SMB Dynamisk ISF @@ -346,14 +343,6 @@ Aktiver SMB Bruk Super Mikro Bolus i stedet for temp basal for raskere resultat Oppdag uannonsert måltid (UAM) - IOB-kurvens topptid - Topptid [min] - Topp - Free-Peak Oref - Rapid-Acting Oref - Ultra-Rapid Oref - Lyumjev - DIA på %1$f for kort - bruker %2$f i stedet! Aktiver profil UGYLDIG Prosent @@ -436,7 +425,6 @@ Ignorer 5m Ignorer 15m Ignorer 30m - beh Historikk leser Varsle på SMB Vis SMB på klokken som en standard bolus. @@ -517,7 +505,6 @@ Bolus snooze DIA divisor Multiplikator for max daglig basal Multiplikator får gjeldende basal - n/a Virtuell pumpetype Pumpedefinisjon Bolus: Step=%1$s\nForlenget bolus: [Step=%2$s, Varighet=%3$smin-%4$sh]\nBasal: Step=%5$s\nTBR: %6$s (av %7$s), Varighet=%8$smin-%9$sh\n%10$s @@ -529,6 +516,7 @@ Velkommen til oppsettveiviseren. Den vil lede deg gjennom installasjonsprosessen\n Les status Hopp over oppsettsveiviser + Trykk på knappen under for å tillate at AndroidAPS foreslår/gjør basal endringer Sensitivitets plugin brukes til å oppdage insulinsensitivitet og COB beregninger. For mer info, se: https://androidaps.readthedocs.io/en/latest/Configuration/Sensitivity-detection-and-COB.html NSClient håndterer tilkobling til Nightscout. Du kan hoppe over denne delen nå, men du vil ikke kunne bestå læringsmålene før den er satt opp. @@ -565,6 +553,7 @@ Fjern oppføringer Sorter elementer Lagrede innstillinger funnet + Varsel: Hvis du aktiverer og kobler til en pumpe, så vil AndroidAPS kopiere basal innstillinger fra din profil over til pumpen og overskrive verdiene som er lagret i pumpen. Sjekk at du har riktige basal verdier i AndroidAPS. Hvis du ikke er sikker eller ikke ønsker å overskrive basal verdiene i pumpen, trykk avbryt og koble til pumpen senere. Behandlingsdata er ufullstendige Vedlikeholds innstillinger E-post mottaker @@ -590,6 +579,7 @@ I åpen Loop modus vil AAPS be om en endring hvis forandringen er større enn denne verdien i %. Standard verdi er 20% == ∑ %1$s E Logg sensor endring til NS + Opprett hendelse \"Sensor bytte\" i NS automatisk ved start av sensoren Tomato (MiaoMiao) Tomato Ditt Tidepool brukernavn, normalt din e-postadresse @@ -655,6 +645,7 @@ ID: Lagre Mest vanlig profil: + Merk: Kun data synlig på denne skjermen vil bli anonymt lastet opp. ID er tilordnet denne installasjonen av AndroidAPS. Du kan sende inn data igjen hvis hovedprofilen din blir endret, men la den kjøre i minst en uke for å se effekten av resultatet i tidsperioden. Din hjelp blir verdsatt. Ugyldig alder Ugyldig vekt Ugyldig % oppføring @@ -716,11 +707,12 @@ Aktiver alarm når det er på tide å spise Nå må du spise!\Bruk bolus veiviseren og beregn på nytt. Aktiver bolus påminnelse + Bruk påminnelse for å sette bolus dosen senere med veiviseren + («post bolus») Opplast av krasj logger er deaktivert! Graf Diagram meny Nullstill filtre - Trend pil Kanyle Bruker registrering Bruk verdiene for det største måltidet du normalt spiser\n @@ -777,18 +769,6 @@ korriger resultatet med % korriger resultatet med enheter Ikke tilgjengelig - høy - i målområdet - lav - synker raskt - synker - synker sakte - stabil - stiger sakte - stiger - stiger raskt - ingen - ukjent graf blodsukkermålingens kvalitet beregnet på nytt @@ -863,7 +843,6 @@ Over Vis loop registreringer Skjul loop registreringer - Konfigurer gjennomsiktighet Loop status Diagram skala Profil 1 @@ -888,4 +867,7 @@ Blokkert på grunn av tilkoblingsalternativer (Ingen klokke tilkoblet) Juster sensitivitet og BS + Database opprydding + Vil du rydde opp i databasen?\nDet vil fjerne sporede endringer og historiske data eldre enn 3 måneder. + Ryddet opp i oppføringer diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 0b774299e2..7409636271 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -16,10 +16,6 @@ Konfiguracja aktywnych modułów systemu Program do nauki Wyświetla dane posiłków zdefiniowanych w Nightscout - Profil insulinowy dla Humalog i Novorapid / NovoLog - Profil insulinowy dla Fiasp - Profil insulinowy dla Lyumjev - Pozwala na określenie czasu wartości szczytowej działania insuliny i powinno być używane tylko przez zaawansowanych użytkowników Włącz lub wyłącz działanie pętli. Synchronizuje twoje dane z Nightscout Stan algorytmu w 2017 @@ -164,7 +160,6 @@ Przycisk 3 Jednostki: Jednostki - DIA Zakres do wizualizacji (na wykresie) Oznaczenia wysokiego i niskiego cukru na wykresie w oknie przegląd i na smartwatch\'u Znacznik NISKI @@ -232,7 +227,6 @@ Pokaż szczegóły IOB Rozłóż IOB na bolus i IOB bazy na zegarku nie udało się - proszę sprawdzić telefon - n/a Typ pacjenta Dziecko Nastolatek @@ -267,9 +261,6 @@ Wyślij start app do NS Zamykanie aplikacji w celu wprowadzenia ustawień. Jakiego typu insuliny używasz? - Novorapid, Novolog, Humalog - Fiasp - INS Zezwalaj na superbolus w kalkulatorze Włącz funkcję Superbolus w kalkulatorze. Nie uruchamiaj, dopóki nie nauczysz się jak ta funkcja działa. MOŻESZ DOPROWADZIĆ DO PRZEDAWKOWANIA INSULINY JEŻELI UŻYJESZ TEJ FUNKCJI NIE POSIADAJĄC ODPOWIEDNIEJ WIEDZY! Pokaż diody stanu na ekranie głównym @@ -340,13 +331,6 @@ Włącz SMB Używaj SMB (Super Mikro Bolusów) zamiast bazy tymczasowej dla szybszego działania Detekcja niezapowiedzianych posiłków (UAM) - IOB Czas piku krzywej działania insuliny - Czas piku [min] - Swobodny-Pik Oref - Szybko-Działający Oref - Ultra-Szybki Oref - Lyumjev - DIA %1$f zbyt krótki - przyjmuję %2$f w zamian! Aktywuj profil NIEPRAWIDŁOWY Procent @@ -428,7 +412,6 @@ Ignoruj 5 min Ignoruj 15 min Ignoruj 30 min - wym Przegląd historii Powiadom na SMB Pokaż SMB na zegarku jak bolus standardowy. @@ -504,7 +487,6 @@ Bolus snooze dia divisor (Dzielnik uśpienia bolusa) Max daily safety multiplier (Mnożnik bezpieczeństwa maksymalnej dziennej dawki bazowej [U/godzinę]) Current basal safety multiplier (Mnożnik bezpieczeństwa aktualnej dziennej dawki bazowej [U/godzinę]) - n/a Pompa wirtualna Definicja Pompy Bolus: Krok =%1$s\nBolus Przedłużony: [krok =%2$s, czas trwania =%3$smin -%4$sh] \nBasal: krok =%5$s\nTBR: %6$s (przez %7$s), czas trwania =%8$smin -%9$sh\n%10$s @@ -694,7 +676,6 @@ Wykres Menu wykresu Wyczyść filtr - Strzałka trendu Kaniula Wpis użytkownika Użyj wartości największego jedzenia, które zazwyczaj zjadasz\n diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 2bb0f07745..5575478edd 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -16,10 +16,6 @@ Usado para configurar os plugins ativos Programa de aprendizagem Exibe as predefinições de comida definidas no Nightscout - Predefinição de Insulina para Humalog e NovoRapid / NovoLog - Pré-ajuste de Insulina para Fiasp - Configuração pre-definida para a Insulina Lyumyev - Permite que você defina o pico da atividade de insulina, deve ser usado apenas por usuários avançados Ative ou desative a implementação ativando o loop. Sincroniza seus dados com o Nightscout Estado do algoritmo em 2017 @@ -164,7 +160,6 @@ Botão 3 Unidades: Unidades - DIA Intervalo para visualização Marca alta e baixa para as cartas em Visão geral e Smartwatch Marca Baixo @@ -233,7 +228,6 @@ Mostrar detalhes da IA Dividir IA entre IA de bolus e de basal na face do relógio não foi bem sucedido - por favor, verifique o telefone - n/a Tipo de paciente Criança Adolescente @@ -268,9 +262,6 @@ Registrar início do app no NS Saindo do app para aplicar as configurações. Que tipo de insulina está usando? - Novorapid, Novolog, Humalog - Fiasp - INS Ativar superbolus no assistente Habilite a funcionalidade de superbolus no assistente. Não habilite até que aprenda o funcionamento. PODE CAUSAR OVERDOSE DE INSULINA SE USAR INDISCRIMINADAMENTE! Mostrar luzes de estado no ecrã principal @@ -325,13 +316,6 @@ Ativar SMB Use Super Micro Boluses em vez de basal temp para uma ação mais rápida Detecção de refeições não Introduzidas - Tempo Pico da curva de IOB - Tempo Pico [min] - Pico - Oref Pico-Livre - Oref Ação Rápida - Ultra-Rapid Oref - Duração de Acção da Insulina (DIA) de %1$f demasiado curto - corrigido para %2$f! Ativar perfil INVÁLIDO Percentagem @@ -476,7 +460,6 @@ Pausa bólus divisor DIA Multiplicador máx. diário de segurança Multiplicador actual de segurança basal - n/a Tipo da Bomba Virtual Definição da Bomba Bólus: Passo=%1$s\nBólus Estendido: [Passo=%2$s, Duração=%3$smin -%4$sh] \nBasal: Passo=%5$s\ nTBR: %6$s (por %7$s), Duração=%8$smin-%9$sh\n%10$s @@ -676,18 +659,6 @@ resultado correto em % resultado correto em unidades Indisponível - hiper - dentro da meta - hipo - caindo rapidamente - caindo - caindo lentamente - estável - subindo lentamente - subindo - subindo rapidamente - nenhum - desconhecido gráfico qualidade da glicemia recalculada @@ -733,7 +704,6 @@ Acima Exibir registros do loop Ocultar registros do loop - Configurar opacidade Status do loop abrir configurações definir alarme temporizador de carboidrato diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 5fad731f79..1b7b52bedb 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -16,10 +16,6 @@ Usado para configurar os plugins ativos Programa de aprendizagem Exibe as predefinições de comida definidas no Nightscout - Predefinição de Insulina Humalog e NovoRapid / NovoLog - Predefinição de Insulina Fiasp - Predefinição para Insulina Lyumjev - Permite definir o pico de atividade da insulina e deve ser usado somente por usuários avançados Ativar ou desativar a aplicação que desencadeia o loop. Sincroniza os seus dados com o Nightscout Estado do algoritmo em 2017 @@ -164,7 +160,6 @@ Botão 3 Unidades: Unidades - DIA Intervalo para visualização Marca Alto e Baixo para os gráficos em Sumário e Smartwatch Marca Baixo @@ -231,7 +226,6 @@ Mostrar IA detalhada Dividir IA entre IA de bólus e de basal no ecrã do relógio sem efeito - por favor verifique no telemóvel - n/d Tipo de Paciente Criança Adolescente @@ -266,9 +260,6 @@ Registar inicio da app no NS A sair da aplicação para aplicar as definições. Qual o tipo de insulina que está a utilizar? - Novorapid, Novolog, Humalog - Fiasp - INS Activar superbólus no assistente Active a funcionalidade de superbolus no assistente. Não active até que aprenda o funcionamento. PODE CAUSAR OVERDOSE DE INSULINA SE UTILIZAR INDISCRIMINADAMENTE! Mostrar luzes de estado no ecrã principal @@ -339,13 +330,6 @@ Activar SMB Use Super Micro Bólus em vez de basal temporária para uma ação mais rápida Deteção de Refeições Não Anunciadas (RNA) - Tempo do Pico da curva de IA - Tempo Pico [min] - Oref Pico-Livre - Oref Acção-Rápida - Oref Ultra-Rápida - Lyumjev - Duração de Acção da Insulina (DIA) de %1$f demasiado curto - corrigido para %2$f! Activar perfil INVÁLIDO Percentagem @@ -427,7 +411,6 @@ Ignorar 5m Ignorar 15m Ignorar 30m - req Navegador do histórico Notificar no SMB Mostrar SMB no relogio como bolus normal. @@ -503,7 +486,6 @@ Pausa bólus divisor DIA Multiplicador máx. diário de segurança Multiplicador actual de segurança basal - n/a Tipo da Bomba Virtual Definição da Bomba Bólus: Passo=%1$s\nBólus Prolongado: [Passo=%2$s, Duração=%3$smin -%4$sh] \nBasal: Passo=%5$s\ nDBT: %6$s (por %7$s), Duração=%8$smin-%9$sh\n%10$s @@ -689,7 +671,6 @@ Gráfico Menu do Gráfico Limpar filtros - Seta de tendência Cânula Entrada de Utilizador Utilize valores da sua maior refeição que normalmente come\n diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index f841aac185..68c5f7f1dc 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -16,10 +16,6 @@ Folosit pentru configurarea facilităţilor active Program de învăţare Afişează mâncărurile predefinite în Nightscout - Setări prestabilite pentru insulinele Humalog sau NovoRapid / NovoLog - Setări prestabilite pentru Fiasp - Setări prestabilite pentru Lyumjev - Vă permite definirea vârfului activităţii insulinei şi ar trebui folosit doar de către utilizatorii avansaţi Activare sau dezactivare a implementării declanşatoare pentru buclă. Sincronizare a datelor cu Nightscout Starea algoritmului în 2017 @@ -164,7 +160,6 @@ Buton 3 Unități: Unități - DIA Intervalul pentru vizualizare Valoarea maximă și minimă pentru graficele din vizualizare și pentru smartwatch Pragul HIPO @@ -231,7 +226,6 @@ Arată IOB detaliat Separă IOB în bolus și IOB bazal pe ceas fără succes - verificați telefonul - indisponibil Tip de pacient Copil Adolescent @@ -266,9 +260,6 @@ Înregistrează pornirea aplicației în NS Se iese din aplicație în vederea aplicării setărilor. Ce tip de insulină folosiți? - Novorapid, Novolog, Humalog - Fiasp - INS Activează superbolus în asistent Activează funcționalitatea de superbolus în asistentul de buclă. Nu activați până nu înțelegeți ce face cu adevărat. DACĂ ESTE FOLOSIT ÎN NECUNOȘTINȚĂ DE CAUZĂ POATE DUCE LA SUPRADOZĂ DE INSULINĂ! Afișați indicatorii luminoși ai pompei pe ecranul de start @@ -339,13 +330,6 @@ Activează SMB Folosește SMB în locul bazalei temporare pentru reacție mai rapidă S-a detectat masă neanunțată - Curbă timp vârf IOB - Timp vârf [min] - Oref Vârf-Liber - Oref Insulină-Rapidă - Oref Insulină-UltraRapidă - Lyumjev - DIA din %1$f prea scurtă - se folosește %2$f în schimb! Activează profil INVALID Procentaj @@ -427,7 +411,6 @@ Ignorați 5min Ignorați 15min Ignorați 30min - req Vizualizare istoric Notifică despre SMB Arată SMB pe ceas ca și un bolus standard. @@ -503,7 +486,6 @@ Amână bolusul prin divizor Multiplicator sigur maxim zilnic Multiplicator sigur pentru bazala curentă - indisponibil Tipul pompei virtuale Definirea pompei Bolus: Pas=%1$s\nBolus Extins: [Pas=%2$s, Durată=%3$smin-%4$sh]\nBazală: Pas=%5$s\nRBT: %6$s (cu %7$s), Durată=%8$smin-%9$sh\n%10$s @@ -689,7 +671,6 @@ Grafic Meniu diagramă Șterge filtru - Săgeată tendinţă Canula Înregistrare utilizator Folosește valorile corespunzătoarea celor mai mari mese pe care le ai de obicei\n diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index dfef107f45..9c1f9aaee5 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -17,10 +17,6 @@ Применяется для настройки активных плагинов Обучающая программа Показывает предварительные настройки приема пищи из Nightscout - Предустановки для Humalog и Novorapid / Novolog - Предустановки для Fiasp - Параметры Lyumjev - Позволяет самостоятельно задавать пик активности инсулина - только для опытных пользователей Активировать или деактивировать запуск цикла. Синхронизирует данные с Nightscout Состояние алгоритма в 2017 году @@ -171,7 +167,6 @@ кнопка 3 Единицы: Единицы - Время действия инсулина DIA диапазон для визуализации Нижняя и верхняя граница диаграммы в отчетах и Smartwatch отметка НИЗКИЙ @@ -240,7 +235,6 @@ показать IOB подробно разбивка IOB на болюсный и базальный IOB на циферблате смарт-часов неудача - проверьте телефон - н/д Тип пациента ребенок подросток @@ -275,9 +269,6 @@ Передать в NS запись о начале работы приложения выход из приложения для применения настроек Какой тип инсулина вы используете? - Novorapid, Novolog, Humalog - Fiasp - ИНС активировать суперболюс активировать возможность суперболюса в мастере. не активируйте если не знаете что это. МОЖЕТ ВЫЗВАТЬ ПЕРЕДОЗИРОВКУ ИНСУЛИНА ЕСЛИ ИСПОЛЬЗУЕТСЯ ВСЛЕПУЮ Показать индикаторы состояния на главном экране @@ -352,14 +343,6 @@ Включить супер микро болюс SMB Для ускорения действия используйте супер микро болюсы SMB вместо временного базала Поиск незапланированного приема пищи - Время пика действующего инс IOB - время пика (в мин.) - Пик - Свободный от пиков Oref - Быстро действующий Oref - Сверхбыстрый Oref - Lyumjev - Значение длительности работы инс %1$f слишком мало - применено %2$f! АКТИВИРОВАТЬ ПРОФИЛЬ НЕВЕРНО Процент @@ -442,7 +425,6 @@ Игнорировать 5 м Игнорировать 15 м Игнорировать 30 м - надо История Сообщить о супер микро болюсе SMB Показывать супер микро болюс SMB на часах как стандартный болюс. @@ -523,7 +505,6 @@ Делитель продолжительности действия инсулина при болюсе OpenAPS AMA Множитель безопасности макс суточного базала Текущий множитель безопасности базала - н/д Тип виртуальной помпы Определение помпы Болюс: Шаг =%1$s\n Пролонгированный Болюс: [Шаг =%2$s, Продолжительность =%3$sмин -%4$sh] \nБазал: Шаг =%5$s\n ВБС: %6$s (на %7$s), Продолжительность =%8$sмин -%9$sh\n%10$s @@ -726,11 +707,11 @@ Напомнить о еде Пора есть!\nЗапустите помощник болюса снова для подсчета. Включить напоминание о болюсе + Применить напоминание о болюсе с помощью мастера (постболюс) Загрузка журналов сбоя на сервер отключена! График Меню графика Очистить фильтр - Стрелка тренда Катетер помпы Запись пользователя Введите максимальные значения вашего приема пищи \n @@ -787,18 +768,6 @@ корректный результат в % корректный результат в ед Недоступно - высокий - в диапазоне - низкий - быстро падает - падает - медленно падает - стабильный - медленно поднимается - растет - стремительно растет - отсутствует - неизвестно график качество глюкозы в крови пересчитано @@ -873,8 +842,6 @@ Выше целевых Показать записи цикла Скрыть записи цикла - Виджет AAPS - Настроить прозрачность Статус цикла Масштаб графика Профиль 1 diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index c0ac5ec301..298e5feab5 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -17,10 +17,6 @@ Používané na konfiguráciu aktívnych pluginov Výukový program Zobrazenie prednastavených jedál, definovaných v Nightscoute - Predvoľba pre inzulín Humalog a Novorapid - Predvoľba pre inzulín Fiasp - Predvoľba pre inzulín Lyumjev - Umožňuje definovať vrchol účinnosti inzulínu a malo by byť používané iba pokročilými užívateľmi Aktivuje alebo deaktivuje spustenie uzavretého okruhu. Synchronizuje vaše dáta s NS Stav algoritmu v roku 2017 @@ -171,7 +167,6 @@ Tlačidlo 3 Jednotky: Jednotky - DIA Rozsah pre zobrazenie Značka vysokej a nízkej hodnoty v prehľade a na hodinkách Wear Dolná značka @@ -240,7 +235,6 @@ Zobraziť detailný IOB Rozpísať IOB na hodinkách do bolusového a bazálneho Neúspešné - skontrolujte telefón - nie je k dispozícii Typ pacienta Dieťa Dospievajúci @@ -275,9 +269,6 @@ Zaznamenávať spustenie aplikácie do NS Zatváram aplikáciu, aby sa aplikovali nové nastavenia. Aký druh inzulínu používate? - Novorapid, Humalog - Fiasp - INZ Povoliť superbolus Povolenie superbolusu v kalkulátore. Nepovoľujte, pokiaľ se nenaučíte, čo to v skutočnosti robí. MÔŽE SPÔSOBIŤ PREDÁVKOVANIE INZULÍNOM PRI NESPRÁVNOM POUŽITÍ! Zobraziť indikátory stavu na domovskej obrazovke @@ -352,14 +343,6 @@ Povoliť SMB Použiť Super Mikro Bolusy namiesto dočasných bazálov, pre zrýchleniu účinku Detekcia neoznámených jedál - Čas vrcholu IOB krivky - Vrchol krivky [min] - Vrchol - Voliteľný vrchol - Oref - Rýchlo pôsobiaci - Oref - Ultra rýchly - Oref - Lyumjev - DIA %1$f je príliš krátke - AAPS namiesto toho použilo %2$f ! Aktivovať profil NEPLATNÝ % zmena @@ -442,7 +425,6 @@ Ignorovať 5m Ignorovať 15m Ignorovať 30m - pož. Prehliadač histórie Oznámenie pri SMB Ukazovať SMB na hodinkách ako normálny bolus. @@ -523,7 +505,6 @@ Deliteľ \"bolus snooze\" Max násobiteľ denného najvyššieho bazálu Max násobiteľ súčasného bazálu - --- Typ virtuálnej pumpy Definícia pumpy Bolus: Krok =%1$s\nPredl. bolus: [Krok=%2$s, Dĺžka=%3$smin-%4$sh]\nBazál: Krok=%5$s\nDoč. bazál: %6$s (%7$s), Dĺžka=%8$smin-%9$sh\n%10$s @@ -732,7 +713,6 @@ Graf Grafové menu Vyčistiť filter - Trendová šípka Kanyla Vstup používateľa Použite hodnoty pre najväčšie jedlo, aké obvykle jete\n @@ -789,18 +769,6 @@ správny výsledok v % správny výsledok s jednotkami Nedostupný - vysoká - v rozsahu - nízka - rýchly pokles - klesajúca - pomaly klesajúca - stabilná - pomaly stúpajúca - stúpajúca - rýchlo stúpajúca - žiadny - neznámy graf kvalita glykémií prepočítané @@ -875,8 +843,6 @@ Vyššie Zobraziť záznamy uzavretého okruhu Skryť záznamy uzavretého okruhu - AAPS widget - Konfigurovať priehľadnosť Stav uzavretého okruhu Mierka grafu Profil 1 diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 32e2d82b44..67c6599a72 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -16,10 +16,6 @@ Används för att konfigurera de aktiva insticksprogrammen Inlärningsprogram Visar förutbestämda inställningar för mat i Nightscout - Insulininställning för vanliga direktverkande insuliner som Humalog, Lispro, Apidra och Novorapid/Novolog - Insulininställning för ultrasnabba insuliner, t ex Fiasp - Insulininställning för Lyumjev - Låter dig ställa in tidpunkten för toppen på insulinets aktivitet. Bör bara användas av avancerade användare Aktivera eller inaktivera implementationen som kör loopen. Synkroniserar dina data med Nightscout Så som algoritmen var definierad år 2017 @@ -166,7 +162,6 @@ Eversense-appen. Knapp 3 Enheter: Enheter - Duration Gränsvärden för visualisering Högt och lågt värde för grafen i Översikt och i klockan LÅG-markering @@ -235,7 +230,6 @@ Eversense-appen. Visa detaljerad IOB Visa IOB med bolus och basal på klocka misslyckat - kontrollera telefonen - - Patienttyp Barn Tonåring @@ -270,9 +264,6 @@ Eversense-appen. Rapportera appstart till Nightscout Avslutar appen för att inställningarna ska läsas in. Vilken typ av insulin använder du? - Novorapid, Novolog, Humalog, Apidra - Fiasp - INS Aktivera superbolus i kalkylatorn Aktiverar superbolusfunktionen i kalkylatorn. Aktivera inte innan du förstått hur den fungerar. DEN KAN ORSAKA ÖVERDOSERING AV INSULIN OM INSIKT SAKNAS OM FUNKTIONEN! Visa \"statuslampor\" på hemskärmen @@ -343,13 +334,6 @@ Eversense-appen. Aktivera SMB Använd Super Micro Bolusar istället för temp basal för snabbare resultat Avkänning av oförberedda måltider (UAM) - Peaktid för IOB-kurvan - Peaktid [min] - Free-Peak Oref - Rapid-Acting Oref - Ultra-Rapid Oref - Lyumjev - %1$f tim DIA är för kort. Använder %2$f istället! Aktivera profil OGILTIG Procent @@ -432,7 +416,6 @@ Eversense-appen. Ignorera 5 min Ignorera 15 min Ignorera 30 min - beh Historikläsare Skicka notis vid SMB Visa SMB på klockan som en standardbolus. @@ -508,7 +491,6 @@ Eversense-appen. Bolus snooze DIA divisor Multiplikator för max daglig basal (max_daily) Multiplikator för nuvarande basal (max_current) - - Typ av virtuell pump Pumpdefinition Bolus: Steg =%1$s\nFörlängd bolus: [Steg=%2$s, duration =%3$smin -%4$sh] \nBasal: Steg=%5$s\nTempbasal: %6$s (av %7$s), duration =%8$smin -%9$sh\n%10$s @@ -696,7 +678,6 @@ Eversense-appen. Graf Diagrammeny Rensa filter - Trendpil Kanyl Angivet av användare Använd värden för den största måltiden som du vanligen äter\n @@ -750,18 +731,6 @@ Eversense-appen. korrigera med % korrigera med enheter Ej tillgängligt - hög - inom målområdet - låg - sjunker snabbt - sjunker - sjunker långsamt - stabilt - stiger långsamt - stiger - stiger snabbt - ingen - okänd graf Kvalitet på BG-data omräknad diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 65e6de6ca0..a65baa0e31 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -17,10 +17,6 @@ Aktif eklentileri yapılandırmak için kullanılır Eğitim programı Nightscout\'ta tanımlanan gıda ön ayarlarını gösterir - Humalog ve NovoRapid / NovoLog için İnsülin Profili - Fiasp için insülin Profili - Lyumjev için insülin ayarı - İnsülin aktivitesinin zirvesini tanımlamanıza izin verir ve yalnızca ileri düzey kullanıcılar tarafından kullanılmalıdır. Döngüyü tetikleyen uygulamayı etkinleştirin veya devre dışı bırakın. Nightscout ile verilerinizi senkronize eder 2017\'da algoritmanın durumu @@ -171,7 +167,6 @@ Buton 3 Birim: Birim - İES Görselleştirme Aralığı Genel bakış ve akıllı saat göstergesi için yüksek ve düşük değerler DÜŞÜK işareti @@ -241,7 +236,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Ayrıntılı AİNS göster Saat arayüzü üzerinde AİNS\'i bolus ve bazal olarak ayırın başarısız - lütfen telefonu kontrol edin - n/a Hasta tipi Çocuk Ergen @@ -276,9 +270,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d NS\'a uygulama başlangıcını kaydet Ayarları uygulamak için uygulamadan çıkılıyor. Hangi tür insülin kullanıyorsunuz? - Novorapid, Novolog, Humalog - Fiasp - İNS Sihirbazda süperbolusu etkinleştir Bolus sihirbazında süperbolus işlevselliğini etkinleştirin. Gerçekten ne yaptığınızı öğrenene kadar etkinleştirmeyin. BİLİNÇSİZ KULLANILDIĞINDA AŞIRI DOZ İNSÜLIN VERİLEBİLİR! Ana ekranda durum ışıklarını göster @@ -353,14 +344,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d SMB (Super Micro Bolus) etkinleştir Daha hızlı bir etki için geçici bazal yerine Super Micro Bolus kullanın (Uam) Bildirilmemiş öğünlerin tespiti - AİNS Eğrisi Tepe Zamanı - Tepe zamanı [min] - Tepe - Serbest tepe Oref - Hızlı etkili Oref - Ultra Hızlı Oref - Lyumjev - DIA %1$f çok kısa - bunun yerine %2$f kullanıyor! Profili etkinleştir GEÇERSİZ Yüzde @@ -443,7 +426,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d 5dk yoksay 15dk yoksay 30dk yoksay - iht. Geçmiş tarayıcısı SMB\'ye (Super Micro Bolus) bildir Saatte SMB\'yi (Super Micro Bolus) standart bir bolus gibi göster. @@ -524,7 +506,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Bolus erteleme dia bölen Maks günlük güvenlik çarpanı Mevcut bazal güvenlik çarpanı - n/a Sanal pompa tipi Pompa tanımı Bolus: Adım=%1$s\nYayma Bolus: [Adım=%2$s, Süre=%3$sdk-%4$ssa]\nBazal: Adım=%5$s\nTBR: %6$s (ile %7$s), Süre=%8$sdk-%9$ssa\n%10$s @@ -733,7 +714,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Grafik Grafik menüsü Filtreyi temizle - Trend oku Kanül Kullanıcı girişi Genellikle yediğiniz en büyük yiyeceğin değerlerini kullanın\n @@ -790,18 +770,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d % ile doğru sonuç ünite ile doğru sonuç Mevcut değil - yüksek - aralık içinde - düşük - hızla düşüyor - düşüyor - yavaşça düşüyor - sabit - yavaşça yükseliyor - yükseliyor - hızla yükseliyor - yok - bilinmiyor grafik kan şekeri kalitesi tekrar hesaplandı @@ -876,8 +844,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Üstünde Döngü kayıtlarını göster Döngü kayıtlarını gizle - AAPS widget - Şeffaflığı yapılandır Döngü durumu Grafik ölçeği Profil 1 diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 56c25533c7..03b8e42c67 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -16,10 +16,6 @@ 用于配置活动插件 学习计划 显示 Nightscout 中定义的食物预设 - 胰岛素预设为 Humalog(优泌乐) 和 NovoRapid(门冬)/NovoLog(诺和锐) - Fiasp 胰岛素预设 - 预设为Lyumjev速效赖脯胰岛素 - 允许您定义胰岛素作用的峰值, 并且只应由高级用户使用 激活或停用这个工具触发闭环。 将数据与 Nightscout 同步 算法的状态在2017年 @@ -165,7 +161,6 @@ 按钮3 单位: 单位 - DIA 可视化范围 在智能手表上的图表上的高值和低值标记 低值标记 @@ -234,7 +229,6 @@ 显示详细 IOB 在手表的表盘上分别显示大剂量IOB和基础IOB 未成功-请检查手机 - 无可用 患者类型 儿童 青少年 @@ -269,9 +263,6 @@ 记录app启动事件到NS服务器 正在退出应用程序以应用设置。 你使用哪种类型的胰岛素? - 诺和锐, 门冬, 优泌乐 - Fiasp超速效 - INS 在向导中启用超级大剂量 在向导中启用 superbolus超级大剂量 功能。不要启用, 直到你了解它真正的用法。如果盲目使用, 可能会导致胰岛素过量! 在主屏幕上显示状态指示灯 @@ -344,13 +335,6 @@ 启用微型大剂量 使用微型大剂量代替使用临时基础率,更快的干预 检测未输入的膳食 - IOB 曲线峰值时间 - 峰值时间 [min] - Free-Peak Oref - 速效 Oref - 超速效 Oref - Lyumjev(超速效赖脯胰岛素) - DIA of %1$f 太短了,请使用 %2$f 代替 激活配置文件 无效 百分比 @@ -433,7 +417,6 @@ 忽略5分钟 忽略 15分钟 忽略30分钟 - 历史浏览 在 SMB 上通知 在手表上像显示常规大剂量一样显示SMB微型大剂量 @@ -509,7 +492,6 @@ 大剂量snooze 胰岛素持续作用时间除数 最大日基础率安全倍数 当前基础率安全倍数 - 无可用 虚拟泵类型 泵定义 大剂量: Step=%1$s\n扩展大剂量: [Step=%2$s, 持续时间=%3$smin-%4$sh]\n基础率: Step=%5$s\nTBR临时基础率: %6$s (by %7$s), 持续时间=%8$smin-%9$sh\n%10$s @@ -703,7 +685,6 @@ 绘图 图表菜单 清除筛选 - 趋势箭头 输注导管 用户条目 \n选择您三餐的最大碳水值和最大胰岛素剂量\n @@ -760,18 +741,6 @@ 校正结果使用% 校正结果使用单位 不可用 - - 在范围内 - - 迅速下降 - 下降 - 缓慢减少 - 稳定 - 缓慢增长 - 上升 - 快速上升 - - 未知 绘图 血糖质量 重新计算 @@ -845,7 +814,6 @@ 上方 显示闭环记录 隐藏闭环记录 - 配置透明度 闭环状态 图形缩放 配置文件 1 diff --git a/automation/src/main/res/values-cs-rCZ/strings.xml b/automation/src/main/res/values-cs-rCZ/strings.xml index c25f63dc99..e438053982 100644 --- a/automation/src/main/res/values-cs-rCZ/strings.xml +++ b/automation/src/main/res/values-cs-rCZ/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Automatická detekce senzitivity %3$s %1$s %2$s Rozdíl glykémie Rozdíl glykémie [%1$s] diff --git a/automation/src/main/res/values-da-rDK/strings.xml b/automation/src/main/res/values-da-rDK/strings.xml index 59f99c5877..fcdc6291ae 100644 --- a/automation/src/main/res/values-da-rDK/strings.xml +++ b/automation/src/main/res/values-da-rDK/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Auto sens %3$s %1$s %2$s BS forskel BS difference [%1$s] diff --git a/automation/src/main/res/values-de-rDE/strings.xml b/automation/src/main/res/values-de-rDE/strings.xml index c6e3b2bc69..c36cf231f1 100644 --- a/automation/src/main/res/values-de-rDE/strings.xml +++ b/automation/src/main/res/values-de-rDE/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Auto sens %3$s %1$s %2$s BZ-Unterschied BZ-Unterschied [%1$s] diff --git a/automation/src/main/res/values-es-rES/strings.xml b/automation/src/main/res/values-es-rES/strings.xml index 3522537a95..edcf10e1b3 100644 --- a/automation/src/main/res/values-es-rES/strings.xml +++ b/automation/src/main/res/values-es-rES/strings.xml @@ -81,7 +81,6 @@ SSID WiFi %1$s %2$s Autosens %1$s %2$s %% Autosens % - Auto sens %3$s %1$s %2$s Diferencia de glucosa Diferencia de glucosa %1$s diff --git a/automation/src/main/res/values-fr-rFR/strings.xml b/automation/src/main/res/values-fr-rFR/strings.xml index bc8aec0c4c..6d4bcaf36e 100644 --- a/automation/src/main/res/values-fr-rFR/strings.xml +++ b/automation/src/main/res/values-fr-rFR/strings.xml @@ -81,7 +81,6 @@ SSID WiFi %1$s %2$s Autosens %1$s %2$s %% Autosens % - Auto sens %3$s %1$s %2$s Delta de glycémies Delta Glyc. [%1$s] diff --git a/automation/src/main/res/values-it-rIT/strings.xml b/automation/src/main/res/values-it-rIT/strings.xml index e341ede3d4..dcf88a4b4f 100644 --- a/automation/src/main/res/values-it-rIT/strings.xml +++ b/automation/src/main/res/values-it-rIT/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Asuto sens %3$s %1$s %2$s Differenza BG Differenza BG [%1$s] diff --git a/automation/src/main/res/values-iw-rIL/strings.xml b/automation/src/main/res/values-iw-rIL/strings.xml index 48ca09ada2..07e4af6ecc 100644 --- a/automation/src/main/res/values-iw-rIL/strings.xml +++ b/automation/src/main/res/values-iw-rIL/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - חישוב רגישות אוטומטי (Autosens) %3$s %1$s %2$s הפרש רמת סוכר הפרש רמת סוכר [%1$s] diff --git a/automation/src/main/res/values-nl-rNL/strings.xml b/automation/src/main/res/values-nl-rNL/strings.xml index d4815fd566..8efbc6493d 100644 --- a/automation/src/main/res/values-nl-rNL/strings.xml +++ b/automation/src/main/res/values-nl-rNL/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Gevoeligheid %1$s %2$s %% Gevoeligheid % - Autosens %3$s %1$s %2$s BG verschil BG verschil [%1$s] diff --git a/automation/src/main/res/values-no-rNO/strings.xml b/automation/src/main/res/values-no-rNO/strings.xml index 92fd9ecf6d..02cf2f84f8 100644 --- a/automation/src/main/res/values-no-rNO/strings.xml +++ b/automation/src/main/res/values-no-rNO/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Autosens %3$s %1$s %2$s BS forskjell BS forskjell [%1$s] diff --git a/automation/src/main/res/values-ru-rRU/strings.xml b/automation/src/main/res/values-ru-rRU/strings.xml index ec29696bf0..1c257052ff 100644 --- a/automation/src/main/res/values-ru-rRU/strings.xml +++ b/automation/src/main/res/values-ru-rRU/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Автосенс %1$s %2$s %% Автосенс % - Auto sens %3$s%1$s%2$s Разница Гк Разница ГК [%1$s] diff --git a/automation/src/main/res/values-sk-rSK/strings.xml b/automation/src/main/res/values-sk-rSK/strings.xml index 13e9c9d977..8f771fdbe0 100644 --- a/automation/src/main/res/values-sk-rSK/strings.xml +++ b/automation/src/main/res/values-sk-rSK/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Automatická detekcia citlivosti %3$s %1$s %2$s Rozdiel glykémie Rozdiel glykémie [%1$s] diff --git a/automation/src/main/res/values-sv-rSE/strings.xml b/automation/src/main/res/values-sv-rSE/strings.xml index aa9770c273..98c412a7db 100644 --- a/automation/src/main/res/values-sv-rSE/strings.xml +++ b/automation/src/main/res/values-sv-rSE/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Autosens %1$s %2$s %% Autosens % - Auto sens %3$s %1$s %2$s BG-förändring BG-förändring [%1$s] diff --git a/automation/src/main/res/values-tr-rTR/strings.xml b/automation/src/main/res/values-tr-rTR/strings.xml index adafbd5e22..3b176bebaf 100644 --- a/automation/src/main/res/values-tr-rTR/strings.xml +++ b/automation/src/main/res/values-tr-rTR/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s Otoduyarlılık %1$s %2$s %% Otoduyarlılık % - Oto duyarlılık %3$s %1$s %2$s KŞ farkı KŞ farkı [%1$s] diff --git a/automation/src/main/res/values-zh-rCN/strings.xml b/automation/src/main/res/values-zh-rCN/strings.xml index 5e02878c3d..5709c59b38 100644 --- a/automation/src/main/res/values-zh-rCN/strings.xml +++ b/automation/src/main/res/values-zh-rCN/strings.xml @@ -81,7 +81,6 @@ WiFi SSID %1$s %2$s 自动传感器 %1$s %2$s %% 自动传感器 % - 自动敏感度 %3$s %1$s (%2$s BG 差异 BG 差异 [%1$s] diff --git a/core/src/main/res/values-bg-rBG/strings.xml b/core/src/main/res/values-bg-rBG/strings.xml index dd52bfa91b..475944a094 100644 --- a/core/src/main/res/values-bg-rBG/strings.xml +++ b/core/src/main/res/values-bg-rBG/strings.xml @@ -47,6 +47,7 @@ ISF (Инс.чувствителност): Базал Целeва КЗ: + Базал Инициализация ... Сериен номер Батерия @@ -105,8 +106,12 @@ Изтрий Добави нов Данните идват от различна помпа. Сменете драйвера на помпата и за да възстановите състоянието на помпата. + КЗ + Калибрация Сларма след %1$d мин Грешка в болуса. Сам провери истинската стойност на доставения инсулин + Болус подсещане + Продължителност гр. Помпата е спряна Не е конфигуриран @@ -286,10 +291,17 @@ %1$.2f ограничен до %2$.2f SMS + %1$.0f %% Базал + Базал % + потребител + Резултат: %1$s + Липсва + Сравняване на профили Апликацията изисква разрешение за bluetooth + SMS команда забранена %1$d дeн %1$d дни diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml index f05af9e3ed..b2817c72de 100644 --- a/core/src/main/res/values-cs-rCZ/strings.xml +++ b/core/src/main/res/values-cs-rCZ/strings.xml @@ -124,6 +124,22 @@ Pumpa pozastavena Není nakonfigurováno Smyčka pozastavena + Šipka trendu + Automatická detekce senzitivity + n/a + pož + rychle klesající + klesající + pomalu klesající + stabilní + pomalu stoupající + stoupající + rychle stoupající + žádný + neznámý + vysoká + v rozsahu + nízká Max bazál omezen na %1$.2f U/h: %2$s limit pumpy diff --git a/core/src/main/res/values-fr-rFR/strings.xml b/core/src/main/res/values-fr-rFR/strings.xml index 71d2f8cb87..a43315abdf 100644 --- a/core/src/main/res/values-fr-rFR/strings.xml +++ b/core/src/main/res/values-fr-rFR/strings.xml @@ -124,6 +124,22 @@ Pompe arrêtée Non configuré La Boucle est suspendue + Flèche de tendance + Auto sens + indisponible + requis + en baisse rapide + en baisse + en baisse lente + stable + en hausse lente + en hausse + en hausse rapide + aucun + inconnu + haut + dans la cible + bas Limiter le débit de basal max à %1$.2f U/h à cause de %2$s Limite de la pompe @@ -502,6 +518,7 @@ Une autre exécution d\'Autotune est détectée, l\'exécution est annulée L\'application a besoin de l\'autorisation Bluetooth + Autorisation SMS manquante %1$d jour %1$d jours diff --git a/core/src/main/res/values-no-rNO/strings.xml b/core/src/main/res/values-no-rNO/strings.xml index d94d6c6004..395f228bc0 100644 --- a/core/src/main/res/values-no-rNO/strings.xml +++ b/core/src/main/res/values-no-rNO/strings.xml @@ -114,12 +114,32 @@ Legg til ny Legg til ny over Data kommer fra forskjellige pumper. Bytt pumpevalg for å nullstille pumpens tilstand. + BS + Kalibrering Aktiver alarm om %1$d min Det er registrert en feil med bolus-leveransen. Sjekk manuelt om den er levert og hvor mye + Bolus påminnelse + Varighet g Pumpen er pauset Ikke konfigurert Loop pauset + Trend pil + Auto sens + n/a + nødv + synker raskt + synkende + synker rolig + stabilt + stiger raskt + stiger + stiger raskt + ingen + ukjent + høyt + i målområdet + lavt Begrenser maks basal dose til %1$.2f E/t på grunn av %2$s pumpebegrensning @@ -367,6 +387,7 @@ EKSPORTER INNSTILLINGER IMPORTER INNSTILLINGER TILBAKESTILL DATABASER + OPPRYDDING DATABASER EKSPORTER DATABASER IMPORTER DATABASER OTP EKSPORT @@ -497,6 +518,7 @@ Autotune kjører allerede. Kjøring avbrutt Appen trenger bluetooth tillatelse + Mangler SMS-tillatelse %1$d dag %1$d dager diff --git a/core/src/main/res/values-ru-rRU/strings.xml b/core/src/main/res/values-ru-rRU/strings.xml index 829d248bb4..88f7f49d07 100644 --- a/core/src/main/res/values-ru-rRU/strings.xml +++ b/core/src/main/res/values-ru-rRU/strings.xml @@ -114,12 +114,32 @@ Добавить новый Добавить строку сверху Данные поступают с другой помпы. Измените драйвер помпы, чтобы сбросить ее состояние. + ГК + калибровка Напомнить через %1$d мин Возможна ошибка в подаче болюса. Проверьте реальное количество поданного инсулина + Напоминание о болюсе + Длительность действия грамм Работа помпы остановлена Не сконфигурировано ЗЦ остановлен + Стрелка тренда + Auto sens + н/д + надо + быстрое падение + падение + медленное падение + стабильно + медленный рост + рост + быстрый рост + отсутствует + неизвестно + высокий + в диапазоне + низкий Макс базальный уровень ограничен до %1$.2f ед/ч вследствие %2$s лимит помпы @@ -498,6 +518,7 @@ Обнаружен другой запуск Autotune, выполнение отменено Приложению требуется разрешение Bluetooth + Отсутствует смс разрешение %1$d день %1$d дня diff --git a/core/src/main/res/values-sk-rSK/strings.xml b/core/src/main/res/values-sk-rSK/strings.xml index 3dfb1c8956..1a72088314 100644 --- a/core/src/main/res/values-sk-rSK/strings.xml +++ b/core/src/main/res/values-sk-rSK/strings.xml @@ -124,6 +124,22 @@ Pumpa pozastavená Nenakonfigurované Uzavretý okruh pozastavený + Trendová šípka + Automatická detekcia citlivosti + n/a + pož. + rýchly pokles + klesajúca + pomaly klesajúca + stabilná + pomaly stúpajúca + stúpajúca + rýchlo stúpajúca + žiadny + neznámy + vysoká + v rozsahu + nízka Max bazál obmedzený na %1$.2f JI/h: %2$s limit pumpy diff --git a/core/src/main/res/values-tr-rTR/strings.xml b/core/src/main/res/values-tr-rTR/strings.xml index a4e9c7d678..f6b04bcb2a 100644 --- a/core/src/main/res/values-tr-rTR/strings.xml +++ b/core/src/main/res/values-tr-rTR/strings.xml @@ -124,6 +124,22 @@ Pompa durduldu Yapılandırılmadı Döngü duraklatıldı + Trend oku + Oto duyarlılık + yok + iht. + hızla düşüyor + düşüyor + yavaşça düşüyor + sabit + yavaşça yükseliyor + yükseliyor + hızla yükseliyor + yok + bilinmiyor + yüksek + aralık içinde + düşük %2$s nedeniyle max bazal oranı %1$.2f Ü/s ile sınırlı pompa sınırı diff --git a/implementation/src/main/res/values-bg-rBG/strings.xml b/implementation/src/main/res/values-bg-rBG/strings.xml index 49ee870c9f..ae1fe90fe4 100644 --- a/implementation/src/main/res/values-bg-rBG/strings.xml +++ b/implementation/src/main/res/values-bg-rBG/strings.xml @@ -1,8 +1,21 @@ + xDrip+ не е инсталиран + Калибрацията е изпратена към xDrip+ + КЗ Липсват данни за КЗ + Време е за ядене + Активиране на болус съветник + Използвай напомняне за старт на хранене вместо съветника по време на висока гликемия (\"пре-болус\") + Съветник на болус + Имаш висока захар. Вместо да се яде сега, се препоръчва да се изчака за по-добра захар. Искате ли да направите корекция сега и да ви напомня кога е време за ядене? В този случай няма да бъдат записвани въглехидрати и трябва да използвате съветника отново, когато ви напомня. Време е за болус!\nВключи болус съветника и направи изчисление отново. + Командата се изпълнява в момента + Базалните стойности са под минимума. Не е зададен профил! Искане Разрешение + ААПС изисква разрешение за да може да Ви уведомява + Приложение се нуждае от достъп до местоположението Ви за сканиране и WiFi идентификация + Приложението се нуждае от разрешение да съхранява данни за да може съхранява лог файлове и експортира настройки Вашият телефон не поддържа оптимизация на батерията - може да се появят проблеми! diff --git a/implementation/src/main/res/values-fr-rFR/strings.xml b/implementation/src/main/res/values-fr-rFR/strings.xml index c103a937d3..845dda8823 100644 --- a/implementation/src/main/res/values-fr-rFR/strings.xml +++ b/implementation/src/main/res/values-fr-rFR/strings.xml @@ -10,8 +10,14 @@ Assistant bolus Vous avez une glycémie élevée. Au lieu de manger maintenant, il est recommandé d\'attendre une meilleure glycémie. Voulez-vous faire un bolus de correction maintenant et avoir une alerte quand il sera temps de manger ? Dans ce cas, aucun glucide ne sera enregistré et vous devrez utiliser l\'assistant à nouveau lorsque nous vous le rappelons. Il est temps de faire le bolus !\nExécutez l\'Assistant et faites de nouveau le calcul. + Commande exécutée à l\'instant + Le débit Basal est inférieur au minimum autorisé. Profil non accepté ! Demande Autorisation + %1$s a besoin d\'être sur la liste blanche de l\'optimisation de la batterie pour des performances correctes + L\'application a besoin de l\'autorisation d\'accès à la fenêtre système pour les notifications + L\'application a besoin de l\'autorisation de localisation pour l\'analyse BT et l\'identification WiFi + L\'application a besoin d\'une autorisation de stockage pour pouvoir stocker les fichiers journaux et les paramètres d\'exportation Erreur lors de la demande des autorisations Ce périphérique ne semble pas permettre l\'optimisation de la batterie par une liste blanche - vous pourriez rencontrer des problèmes de performance. diff --git a/implementation/src/main/res/values-no-rNO/strings.xml b/implementation/src/main/res/values-no-rNO/strings.xml index d4b08ead14..97237f8d08 100644 --- a/implementation/src/main/res/values-no-rNO/strings.xml +++ b/implementation/src/main/res/values-no-rNO/strings.xml @@ -1,9 +1,23 @@ + xDrip+ ikke installert + Kalibrering er sendt til xDrip+ + BS Mangler BS-målinger + Nå må du spise + Aktiver boluskalkulator + Bruk en påminnelse om å spise senere enn kalkulator resultatet fra wizard ved høyt blodsukker (\"pre-bolus\") + Bolusguide + Du har høyt blodsukker. I stedet for å spise nå er det bedre å utsette det til du har et lavere blodsukker. Ønsker du å sette en korrigerings bolus nå og få en påminnelse om når den er på tide å spise? I dette tilfellet vil ingen karbohydrater registreres nå, og du må bruke måltids veiviseren igjen når vi gir deg en påminnelse. Tid for bolus!\nStart bolus-veiviser og gjør beregning på nytt. + Kommandoen utføres akkurat nå + Basalverdi under minimum. Profilen settes ikke! Forespørsel Tillatelse + %1$s trenger tillatelse for å omgå automatisk batterisparefunksjonene for å fungere tilfredsstillende + App trenger tillatelse til å bruke Varslinger for å vise meldinger + App trenger tilgang til Posisjon for å søke etter Bluetooth og Wifi enheter + App trenger tilgang til Lagring for lagre logg filer og eksportere innstillinger Feil under spørring etter tillatelser Det ser ikke ut som mobilen støtter registrering av apper som unntas fra batterioptimalisering - du kan oppleve ytelsesproblemer. diff --git a/implementation/src/main/res/values-ru-rRU/strings.xml b/implementation/src/main/res/values-ru-rRU/strings.xml index 16b19604e8..1808c9be74 100644 --- a/implementation/src/main/res/values-ru-rRU/strings.xml +++ b/implementation/src/main/res/values-ru-rRU/strings.xml @@ -1,9 +1,23 @@ + xdrip+ не установлен + Калибровка отправлена на xDrip+ + ГК Пропущенные данные СК + Пора есть + Вкл помощник болюса + Воспользуйтесь напоминанием для того, чтобы начать есть позже, вместо того, чтобы задействовать помощник болюса на высоких значениях ГК (\"пре-болюс\") + Помощник болюса + У вас высокая гликемия. Лучше подождать, чем есть сейчас. Хотите сделать болюс на коррекцию и установить напоминание о приеме пищи? В этом случае углеводы не будут записаны и после напоминания надо будет снова воспользоваться помощником. Пора дать болюс!\nЗапустите помощник болюса и повторите расчет. + Команда выполняется + значение базала ниже минимума. профиль не создан! Запрос Права доступа + для корректной работы %1$s необходимо включить в белый список оптимизации батареи + Приложению требуется разрешение системного окна для уведомлений + Приложению требуется разрешение на доступ к местоположению для сканирования BT и идентификации WiFi + Приложение требует разрешения на доступ к записи в память, чтобы хранить файлы журналов и настройки экспорта Ошибка при запросе разрешения Это устройство не поддерживает меню оптимизации батареи - могут быть проблемы с производительностью. diff --git a/openhumans/src/main/res/values-bg-rBG/strings.xml b/openhumans/src/main/res/values-bg-rBG/strings.xml index eab54d5cf6..09a29d9416 100644 --- a/openhumans/src/main/res/values-bg-rBG/strings.xml +++ b/openhumans/src/main/res/values-bg-rBG/strings.xml @@ -15,7 +15,15 @@ Излязохте от \"Open Humans\". Натиснете тук за да влезете отново, ако това не е било нарочно. Качи сега + Следващ Условия за ползване + Това е отворен код, който ще копира данните ви в Open Humans. Ние не запазваме никакви права да споделяме вашите данни с трети страни без изричното ви разрешение. Данните, които проектът и приложението получават, се идентифицират чрез случаен идентификатор на потребител и ще бъдат надеждно предадени на Open Humans акаунт с вашето разрешение за този процес. Можете да спрете качването и да изтриете данните за качване по всяко време чрез www.openhumans.org. + Болуси + Въглехидрати + Настройки + Модел + Nightscout адрес + Разбирам и съм съгласен. Откажи Затвори diff --git a/openhumans/src/main/res/values-no-rNO/strings.xml b/openhumans/src/main/res/values-no-rNO/strings.xml index 7fbd6a45ac..26d42bcaa7 100644 --- a/openhumans/src/main/res/values-no-rNO/strings.xml +++ b/openhumans/src/main/res/values-no-rNO/strings.xml @@ -12,6 +12,7 @@ Last opp kun ved mobillading Laster opp til Open Humans… Open Humans notifikasjon + AndroidAPS laster opp til Open Humans. Dette kan ta en stund. Du har blitt logget ut fra Open Humans Klikk her for å logge inn igjen hvis dette ikke var hensikten. Last opp nå diff --git a/plugins/src/main/res/values-af-rZA/strings.xml b/plugins/src/main/res/values-af-rZA/strings.xml index 20fec0ff5f..24a640a3b6 100644 --- a/plugins/src/main/res/values-af-rZA/strings.xml +++ b/plugins/src/main/res/values-af-rZA/strings.xml @@ -37,4 +37,18 @@ IAB: Bolus: Basale: + + DIA + Insulien voorkeure vir Humalog en NovoRapid / NovoLog + Insulien voorkeure vir Fiasp + Laat jou toe om die piek van die insulien aktiwiteit definieer en behoort slegs gebruik te word deur gevorderde gebruikers + INS + IAB kurwe piek tyd + Piek tyd [min] + Vry-piek Oref + Snelaksie Oref + Ultra-Snel Oref + DIA van %1$f is te kort - %2$f in stede gebruik! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-bg-rBG/strings.xml b/plugins/src/main/res/values-bg-rBG/strings.xml index d1c9478802..b536fe1804 100644 --- a/plugins/src/main/res/values-bg-rBG/strings.xml +++ b/plugins/src/main/res/values-bg-rBG/strings.xml @@ -6,6 +6,7 @@ от приложението AUTHENTICATOR за: %1$s , последвано от PIN Допълнителен PIN в края на токен Допълнителни цифри, които следва да бъдат залепени в края на всяка генерирана еднократна парола + Настройка на удостоверителя Код за проверка: OTP + PIN Кодът за проверката се състои от 6 цифри, от приложението за аудиентикация (известно като OTP), следвани от 3 или повече цифри на задължителния PIN. @@ -20,9 +21,13 @@ 3. Тест на еднократна парола Нулиране на удостоверители На всеки следящ телефона инсталирайте приложение Аутентификатор, който поддържа RFC 6238 ТОТР токени. Популярни безплатни приложения:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Грешен код. Командата не е изпълнена. + Изтичане на времето на предишна комуникация с помпата Потребител Разрешени телефонни номера +XXXXXXXXXX;+YYYYYYYYYY + За да доставите болус от %1$.2fЕ отговорете с код %2$s + За да стартирате болус от %1$.2fЕ отговорете с код %2$s Зa zадаване на временна цел %1$s отговорете с код %2$s За да спрете временната цел отговорете с код %1$s За да изключите услугата за отдалечен SMS контрол отговорете с код %1$s.\n\nИмайте предвид, че можете да го активирате само от AAPS смартфона. @@ -81,8 +86,33 @@ Невалиден текст на съобщение Изпращане на SMS, ако помпата е недостъпна Докладвай недостъпна помпа + Грешен формат + КЗ: + Последна КЗ: Изменение (делта): IOB: Болус: Базал: + преди %1$d мин + Изключен (%1$d мин) + Четенето на статуса се провали + Създаден запис - Промяна на профил + Продължителността на временния база; трябва да бъде кратна на %1$d минути и по-голяма от 0. + + DIA + Lyumjev + Действие на инсулините Humalog и NovoRapid / NovoLog + Действие на инсулин Fiasp + Действие на инсулин Lyumjev + Позволява да зададете сами пика на инсулиновата активност (не използвайте, ако сте нови потребители) + ИНС + Пик на кривата на IOB + Време на пик [мин.] + Връх + Със свободен пик по Oref + Бързодействащ по Oref + Ултра бързодействащ по Oref + DIA от %1$f е твърде кратка - използвай %2$f вместо това! + Novorapid Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-ca-rES/strings.xml b/plugins/src/main/res/values-ca-rES/strings.xml index eb3dd14d3e..78f41fcc5f 100644 --- a/plugins/src/main/res/values-ca-rES/strings.xml +++ b/plugins/src/main/res/values-ca-rES/strings.xml @@ -85,4 +85,20 @@ IOB: Bolus: Basal: + + DIA (Durada de l\'Acció de la Insulina) + Lyumjev + Configuració preestablerta per insulina Humalog i NovoRapid/NovoLog + Configuració preestablerta per insulina Fiasp + Configuració preestablerta per insulina Lyumjev + Permet definir el pic d\'activitat de la insulina. A utilitzar només per usuaris avançats + INS + Pic de la corba IOB + Temps del pic [min] + Oref sense pic + Oref ràpida + Oref ultra ràpida + DIA de %1$f massa curt - utilitzant %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-cs-rCZ/strings.xml b/plugins/src/main/res/values-cs-rCZ/strings.xml index 078f37105c..ad4b11c47e 100644 --- a/plugins/src/main/res/values-cs-rCZ/strings.xml +++ b/plugins/src/main/res/values-cs-rCZ/strings.xml @@ -102,4 +102,21 @@ Přepnutí profilu vytvořeno Trvání dočasného bazálu musí být násobkem %1$d minut a musí být větší než 0. QR kód pro nastavení jednorázového hesla + + DIA + Lyumjev + Předvolba pro Novorapid + Předvolba pro Fiasp + Předvolba pro Lyumjev + Možnost definice vrcholu účinnosti inzulínu pro pokročilé uživatele + INZ + Čas vrcholu IOB křivky + Vrchol křivky [min] + Vrchol + Volitelný vrchol - Oref + Rychle působící - Oref + Ultra rychlý - Oref + DIA %1$f je příliš krátké - použito %2$f ! + Novorapid + Fiasp diff --git a/plugins/src/main/res/values-da-rDK/strings.xml b/plugins/src/main/res/values-da-rDK/strings.xml index 25ab50b94b..9193f943b8 100644 --- a/plugins/src/main/res/values-da-rDK/strings.xml +++ b/plugins/src/main/res/values-da-rDK/strings.xml @@ -88,4 +88,21 @@ Bolus: Basal: QR-kode til opsætning af engangs kodeord + + DIA + Lyumjev + Insulin forudindstillet til Humalog og NovoRapid / NovoLog + Insulinforudindstilling til Fiasp + Insulin forudindstillet til Lyumjev + Giver dig mulighed for at definere spidsbelastningen af insulin-aktiviteten og bør kun bruges af avancerede brugere + INS + IOB Kurve Peak-Tid + Spidstidspunkt [min] + Top + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + DIA af %1$f for kort - bruger %2$f i stedet! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-de-rDE/strings.xml b/plugins/src/main/res/values-de-rDE/strings.xml index 638e5ecaac..19ccf51a53 100644 --- a/plugins/src/main/res/values-de-rDE/strings.xml +++ b/plugins/src/main/res/values-de-rDE/strings.xml @@ -86,4 +86,21 @@ Bolus: Basal: QR Code für einmaliges Passwort einrichten + + DIA + Lyumjev + Insulinprofil für Humalog und NovoRapid / NovoLog + Insulinprofil für Fiasp + Insulin-Voreinstellung für Lyumjev + Erlaubt dir, das Wirkmaximum der Insulinaktivität zu definieren, und sollte nur von erfahrenen Anwendern genutzt werden + INS + Wirkungshoch der IOB-Kurve + Wirkungshoch [min] + Gipfel + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + DIA von %1$f ist zu kurz - AAPS nutzt stattdessen %2$f! + NovoRapid, NovoLog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-el-rGR/strings.xml b/plugins/src/main/res/values-el-rGR/strings.xml index 7acb63bd0d..7797e3d5f1 100644 --- a/plugins/src/main/res/values-el-rGR/strings.xml +++ b/plugins/src/main/res/values-el-rGR/strings.xml @@ -64,4 +64,18 @@ IOB: Bolus: Βασικός Ρυθμός: + + Η ινσουλίνη που ορίζεται Humalog και NovoRapid / NovoLog + Η ινσουλίνη που ορίζεται για Fiasp + Προκαθορισμός ινσουλίνης για την Lyumjev + Σας επιτρέπει να ορίσετε το μέγιστο της δράσης της ινσουλίνης και πρέπει να χρησιμοποιείται μόνο από προχωρημένους χρήστες + INS + Μέγιστη τιμή καμπύλης IOB + Μέγιστο καμπύλης [λεπτά] + Προαιρετικά-αιχμή Oref + Γρήγορη δράση - Oref + Έξτρα Γρήγορη δράση - Oref + DIA για %1$f πολύ μικρή - χρησιμοποιήστε %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-es-rES/strings.xml b/plugins/src/main/res/values-es-rES/strings.xml index e16216dcb7..5a43c7a81c 100644 --- a/plugins/src/main/res/values-es-rES/strings.xml +++ b/plugins/src/main/res/values-es-rES/strings.xml @@ -89,4 +89,21 @@ Bolo: Dosis Basal: Código QR para la configuración de la contraseña de un sólo uso + + DIA + Lyumjev + Ajustes de insulina preestablecidos para Humalog y NovoRapid/NovoLog + Ajuste de insulina preestablecido para Fiasp + Ajuste de insulina preestablecido para Lyumjev + Permite personalizar el pico de acción máxima de la insulina. Debe ser utilizado únicamente por usuarios avanzados + INS + Tiempo del pico máximo de la curva de IOB + Tiempo del pico máximo de acción de la insulina [min] + Pico + Personalizar Pico + Acción Rápida + Acción Ultra Rápida + DIA de %1$f demasiado corto - usando %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-fr-rFR/strings.xml b/plugins/src/main/res/values-fr-rFR/strings.xml index cd997ae3ec..816d24675b 100644 --- a/plugins/src/main/res/values-fr-rFR/strings.xml +++ b/plugins/src/main/res/values-fr-rFR/strings.xml @@ -7,6 +7,7 @@ depuis l\'application Authenticator pour : %1$s suivie du code PIN Code PIN obligatoire à la fin de l\'OTP Chiffres supplémentaires qui doivent être mémorisés et collés à la fin de chaque OTP généré + Configuration de l\'Authentificateur Code à vérifier : OTP + PIN Le code de vérification est composé de 6 chiffres affichés par l\'application Authenticator (appelée OTP) suivi du code PIN obligatoire constitué de 3 chiffres ou plus. @@ -23,9 +24,13 @@ Réinitialiser les authentificateurs Sur chaque téléphone suiveur, installez une appli. Authentificateur qui prend en charge les jetons RFC 6238 TOTP. Les applications libres populaires sont:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator En réinitialisant l\'Authentificateur, vous invalidez tous les authentificateurs déjà initialisés. Vous devrez les reconfigurer ! + Code incorrect. Commande annulée. + Délai d\'attente pour finir la communication précédente avec la pompe Patient Numéros de tél autorisés +XXXXXXXXXX;+YYYYYYYYYY + Pour injecter le bolus de %1$.2f U, renvoyez le code %2$s + Pour injecter le bolus repas de %1$.2f U, renvoyez le code %2$s Pour définir la cible temp %1$s, renvoyez le code %2$s Pour annuler la cible temp, renvoyez le code %1$s Pour désactiver les commandes à distance SMS, renvoyez le code %1$s.\n\nGardez à l\'esprit que vous ne pourrez le réactiver que directement à partir de l\'application AAPS du smartphone maître. @@ -84,9 +89,34 @@ Message invalide Envoyer un SMS si l\'événement Pompe hors de portée est déclenché Signaler Pompe hors de portée + Format incorrect + Gly: + Dernière Gly: Delta: IA: Bolus: Basal: + il y a %1$d min + Suspendu (%1$d m) + La lecture du statut a échoué + Changement de profil effectué + La durée du DBT doit être un multiple de %1$d minutes et supérieure à 0. Code QR pour configurer un mot de passe à usage unique + + DAI + Lyumjev + Réglages pour les insulines Humalog et NovoRapid / NovoLog + Réglages pour l\'insuline Fiasp + Réglages pour l\'insuline Lyumjev + Permet de définir le pic de l’activité de l’insuline et ne doit être utilisé que par les utilisateurs avancés + INS + Durée du Pic de la Courbe IA + Temps du Pic [min] + Pic + Profil d\'insuline ajustable Oref + Insuline à Action Rapide Oref + Insuline Ultra Rapide Oref + Durée d’Action pour %1$f trop courte - utiliser %2$f à la place ! + Novorapid, Novolog, Humalog, Apidra + Fiasp diff --git a/plugins/src/main/res/values-ga-rIE/strings.xml b/plugins/src/main/res/values-ga-rIE/strings.xml index 33c47da0fc..98bc143759 100644 --- a/plugins/src/main/res/values-ga-rIE/strings.xml +++ b/plugins/src/main/res/values-ga-rIE/strings.xml @@ -12,4 +12,12 @@ IOB: Bólas: Bunaidh: + + DIA + Lyumjev + INS + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + Fiasp diff --git a/plugins/src/main/res/values-hr-rHR/strings.xml b/plugins/src/main/res/values-hr-rHR/strings.xml index 0fef4c22e5..624efa2c5e 100644 --- a/plugins/src/main/res/values-hr-rHR/strings.xml +++ b/plugins/src/main/res/values-hr-rHR/strings.xml @@ -6,4 +6,5 @@ Poništavanjem autentifikatora činite sve već osigurane autentifikatore nevažećima. Morat ćete ih ponovno postaviti! Delta: QR kod za postavljanje jednokratne lozinke + diff --git a/plugins/src/main/res/values-hu-rHU/strings.xml b/plugins/src/main/res/values-hu-rHU/strings.xml index bf1e1af079..c06005a667 100644 --- a/plugins/src/main/res/values-hu-rHU/strings.xml +++ b/plugins/src/main/res/values-hu-rHU/strings.xml @@ -3,4 +3,10 @@ OTP + PIN Bázis: + + DIA + Lyumjev + Ultra-Rapid Oref + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-it-rIT/strings.xml b/plugins/src/main/res/values-it-rIT/strings.xml index 5da346df04..848b36516e 100644 --- a/plugins/src/main/res/values-it-rIT/strings.xml +++ b/plugins/src/main/res/values-it-rIT/strings.xml @@ -88,4 +88,21 @@ Bolo: Basale: Codice QR per configurare OTP + + DIA + Lyumjev + Preset per insulina Humalog e NovoRapid / NovoLog + Preset per insulina Fiasp + Preset per insulina Lyumjev + Ti consente di definire il picco di attività dell\'insulina e dovrebbe essere usato solo dagli utenti avanzati + INS + Tempo picco Curva IOB + Tempo del picco [min] + Picco + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + DIA di %1$f troppo breve - uso %2$f. + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-iw-rIL/strings.xml b/plugins/src/main/res/values-iw-rIL/strings.xml index bac97e5bd2..8b87aa3169 100644 --- a/plugins/src/main/res/values-iw-rIL/strings.xml +++ b/plugins/src/main/res/values-iw-rIL/strings.xml @@ -86,4 +86,21 @@ בולוס: אינסולין בזאלי: ברקוד QR ליצירת סיסמה חד פעמית + + משך פעילות אינסולין + Lyumjev + הגדרת אינסולין ל-Humalog ו- NovoRapid / Novolog + הגדרת אינסולין מסוג Fiasp + הגדרת אינסולין מסוג Lyumjev + מאפשר להגדיר את שיא פעילות האינסולין, לשימוש על ידי משתמשים מתקדמים בלבד + אינסולין + שעת שיא של עקומת IOB + זמן שיא [min] + שיא + Oref שיא חופשי + Oref אינסולין מהיר + Oref אינסולין אולטרה מהיר + DIA במשך %1$f הוא קצר מדי - משתמש ב-%2$f במקום! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-ko-rKR/strings.xml b/plugins/src/main/res/values-ko-rKR/strings.xml index 7a9ff2acbb..bda785e95c 100644 --- a/plugins/src/main/res/values-ko-rKR/strings.xml +++ b/plugins/src/main/res/values-ko-rKR/strings.xml @@ -85,4 +85,20 @@ IOB: Bolus: Basal: + + DIA + Lyumjev + 휴마로그와 노보래피드에 대한 인슐린 설정 + 피아스프에 대한 인슐린 설정 + Lyumjev에 대한 인슐린 설정 + 인슐린활동의 피크를 직접 정의할 수 있습니다. 고급 사용자만 사용해야 합니다. + INS + IOB 커브 피크 시간 + 피크 시간 [min] + 사용자지정-피크 Oref + 초속효성 Oref + 초-초속효성 Oref + DIA %1$f는 너무 짧습니다. 대신 %2$f을 사용하세요! + 노보래피드, 휴마로그, 에피드라 + 피아스프(Fiasp) diff --git a/plugins/src/main/res/values-lt-rLT/strings.xml b/plugins/src/main/res/values-lt-rLT/strings.xml index c2f9b647d9..196bc05bf2 100644 --- a/plugins/src/main/res/values-lt-rLT/strings.xml +++ b/plugins/src/main/res/values-lt-rLT/strings.xml @@ -85,4 +85,20 @@ AIO: Bolusas: Valandinė bazė: + + IVT + Lyumjev + Nustatymai Humalog ir NovoRapid / NovoLog insulinams + Nustatymai Fiasp insulinui + Nustatymai Lyumjev insulinui + Leidžia pasirinkti insulino veikimo piką ir turėtų būti naudojama tik patyrusių vartotojų + INS + AIO kreivės pikas + Piko laikas [min] + Oref be piko + Greito veikimo Oref + Staigaus veikimo Oref + IVT %1$f per trumpa - bus naudojama %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-nl-rNL/strings.xml b/plugins/src/main/res/values-nl-rNL/strings.xml index f1324be33d..21ccfc3420 100644 --- a/plugins/src/main/res/values-nl-rNL/strings.xml +++ b/plugins/src/main/res/values-nl-rNL/strings.xml @@ -87,4 +87,21 @@ Bolus: Basaal: QR Code voor het instellen van een eenmalig wachtwoord + + DIA + Lyumjev + Insuline instelling voor Humalog en NovoRapid / NovoLog + Insuline instelling voor Fiasp + Insuline instelling voor Lyumjev + Hiermee kan je de piek van de insulineactiviteit definiëren, mag alleen worden gebruikt door gevorderde gebruikers + INS + IOB curve piek tijd + Piek tijd [min] + Piek + Free-Peak Oref + Snel-werkende Oref + Ultra-Rapid Oref + DIA van %1$f te kort - %2$f wordt inplaats gebruikt! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-no-rNO/strings.xml b/plugins/src/main/res/values-no-rNO/strings.xml index 822428ff96..0d3c3de6d6 100644 --- a/plugins/src/main/res/values-no-rNO/strings.xml +++ b/plugins/src/main/res/values-no-rNO/strings.xml @@ -7,6 +7,7 @@ fra Authenticator appen for: %1$s etterfulgt av PIN PIN kode som legges til på slutten av token Ytterligere sifre som MÅ memoreres og legges til på slutten av hvert generert engangspassord + Oppsett for 2 faktor autentisering Kode som skal kontrolleres: OTP + PIN Bekreftelseskoden består av 6 sifre som vises av Authenticator appen (kjent som OTP) etterfulgt av 3 eller flere siffer for obligatorisk PIN-kode. @@ -18,12 +19,18 @@ Er du sikker på at du vil kopiere OTP hemmelig kode til utklippstavlen?\n\nDu trenger bare det hvis din Authenticator app har problemer med skanning av QRCode og du ønsker å legge den inn manuelt, eller du ønsker å konfigurere maskinvare OTP-kode ved hjelp av dedikert app. OTP hemmelig kode (i base32-format) er eksportert og kopiert til utklippstavlen. Lim den inn i Authenticator app eller hardware OTP system! 1. Installer Authenticator + 2. Skann kode for å sette opp AndroidAPS OTP koder 3. Test engangspassord Tilbakestill Authenticators I hver følger telefon installerer du en Authenticator-app som støtter RFC 6238 TOTP token. Populære gratis apper er:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Ved å tilbakestille autentiseringen vil du gjøre alle lagrede autentiseringer ugyldige. Du må sette alle opp på nytt igjen! + Feil kode. Kommandoen avbrutt. + Tidsavbrudd fordi vi ventet på avslutning av forrige pumpekommunikasjon Bruker Godkjente mobilnumre +XXXXXXXXXX;+YYYYYYYYYY + For å levere bolus på %1$.2fE, svar med kode %2$s + For å levere måltidsbolus på %1$.2fE, svar med kode %2$s For å sette Temp Target på %1$s, svar med kode %2$s For å avbryte Temp Target, svar med kode %1$s For å deaktivere fjernstyring via SMS-meldinger, svar med kode %1$s.\n\nHusk at du vil kunne reaktivere den igjen kun fra AAPS hovedtelefon. @@ -82,9 +89,34 @@ Ugyldig innhold i meldingen Send SMS hvis det ikke oppnås kontakt med pumpa Rapporter når kontakt med pumpe ikke oppnås + Feil format + BS: + Siste BS: Delta: IOB: Bolus: Basal: + %1$d min siden + Pauset (%1$d m) + Feil i lesing av status + Profilbytte opprettet + Temp basal varighet må oppgis i antall %1$d minutter og større enn 0. QR-kode for oppsett av engangspassord + + DIA + Lyumjev + Insulininnstillinger for Humalog og NovoRapid / NovoLog + Insulininnstillinger for Fiasp + Insulininnstillinger for Lyumjev + Lar deg definere toppen på insulinaktiviteten og skal kun brukes av avanserte brukere + INS + IOB-kurvens topptid + Topptid [min] + Topp + Egendefinert topp Oref + Hurtigvirkende Oref + Ultrahurtig Oref + DIA på %1$f er for kort - bruker %2$f i stedet! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-pl-rPL/strings.xml b/plugins/src/main/res/values-pl-rPL/strings.xml index 06e2d417f8..453ac0ff80 100644 --- a/plugins/src/main/res/values-pl-rPL/strings.xml +++ b/plugins/src/main/res/values-pl-rPL/strings.xml @@ -85,4 +85,21 @@ IOB: Bolus: Baza: + + DIA + Lyumjev + Profil insulinowy dla Humalog i Novorapid / NovoLog + Profil insulinowy dla Fiasp + Profil insulinowy dla Lyumjev + Pozwala na określenie czasu wartości szczytowej działania insuliny i powinno być używane tylko przez zaawansowanych użytkowników + INS + IOB Czas piku krzywej działania insuliny + Czas piku [min] + Szczyt + Swobodny-Pik Oref + Szybko-Działający Oref + Ultra-Szybki Oref + DIA %1$f zbyt krótki - przyjmuję %2$f w zamian! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-pt-rBR/strings.xml b/plugins/src/main/res/values-pt-rBR/strings.xml index e863e6991c..c18bf9ff9c 100644 --- a/plugins/src/main/res/values-pt-rBR/strings.xml +++ b/plugins/src/main/res/values-pt-rBR/strings.xml @@ -89,4 +89,21 @@ Bolus: Basal: Código QR para configuração de senha de uso único + + DIA + Lyumjev + Predefinição de Insulina para Humalog e NovoRapid / NovoLog + Pré-ajuste de Insulina para Fiasp + Configuração pre-definida para a Insulina Lyumyev + Permite que você defina o pico da atividade de insulina, deve ser usado apenas por usuários avançados + INS + Tempo Pico da curva de IOB + Tempo Pico [min] + Pico + Oref Pico-Livre + Oref Ação Rápida + Ultra-Rapid Oref + Duração de Acção da Insulina (DIA) de %1$f demasiado curto - corrigido para %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-pt-rPT/strings.xml b/plugins/src/main/res/values-pt-rPT/strings.xml index fff9faba46..092481e3c2 100644 --- a/plugins/src/main/res/values-pt-rPT/strings.xml +++ b/plugins/src/main/res/values-pt-rPT/strings.xml @@ -85,4 +85,20 @@ IA: Bólus: Basal: + + DIA + Lyumjev + Predefinição de Insulina Humalog e NovoRapid / NovoLog + Predefinição de Insulina Fiasp + Predefinição para Insulina Lyumjev + Permite definir o pico de atividade da insulina e deve ser usado somente por usuários avançados + INS + Tempo do Pico da curva de IA + Tempo Pico [min] + Oref Pico-Livre + Oref Acção-Rápida + Oref Ultra-Rápida + Duração de Acção da Insulina (DIA) de %1$f demasiado curto - corrigido para %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-ro-rRO/strings.xml b/plugins/src/main/res/values-ro-rRO/strings.xml index bc762bd907..90d0953391 100644 --- a/plugins/src/main/res/values-ro-rRO/strings.xml +++ b/plugins/src/main/res/values-ro-rRO/strings.xml @@ -85,4 +85,20 @@ IOB: Bolus: Bazală: + + DIA + Lyumjev + Setări prestabilite pentru insulinele Humalog sau NovoRapid / NovoLog + Setări prestabilite pentru Fiasp + Setări prestabilite pentru Lyumjev + Vă permite definirea vârfului activităţii insulinei şi ar trebui folosit doar de către utilizatorii avansaţi + INS + Curbă timp vârf IOB + Timp vârf [min] + Oref Vârf-Liber + Oref Insulină-Rapidă + Oref Insulină-UltraRapidă + DIA din %1$f prea scurtă - se folosește %2$f în schimb! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-ru-rRU/strings.xml b/plugins/src/main/res/values-ru-rRU/strings.xml index f6f72bcd77..79a2e767b0 100644 --- a/plugins/src/main/res/values-ru-rRU/strings.xml +++ b/plugins/src/main/res/values-ru-rRU/strings.xml @@ -7,6 +7,7 @@ из приложения Authenticator для %1$s и дополните пином в конце Дополнительный обязательный пин-код в конце маркера Дополнительные цифры, которые должны быть запомнены и добавлены в конце каждого сгенерированного одноразового пароля + Настройка аутентификации Код для проверки: OTP + ПИН-код Проверочный код состоит из 6 цифр, отображаемых приложением Authenticator (известным как OTP), за которым следует 3 или более цифр обязательного PIN-кода. @@ -23,9 +24,13 @@ Сбросить аутентификаторы В каждом отслеживающем телефоне установите приложение Authenticator, поддерживающее маркеры TOTP RFC 6238. Популярные бесплатные приложения: \n Authy\n Google Authenticator\n LastPass Authenticator\n FreeOTP Authenticator После сброса аутентификатора вы делаете все созданные идентификаторы недействительными. Вам нужно будет снова создать их! + Неверный код. Команда отменена. + Время ожидания окончания предыдущего соединения с помпой истекло Пользователь разрешенные телефонные номера + XXXXXXXXXX; + YYYYYYYYYY + Для подачи болюса %1$.2fед ответьте кодом %2$s + Для подачи болюса %1$.2fед ответьте кодом %2$s Чтобы установить временную цель %1$s ответьте кодом %2$s Чтобы отменить временную цель ответьте кодом %1$s Чтобы отключить службу удаленных SMS-сообщений ответьте кодом %1$s.\n\n Имейте в виду, что вы сможете вновь активировать ее только с основного телефона AAPS. @@ -84,9 +89,34 @@ Недопустимое тело сообщения Отправить SMS, если инициируется запись о недоступности помпы Сообщить о недоступности помпы + Неверный формат + ГК: + Предыдущая ГК: дельта: IOB: активный инсулин болюс: базал: + %1$dмин. назад + Остановлен на(%1$d мин) + Статус чтения: неудача + Переключатель профиля создан + Длительность временного базала TBR должна быть кратной %1$d минутам и больше 0. QR код для введения временного пароля + + Время действия инсулина DIA + Lyumjev + Предустановки для Humalog и Novorapid / Novolog + Предустановки для Fiasp + Предустановки для Lyumjev + Позволяет самостоятельно задавать пик активности инсулина - только для опытных пользователей + ИНС + Время пика активного инс IOB + Время пика [min] + Пик + Свободный от пиков Oref + Быстро действующий Oref + Сверхбыстрый Oref + Значение времени действия инс %1$f слишком мало - применено %2$f! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-sk-rSK/strings.xml b/plugins/src/main/res/values-sk-rSK/strings.xml index a1c75045c7..355c27e341 100644 --- a/plugins/src/main/res/values-sk-rSK/strings.xml +++ b/plugins/src/main/res/values-sk-rSK/strings.xml @@ -102,4 +102,21 @@ Prepnutie profilu vytvorené Trvanie dočasného bazálu musí byť násobkom %1$d minút a musí byť väčšie ako 0. QR kód pre nastavenie jednorázového hesla + + DIA + Lyumjev + Predvoľba pre inzulín Humalog a Novorapid + Predvoľba pre inzulín Fiasp + Predvoľba pre inzulín Lyumjev + Umožňuje definovať vrchol účinnosti inzulínu a malo by byť používané iba pokročilými užívateľmi + INZ + Čas vrcholu IOB krivky + Vrchol krivky [min] + Vrchol + Voliteľný vrchol - Oref + Rýchlo pôsobiaci - Oref + Ultra rýchly - Oref + DIA %1$f je príliš krátke - AAPS namiesto toho použilo %2$f ! + Novorapid, Humalog + Fiasp diff --git a/plugins/src/main/res/values-sr-rCS/strings.xml b/plugins/src/main/res/values-sr-rCS/strings.xml index c06688ea2e..1e2f84fd68 100644 --- a/plugins/src/main/res/values-sr-rCS/strings.xml +++ b/plugins/src/main/res/values-sr-rCS/strings.xml @@ -43,4 +43,9 @@ IOB: Bolus: Basal: + + Unapred podešena postavka insulina za Humalog i NovoRapid / NovoLog + Unapred podešena postavka insulina za Fiasp + Unapred podešena postavka insulina za Lyumjev + Omogućava definisanje vrhunca aktivnosti insulina i trebaju ga koriste samo napredni korisnici diff --git a/plugins/src/main/res/values-sv-rSE/strings.xml b/plugins/src/main/res/values-sv-rSE/strings.xml index ee3658d266..bc6a547866 100644 --- a/plugins/src/main/res/values-sv-rSE/strings.xml +++ b/plugins/src/main/res/values-sv-rSE/strings.xml @@ -85,4 +85,20 @@ IOB: Bolus: Basal: + + Duration + Lyumjev + Insulininställning för vanliga direktverkande insuliner som Humalog, Lispro, Apidra och Novorapid/Novolog + Insulininställning för ultrasnabba insuliner, t ex Fiasp + Insulininställning för Lyumjev + Låter dig ställa in tidpunkten för toppen på insulinets aktivitet. Bör bara användas av avancerade användare + INS + Peaktid för IOB-kurvan + Peaktid [min] + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + %1$f tim DIA är för kort. Använder %2$f istället! + Novorapid, Novolog, Humalog, Apidra + Fiasp diff --git a/plugins/src/main/res/values-tr-rTR/strings.xml b/plugins/src/main/res/values-tr-rTR/strings.xml index 950efffb5b..81d93c2022 100644 --- a/plugins/src/main/res/values-tr-rTR/strings.xml +++ b/plugins/src/main/res/values-tr-rTR/strings.xml @@ -7,6 +7,7 @@ authenticator uygulamasından %1$s için PIN girin İlave zorunlu şifre (PIN) Oluşturulan Her Tek Kullanımlık Şifrenin sonunda ezberlenmesi ve yapıştırılması gereken ek şifre + Kimlik doğrulayıcı (OTP-Authenticator) kurulumu Kontrol edilecek kod: OTP + PIN Doğrulama kodu, Authenticator uygulaması (OTP olarak bilinir) tarafından görüntülenen 6 haneden ve ardından 3 veya daha fazla zorunlu PIN hanesinden oluşur. @@ -23,9 +24,13 @@ Doğrulayıcıları (Authenticators) Sıfırla Her takipçi telefonunda, RFC 6238 TOTP belirteçlerini destekleyen Kimlik Doğrulayıcı uygulamasını yükleyin. Popüler ücretsiz uygulamalar şunlardır:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator Kimlik doğrulayıcıyı sıfırlayarak, önceden sağlanmış tüm doğrulayıcıları geçersiz kılarsınız. Onları tekrar kurmanız gerekecek! + Hatalı kod. Komut iptal edildi. + Önceki pompa iletişiminin bitmesini beklerken zaman aşımı Kullanıcı İzinli telefon numaraları +XXXXXXXXXX;+YYYYYYYYYY + %1$.2fÜ Bolus gönderilecek, kod ile cevap ver %2$s + %1$.2fU Yemek bolusu göndermek için %2$s koduyla yanıt verin Geçici Hedefi %1$s yapmak için %2$s koduyla yanıt verin Geçici Hedefi iptal etmek için %1$s koduyla yanıt verin SMS Uzak Hizmet desteğini devre dışı bırakmak için %1$s koduyla yanıt verin.\n\nBu hizmeti yalnızca AAPS yüklü ana telefondan yeniden etkinleştirebileceğinizi unutmayın. @@ -84,9 +89,34 @@ Geçersiz mesaj Pompa ulaşılamazsa SMS gönder Pompaya ulaşılamadığını bildir + Yanlış Format + KŞ: + Son KŞ: Delta: AİNS: Bolus: Bazal: + %1$ddak önce + (%1$d dk) Duraklatıldı + Durum okuması başarısız oldu + Profil değiştirme yapıldı + GBO süresi %1$d dakikanın katı ve 0\'dan büyük olmalıdır. Tek kullanımlık şifre kurulumu için QR Kodu + + İES + Lyumjev + Humalog ve NovoRapid / NovoLog için İnsülin Profili + Fiasp için insülin Profili + Lyumjev için insülin ayarı + İnsülin aktivitesinin zirvesini tanımlamanıza izin verir ve yalnızca ileri düzey kullanıcılar tarafından kullanılmalıdır. + İNS + AİNS Eğrisi Tepe Zamanı + Tepe zamanı [min] + Tepe + Serbest tepe Oref + Hızlı etkili Oref + Ultra Hızlı Oref + DIA %1$f çok kısa - bunun yerine %2$f kullanıyor! + Novorapid, Novolog, Humalog + Fiasp diff --git a/plugins/src/main/res/values-zh-rCN/strings.xml b/plugins/src/main/res/values-zh-rCN/strings.xml index ca3e93e362..5ab95e4e08 100644 --- a/plugins/src/main/res/values-zh-rCN/strings.xml +++ b/plugins/src/main/res/values-zh-rCN/strings.xml @@ -86,4 +86,20 @@ 大剂量: 基础率: 用于安装一次性随机验证码的二维码 + + DIA + Lyumjev(超速效赖脯胰岛素) + 胰岛素预设为 Humalog(优泌乐) 和 NovoRapid(门冬)/NovoLog(诺和锐) + Fiasp 胰岛素预设 + 预设为Lyumjev速效赖脯胰岛素 + 允许您定义胰岛素作用的峰值, 并且只应由高级用户使用 + INS + IOB 曲线峰值时间 + 峰值时间 [min] + Free-Peak Oref + 速效 Oref + 超速效 Oref + DIA of %1$f 太短了,请使用 %2$f 代替 + 诺和锐, 门冬, 优泌乐 + Fiasp超速效 diff --git a/pump/combo/src/main/res/values-af-rZA/strings.xml b/pump/combo/src/main/res/values-af-rZA/strings.xml index c4439cf2e1..f0a74d7f81 100644 --- a/pump/combo/src/main/res/values-af-rZA/strings.xml +++ b/pump/combo/src/main/res/values-af-rZA/strings.xml @@ -3,6 +3,7 @@ Pomp Integrasie met Accu-Chek Combo pompe, vereis dat ruffy geïnstalleer is Programmeer pomp vir bolusing Staat + Aktiwiteit Geen verbinding vir %1$d min %1$d%% (%2$d min oorblywend) Inisialiseer tans @@ -49,4 +50,5 @@ TBR telling Bolus gestaak Staak bolus + Nooit diff --git a/pump/combo/src/main/res/values-bg-rBG/strings.xml b/pump/combo/src/main/res/values-bg-rBG/strings.xml index 2e184e645b..9b5b14b905 100644 --- a/pump/combo/src/main/res/values-bg-rBG/strings.xml +++ b/pump/combo/src/main/res/values-bg-rBG/strings.xml @@ -51,4 +51,10 @@ Брой TBR Болусът е спрян Спиране на болус + Брой комуникационни грешки + Покажи брой комуникационни грешки + Покажи броя грешки докато комуникира с Ruffi. В повечето случаи, ако има една или повече грешки грешка сепрепоръчва рестарт. + Никога + Когато има грешка + Винаги diff --git a/pump/combo/src/main/res/values-ca-rES/strings.xml b/pump/combo/src/main/res/values-ca-rES/strings.xml index e513f2af5e..90930e41e6 100644 --- a/pump/combo/src/main/res/values-ca-rES/strings.xml +++ b/pump/combo/src/main/res/values-ca-rES/strings.xml @@ -51,4 +51,5 @@ Nr. de TBR Bolus aturat Aturant bolus + Mai diff --git a/pump/combo/src/main/res/values-cs-rCZ/strings.xml b/pump/combo/src/main/res/values-cs-rCZ/strings.xml index 5301ba10a3..df3b0c3d33 100644 --- a/pump/combo/src/main/res/values-cs-rCZ/strings.xml +++ b/pump/combo/src/main/res/values-cs-rCZ/strings.xml @@ -17,7 +17,7 @@ Požadovaná operace není pumpou podporována Nebezpečné použití: extended nebo multiwave bolus je aktivní. Pumpa byla vypnuta jen na 6 hodin. Povolené jsou pouze normální bolusy. Nebezpečné použití: pumpa má nastavený jiný bazální profil než první. Smyčka byla zakázána. Nastavte první profil a znovu načtěte. - Bolus stejné velikosti už byl během poslední minuty požadován. Jako preventivní ochrana před zdvojeným bolusem byla operace zakázána. + Během posledních dvou minut již byl požadován bolus o stejné velikosti. Jako preventivní ochrana před zdvojeným bolusem a chybám byla operace zakázána. Teď Načítání historie pumpy Nastavení bazálního profilu diff --git a/pump/combo/src/main/res/values-el-rGR/strings.xml b/pump/combo/src/main/res/values-el-rGR/strings.xml index 19f9e93b0a..7dd3c26239 100644 --- a/pump/combo/src/main/res/values-el-rGR/strings.xml +++ b/pump/combo/src/main/res/values-el-rGR/strings.xml @@ -50,4 +50,5 @@ Αριθμός TBR Το bolus σταμάτησε Το bolus σταματάει + Ποτέ diff --git a/pump/combo/src/main/res/values-ga-rIE/strings.xml b/pump/combo/src/main/res/values-ga-rIE/strings.xml index 3ea04e700d..51f3d46c65 100644 --- a/pump/combo/src/main/res/values-ga-rIE/strings.xml +++ b/pump/combo/src/main/res/values-ga-rIE/strings.xml @@ -1,2 +1,30 @@ - + + Cláir Caidéil bólas + Stáit + Gníomhaíocht + Níl nasc le haghaidh %1$d nóim + %1$d%% (%2$d nóim fágtha) + Tosaithe + Ar fionraí ag earráid + Ar fionraí ag úsáideoir + Ag reáchtáil + Cealú BRS + Socrú BRS (%1$d%% / %2$d nóim) + Ag bólas (%1$.1f A) + Athnuaigh + Anois + Léigh stair caidéil + Socrú próifíl bunaidh + Is leibhéal cartús íseal + Is ceallraí Caidéil íseal + Íseal + Folamh + Gnáth + Is nuashonrú gá clog Caidéil + Léigh próifíl bunaidh + Athnuaigh caidéil stáit + Ag féachaint d\'athruithe stair + Bólas stopadh + Ag stopadh bólas + diff --git a/pump/combo/src/main/res/values-hr-rHR/strings.xml b/pump/combo/src/main/res/values-hr-rHR/strings.xml index c4ed9adf68..4d82db6368 100644 --- a/pump/combo/src/main/res/values-hr-rHR/strings.xml +++ b/pump/combo/src/main/res/values-hr-rHR/strings.xml @@ -1,4 +1,6 @@ Integracija za pumpu Accu-Check Combo, zahtjeva instalaciju ruffy aplikacije + Nisko + Nikada diff --git a/pump/combo/src/main/res/values-hu-rHU/strings.xml b/pump/combo/src/main/res/values-hu-rHU/strings.xml index 3ea04e700d..c73ea0f047 100644 --- a/pump/combo/src/main/res/values-hu-rHU/strings.xml +++ b/pump/combo/src/main/res/values-hu-rHU/strings.xml @@ -1,2 +1,40 @@ - + + Accu-Chek Combo pumpák kezeléséhez ruffy telepítése szükséges + Pumpa programozása bólushoz + Állapot + Nincs kapcsolat %1$d perce + Inicializálás + Hiba miatt felfüggesztve + Felhasználó által felfüggesztve + ÁB törlése + ÁB beállítása (%1$d%% / %2$d perc) + Bólus beadása (%1$.1f E) + Frissítés + A kért műveletet nem támogatja a pumpa + Most + Pumpa előzmények lekérése + Bázisprofil beállítása + Ürülő tartály + Pumpa eleme merülőben + Pumpa hibát jelez E%1$d: %2$s + Alacsony + Üres + Normál + Pumpa idő frissítése szükséges + Pumpa nem elérhető. Bólus nem került beadásra + Bólus beadása nem sikerült. Úgy tűnik, hogy nem került bólus beadásra. A biztonság érdekében ellenőrizze a pumpát, hogy elkerülje a dupla bólust, majd ismételt bólust. A hibák elkerülése érdekében a bólusokat a rendszer nem próbálja újra automatikusan beadni. + Hiba miatt a %1$.2f E bólusból csak %2$.2f E került beadásra. Ellenőrizze a pumpát és tegye meg a megfelelő intézkedéseket. + A bólus beadása és a pumpaelőzmények ellenőrzése nem sikerült, kérjük, ellenőrizze a pumpát. Ha bólus beadása megtörtént, akkor az felvételre kerül majd a kezelések közé a pumpához való következő kapcsolódáskor. + Nincs elég inzulin a bólushoz a tartályban + Érvénytelen pumpabeállítás, nézze meg a dokumentációt és ellenőrizze az ACCU-CHECK 360 Configuration Software alkalmazással, hogy a Quick Info menü neve QUICK INFO. + Bázisprofil lekérése + Pumpa állapot frissítése + Változások előzményekben ellenőrzése + \n\ndokumentáció:\nhttps://androidaps.readthedocs.io\n\nfacebook:\nhttps://www.facebook.com/groups/AndroidAPSUsers + Bólusok száma + ÁB-k száma + Bólus leállítva + Bólus leállítása + Soha + diff --git a/pump/combo/src/main/res/values-ko-rKR/strings.xml b/pump/combo/src/main/res/values-ko-rKR/strings.xml index da062674be..7323c66450 100644 --- a/pump/combo/src/main/res/values-ko-rKR/strings.xml +++ b/pump/combo/src/main/res/values-ko-rKR/strings.xml @@ -3,6 +3,7 @@ 아큐-첵 Combo 펌프와 연동, ruffy 설치 필요 Bolus 주입을 위한 펌프 프로그래밍 상태 + 활동 %1$d분 동안 연결되지 않음 %1$d%% (%2$d분 남음) 초기화중 @@ -49,4 +50,5 @@ 임시기초주입 수 Bolus 중지됨 Bolus 중지중 + 절대 diff --git a/pump/combo/src/main/res/values-lt-rLT/strings.xml b/pump/combo/src/main/res/values-lt-rLT/strings.xml index 56aa4d18dd..cbafab893f 100644 --- a/pump/combo/src/main/res/values-lt-rLT/strings.xml +++ b/pump/combo/src/main/res/values-lt-rLT/strings.xml @@ -51,4 +51,10 @@ LBD skaičius Bolusas sustabdytas Bolusas stabdomas + Comm. Klaidų skaičius + Rodyti com. klaidų skaičius + Rodo klaidų skaičių bendraujant su Ruffy. Daugeliu atvejų skaičius, didesnis nei 0, reiškia „Ruffy“ ryšio problemas (gali prireikti paleisti iš naujo). + Niekada + Kai klaida + Visada diff --git a/pump/combo/src/main/res/values-no-rNO/strings.xml b/pump/combo/src/main/res/values-no-rNO/strings.xml index d4e77f09b0..83750a4a09 100644 --- a/pump/combo/src/main/res/values-no-rNO/strings.xml +++ b/pump/combo/src/main/res/values-no-rNO/strings.xml @@ -33,25 +33,25 @@ Bolus avbrutt. Det virker som ingen bolus er levert. For å være sikker, sjekk pumpen for å unngå levering av dobbel bolus og gjør evt et nytt forsøk. For å unngå feil vil systemet aldri prøve å levere ny bolus. Bare %1$.2f E av bolusdosen på %2$.2f E ble levert på grunn av en feil. Sjekk pumpen for å kontrollere dette og iverksett nødvendige tiltak. Levering av bolusdose og kontroll av pumpens historikk feilet. Vennligst sjekk pumpen. Hvis en bolus ble levert vil den automatisk bli lagt til ved neste tilkobling til pumpen. - Ikke nok insulin til bolus i ampullen + Ikke nok insulin i ampullen til å gi bolus Ugyldig oppsett av pumpen. Les dokumentasjonen og sjekk at Quick Info menyen heter QUICK INFO ved hjelp av 360 programvaren. Leser basalprofil Pumpe historikken har blitt endret siden bolus kalkuleringen ble utført. Bolus har ikke blitt levert. Vennligst rekalkuler om bolus fortsatt er nødvendig. - Bolus har blitt levert, men det oppsto en feil ved loggføring i behandlinger. Dette kan oppstå hvis to små bolus på samme størrelse blir levert i løpet av to minutter. Vennligst sjekk pumpe historikken og behandlinger logg, og bruk Careportal for å legge til de manglende behandlingene. Pass på at du ikke legger til to identiske behandlinger på samme minutt. + Bolus har blitt levert, men det oppsto en feil ved loggføring i behandlinger. Dette kan oppstå hvis to små bolus på samme størrelse blir levert i løpet av to minutter. Vennligst sjekk pumpe historikken og behandlinger loggen, og bruk Careportal for å legge til de manglende behandlingene. Pass på at du ikke legger til to identiske behandlinger på samme minutt. Avviser høy temp target siden kalkuleringen ikke tok hensyn til nylige endringer i pumpe historikken Oppdaterer pumpestatus Basal dosen i pumpen har blitt endret og vil i løpet av kort tid bli oppdatert - Basal raten i pumpen er endret, men feilet i å lese ny verdi + Basalsats endret i pumpe, men lesing av den feilet Sjekker for endringer i historikken - Flere boluser levert i samme minutt og med samme insulinmengde ble importert. Bare en av doseringene ble lagt til i behandlinger. Vennligst sjekk pumpen og legg til manuelt ekstra bolus doseringer i Careportal. Ikke legg til flere boluser i samme minutt. + Flere boluser levert i samme minutt og med samme insulinmengde ble importert. Bare en av doseringene ble lagt til i behandlinger. Vennligst sjekk pumpen og legg manuelt til ekstra bolus doseringer i Careportal. Ikke legg til flere boluser i samme minutt. \n\ndokumentasjon:\nhttps://androidaps.readthedocs.io\n\nfacebook:\nhttps://www.facebook.com/groups/AndroidAPSUsers Den siste bolus er eldre enn 24t eller er i fremtiden. Vennligst sjekk at datoen i pumpen er korrekt. Tid/dato for levert bolus i pumpen er trolig feil, og IOB beregningen blir da feil. Vennligst sjekk pumpens tid/dato. Antall boluser - Antall temp basaler + Antall temp basaler TBR Bolus stoppet Stopper bolus - Komm. Feiltelling + Komm. feiltelling Vis komm. feiltelling Viser antall feil i kommunikasjonen med Ruffy. Hvis høyere tall enn 0 vises innebærer det problemer med Ruffy kommunikasjonen og en omstart kan være nødvendig. Aldri diff --git a/pump/combo/src/main/res/values-pl-rPL/strings.xml b/pump/combo/src/main/res/values-pl-rPL/strings.xml index fac6f9dd6a..55264325e4 100644 --- a/pump/combo/src/main/res/values-pl-rPL/strings.xml +++ b/pump/combo/src/main/res/values-pl-rPL/strings.xml @@ -51,4 +51,5 @@ Obliczenia TBR Bolus zatrzymany Zatrzymuję bolus + Nigdy diff --git a/pump/combo/src/main/res/values-pt-rPT/strings.xml b/pump/combo/src/main/res/values-pt-rPT/strings.xml index f81d4c879d..0cfe15cecf 100644 --- a/pump/combo/src/main/res/values-pt-rPT/strings.xml +++ b/pump/combo/src/main/res/values-pt-rPT/strings.xml @@ -51,4 +51,5 @@ Contagem DBT O bolus parou A parar o bolus + Nunca diff --git a/pump/combo/src/main/res/values-ro-rRO/strings.xml b/pump/combo/src/main/res/values-ro-rRO/strings.xml index a967362540..a306c975ad 100644 --- a/pump/combo/src/main/res/values-ro-rRO/strings.xml +++ b/pump/combo/src/main/res/values-ro-rRO/strings.xml @@ -51,4 +51,5 @@ Total RBTuri Bolus oprit Se oprește bolusul + Niciodată diff --git a/pump/combo/src/main/res/values-ru-rRU/strings.xml b/pump/combo/src/main/res/values-ru-rRU/strings.xml index 3b397051e1..056c1c92f6 100644 --- a/pump/combo/src/main/res/values-ru-rRU/strings.xml +++ b/pump/combo/src/main/res/values-ru-rRU/strings.xml @@ -3,7 +3,7 @@ Интеграция с помпой Accu-Chek Combo, требует наличия утилиты Ruffy Помпа программируется для болюса Состояние - Нагрузка + Активность Нет связи в течение %1$d мин %1$d%% (%2$d мин осталось) Инициализация @@ -28,10 +28,10 @@ Пусто Нормальный Необходимо обновить часы помпы - Предупреждение об отмене скорости временного базала было подтверждено + Предупреждение об отмене скорости временного базала подтверждено Не удалось подключиться к помпе. Болюс не подан Подача болюса не состоялась. Чтобы удостовериться, проверьте помпу во избежание двойного болюса и повторите подачу. Для защиты от ложных срабатываний болюсы не повторяются автоматически. - Только %1$.2f ед. из запрошенного болюса %2$.2f ед. было подано из-за ошибки. Пожалуйста, проверьте помпу, чтобы удостовериться в этом и принять соответствующие меры. + Подано только %1$.2f ед. из запрошенного болюса %2$.2f ед. из-за ошибки. Пожалуйста, проверьте помпу, чтобы удостовериться в этом и принять соответствующие меры. Подача болюса и проверка истории помпы не состоялись, пожалуйста проверьте помпу. Если болюс был подан, он будет добавлен в назначения во время следующего соединения с помпой. В резервуаре недостаточно инсулина для болюса Недопустимые установки помпы, проверьте документацию и убедитесь, что меню Quick Info называется QUICK INFO, используя приложение 360 для конфигурации помпы. @@ -52,7 +52,7 @@ Болюс остановлен Остановка болюса Ошибок связи - Показать количество ошибок связи + Показать отсчет ошибок связи Показывает количество ошибок связи с Ruffy. В большинстве случаев число выше 0 означает проблемы коммуникации с Ruffy (может потребоваться перезапуск). Никогда При ошибке diff --git a/pump/combo/src/main/res/values-tr-rTR/strings.xml b/pump/combo/src/main/res/values-tr-rTR/strings.xml index 889c8e4a69..a96f6aac7f 100644 --- a/pump/combo/src/main/res/values-tr-rTR/strings.xml +++ b/pump/combo/src/main/res/values-tr-rTR/strings.xml @@ -1,6 +1,6 @@ - Accu-Chek Combo pompalar için pompa entegrasyonu, ruffy yüklü olması gerektirir + Accu-Chek Combo pompaları pompa entegrasyonu için ruffy yüklenmesi gerekir Pompa bolus vermek için programlanıyor Durum Aktivite @@ -10,9 +10,9 @@ Hatadan dolayı durduruldu Kullanıcı tarafından durduruldu Çalışıyor - TBR (Geçici Bazal Oranı) İptal ediliyor - TBR(Geçici Bazal Oranı) ayarı (%1$d%% / %2$d dak) - Bolus (%1$.1f Ü) teslim ediliyor + GBO İptal ediliyor + GBO ayarlanıyor (%1$d%% / %2$d dak) + Bolus iletimi (%1$.1f Ü) Yenileniyor... İstenen işlem pompa tarafından desteklenmiyor Güvenli olmayan kullanım: yayma veya çoklu yayma boluslar aktif. Döngü 6 saat boyunca düşük moda alındı. Bu modda yalnızca normal boluslar desteklenir, program otomatik düzeltme yapmaz. @@ -28,14 +28,14 @@ Boş Normal Pompa saati güncellemesi gerekli - TBR İPTAL EDİLDİ uyarısı onaylandı - Pompaya ulaşılamadı. Bolus verilmedi + GBO İPTAL EDİLDİ uyarısı onaylandı + Pompaya ulaşılamadı. Bolus iletilmedi Bolus iletimi başarısız oldu. Bolus verilmemiş görünüyor. Çift bolus gönderimini önlemek için lütfen pompayı kontrol edin ve gerekirse tekrar bolus gönderin. Yazılımsal hatalara karşı bolus iletimi otomatik olarak yeniden denenmez. - Bir hata nedeniyle %2$.2f U istenen bolusun sadece %1$.2f U gönderildi.Bunu doğrulamak ve uygun önlemleri almak için lütfen pompayı kontrol edin. + Bir hata nedeniyle %2$.2f Ü istenen bolus %1$.2f Ü gönderildi. Bunu doğrulamak ve uygun önlemleri almak için lütfen pompayı kontrol edin. Bolus iletimi ve pompa geçmişinin doğrulanması başarısız oldu, lütfen pompayı kontrol edin. Eğer bolus iletilmişse, pompaya bir sonraki bağlantıda tedavilere eklenecektir. Rezervuarda bolus için yeterli insülin yok Geçersiz pompa kurulumu, belgeleri kontrol edin ve 360 konfigürasyon yazılımını kullanarak Quick info menüsünün QUICK INFO olarak adlandırıldığını doğrulayın. - Bazal oranı profili okunuyor + Bazal profili okunuyor Bolus hesaplaması yapıldıktan sonra pompa geçmişi değişti. Bolus teslim edilmedi. Bir bolus hala gerekli ise lütfen yeniden hesaplayın. Bolus başarıyla iletildi, ancak tedavi girişi eklenemedi. Bu, son iki dakika içinde aynı boyutta iki küçük bolus verilirse meydana gelebilir. Lütfen pompa geçmişini ve tedavi girişlerini kontrol edin ve eksik girişleri eklemek için Tedavi Portalını kullanın. Tam olarak aynı dakika ve aynı miktarda herhangi bir giriş eklemediğinizden emin olun. Hesaplama, yakın zamanda değiştirilen pompa geçmişini dikkate almadığı için yüksek geçici bazal reddediliyor @@ -46,9 +46,9 @@ Aynı dakika içinde aynı miktarda birden fazla bolus içe aktarıldı. Tedavilere sadece bir kayıt eklenebildi. Lütfen pompayı kontrol edin ve Careportal sekmesini kullanarak manuel olarak bir bolus kaydı ekleyin. Diğer boluslardan farklı zamana sahip bir bolus kaydı eklediğinizden emin olun. \n\ndocumentation:\nhttps://androidaps.readthedocs.io\n\nfacebook:\nhttps://www.facebook.com/groups/AndroidAPSUsers Son bolus 24 saatten eski veya ileri tarihli. Lütfen pompa üzerindeki tarihin doğru ayarlandığını kontrol edin. - Pompada iletilen bolusun saati/tarihi yanlış görünüyor, IOB büyük olasılıkla yanlış. Lütfen pompa saatini/tarihini kontrol edin. - Bolus sayısı - TBR (GBO) Geçici Bazal Oranı sayısı + Pompada iletilen bolusun saati/tarihi yanlış görünüyor, AİNS büyük olasılıkla yanlış. Lütfen pompa saatini/tarihini kontrol edin. + Bolus Sayımı + GBO sayımı Bolus durdu Bolus durdurma İletişim Hata sayısı diff --git a/pump/dana/src/main/res/values-af-rZA/strings.xml b/pump/dana/src/main/res/values-af-rZA/strings.xml index 3ea04e700d..a08087ceac 100644 --- a/pump/dana/src/main/res/values-af-rZA/strings.xml +++ b/pump/dana/src/main/res/values-af-rZA/strings.xml @@ -1,2 +1,96 @@ - + + Paring + Geen toestel gevind so ver + Paring OK + Paring tyd verstreke + Wag vir paring op pomp + Dana + Max bolus skending + Opdrag fout + Spoedfout + Insulien limiet skending + Versoek: %1$.2fU Gelewer: %2$.2fU Fout kode: %3$s + Waarde nie behoorlik gestel + Stel basale stap tot 0.01 U/h + Verwerk gebeurtenis + Uitgebreide boluses op pomp aktiveer + Gelewer + Gestaak + Onondersteunde pomp firmware + Pomp fout + Battery laag + Pomp afskakeling + Pomp Battery leeg + Verstopping + Leë stoor + Bloed suiker meting alarm + Oorblywende insulien vlak + Verkry pomp status + Verkry verlengde bolus status + Verkry bolus status + Verkry tydelike basale status + Kry pomp instellings + Verkry pomp tyd + Enorme tydsverskil + Groot tydverskil: \nTyd in pomp is uit met meer as 1,5 uur. \nVerstel asb die tyd per hand op die pomp en maak seker dat lees die geskiedenis van die pomp nie onverwagte gedrag veroorsaak. \nAs moontlik, verwyder die geskiedenis vanaf die pomp voor die verandering van die tyd of versper die geslote lus vir een DIA na die laaste verkeerde geskiedenis inskrywing maar minimum een DIA van nou. + Verbind asseblief jou pomp met jou selfoon! + Naderende insulien daaglikse limiet + Begin bolus aflewering + Wag tans vir bolus se einde. Oorblywende %1$d sec. + Stop tydelike basale + Stel verlengde bolus + Stop verlengde bolus + Outobywerking basale tariewe + Stel tydelike basale + Wag vir tydsinkronisasie (%1$d sec) + Verkeerde pomp wagwoord! + Alarms + Basale ure + Boluses + Karbohidrate + Daaglikse insulien + Foute + Glukose + Hervul + Opgeskort + Prima + Gebruiker opsies + Vertoon tyd formaat + Knoppie rol + Biep op knoppie druk + Alarm + Klank + Vibreer + Beide + LCD aantyd [seconds] + Agterlig aantyd [seconds] + Glukose eenhede + Afsluit [hours] + Lae reserwe [Units] + Stoor opsies te pomp + Pomp integrasie vir DANA Diabecare R pompe + Pomp integrasie vir Koreanse DANA Diabecare R pompe + Pomp integrasie vir DANA Diabecare R pompe met opgegradeerde firmware + DANA + Geen bluetooth passtuk gevind + Geselekteerde toestel nie gevind nie + Verander in modus van U/d U/h op pomp + DanaR Koreaans + DanaR + Pomp drywer gekorrigeer + DanaRv2 + Versper EasyUI modus in pomp + Instelling van basale profiel het misluk + Bluetooth status + Pomp IAB + Firmware + Dana pomp instellings + Aan + Af + DanaR Bluetooth-toestel + Pomp wagwoord + Gebruik verlengde boluses vir >200%% + Bolus spoed + Geselekteerde pomp + diff --git a/pump/dana/src/main/res/values-bg-rBG/strings.xml b/pump/dana/src/main/res/values-bg-rBG/strings.xml index 600425914c..7a0a76ae7e 100644 --- a/pump/dana/src/main/res/values-bg-rBG/strings.xml +++ b/pump/dana/src/main/res/values-bg-rBG/strings.xml @@ -116,4 +116,5 @@ 1: (12 цифри) 2: (8 цифри) Базал/Болус стъпка + Възможно е въглехидратите да не са се запазили. Моля, проверете ръчно и ги запишете отново ако е необходимо. diff --git a/pump/dana/src/main/res/values-ca-rES/strings.xml b/pump/dana/src/main/res/values-ca-rES/strings.xml index 3ea04e700d..a79b98c0d6 100644 --- a/pump/dana/src/main/res/values-ca-rES/strings.xml +++ b/pump/dana/src/main/res/values-ca-rES/strings.xml @@ -1,2 +1,116 @@ - + + Sincronitzant + Cap dispositiu trobat fins ara + Sincronització OK + Temps d\'espera excedit en sincronitzar + Esperant sincronitació a la bomba + Dana + Superat el bolus màxim + Ordre errònia + Error de velocitat + Superat el límit d\'insulina + Demanat: %1$.2fU Lliurat: %2$.2fU Codi error: %3$s + Valor no configurat correctament + Configurar increment de basal a 0.01 U/h + Reiniciar informació de sincronització? + %1$s\nModel: %2$02X\nProtocol: %3$02X\nCodi: %4$02X + Processant event + Activar bolus estesos a la bomba + Lliurat + Aturat + Firmware de bomba no compatible + Error bomba + Bateria Baixa + Lliurant menys que ràtio basal preconfigurada + Bomba aturada + Bateria de la bomba descarregada + Oclusió + Reservori buit + Comprovar eix + Màx. basal + Màx. diari + Alerta glucèmia + Insulina que queda al reservori + Bolus perdut + Info de sincronització no vàlida. Sol·licitant nova sincronització + Obtenint estat bomba + Obtenint estat bolus estès + Obtenint estat bolus + Obtenint estat basal temporal + Obtenint configuració bomba + Obtenint hora bomba + Gran diferència d\'hora + Gran diferència d\'hora:\nLa hora a la bomba és més d\'1.5h diferent.\nSi us plau configureu l\'hora manualment a la bomba i assegureu-vos que la lectura de l\'historial de la bomba no causa efectes inesperats.\nSi és possible, elimineu l\'historial de la bomba abans de canviar-li l\'hora o desactiveu el llaç tancat durant les hores que tingueu configurat el DIA (Durada de l\'Acció de la Insulina) després de la darrera entrada errònia de l\'historial però al menys un període DIA des d\'ara. + Sincronitzeu la bomba amb el telèfon! + Arribant al límit d\'insulina diari + Iniciant lliurament de bolus + Esperant final de bolus. Queden %1$d segons. + Aturant basal temporal + Establint bolus estès + Aturant bolus estès + Actualitzant ràtios basal + Establint basal temporal + Esperant sincronització de l\'hora (%1$d sec) + Contrasenya bomba incorrecta! + Alarmes + Hores basal + Bolus + Carbohidrats + Insulina diària + Errors + Glucèmia + Reomplir + Suspendre + Encebar + Opcions d\'usuari + Format de visualització de l\'hora + Desplaçament de botons + Bip en clicar botó + Alarma + So + Vibració + Ambdós + Temps pantalla LCD encesa [seconds] + Temps llum de fons encesa [seconds] + Unitats glucèmia + Apagat [hours] + Reservori baix [Units] + Gravar opcions a bomba + Sincronització de bombes model DANA Diabecare R + Sincronització de bombes model DANA Diabecare R Corea + Sincronització de bombes model DANA Diabecare R amb firmware actualitzat + DANA + No s\'ha trobat cap adaptador Bluetooth + No s\'ha trobat el dispositiu seleccionat + Canviar mode de U/d a U/h a la bomba + DanaR Coreana + DanaR + Controlador de bomba corregit + DanaRv2 + Desactivar mode EasyUI a la bomba + Error en configurar el perfil basal + Estat Bluetooth + IOB Bomba + Firmware + Configuració bomba Dana + 12h + 24h + On + Off + Dispositiu Bluetooth DanaR + Contrasenya bomba (només v1) + Contrasenya bomba + Utilitzar bolus estesos durant >200%% + Velocitat bolus + Bomba seleccionada + Enregistrar canvi de reservori + Afegir event \"Canvi d\'insulina\" al portal de cures quan es detecti a l\'historial + Enregistrar canvi d cànula + Afegir event \"Canvi de cànula\" al portal de cures quan es detecti a l\'historial + PIN1 + PIN2 + Cliqueu OK a la bomba\ni introduïu els 2 números mostrats\nManteniu la pantalla de la bomba engegada clicant el botó \"minus\" fins que hagueu introduït el codi. + 1: (12 dígits) + 2: (8 dígits) + diff --git a/pump/dana/src/main/res/values-el-rGR/strings.xml b/pump/dana/src/main/res/values-el-rGR/strings.xml index 3ea04e700d..cfc4c72df9 100644 --- a/pump/dana/src/main/res/values-el-rGR/strings.xml +++ b/pump/dana/src/main/res/values-el-rGR/strings.xml @@ -1,2 +1,92 @@ - + + Δεν βρέθηκε συσκευή ακόμα + Σύζευξη ΟΚ + Τέλος χρόνου σύζευξης + Περιμένετε για σύζευξη με αντλία + Dana + Υπέρβαση μέγιστου bolus + Σφάλμα εντολής + Σφάλμα ταχύτητας + Υπέρβαση του ορίου ινσουλίνης + Απαιτείται: %1$.2fU Παραδόθηκε: %2$.2fU Κωδικός σφάλματος: %3$s + Η τιμή δεν μπήκε σωστά + Ρυθμίστε το βήμα βασικού στο 0.01 U/h + Επεξεργασία συμβάντος + Ενεργοποιήστε εκτεταμμένο bolus στην αντλία + Παραδόθηκε + Σταμάτησε + Μη υποστηριζόμενη έκδοση στην αντλία + Σφάλμα Αντλίας + Χαμηλή Μπαταρία + Αντλία κλειστή + Μπαταρία αντλίας Αποφορτίστηκε + Έμφραξη + Άδεια αμπούλα + Ειδοποίηση υψηλής τιμής σακχάρου + Υπόλοιπο Ινσουλίνης + Φόρτωση κατάστασης αντλίας + Κατάσταση εκτεταμένου bolus + Κατάσταση bolus + Λήψη κατάστασης Προσ Ρυθμού + Λήψη ρυθμίσεων αντλίας + Λήψη ώρας αντλίας + Μεγάλη χρονική διαφορά + Μεγάλη χρονική διαφορά:\nΗ ώρα στην αντλία διαφέρει περισσότερο από 1,5 ώρες. \nΠαρακαλώ ρυθμίστε την ώρα χειροκίνητα στην αντλία και βεβαιωθείτε ότι η ανάγνωση του ιστορικού από την αντλία δεν προκαλεί απροσδόκητη συμπεριφορά. \nΑν είναι δυνατόν, αφαιρέστε το ιστορικό από την αντλία πριν την αλλαγή της ώρας ή κλείστε το κλειστό κύκλωμα για μία DIA μετά την τελευταία λάθος καταχώρηση ιστορικού αλλά κατ΄ελάχιστο μία DIA από τώρα. + Παρακαλώ συνδέστε την αντλία στο τηλέφωνο! + Φτάνετε το ημερήσιο όριο ινσουλίνης + Έναρξη bolus + Αναμονή για το τέλος του bolus. Απομένουν %1$d δευτερόλεπτα. + Σταμάτημα Προσ Ρυθμού + Ρύθμιση εκτεταμμένου bolus + Σταμάτημα εκτεταμμένου bolus + Ενημέρωση Βασικού ρυθμού + Ρύθμιση Προσ Ρυθμού + Αναμονή για συγχρονισμό ώρας (%1$d δευτ) + Λάθος κωδικός αντλίας! + Συναγερμοί + Ώρες Βασικού + Bolus + Υδατάνθρακες + Ημερήσια Ινσουλίνη + Σφάλματα + Γλυκόζη + Ξαναγέμισμα + Αναστολή + Πλήρωση + Ρυθμίσεις χρήστη + Μορφή ώρας + Πλήκτρα κύλισης + Ήχος πλήκτρων + Συναγερμός + Ήχος + Δόνηση + Και τα δύο + Χρόνος ενεργής οθόνης [seconds] + Χρόνος οπίσθιου φωτισµού [seconds] + Μονάδες γλυκόζης + Αποθήκευση ρυθμίσεων στην αντλία + Ολοκλήρωση αντλίας για τις αντλίες Dana Diabecare R + Ολοκλήρωση αντλίας για τις εγχώριες αντλίες Dana Diabecare R + Ολοκλήρωση αντλίας για τις αντλίες Dana Diabecare R με αναβαθμισμένο λογισμικό + DANA + Δεν βρέθηκε προσαρμογέας Bluetooth + Δεν βρέθηκε η επιλεγμένη συσκευή + Αλλάξτε την επιλογή από U/d σε U/h στην αντλία + DanaR Korean + DanaR + Ο οδηγός αντλίας διορθώθηκε + DanaRv2 + Απενεργοποιήστε την λειτουργία EasyUI στην αντλία + Αποτυχία ρύθμισης βασικού προφίλ + Κατάσταση Bluetooth + IOB αντλίας + Έκδοση + Ενεργό + Ανενεργό + DanaR συσκευή Bluetooth + Κωδικός αντλίας + Χρησιμοποιήστε Εκτεταμένο bolus για >200%% + Ταχύτητα Bolus + Επιλεγμένη αντλία + diff --git a/pump/dana/src/main/res/values-ga-rIE/strings.xml b/pump/dana/src/main/res/values-ga-rIE/strings.xml index 3ea04e700d..9f2a8bd137 100644 --- a/pump/dana/src/main/res/values-ga-rIE/strings.xml +++ b/pump/dana/src/main/res/values-ga-rIE/strings.xml @@ -1,2 +1,26 @@ - + + Dana + Seachadta + Stopadh + Ceallraí Íseal + Taiscumar folamh + Aláraim + Bólasi + Carbaihiodráití + Inslin lá + Earráidí + Glúcóis + Athlán + Fionraí + Aláram + Aonaid Glúcóis + DANA + DanaR Cóiréis + DanaR + DanaRv2 + Bluetooth stádas + 12u + 24u + DanaR Bluetooth gléas + diff --git a/pump/dana/src/main/res/values-hr-rHR/strings.xml b/pump/dana/src/main/res/values-hr-rHR/strings.xml index 3ea04e700d..0d7ac4cea4 100644 --- a/pump/dana/src/main/res/values-hr-rHR/strings.xml +++ b/pump/dana/src/main/res/values-hr-rHR/strings.xml @@ -1,2 +1,10 @@ - + + Bolusi + Ugljikohidrati + Greške + Integracija za DANA Diabecare R pumpe + Integracija DANA Diabecare R pumpe Korejskog porijekla + DanaR Bluetooth uređaj + Koristi produženi bolus za >200%% + diff --git a/pump/dana/src/main/res/values-hu-rHU/strings.xml b/pump/dana/src/main/res/values-hu-rHU/strings.xml index 3ea04e700d..347519f69d 100644 --- a/pump/dana/src/main/res/values-hu-rHU/strings.xml +++ b/pump/dana/src/main/res/values-hu-rHU/strings.xml @@ -1,2 +1,9 @@ - + + Párosítás + Hibák + Glükóz + Riasztás + Be + Ki + diff --git a/pump/dana/src/main/res/values-no-rNO/strings.xml b/pump/dana/src/main/res/values-no-rNO/strings.xml index f10a570d51..edb208e032 100644 --- a/pump/dana/src/main/res/values-no-rNO/strings.xml +++ b/pump/dana/src/main/res/values-no-rNO/strings.xml @@ -67,14 +67,14 @@ Prime Bruker valg Format for visning av tid - Knapprulling - Pip ved knapptrykking + Knapperulling + Pip ved knappetrykking Alarm Lyd Vibrer Begge - LCD i tid [seconds] - Bakgrunnsbelysning i tid [seconds] + LCD påslått [seconds] + Bakgrunnsbelysning påslått [seconds] Glukoseenheter Stopp [hours] Lavt reservoar [Units] @@ -92,7 +92,7 @@ DanaRv2 Deaktiver EasyUI modus i pumpe Innstilling av basalprofil mislyktes - Status for Bluetooth + Bluetooth status Pumpens IOB Firmware Innstillinger for Dana pumpe diff --git a/pump/dana/src/main/res/values-pt-rBR/strings.xml b/pump/dana/src/main/res/values-pt-rBR/strings.xml index 66f5932818..5c44661bdc 100644 --- a/pump/dana/src/main/res/values-pt-rBR/strings.xml +++ b/pump/dana/src/main/res/values-pt-rBR/strings.xml @@ -5,7 +5,9 @@ Emparelhamento OK Tempo emparelhamento excedido Aguardando emparelhamento na bomba + Dana-i/RS Dana + Integração da bomba para o DANA Diabecare RS e para bombas Dana-i Transgressão Bólus máx Erro no comando Erro velocidade @@ -13,6 +15,8 @@ Pedido: %1$.2fU Entregue: %2$.2fU Código Erro: %3$s Valor não definido corretamente Coloque o incremento da basal em 0.01 U/h + Redefinir informações de pareamento? + %1$s\nModelo: %2$02X\nProtocolo: %3$02X\nCódigo: %4$02X Processando ação Habilitar bolus estendido na bomba Entregue @@ -20,12 +24,18 @@ Firmware bomba não suportado Erro da Bomba Bateria fraca + Administrando menos que a taxa basal pré-definida Bomba desligada Bateria da Bomba Descarregada Oclusão Reservatório vazio + Verifique a seta + Basal máxima + Máximo diário Alerta medição da glicemia Nível de insulina restante + Bolus não administrado + Informações de pareamento inválidas. Solicitando novo pareamento A obter estado bomba Procurando o status do bolus estendido A obter estado bólus @@ -86,11 +96,25 @@ IOB Bomba Firmware Configurações da bomba Dana + 12h + 24h Ligado Desligado Dispositivo Bluetooth DanaR + Senha da bomba (apenas v1) Senha da bomba Usar bólus prolongado de >200%% Velocidade Bólus Bomba seleccionada + Mudança do reservatório do log + Adicionar evento \"Mudança de Insulina\" ao portal de cuidados, quando detectado no histórico + Mudança do log da cânula + Adicionar evento \"Mudança de local\" ao portal de cuidados, quando detectado no histórico + PIN1 + PIN2 + Pressione OK na bomba\ne digite 2 números exibidos\nMantenha a exibição ligada na bomba pressionando o botão menos até terminar de digitar o código. + 1: (12 dígitos) + 2: (8 dígitos) + Etapa basal/bolus + Carboidratos provavelmente não foram armazenados corretamente. Verifique e armazene manual e novamente se necessário. diff --git a/pump/dana/src/main/res/values-pt-rPT/strings.xml b/pump/dana/src/main/res/values-pt-rPT/strings.xml index 94bf982a3a..069a746fdf 100644 --- a/pump/dana/src/main/res/values-pt-rPT/strings.xml +++ b/pump/dana/src/main/res/values-pt-rPT/strings.xml @@ -5,7 +5,9 @@ Emparelhamento OK Tempo emparelhamento excedido Aguardando emparelhamento na bomba + Dana-i/RS Dana + Integração para bombas DANA Diabecare RS Transgressão Bólus máx Erro no comando Erro velocidade diff --git a/pump/dana/src/main/res/values-ru-rRU/strings.xml b/pump/dana/src/main/res/values-ru-rRU/strings.xml index 7883125a30..5b488e917c 100644 --- a/pump/dana/src/main/res/values-ru-rRU/strings.xml +++ b/pump/dana/src/main/res/values-ru-rRU/strings.xml @@ -31,7 +31,7 @@ Резервуар пуст Проверьте шток помпы Макс. шаг базала - Максимум в день + Максимум за сутки Предупреждение при измерении уровня СК Уровень оставшегося инсулина Недоставленный болюс @@ -46,17 +46,17 @@ Большая разница во времени: \n Время в помпе расходится более чем 1,5 ч. \n. Пожалуйста установите время на помпе вручную и убедитесь, что чтение истории помпы не вызывает неожиданное поведение.\n если возможно, удалите историю из помпы перед изменением времени или отключите замкнутый цикл на один DIA после последней неверной записи в журнале, как минимум на один DIA с настоящего момента. Выполните сопряжение помпы с телефоном! приближается суточный лимит инсулина - Начало подачи болюса - Ожидание окончания болюса. Оставшиеся %1$d сек. + Начинается подача болюса + Ожидание окончания болюса. Осталось %1$d сек. остановка врем базала Настройка пролонгированного болюса Остановка пролонгированного болюса - обновление значений базала + Обновление базальной скорости установка врем базала Ожидание синхронизации времени (%1$d сек) неверный пароль помпы - оповещения об опасности - почасовые базалы + Сигналы тревоги + Почасовой базал болюсы углеводы суточный инсулин @@ -64,12 +64,12 @@ гликемия Перезаправка Останов - Заполнить перед работой + Заполнение Параметры пользователя Формат отображения времени Кнопка прокрутки Звуковой сигнал при нажатии кнопки - Оповещение об опасности + Сигнал тревоги Звуковой сигнал Вибросигнал Оба @@ -80,7 +80,7 @@ В резервуаре мало инсулина [Units] Сохранить параметры в помпе Интеграция с помпой DANA Diabetcare R - Интеграция с отечественной помпой DANA Diabetcare R + Интеграция с локальной помпой DANA Diabetcare R Интеграция с помпой Dana Diabetcare R с обновленной прошивкой DANA адаптер блутус не найден @@ -88,7 +88,7 @@ замена режима с ед/дн на ед/ч на помпе DanaR Корея DanaR - Драйвер помпы откорректирован + Драйвер помпы исправлен DanaRv2 отключить режим упрощенного интерфейса EasyUI в помпе настройка базального профиля не состоялась @@ -109,7 +109,7 @@ Отслеживать замену резервуара Добавить событие \"Замена инсулина\" в портал терапииl при обнаружении в хронологии Отслеживать замену катетера помпы в журнале - Добавить событие \"Замена инсулина\" в портал терапииl при обнаружении в хронологии + Добавить событие \"Замена места катетера помпы\" в портал терапииl при обнаружении в журнале PIN1 PIN2 Нажмите OK на помпе\nи введите 2 отображаемых номера\nДержите экран помпы включенным нажимая кнопку минус, пока не закончите ввод кода. diff --git a/pump/dana/src/main/res/values-tr-rTR/strings.xml b/pump/dana/src/main/res/values-tr-rTR/strings.xml index 9149e453c6..918a1afcec 100644 --- a/pump/dana/src/main/res/values-tr-rTR/strings.xml +++ b/pump/dana/src/main/res/values-tr-rTR/strings.xml @@ -27,15 +27,15 @@ Önceden ayarlanmış bazal orandan daha az teslimat Pompa Kapatma Pompa pili bitmiş - Tıkanıklık + Tıkanma Rezervuar boş Mili kontrol edin - Bazal maks - Günlük maks + Maks Bazal + Maks günlük Kan şekeri ölçüm uyarısı - Kalan insülin düzeyi - Kaçırılan bolus - Geçersiz eşleştirme bilgisi. Yeni eşleştirme isteği + Kalan insülin seviyesi + Eksik Bolus + Geçersiz eşleştirme bilgisi. Yeniden eşleştirme isteniyor Pompa durumu alınıyor Yayma bolus durumu alınıyor Bolus durumu alınıyor @@ -43,7 +43,7 @@ Pompa ayarları alınıyor Pompa zamanı alınıyor Büyük zaman farkı - Büyük zaman farkı:\n1,5 saatten fazla olduğunda pompada zaman kapalıdır.\nLütfen pompanın üzerindeki zamanı manuel olarak ayarlayın ve geçmişin pompadan okunmasından dolayı beklenmedik davranışlara neden olmadığından emin olun.\nMümkünse, zamanı değiştirmeden önce geçmişini pompadan çıkarın veya son yanlış geçmiş girişinden sonra bir DIA için Kapalı Döngü\'yü iptal edin, ancak o andan itibaren en az bir DIA\'yı devre dışı bırakın. + Büyük zaman farkı:\nPompa saati 1,5 saatten fazla kapalı\nLütfen pompanın üzerindeki zamanı manuel olarak ayarlayın ve geçmişin pompadan okunmasından dolayı beklenmedik davranışlara neden olmadığından emin olun.\nMümkünse, zamanı değiştirmeden önce geçmişi pompadan silin veya son yanlış geçmiş girişinden sonra bir İES için Kapalı Döngü\'yü iptal edin, şu andan itibaren en az bir İES\'i devre dışı bırakın. Lütfen pompanızı telefonunuzla bağlayın! Günlük İnsülin limitine yaklaşıldı Bolus teslimatı başlatılıyor @@ -63,7 +63,7 @@ Hatalar Glikoz Doldur - Askıya alınan + Askıya al Doldur Kullanıcı seçenekleri Saat formatı @@ -93,7 +93,7 @@ Pompada EasyUI modunu devre dışı bırak Bazal profil ayarı başarısız oldu Bluetooth durumu - IOB(Aktif insülin) pompa + Pompa AİNS Firmware Dana pompa ayarları 12sa @@ -109,7 +109,7 @@ Rezervuar değişikliği günlüğü Geçmişte tespit edildiğinde careportal\'a \"İnsülin Değişimi\" olayı ekleyin Kanül değişikliği günlüğü - Geçmişte tespit edildiğinde careportal\'a \"Kanül Değişikliği\" olayı ekle + Geçmişte tespit edildiğinde careportal\'a \"Kanül Değişikliği\" olayı ekleyin PIN1 PIN2 Pompada OK\'e basın\nve görüntülenen 2 sayıyı girin\nKodu girmeyi bitirene kadar eksi düğmesine basarak pompa ekranını AÇIK tutun. diff --git a/pump/danar/src/main/res/values-no-rNO/strings.xml b/pump/danar/src/main/res/values-no-rNO/strings.xml index 1d5e4c4238..eea84e135f 100644 --- a/pump/danar/src/main/res/values-no-rNO/strings.xml +++ b/pump/danar/src/main/res/values-no-rNO/strings.xml @@ -1,4 +1,4 @@ - Kommando ikke støttet i pumpen. Bruk kun AndroidAPS brukergrensesnittet! + Kommando støttes ikke i pumpen. Bruk kun AndroidAPS brukergrensesnittet! diff --git a/pump/danar/src/main/res/values-pl-rPL/strings.xml b/pump/danar/src/main/res/values-pl-rPL/strings.xml index 3ea04e700d..4924a43870 100644 --- a/pump/danar/src/main/res/values-pl-rPL/strings.xml +++ b/pump/danar/src/main/res/values-pl-rPL/strings.xml @@ -1,2 +1,4 @@ - + + Nieobsługiwana akcja w pompie. Używaj tylko interfejsu AndroidAPS! + diff --git a/pump/danar/src/main/res/values-pt-rBR/strings.xml b/pump/danar/src/main/res/values-pt-rBR/strings.xml index 3ea04e700d..4e15224a1f 100644 --- a/pump/danar/src/main/res/values-pt-rBR/strings.xml +++ b/pump/danar/src/main/res/values-pt-rBR/strings.xml @@ -1,2 +1,4 @@ - + + Ação não suportada na bomba. Use apenas a interface do usuário do AndroidAPS! + diff --git a/pump/diaconn/src/main/res/values-af-rZA/strings.xml b/pump/diaconn/src/main/res/values-af-rZA/strings.xml index f1d8fa5890..3b7cd2274e 100644 --- a/pump/diaconn/src/main/res/values-af-rZA/strings.xml +++ b/pump/diaconn/src/main/res/values-af-rZA/strings.xml @@ -1,6 +1,14 @@ Pomp fout + Alarms + Basale ure + Boluses + Daaglikse insulien + Foute + Prima + Hervul + Opgeskort Kry pomp instellings Verkry pomp tyd Groot tydverskil: \nTyd in pomp is uit met meer as 1,5 uur. \nVerstel asb die tyd per hand op die pomp en maak seker dat lees die geskiedenis van die pomp nie onverwagte gedrag veroorsaak. \nAs moontlik, verwyder die geskiedenis vanaf die pomp voor die verandering van die tyd of versper die geslote lus vir een DIA na die laaste verkeerde geskiedenis inskrywing maar minimum een DIA van nou. @@ -16,9 +24,25 @@ Spoedfout Insulien limiet skending Versoek: %1$.2fU Gelewer: %2$.2fU Fout kode: %3$s + Waarde nie behoorlik gestel Bolus spoed Geselekteerde pomp + Gebruik verlengde boluses vir >200%% + Visualiseer verlengde bolus as %% + TDD Bolus Stap Basale Stap + Firmware Verbind asseblief jou pomp met jou selfoon! + Klank + klank + vibreer + laag + hoog + LCD aantyd [second] + Bolus spoed + Engels + laag + Ander + Sukses diff --git a/pump/diaconn/src/main/res/values-ca-rES/strings.xml b/pump/diaconn/src/main/res/values-ca-rES/strings.xml index 088ebce930..0584332d5a 100644 --- a/pump/diaconn/src/main/res/values-ca-rES/strings.xml +++ b/pump/diaconn/src/main/res/values-ca-rES/strings.xml @@ -1,6 +1,15 @@ Error bomba + Alarmes + Hores basal + Bolus + Insulina diària + Errors + Encebar + Reomplir + Suspendre + Versió Info de sincronització no vàlida. Sol·licitant nova sincronització Obtenint configuració bomba Obtenint hora bomba @@ -17,9 +26,28 @@ Error de velocitat Superat el límit d\'insulina Demanat: %1$.2fU Lliurat: %2$.2fU Codi error: %3$s + Valor no configurat correctament Velocitat bolus Bomba seleccionada + Utilitzar bolus estesos durant >200%% + Visualitzar bolus estesos com %% + Estat Bluetooth + TDD Increment bolus Increment basal + Firmware Sincronitzeu la bomba amb el telèfon! + So + so + vibració + baix + alt + Temps pantalla LCD encesa [second] + Velocitat bolus + baix + Enregistrar canvi de reservori + Afegir event \"Canvi d\'insulina\" al portal de cures quan es detecti a l\'historial + Afegir event \"Canvi de cànula\" al portal de cures quan es detecti a l\'historial + Altres + Correcte diff --git a/pump/diaconn/src/main/res/values-el-rGR/strings.xml b/pump/diaconn/src/main/res/values-el-rGR/strings.xml index 58bf94fd0a..a4c5062555 100644 --- a/pump/diaconn/src/main/res/values-el-rGR/strings.xml +++ b/pump/diaconn/src/main/res/values-el-rGR/strings.xml @@ -1,6 +1,14 @@ Σφάλμα Αντλίας + Συναγερμοί + Ώρες Βασικού + Bolus + Ημερήσια Ινσουλίνη + Σφάλματα + Πλήρωση + Ξαναγέμισμα + Αναστολή Λήψη ρυθμίσεων αντλίας Λήψη ώρας αντλίας Μεγάλη χρονική διαφορά:\nΗ ώρα στην αντλία διαφέρει περισσότερο από 1,5 ώρες. \nΠαρακαλώ ρυθμίστε την ώρα χειροκίνητα στην αντλία και βεβαιωθείτε ότι η ανάγνωση του ιστορικού από την αντλία δεν προκαλεί απροσδόκητη συμπεριφορά. \nΑν είναι δυνατόν, αφαιρέστε το ιστορικό από την αντλία πριν την αλλαγή της ώρας ή κλείστε το κλειστό κύκλωμα για μία DIA μετά την τελευταία λάθος καταχώρηση ιστορικού αλλά κατ΄ελάχιστο μία DIA από τώρα. @@ -16,9 +24,27 @@ Σφάλμα ταχύτητας Υπέρβαση του ορίου ινσουλίνης Απαιτείται: %1$.2fU Παραδόθηκε: %2$.2fU Κωδικός σφάλματος: %3$s + Η τιμή δεν μπήκε σωστά Ταχύτητα Bolus Επιλεγμένη αντλία + Χρησιμοποιήστε Εκτεταμένο bolus για >200%% + Εμφάνιση εκτεταμένου bolus σε %% + TDD Βήμα Bolus Βήμα Βασικού + Έκδοση Παρακαλώ συνδέστε την αντλία στο τηλέφωνο! + Ήχος + ήχος + δόνηση + χαμηλό + υψηλό + Χρόνος ενεργής οθόνης [second] + Γλώσσα + Ταχύτητα Bolus + Korean + Αγγλικά + χαμηλό + Άλλο + Επιτυχία diff --git a/pump/diaconn/src/main/res/values-ga-rIE/strings.xml b/pump/diaconn/src/main/res/values-ga-rIE/strings.xml index 3ea04e700d..52b4accfd3 100644 --- a/pump/diaconn/src/main/res/values-ga-rIE/strings.xml +++ b/pump/diaconn/src/main/res/values-ga-rIE/strings.xml @@ -1,2 +1,5 @@ - + + Bólas Céim + Bunaidh Céim + diff --git a/pump/diaconn/src/main/res/values-hr-rHR/strings.xml b/pump/diaconn/src/main/res/values-hr-rHR/strings.xml index 3ea04e700d..ccf150fb6f 100644 --- a/pump/diaconn/src/main/res/values-hr-rHR/strings.xml +++ b/pump/diaconn/src/main/res/values-hr-rHR/strings.xml @@ -1,2 +1,10 @@ - + + Bolusi + Greške + Koristi produženi bolus za >200%% + nisko + visoko + nisko + Ostalo + diff --git a/pump/diaconn/src/main/res/values-hu-rHU/strings.xml b/pump/diaconn/src/main/res/values-hu-rHU/strings.xml index 3ea04e700d..a98eb1d69a 100644 --- a/pump/diaconn/src/main/res/values-hu-rHU/strings.xml +++ b/pump/diaconn/src/main/res/values-hu-rHU/strings.xml @@ -1,2 +1,10 @@ - + + Hibák + Verzió + TND + alacsony + magas + alacsony + Egyéb + diff --git a/pump/diaconn/src/main/res/values-no-rNO/strings.xml b/pump/diaconn/src/main/res/values-no-rNO/strings.xml index 6ede995fb4..628a1ede34 100644 --- a/pump/diaconn/src/main/res/values-no-rNO/strings.xml +++ b/pump/diaconn/src/main/res/values-no-rNO/strings.xml @@ -147,7 +147,7 @@ Logg bytte av slangesett Legg til \"Slangesettbytte\" i Careportal når den oppdages i historikken Temp Basal startet - Vel Lav Glukose Stopp er injeksjoner begrenset + Vel Lav Glukose Stopp (LGS) er injeksjoner begrenset LGS status er PÅ. PÅ kommando er nektet. LGS status er AV. AV kommandoen er avslått. Temp basal avslått siden det allerede kjøres en temp basal diff --git a/pump/diaconn/src/main/res/values-pt-rBR/strings.xml b/pump/diaconn/src/main/res/values-pt-rBR/strings.xml index eba1746902..e1b476b311 100644 --- a/pump/diaconn/src/main/res/values-pt-rBR/strings.xml +++ b/pump/diaconn/src/main/res/values-pt-rBR/strings.xml @@ -1,24 +1,150 @@ + Reiniciar pareamento + Nenhum dispositivo disponível + Pareamento de bomba Diaconn Erro da Bomba + Alarmes + Horas de Basal + Bolus + Insulina diária + Erros + Purgar/Preencher + Reabastecimento + Suspender + Pareamento Ok + Aguarde para pareamento + Versão + Informações de pareamento inválidas. Solicitando novo pareamento A obter as definições da bomba A obter hora bomba Grande diferença horária:\n A diferença de hora para a bomba é superior a 1.5h.\nPor favor ajuste manualmente a hora na bomba e certifique-se que a leitura do histórico da bomba não provoca problemas.\nSe possível apague o histórico da bomba antes de modificar a hora ou desabilite o loop durante toda a duração de ação da insulina DIA depois da ultima entrada no histórico da bomba ou mais um DIA desde o momento da correção, qual delas seja a que mantenha o loop aberto durante mais tempo. + Título de grande diferença de tempo Aproximação do limite diario de insulina A iniciar administração de bolus + Esperando pelo fim do bolus estimado + Obtendo status do bolus A parar basal temp Definindo basal temp Configurando bolus prolongado Parando bolus prolongado Atualizar valores das basais + Integração da bomba para bombas Diaconn G8 + Diaconn G8 + Diaconn G8 Transgressão Bólus máx Erro no comando Erro velocidade Transgressão limite insulina Pedido: %1$.2fU Entregue: %2$.2fU Código Erro: %3$s + Valor não definido corretamente + Dispositivo bluetooth Diaconn G8 + Senha da bomba Velocidade Bólus Bomba seleccionada + Usar bólus prolongado de >200%% + Visualizar bólus prolongado como %% + Status do bluetooth + TDD Incremento de bolus Valor da Basal + Firmware + OPÇÕES DO USUÁRIO Emparelhe a sua bomba com o seu telefone! + "Processando evento " + aps_último_registro_numérico + aps_contagem_pacote + Basal temporaria + Ajustes da bomba Dana + Som + som + vibrar + silencioso + Intensidade do alarme + hipo + médio + hiper + Desligar LCD [second] + SALVAR OPÇÃO PARA A BOMBA + Idioma + Velocidade Bólus + Chinês + Coreano + Inglês + "10 " + 10 + 20 + 30 + hipo + Injeção Bloqueada + Alerta de bateria + Aviso de falta de insulina + É necessária a troca da bateria + É necessária a troca da insulina + versão da bomba + número de série da bomba + Mudança do reservatório do log + Adicionar evento \"Mudança de Insulina\" ao portal de cuidados, quando detectado no histórico + Log de mudança da agulha + Adicionar evento \"Mudança de local\" ao portal de cuidados, quando detectado no histórico + Adicionar evento \"Mudança de bateria\" ao portal de cuidados, quando detectado no histórico + Log de mudança de bateria + Log de sincronização em andamento + Falta da insulina + Pouca bateria + Reiniciar ao redefinir dados de fábrica + Redefinir após desligar Emergência + Redefinir após substituição de bateria + Reiniciar após calibração + Reiniciar após a configuração de pré-envio + Reinicio inesperado do sistema + Completo + Injeção bloqueada + Pouca bateria + Falta da insulina + Parada de usuário + Redefinição de sistema + Outro + Paradas de emergência + BASAL + BOLUS DE REFEIÇÃO + BOLUS NORMAL + BOLUS MULTIONDA + BOLUS DUPLO + TROCAR CATÉTER + TROCAR AGULHA + TROCAR SERINGA + Injeção Bloqueada (%s) + autorização da basal (%s) + basal suspensa (%s) + Bolus multionda iniciou + Bolus multionda aplicado com sucesso + Falha na refeição + Sucesso + Refeição: ok + Não foi possível pesquisar pacote devido a erro CRC + Não pode ser definido por erro em parâmetro de entrada. + Não pode ser definido por erro de especificação do protocolo + Hora de comer, não pode ser injetado. + Cancelado pela bomba + Tomando outras ações, limitando as configurações do aplicativo. + Durante outra aplicação de bolus, a aplicação é proibida. + Necessita complementar a aplicação da basal + Cancelado devido a falta de resposta da bomba. + Aplicação não é possível devido à bateria fraca. + Insulina insuficiente. Não pode ser aplicada. + Você não pode aplicar porque excede o limite. + Não pode ser aplicado porque excede o volume total de aplicação diário. + Após completar configuração da basal, a aplicação da basal pode ser realizada. + Este comando não foi entregue. Por favor, tente novamente. + Log de mudança de cartucho + Adicionar evento \"Mudança de cartucho\" ao portal de cuidados, quando detectado no histórico + Início da basal temporária + Durante a suspensão por hipoglicemia, há restrição da injeção + Supensão por hipoglicemia está ligada, o comando ON é recusado. + Supensão por hipoglicemia está desligada, o comando OFF é recusado. + Início da basal temporária é recusado quando a basal temporária está sendo administrada + Interrupção da basal temporária é recusada quando a basal temporária não está sendo administrada + Enviar logs da bomba para a Diaconn Cloud. + Diaconn Cloud sincronizada diff --git a/pump/diaconn/src/main/res/values-pt-rPT/strings.xml b/pump/diaconn/src/main/res/values-pt-rPT/strings.xml index bed9bce412..2ac022a363 100644 --- a/pump/diaconn/src/main/res/values-pt-rPT/strings.xml +++ b/pump/diaconn/src/main/res/values-pt-rPT/strings.xml @@ -72,4 +72,32 @@ Coreano Inglês "10 " + 10 + 20 + 30 + baixo + Injeção bloqueada + Aviso da Bateria + Aviso de falta de insulina + Substituição da bateria é necessária + Substituição de insulina é necessária + pump_version + aps_incarnation_no + pump_serial_no + Registar mudança de reservatório + Adicionar evento \"Mudança de Insulina\" ao careportal quando detectado no histórico + Registar mudança de agulha + Adicionar evento \"Mudança Local Bomba\" ao careportal, quando detectado no histórico + Adicionar evento \"Mudança de bateria\" ao careportal, quando detectado no histórico + Registar mudança de bateria + Sincronização em progresso + Insulina insuficiente + Pouca bateria + Pouca bateria + Interrupção pelo utilizador + Restaurar sistema + Outro + Paragem de emergência + BASAL + Sucesso diff --git a/pump/diaconn/src/main/res/values-sr-rCS/strings.xml b/pump/diaconn/src/main/res/values-sr-rCS/strings.xml index 3ea04e700d..c4aaf493dd 100644 --- a/pump/diaconn/src/main/res/values-sr-rCS/strings.xml +++ b/pump/diaconn/src/main/res/values-sr-rCS/strings.xml @@ -1,2 +1,4 @@ - + + Ostalo + diff --git a/pump/medtronic/src/main/res/values-af-rZA/strings.xml b/pump/medtronic/src/main/res/values-af-rZA/strings.xml index 65f99ac952..88bff175b8 100644 --- a/pump/medtronic/src/main/res/values-af-rZA/strings.xml +++ b/pump/medtronic/src/main/res/values-af-rZA/strings.xml @@ -23,6 +23,7 @@ Lithium (Uitgebreide modus) + Foute Reeksno # nie gestel. Reeksno # is ongeldig. Pomp tipe nie gestel. @@ -44,6 +45,7 @@ + Medtronic Pomp Geskiedenis U het Bolus gekanselleer nadat dit reeds gestel was op pomp. Aangesien Medtronic pomp nie kansellasie ondesteun sal jy dit self moet kanselleer. Sit pomp in Suspend en hervat(Resume) (as jy steeds wil kanselleer). Spplikasie sal die verandering sppor op volgende opdatering in minder as 5 minute. Kon nie huidige TBR lees. @@ -66,8 +68,14 @@ Stel Tydelike Basale Stel Bolus Pomp onbeskikbaar + Waarskuwing + Nou + terug + Pomp tyd/horlosie se opdatering is nodig + Aan + Af Pomp tyd opgedateer diff --git a/pump/medtronic/src/main/res/values-bg-rBG/strings.xml b/pump/medtronic/src/main/res/values-bg-rBG/strings.xml index 0bc2bcc785..7be40691ae 100644 --- a/pump/medtronic/src/main/res/values-bg-rBG/strings.xml +++ b/pump/medtronic/src/main/res/values-bg-rBG/strings.xml @@ -86,4 +86,6 @@ Актуализирано време на помпата Прилагане на неутрални временни базали Ако е вкл, то ще анулира временен базал на всеки час. Това може да помогне за спиране на звук/вибрация от някой помпи на всеки час. + Статистика на RL + Тип: diff --git a/pump/medtronic/src/main/res/values-ca-rES/strings.xml b/pump/medtronic/src/main/res/values-ca-rES/strings.xml index 7dd05e5965..8562e40bda 100644 --- a/pump/medtronic/src/main/res/values-ca-rES/strings.xml +++ b/pump/medtronic/src/main/res/values-ca-rES/strings.xml @@ -1,9 +1,48 @@ + Integració de bomba per models Medtronic, calen dispositiu RileyLink i model de bomba específic + Número de sèrie bomba + Tipus bomba + Freqüència bomba + Retard fins que bolus comenci (s) + Màx. bolus a la bomba (U) + Màx. basal a la bomba (U/h) + Codificació Medtronic + EEUU & Canadà (916 MHz) + Global (868 Mhz) + Codificació 4b6b software + Codificació 4b6b hardware + Engegar i ajustar + Esborrar bloc de bolus + Restablir configuració RileyLink + Tipo de batería (Vista d\'energia) + No seleccionat (Vista simple) + Alcalina (Vista ampliada) + Liti (Vista ampliada) + NiZn (Vista ampliada) + NiMH (Vista ampliada) + Depuració de bolus/tractaments + Bateria RileyLink + Errors + Nr. de sèrie # no configurat. + Nr. de sèrie # no vàlid. + Tipus de bomba no configurat. + Tipus de bomba no compatible. + Freqüència bomba no configurada. + Freqüència bomba no compatible. + Adreça RileyLink no vàlida. + Tipus de bomba detectat diferent al configurat. + Perfils de basal configurats no activats a la bomba. Activeu-los a la bomba. + Perfil de basal configurat a la bomba no correcte (ha de ser STD). + Tipus de basal temporal errònia configurada a la bomba (ha de ser Absolut). + Bolus màx. erroni configurat a la bomba (ha de ser %1$.2f). + Basal màx. errònia configurada a la bomba (ha de ser %1$.2f). + Operació no possible.\n\n Heu de configurar la bomba Medtronic abans de fer servir aquesta operació. + S\'ha sol·licitat un canvi d\'hora de més de 24h. @@ -11,8 +50,45 @@ + Historial bomba Medtronic + Heu cancel·lat un bolus un cop ja havia estat enviat a la bomba. Donat que la bomba de Medtronic no permet la comanda \"cancel·lar\", haureu de fer-ho manualment: poseu la bomba en mode \"Suspendre\" i després feu \"Reprendre\" (si encara voleu cancel·lar). L\'aplicació agafarà els canvis la següent vegada que s\'actualitzi (menys de 5 minuts). + No s\'ha pogut llegir la basal temporal actual. + No s\'ha pogut cancel·lar la basal temporal actual. Aturant l\'operació. + Ha fallat l\'activació de perfil, ja que els següents patrons tenen una basal massa gran: %1$s + No s\'ha pogut lliurar el bolus. + No s\'ha pogut lliurar el bolus, perquè la quantitat d\'insulina que queda (%1$.2f) és menor que el bolus sol·licitat (%2$.2f). + No s\'ha pogut activar la basal temporal. + No s\'ha pogut cancel·lar la basal temporal actual. + No s\'ha pogut activar el perfil de basal. + El perfil basal és el mateix, per tant no serà modificat. + Recuperar historial - Pàgina %1$d (%2$d/16) + Recuperar historial - Pàgina %1$d + Obtenir hora bomba + Configurar hora bomba + Obtenir estat bateria + Obtenir configuració + Obtenir model bomba + Obtenir perfil basal + Obtenir perfil basal + Obtenir basal temporal + Establir basal temporal + Cancel·lar basal temporal + Establir bolus + Obtenir insulina restant + Bomba no accessible + Avís + Ara + fa + Cal actualitzar l\'hora de la bomba + On + Off + Actualitzada hora de la bomba + Establir basals temporals neutres + Si està activat, cancel·larà la basal temporal abans del final de cada hora. Aquest mètode pot ajudar a evitar que algunes bombes pitin/vibrin cada hora. + %1$.1f U/h (queden %2$d min) + Tipus: diff --git a/pump/medtronic/src/main/res/values-el-rGR/strings.xml b/pump/medtronic/src/main/res/values-el-rGR/strings.xml index 5de07dba78..ad121be90c 100644 --- a/pump/medtronic/src/main/res/values-el-rGR/strings.xml +++ b/pump/medtronic/src/main/res/values-el-rGR/strings.xml @@ -23,6 +23,7 @@ Λιθίου (Extended view) + Σφάλματα Δεν ορίστηκε # Serial. Serial # μη έγκυρο. Δεν ορίστηκε Τύπος Αντλίας. @@ -44,6 +45,7 @@ + Ιστορικό Αντλίας Medtronic Ακυρώσατε τον Bolus, αφού είχε ήδη σταλεί στην αντλία. Επειδή η αντλία Medtronic δεν υποστηρίζει ακύρωση, θα χρειαστεί να ακυρωθεί χειροκίνητα. Βάλτε την αντλία σε αναστολή λειτουργίας και μετά κάντε Συνέχιση (αν θέλετε να ακυρώσετε ακόμα). Η εφαρμογή θα πάρει τις αλλαγές, στην επόμενη ενημέρωση (σε λιγότερο από 5 λεπτά). Αδυναμία ανάγνωσης τρέχοντος TBR. @@ -65,8 +67,15 @@ Λάβετε Προσωρινό Ρυθμό Βάλτε Προσωρινό Ρυθμό Βάλτε Bolus + Η αντλία δεν είναι διαθέσιμη + Προειδοποίηση + Τώρα + πριν + Η ώρα της αντλίας χρειάζεται ανανέωση + Ενεργό + Ανενεργό Η ώρα στην αντλία άλλαξε diff --git a/pump/medtronic/src/main/res/values-ga-rIE/strings.xml b/pump/medtronic/src/main/res/values-ga-rIE/strings.xml index 7dd05e5965..124cf31da4 100644 --- a/pump/medtronic/src/main/res/values-ga-rIE/strings.xml +++ b/pump/medtronic/src/main/res/values-ga-rIE/strings.xml @@ -4,6 +4,7 @@ + Earráidí @@ -12,7 +13,11 @@ + Rabhadh + Anois + ó shin + Is nuashonrú gá clog Caidéil diff --git a/pump/medtronic/src/main/res/values-hr-rHR/strings.xml b/pump/medtronic/src/main/res/values-hr-rHR/strings.xml index 7dd05e5965..e4a543e239 100644 --- a/pump/medtronic/src/main/res/values-hr-rHR/strings.xml +++ b/pump/medtronic/src/main/res/values-hr-rHR/strings.xml @@ -1,9 +1,48 @@ + Integracija pumpe Medtronic zahtijeva uređaj RileyLink i određeni model pumpe + Serijski broj pumpe + Tip pumpe + Frekventno područje pumpe + Odgoda prije početka bolusa (s) + Max Bolus na Pumpi (U) + Max Basal na Pumpi (U/h) + Medtronic kodiranje + US & Canada (916 MHz) + Ostatak svijeta (868 Mhz) + Software 4b6b kodiranje + Hardware 4b6b kodiranje + Buđenje i podešavanje + Izbriši bolusni blok + Resetirajte konfiguraciju RileyLink + Vrsta baterije (Power View) + Nije odabrano (jednostavan prikaz) + Alkalno (prošireni prikaz) + Litij (prošireni prikaz) + Nikal-Cink (prošireni prikaz) + NiMH (prošireni prikaz) + Bolus/tretmani Otklanjanje pogrešaka + Baterija RileyLink + Greške + Serijski broj nije unesen. + Greška serijskog broja. + Vrsta pumpe nije postavljena. + Vrsta pumpe nije podržana. + Frekvencija pumpe nije postavljena. + Frekvencija pumpe nije podržana. + RileyLink adresa nevažeća. + Otkrivena vrsta pumpe nije ista kao konfigurirana vrsta. + Postavka bazalnih profila/uzoraka nije omogućena na pumpi. Omogućite ga na pumpi. + Bazalni profil postavljen na pumpi nije točan (mora biti STD). + Pogrešan tip TBR postavljen na pumpi (mora biti Apsolutan). + Pogrešan maksimalni bolus postavljen na pumpi (mora biti %1$.2f). + Pogrešan maksimalni bazal postavljen na pumpi (mora biti %1$.2f). + Rad nije moguć.\n\n Najprije morate konfigurirati Medtronic Pumpu prije nego što možete koristiti ovu operaciju. + Zatražena je promjena vremena preko 24 sata. @@ -11,8 +50,22 @@ + Povijest Medtronic pumpe + Otkazali ste bolus nakon što je već bio postavljen na Pumpi. Budući da Medtronic Pump ne podržava otkazivanje, morat ćete ga ručno otkazati. Stavite pumpu u način rada Suspend, a zatim izvršite Resume (ako još uvijek želite otkazati). Aplikacija će pokupiti promjene pri sljedećem ažuriranju (za manje od 5 minuta). + Nije moguće pročitati trenutni TBR. + Nije moguće otkazati trenutni TBR. Zaustavljanje operacije. + Postavljanje profila nije uspjelo, jer sljedeći uzorci imaju preveliku bazalnu stopu: %1$s + Bolus se nije mogao isporučiti. + Bolus nije mogao biti isporučen jer je dostupna količina inzulina (%1$.2f) manja od potrebnog bolusa (%2$.2f). + TBR se nije mogao postaviti. + Nije moguće otkazati trenutni TBR. + Bazalni profil nije mogao biti postavljen. + Bazalni profil je isti, tako da se više neće postavljati. + Pumpa nedostupna + RL statistika + Tip: diff --git a/pump/medtronic/src/main/res/values-hu-rHU/strings.xml b/pump/medtronic/src/main/res/values-hu-rHU/strings.xml index 7dd05e5965..605b3758b4 100644 --- a/pump/medtronic/src/main/res/values-hu-rHU/strings.xml +++ b/pump/medtronic/src/main/res/values-hu-rHU/strings.xml @@ -1,9 +1,48 @@ + Medtronic pumpakapcsolat, egy RileyLink típusú eszköz és megfelelő típusú pumpa szükséges + Pumpa sorozatszáma + Pumpa típusa + Pumpa frekvencia + Várakozás bólus indítása előtt (mp) + Max. Bólus a pumpán (E) + Max. Bázis a pumpán (E/ó) + Medtronic kódolás + USA & Kanada (916 MHz) + Nemzetközi (868 Mhz) + Szoftveres 4b6b kódolás + Hardveres 4b6b kódolás + Ébresztés és hangolás + Bólus blokk törlése + RileyLink beállítás törlése + Elem típusa (Töltöttség nézet) + Nincs kiválasztás (Egyszerű nézet) + Alkáli (Kiterjesztett nézet) + Lítium (Kiterjesztett nézet) + NiZn (Kiterjesztett nézet) + NiMH (kiterjesztett nézet) + Bólus/Kezelések hibakeresés + RileyLink elem + Hibák + Sorozatszám hiányzik. + Sorozatszám hibás. + Pumpa típusa hiányzik. + Pumpa típusa nem támogatott. + Pumpa frekvencia hiányzik. + Pumpa frekvencia nem támogatott. + RileyLink címe hibás. + Csatlakoztatott pumpa típusa eltér a beállított típustól. + Bázis profilok/sémák beállítás nincs engedélyezve a pumpán. Engedélyezze a pumpán. + Hibás a pumpán beállított bázisséma (STD kell legyen). + Hibás a pumpán beállított ÁB típusa (Inzulinütem kell legyen). + Hibás a pumpán beállított Max. Bólus (%1$.2f kell legyen). + Hibás a pumpán beállított Max. Bázis (%1$.2f kell legyen). + Művelet nem végrehajtható.\n\n Először be kell állítani a Medtronic pumpát, mielőtt használni lehet ezt a műveletet. + 24 óránál nagyobb időmódosítás szükséges. @@ -11,8 +50,44 @@ + Medtronic pumpa előzmények + A bólus a pumpára való elküldés után lett törölve. Mivel a Medtronic pumpa nem támogatja a törlést, ezért manuálisan kell törölni. Felfüggesztett módba kell állítani a pumpát, majd utána újraindítani (ha továbbra is meg akarja szakítani). Az alkalmazás a következő frissítéskor (kevesebb, mint 5 percen belül) veszi át a változásokat. + Jelenlegi ÁB lekérése nem sikerült. + Jelenlegi ÁB törlése nem sikerült. Művelet megszakítása. + Profil beállítása nem sikerült, mivel a következő bázis ráták túl nagyok: %1$s + Bólus beadása nem sikerült. + Bázis beadása nem sikerült, mivel a hátralévő inzulin (%1$.2f) kevesebb, mint a bólushoz szükséges (%2$.2f). + ÁB beállítása nem sikerült. + Jelenlegi ÁB törlése nem sikerült. + Bázisséma beállítása nem sikerült. + Bázis séma ugyanaz, ezért nem kerül újra beállításra. + Előzmények - Oldal %1$d (%2$d/16) + Előzmények - Oldal %1$d + Pumpaidő lekérése + Pumpaidő beállítása + Elemállapot lekérése + Beállítások lekérése + Pumpatípus lekérése + Bázisséma lekérése + Bázisséma beállítása + Átmeneti bázis lekérése + Átmeneti bázis beállítása + Átmeneti bázis törlése + Bólus beállítása + Hátralévő inzulin + Pumpa nem elérhető + Figyelmeztetés + Most + ezelőtt + Pumpa idő frissítése szükséges + Be + Ki + Pumpa idő frissítve + Semleges átmeneti bázis beállítása + Ha be van kapcsolva, akkor minden óra végén törli az átmeneti bázist. Ez a módszer segíthet elkerülni bizonyos pumpákon az óránkénti hangjelzést/rezgést. + %1$.1f E/ó (%2$d perc van hátra) diff --git a/pump/medtronic/src/main/res/values-ko-rKR/strings.xml b/pump/medtronic/src/main/res/values-ko-rKR/strings.xml index 244dc5ef7f..b1c3efdf2d 100644 --- a/pump/medtronic/src/main/res/values-ko-rKR/strings.xml +++ b/pump/medtronic/src/main/res/values-ko-rKR/strings.xml @@ -90,4 +90,5 @@ 기본 임시 basal 설정 활성화되면, 매 한 시간 전에 임시 basal을 취소할 것입니다. 이 기능은 일부 펌프에서 한 시간마다 울리는 소리/진동 경고를 멈추게 합니다. %1$.1f U/h (%2$d 분 남음) + 종류: diff --git a/pump/medtronic/src/main/res/values-lt-rLT/strings.xml b/pump/medtronic/src/main/res/values-lt-rLT/strings.xml index d5b70145c2..9a12018987 100644 --- a/pump/medtronic/src/main/res/values-lt-rLT/strings.xml +++ b/pump/medtronic/src/main/res/values-lt-rLT/strings.xml @@ -91,4 +91,6 @@ Jei įjungta, laikina valandinė bazė bus anuliuota iki kiekvienos valandos pabaigos. Šis metodas gali padėti išvengti kai kurių pompų pypsėjimo ar vibravimo. %1$.1f vv/h (liko %2$d min) Aptikti neteisingi pompos istorijos duomenys. Sukurkite naują problemos įrašą ir pateikite žurnalus. + RL statistika + Tipas: diff --git a/pump/medtronic/src/main/res/values-pl-rPL/strings.xml b/pump/medtronic/src/main/res/values-pl-rPL/strings.xml index 5e737ac35a..8487015c67 100644 --- a/pump/medtronic/src/main/res/values-pl-rPL/strings.xml +++ b/pump/medtronic/src/main/res/values-pl-rPL/strings.xml @@ -91,4 +91,6 @@ Jeśli ta opcja jest włączona, anuluje tymczasową wartość bazową przed końcem każdej godziny. Może to pomóc wyciszyć alarmy/wibracje związane z TBR występujące co godzinę w niektórych pompach. %1$.1f U/h (pozostało %2$d min) Wykryto nieprawidłowe dane historii pompy. Otwórz nowy problem (\"Issue\") na GitHub i dodaj logi. + Statystyki RL + Typ: diff --git a/pump/medtronic/src/main/res/values-pt-rBR/strings.xml b/pump/medtronic/src/main/res/values-pt-rBR/strings.xml index 210753f7c6..6c74430cd7 100644 --- a/pump/medtronic/src/main/res/values-pt-rBR/strings.xml +++ b/pump/medtronic/src/main/res/values-pt-rBR/strings.xml @@ -25,7 +25,9 @@ NiMH (Visualização estendida) Depuração de Bólus/Tratamentos + Bateria RileyLink + Erros Núm. Série não definido. Núm. Série inválido. Tipo de Bomba não definido. @@ -48,6 +50,7 @@ + Histórico da Bomba Medtronic Cancelou o Bolus, depois de ele já ter sido definido na Bomba. Uma vez que a Bomba Medtronic não suporta cancelamento, precisará de cancelar manualmente. Coloque a Bomba no modo de Suspender e depois Retome (se ainda quiser cancelar). A aplicação irá obter as alterações, na próxima actualização (em menos de 5 minutos). Não foi possível ler a TBR actual. @@ -62,15 +65,31 @@ Obter Histórico - Página %1$d (%2$d/16) Obter Histórico - Página %1$d Obter Hora da Bomba + Definir tempo da bomba + Obter status da bateria Obter Definições Obter Modelo de Bomba Obter Perfil Basal Definir Perfil Basal Obter Basal temporário Definir Basal temporário + Cancelar a basal temporária Definir Bólus + Obter a insulina restante + Bomba inacessível + Aviso + Agora + atrás + É necessário atualizar o relógio da bomba + Lig. + Desligado Hora da bomba actualizada + Definir as basais temporárias neutras + Se ativado, cancelará uma basal temporária antes do final de cada hora. Este método pode ajudar a parar algumas bombas de alarmar/vibrar por uma hora. + %1$.1f U/h (%2$d min restantes) + Dados inválidos do histórico da bomba detectados. Abra nova solicitação e forneça logs. + Tipo: diff --git a/pump/medtronic/src/main/res/values-pt-rPT/strings.xml b/pump/medtronic/src/main/res/values-pt-rPT/strings.xml index 1e88d9ec58..03b37363e7 100644 --- a/pump/medtronic/src/main/res/values-pt-rPT/strings.xml +++ b/pump/medtronic/src/main/res/values-pt-rPT/strings.xml @@ -89,4 +89,6 @@ Hora da bomba actualizada Definir basais temporárias neutras Se activado, cancela a basal temporária antes de perfazer uma hora. Este método evita que as bombas Medtronic emitam um sinal sonoro e/ou vibrem quando a basal temporária se estende por mais de uma hora. + Estatísticas RL + Tipo: diff --git a/pump/medtronic/src/main/res/values-ro-rRO/strings.xml b/pump/medtronic/src/main/res/values-ro-rRO/strings.xml index eb617e1d9e..36a7846e6a 100644 --- a/pump/medtronic/src/main/res/values-ro-rRO/strings.xml +++ b/pump/medtronic/src/main/res/values-ro-rRO/strings.xml @@ -91,4 +91,6 @@ Dacă este activată, va anula o bazală temporară înainte de sfârșitul fiecărei ore. Aceasta metoda poate ajuta la oprirea vibrațiilor/bipurilor orare pe anumite pompe. %1$.1f U/h (%2$d min ramase) Au fost detectate date nevalide din istoricul pompei. Deschideți o nouă problemă și furnizați jurnalele. + Statistici RL + Tip: diff --git a/pump/medtronic/src/main/res/values-ru-rRU/strings.xml b/pump/medtronic/src/main/res/values-ru-rRU/strings.xml index 71e7be8ba3..7046efc365 100644 --- a/pump/medtronic/src/main/res/values-ru-rRU/strings.xml +++ b/pump/medtronic/src/main/res/values-ru-rRU/strings.xml @@ -6,7 +6,7 @@ Серийный номер помы Тип помпы Частота помпы - Задержка перед подачей болюса (с) начата + Задержка перед подачей болюса (сек) Макс. болюс на помпе (ед) Макс. базал на помпе (ед/ч) Кодировка Medtronic @@ -14,7 +14,7 @@ Глобальн (868 Мгц) Программное 4b6b кодирование Аппаратное кодирование 4b6b - Пробудить и настроить + Пробуждение и настройка Очистить блок болюса Сбросить конфигурацию RileyLink Тип батареи (по мощности) diff --git a/pump/medtronic/src/main/res/values-sv-rSE/strings.xml b/pump/medtronic/src/main/res/values-sv-rSE/strings.xml index 88102781ce..2a3698b19e 100644 --- a/pump/medtronic/src/main/res/values-sv-rSE/strings.xml +++ b/pump/medtronic/src/main/res/values-sv-rSE/strings.xml @@ -91,4 +91,6 @@ Om aktiverad, kommer en eventuell temporär basal automatiskt avbrytas före utgången av varje timme. Denna metod kan förhindra att vissa pumpar piper/vibrerar. %1$.1f U/h (%2$d min kvar) Ogiltig pumpdata upptäckt. Öppna nytt ärende och bifoga loggar. + RL-statistik + Typ: diff --git a/pump/medtronic/src/main/res/values-tr-rTR/strings.xml b/pump/medtronic/src/main/res/values-tr-rTR/strings.xml index 1f3ab7a93c..85d8ee41e2 100644 --- a/pump/medtronic/src/main/res/values-tr-rTR/strings.xml +++ b/pump/medtronic/src/main/res/values-tr-rTR/strings.xml @@ -54,7 +54,7 @@ Pompa üzerinde ayarlandıktan sonra Bolus\'u iptal ettiniz. Medtronic Pompa iptali desteklemediğinden, elle iptal etmeniz gerekecektir. Pompayı Askıya Al moduna getirin ve ardından Devam et\'e basın. (yine de iptal etmek istiyorsanız). Uygulama, bir sonraki güncellemede (5 dakikadan daha kısa sürede) değişiklikleri alacaktır. Mevcut TBR (geçici bazal oranı) okunamadı. - Mevcut TBR (geçici bazal oranı) iptal edilemedi. İşlem durduruldu. + Mevcut GBO iptal edilemedi. İşlem durduruldu. Profil kümesi başarısız oldu, çünkü aşağıdaki şablonlar çok büyük bazal orana sahip: %1$s Bolus gönderilemedi. Bolus gönderilemedi, çünkü mevcut insülin miktarı (%1$.2f) gereken bolustan (%2$.2f) az. diff --git a/pump/omnipod-common/src/main/res/values-af-rZA/strings.xml b/pump/omnipod-common/src/main/res/values-af-rZA/strings.xml index e35fcaa95a..388a00b81a 100644 --- a/pump/omnipod-common/src/main/res/values-af-rZA/strings.xml +++ b/pump/omnipod-common/src/main/res/values-af-rZA/strings.xml @@ -2,17 +2,48 @@ + Aksies + Bevestiging + Opgeskort + %1$.2f U + Stoor + Foute + Kanselleer + Volgende + Gaan uit + Ander + Kennisgewings + Loop tans + Stel Bolus + Stel Tydelike Basale + Ja + Nee + OK + Kanselleer + Waarskuwing + + %1$d minuut + %1$d minute + + + %1$d uur + %1$d ure + + + %1$d dae + %1$d dae + diff --git a/pump/omnipod-common/src/main/res/values-ca-rES/strings.xml b/pump/omnipod-common/src/main/res/values-ca-rES/strings.xml index e35fcaa95a..974084c7f1 100644 --- a/pump/omnipod-common/src/main/res/values-ca-rES/strings.xml +++ b/pump/omnipod-common/src/main/res/values-ca-rES/strings.xml @@ -2,17 +2,193 @@ + Gestió del pod + Accions + Eines + Activar pod + Desactivar pod + Descartar pod + Si descarteu el pod, no us podreu comunicar més amb ell. Només haurieu de descartar-lo quan tota comunicació amb el pod falli definitivament. Si encara us podeu comunicar amb el pod, utilitzeu l\'opció Desactivar pod.\n\nSi voleu continuar, assegureu-vos de desconnectar el pod del vostre cos! + Fer sonar bip de prova + Fent sonar bip de prova… + Historial del pod + Cap pod actiu + Error en establir perfil basal. + Bolus no lliurat. + Error en establir perfil basal: s\'ha rebut un perfil buit. Assegureu-vos d\'activar el vostre perfil basal. + Cap perfil basal actiu. Assegureu-vos d\'activar el vostre perfil basal. + Comanda personalitzada no permesa: %1$s + Error en actualizar estat + Error en refrescar estat a l\'iniciar + Error en silenciar alertes + Error en aturar lliurament + Error en establir hora + Error en reprendre lliurament + Error en inicialitzar el pod + Error en inserir cànula + S\'ha excedit el temps d\'activació del pod. Aquest pod ja no es pot activar. + Error en verificar el progrés del procés d\'activació. Torneu a intentar-ho si us plau. + Pod en pausa + Error en fer sonar bip de prova + La hora al pod no està sincronitzada. Si us plau actualitzeu l\'hora a la pestanya Omnipod. + Error inesperat. Si us plau, informeu! (%1$s: %2$s). + Confirmació + L\'hora i/o la zona horària han canviat al pod. + La configuració d\'alertes al pod ha estat actualitzada. + L\'hora al pod ha estat actualitzada. + El lliurament d\'insulina ha estat suspès. + S\'han silenciat les alertes actives. + S\'ha reprès el lliurament d\'insulina. + Configurar hora + Suspendre + Reprendre lliurament + Gestió pod + Silenciar alertes + Estat pod + Total lliurat + %1$.2f U + ID únic + Nr. LOT + Nr. de seqüència + El pod expira + Última connexió + Darrer bolus + Basal temporal + Basal base + Reservori + Alertes pod actiu + Versió del firmware + Hora al pod + %1$.2fU/h @%2$s (%3$d/%4$d minuts) + Queden %1$.2f U + Queden més de 50 U + Errors + Cancel·lar + Finalitzar + Següent + Reintentar + Desactivar pod + Descartar pod + Encara no heu completat tots els passos. Esteu segurs que voleu sortir? + Sortir + Omplir pod + Inicialitzar pod + Adherir pod + Prepareu el punt d\'infusió. Retireu la funda de l\'agulla i l\'adhesiu del pod i col·loqueu el pod al punt d\'infusió.\n\nSi la cànula sobresurt, si us plau premeu Cancel·lar i descarteu el pod.\n\nPremeu Següent per inserir la cànula i iniciar el lliurament de basal. + Quan premeu OK, la cànula serà inserida. Assegureu-vos que heu col·locat el pod al punt d\'infusió. + Inserir cànula + Intentant establir programació inicial de basal i inserir cànula.\n\nQuan la cànula hagi estat inserida correctament, premeu Següent. + Pod activat + El nou pod ja està actiu.\n\nLa vostra basal ha estat programada i la cànula inserida.\n\nComproveu que la cànula ha estat inserida correctament i canvieu el pod en cas contrari. + Desactivar pod + Premeu Següent per desactivar el pod.\n\nNota: Això aturarà tot lliurament d\'insulina i desactivarà el pod. + Desactivant pod + Desactivant pod.\n\nQuan la desactivació s\'hagi completat amb èxit, podeu prémer Següent. + Pod desactivat + El vostre pod ha estat desactivat.\n\nSi us plau retireu el pod del vostre cos i recicleu-lo. + Pod descartat + L\'estat del pod ha estat descartat. El lliurament d\'insulina no ha estat aturat perquè el pod no ha estat desactivat correctament!\n\nSi us plau retireu el pod del vostre cos i recicleu-lo. + Si descarteu el pod, no us podreu comunicar més amb ell. Només haurieu de descartar-lo quan tota comunicació amb el pod falli definitivament. Esteu segurs que voleu descartar el pod? + Descartar pod + Bips de bolus activats + Bips de basal activats + Bips d\'SMS activats + Bips de basals temporals activats + Mostrar botó \"Suspendre lliurament\" a la pestanya Omnipod + Detecció d\'horari d\'estiu/hivern activada + Recordatori d\'expiració activat + Hores fins aturada + Alerta de reservori baix activada + Nr. d\'unitats + Silenciar automàticament alertes del pod + Altres + Alertes + Bips de confirmació + Notificacions + Habilitat so per avisos de TBR dubtoses + Habilitat so per avisos de bolus dubtosos + Cap pod actiu + Configuració en curs (esperant activació de pod) + Configuració en curs (esperant inserció de cànula) + Funcionant + En pausa + Error del pod + Temps d\'activació superat + Inactiu + Error del pod: %1$03d %2$s + Desactivar pod + Descartar pod + Establir bolus + Cancel·lar bolus + Establir basal temporal + Cancel·lar basal temporal (internament via controlador) + Cancel·lar basal temporal + Establir programació de basal + Obtenir estat pod + Obtenir info pod + Configurar hora + Configurar alertes + Silenciar alertes + Aturar lliuraments + Reprendre lliurament + Entrada desconeguda + Inicialitzar pod + Inserir cànula + Llegir registre pols + Establir basal temporal falsa perquè el pod està en pausa + Cancel·lar basal temporal falsa creada per haver estat el pod en pausa + Dividir basal temporal a causa d\'un error indeterminat en la cancel·lació + Configuració bip + Fer sonar bip de prova + Finalitzar recordatori d\'emparellament + Recordatori finalitzar configuració + El pod està a punt de caducar + El pod està a punt de caducar + L\'apagada és inminent + Reservori baix + Alerta desconeguda + Cap pod actiu + Darrera connexió: fa %1$d min + Darrer bolus: %1$s @ %2$s + Temp: %1$s + Estès: %1$s + Reservori.: %1$s U + + No + OK + Cancel·lar + Avís + Fa un moment + Fa menys d`un minut + %1$s i %2$s + Fa %1$s + + %1$d minut + %1$d minuts + + + %1$d hora + %1$d hores + + + %1$d dia + %1$d dies + + + Alerta pod: %1$s + Alertes pod: %1$s + diff --git a/pump/omnipod-common/src/main/res/values-el-rGR/strings.xml b/pump/omnipod-common/src/main/res/values-el-rGR/strings.xml index e35fcaa95a..0082230e2c 100644 --- a/pump/omnipod-common/src/main/res/values-el-rGR/strings.xml +++ b/pump/omnipod-common/src/main/res/values-el-rGR/strings.xml @@ -2,17 +2,49 @@ + Ενέργειες + Επιβεβαίωση + Αναστολή + %1$.2f U + Αμπούλα + Σφάλματα + Ακύρωση + Επόμενο + Έξοδος + Άλλο + Ειδοποιήσεις + Εκτελείτε + Όρισε bolus + Ακύρωση του Bolus + Βάλτε Προσωρινό Ρυθμό + Ναι + Όχι + ΟΚ + Ακύρωση + Προειδοποίηση + + %1$d minute + %1$d λεπτά + + + %1$d hour + %1$d ώρες + + + %1$d ημέρες + %1$d ημέρες + diff --git a/pump/omnipod-common/src/main/res/values-hr-rHR/strings.xml b/pump/omnipod-common/src/main/res/values-hr-rHR/strings.xml index e35fcaa95a..f6487611ba 100644 --- a/pump/omnipod-common/src/main/res/values-hr-rHR/strings.xml +++ b/pump/omnipod-common/src/main/res/values-hr-rHR/strings.xml @@ -5,14 +5,21 @@ + Greške + Otkaži + Sljedeći + Izlaz + Ostalo + Suspendiran + Otkaži diff --git a/pump/omnipod-common/src/main/res/values-hu-rHU/strings.xml b/pump/omnipod-common/src/main/res/values-hu-rHU/strings.xml index e35fcaa95a..549a16425d 100644 --- a/pump/omnipod-common/src/main/res/values-hu-rHU/strings.xml +++ b/pump/omnipod-common/src/main/res/values-hu-rHU/strings.xml @@ -2,17 +2,42 @@ + Műveletek + Eszközök + %1$.2f E + Firmware verzió + Hibák + Mégse + Tovább + Kilép + Egyéb + Bólus beállítása + Átmeneti bázis beállítása + Átmeneti bázis törlése + Igen + Nem + OK + Mégse + Figyelmeztetés + + %1$d óra + %1$d óra + + + %1$d nap + %1$d nap + diff --git a/pump/omnipod-common/src/main/res/values-ko-rKR/strings.xml b/pump/omnipod-common/src/main/res/values-ko-rKR/strings.xml index 93961277b6..6cc6fa107e 100644 --- a/pump/omnipod-common/src/main/res/values-ko-rKR/strings.xml +++ b/pump/omnipod-common/src/main/res/values-ko-rKR/strings.xml @@ -111,6 +111,9 @@ 기타 경고 확인 신호음 + 알림 + 불확실한 TBR 알림 소리 활성화 + 불확실한 볼루스 알림 소리 활성화 활성화된 Pod 없음 설정 진행 중 (Pod 활성화를 기다리는 중) diff --git a/pump/omnipod-common/src/main/res/values-pt-rBR/strings.xml b/pump/omnipod-common/src/main/res/values-pt-rBR/strings.xml index e35fcaa95a..434af90031 100644 --- a/pump/omnipod-common/src/main/res/values-pt-rBR/strings.xml +++ b/pump/omnipod-common/src/main/res/values-pt-rBR/strings.xml @@ -2,17 +2,194 @@ + Gerenciamento do Pod + Ações + Ferramentas + Pod ativo + Pod Desativado + Descartar Pod + Se você descartar o Pod, você nunca mais será capaz de se comunicar com ele. Você só deve fazer isso quando todas as comunicações com o Pod persistirem em falhar. Se você ainda consegue se comunicar com o Pod, por favor, use a opção Desativar Pod.\n\nSe quiser continuar, certifique-se de remover o Pod do seu corpo! + Faça os testes sonoros + Fazendo testes sonoros… + Histórico do Pod + Sem Pod ativo + Falha ao configurar perfil basal. + Bolus não foi administrado. + Falha ao definir o perfil basal: recebeu um perfil vazio. Certifique-se de ativar o seu perfil basal. + Nenhum perfil basal está ativo. Certifique-se de ativar seu perfil basal. + Comando personalizado não suportado: %1$s + Falha ao atualizar o status + Falha na atualização do status ao iniciar + Falha ao silenciar os alertas + Falha ao suspender a administração + Falha ao definir o tempo + Falha ao reiniciar a administração + Falha ao iniciar o Pod + Falha ao inserir a cânula + O tempo de ativação do Pod foi ultrapassado. Este Pod não pode mais ser ativado. + Falha ao verificar o progresso da ativação. Por favor, reinicie novamente. + Pod suspenso + Falha ao realizar teste sonoro + O tempo no Pod está dessincronizado. Por favor, atualize o tempo na aba Omnipod. + Um erro inesperado aconteceu. Por favor, relate! (%1$s: %2$s). + Confirmação + O tempo e/ou o fuso horário mudaram no Pod. + A configuração de alerta foi atualizada no Pod. + O tempo no Pod foi atualizado. + Toda a entrega de insulina foi suspensa. + Alertas ativos foram silenciados. + Toda a entrega de insulina foi reiniciada. + Configurar a hora + Suspender + Reiniciar a administração + Gerenciamento do Pod + Alertas silenciados + Status do Pod + Total entregue + %1$.2f U + ID único + Número do LOT + Número sequencial + Pod expira + Última conexão + Último bolus + Taxa Basal Temporária + Taxa Basal de base + Reservatório + Alertas ativos do Pod + Versão do firmware + Tempo no Pod + %1$.2fU/h @%2$s (%3$d/%4$d minutos) + %1$.2f U restantes + Mais de 50 U restantes + Erros + Cancelar + Fim + Seguinte + Tente novamente + Pod Desativado + Descartar Pod + Você ainda não concluiu todas as etapas. Tem certeza que deseja sair? + Sair + Preencha o Pod + Inicializar o Pod + Anexe o Pod + Prepare o local de infusão. Remova a proteção da agulha do Pod e o fundo adesivo e anexe o Pod ao site de infusão.\n\nSe a canula sair, pressione Cancelar e descarte o seu Pod.\n\nPressione Próximo para inserir a cânula e inicie a infusão da basal. + Quando você pressionar OK, a cânula será inserida. Certifique-se de ter aderido o Pod ao local de infusão. + Inserir cânula + Tentando estabelecer o esquema basal inicial e inserir a cânula.\n\nQuando a cânula for inserida com sucesso, você pode pressionar Próximo. + Pod ativado + O novo Pod agora está ativo.\n\nSeu esquema basal foi programado e a cânula foi inserida.\n\nPor favor, verifique se a cânula foi inserida corretamente e altere seu Pod se você acha que não. + Pod Desativado + Pressione Próximo para desativar o Pod.\n\nNota: Isso irá suspender todas as administrações de insulina e desativar o Pod. + Desativando o Pod + Desativação do Pod.\n\nQuando a desativação for concluída com sucesso, pressione Próximo. + Pod desativado + Seu Pod foi desativado.\n\nPor favor, remova o Pod do seu corpo e o recicle. + Pod descartado + O estado do Pod foi descartado. A entrega da insulina não foi suspensa porque o Pod não foi adequadamente desativado!\n\nPor favor, remova o Pod do seu corpo e o recicle. + Se você descartar o Pod, você não será mais capaz de se comunicar com ela. Você só deve fazer isso quando todas as comunicações com o Pod falharem persistentemente. Você tem certeza que deseja descartar o Pod? + Descartar o Pod + Beeps de bolus ativados + Beeps de basais ativados + Beeps de SMB ativados + Beeps de taxa basal temporária ativados + Mostrar botão de suspensão de entrega na aba Omnipod + Detecção de fuso horário/zona de horário de verão ativada + Lembrete de expiração ativado + Horas antes do desligamento + Alerta de reservatório baixo habilitado + Número de unidades + Silenciar alertas do Pod automaticamente + Outro + Alertas + Beeps de confirmação + Notificações + Sons para notificações incertas de taxa basal temporária ativados + Sons para notificações incertas de taxa basal temporária ativados + Sons para notificações incertas de bolus ativados + Nenhum Pod Ativo + Configuração em andamento (aguardando ativação do Pod) + Configuração em andamento (aguardando inserção da cânula) + Funcionando + Suspenso + Falha do Pod + Tempo de ativação excedido + Inativo + Falha do Pod: %1$03d %2$s + Pod Desativado + Descartar Pod + Definir Bólus + Cancelar bolus + Definir Basal temporário + Cancelar basal temporária (internamente pelo driver) + Cancelar a basal temporária + Definir a programação basal + Obter status do Pod + Obter informações do Pod + Configurar a hora + Configurar alertas + Silenciar alertas + Suspender a entrega + Reiniciar a administração + Entrada desconhecida + Inicializar o Pod + Inserir Cânula + Ler Log do Pulso + Definir basal temporária falsa porque o Pod está suspenso + Cancelar basal temporária falsa que foi criado porque o Pod estava suspenso + Separar a basal temporária devido a falhas incertas no cancelamento + Configuração de bipe + Fazendo testes sonoros + Encerrar o lembrete de pareamento + Terminar o lembrete de configuração + Pod vai expirar em breve + Pod vai expirar em breve + Desligamento iminente + Reservatório baixo + Alerta Desconhecido + Nenhum Pod Ativo + Última conexão: %1$d minutos atrás + Último bolus: %1$s @ %2$s + AlvoTemporário: %1$s + Estendido: %1$s + Reservatório: %1$sU + Sim + Não + OK + Cancelar + Aviso + Momentos atrás + Há menos de um minuto + %1$s e %2$s + %1$s atrás + + %1$d minuto + %1$d minutos + + + %1$d hora + %1$d horas + + + %1$d dia + %1$d dias + + + Alerta de Pod %1$s + Alertas de Pod: %1$s + diff --git a/pump/omnipod-common/src/main/res/values-ru-rRU/strings.xml b/pump/omnipod-common/src/main/res/values-ru-rRU/strings.xml index d7fe97eac0..9a3521b68c 100644 --- a/pump/omnipod-common/src/main/res/values-ru-rRU/strings.xml +++ b/pump/omnipod-common/src/main/res/values-ru-rRU/strings.xml @@ -11,9 +11,9 @@ Если нажать Утилизировать Pod, вы больше не сможете обмениваться командами с Pod. Сделайте это только в том случае, если связь с помпой постоянно отсутствует. Если связь с Pod еще возможна, воспользуйтесь опцией Деактивировать Pod.\n\n Если все же хотите продолжить, снимите помпу с тела! Воспроизвести тестовый звуковой сигнал Воспроизводится тестовый звуковой сигнал… - Журнал помпы + Журнал Pod - Активная помпа не выбрана + Нет активных Pod Настройка базального профиля не состоялась. Болюс не подан. Не удалось задать базальный профиль: получен пустой профиль. Активируйте профиль базала. diff --git a/pump/omnipod-common/src/main/res/values-sr-rCS/strings.xml b/pump/omnipod-common/src/main/res/values-sr-rCS/strings.xml index e35fcaa95a..28e1a5c32b 100644 --- a/pump/omnipod-common/src/main/res/values-sr-rCS/strings.xml +++ b/pump/omnipod-common/src/main/res/values-sr-rCS/strings.xml @@ -6,9 +6,11 @@ + Izađi + Ostalo diff --git a/pump/omnipod-dash/src/main/res/values-af-rZA/strings.xml b/pump/omnipod-dash/src/main/res/values-af-rZA/strings.xml index 942b365512..759fb22223 100644 --- a/pump/omnipod-dash/src/main/res/values-af-rZA/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-af-rZA/strings.xml @@ -3,7 +3,10 @@ + Datum + %1$.2f U + %1$.2f U diff --git a/pump/omnipod-dash/src/main/res/values-ca-rES/strings.xml b/pump/omnipod-dash/src/main/res/values-ca-rES/strings.xml index 942b365512..7b8c1e956c 100644 --- a/pump/omnipod-dash/src/main/res/values-ca-rES/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-ca-rES/strings.xml @@ -1,9 +1,22 @@ + Integració de la bomba per Omnipod Dash (el nou model amb Bluetooth i agulla amb tap blau). + Historial del pod + Descripció + Font + Data + Tipus: + %1$.2f U + %1$.2f U, CH=%2$.1f g + Basal: %1$.2f U, durada: %2$d minuts + Estat Bluetooth + Adreça Bluetooth + Basal: %1$.2f U, durada: %2$d minuts + %1$.2f U diff --git a/pump/omnipod-dash/src/main/res/values-el-rGR/strings.xml b/pump/omnipod-dash/src/main/res/values-el-rGR/strings.xml index 942b365512..7d0dbe22ce 100644 --- a/pump/omnipod-dash/src/main/res/values-el-rGR/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-el-rGR/strings.xml @@ -3,7 +3,11 @@ + Περιγραφή + Ημερομηνία + %1$.2f U + %1$.2f U diff --git a/pump/omnipod-dash/src/main/res/values-hr-rHR/strings.xml b/pump/omnipod-dash/src/main/res/values-hr-rHR/strings.xml index 942b365512..666f7c16c6 100644 --- a/pump/omnipod-dash/src/main/res/values-hr-rHR/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-hr-rHR/strings.xml @@ -3,6 +3,7 @@ + Tip: diff --git a/pump/omnipod-dash/src/main/res/values-hu-rHU/strings.xml b/pump/omnipod-dash/src/main/res/values-hu-rHU/strings.xml index 942b365512..46c5c82092 100644 --- a/pump/omnipod-dash/src/main/res/values-hu-rHU/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-hu-rHU/strings.xml @@ -3,7 +3,9 @@ + %1$.2f E + %1$.2f E diff --git a/pump/omnipod-dash/src/main/res/values-ko-rKR/strings.xml b/pump/omnipod-dash/src/main/res/values-ko-rKR/strings.xml index 91fdf1f9e3..270d1df315 100644 --- a/pump/omnipod-dash/src/main/res/values-ko-rKR/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-ko-rKR/strings.xml @@ -4,7 +4,19 @@ 옴니파드 대쉬(파란색 바늘 캡이 달린 새로운 블루투스 연결 모델)를 위한 펌프 통합 + Pod 이력 + 상세설명 + 소스 + 날짜 + 종류: + %1$.2f U + %1$.2f U, CH=%2$.1f g + Rate: %1$.2f U, 기간: %2$d 분 + 블루투스 상태 + 블루투스 주소 + Rate: %1$.2f U, 기간: %2$d 분 + %1$.2f U diff --git a/pump/omnipod-dash/src/main/res/values-pt-rBR/strings.xml b/pump/omnipod-dash/src/main/res/values-pt-rBR/strings.xml index 942b365512..99af429dc7 100644 --- a/pump/omnipod-dash/src/main/res/values-pt-rBR/strings.xml +++ b/pump/omnipod-dash/src/main/res/values-pt-rBR/strings.xml @@ -1,9 +1,41 @@ + Integração da bomba para o Omnipod Dash (o novo modelo habilitado com Bluetooth com uma agulha de tampa azul). + Histórico do Pod + Descrição + Origem + Data + Tipo: + %1$.2f U + %1$.2f U, Carboidratos=%2$.1f g + Taxa: %1$.2f U, duração: %2$d minutos + Status do bluetooth + Endereço Bluetooth + Firmware %1$s / Bluetooth %2$s + Qualidade da conexão + Status da entrega + Preencha um novo Pod + com insulina suficiente para 3 dias.\n\nEscute dois beeps do Pod durante o processo de preenchimento. Eles indicam que a quantidade mínima de 80U foi inserida. Certifique-se de esvaziar completamente a seringa de preenchimento, mesmo depois de ouvir os dois beeps.\n\nDepois de preencher o Pod, por favor, pressione Next.\n\nNota: não remova a tampa da agulha do Pod neste momento. + Tentando parear com o novo Pod e preenchê-lo.\n\nQuando o processo de inicialização for concluído com sucesso, pressione Next. + Som quando ativar a notificação de suspensão da administração + Falha de conexão ao pod + Encontrados muitos pods para ativação + Não foi possível encontrar um pod disponível para ativação + Erro genérico: %1$s + Falha no envio do comando + Comando não enviado + Comando não recebido pelo pod + Status desconhecido para o comando + Taxa: %1$.2f U, duração: %2$d minutos + %1$.2f U + A administração da insulina está suspensa + Conexão perdida com o pod + Outro bolus está sendo administrado + Não há insulina suficiente no reservatório diff --git a/pump/omnipod-eros/src/main/res/values-af-rZA/strings.xml b/pump/omnipod-eros/src/main/res/values-af-rZA/strings.xml index bc89093c83..6f19cf1460 100644 --- a/pump/omnipod-eros/src/main/res/values-af-rZA/strings.xml +++ b/pump/omnipod-eros/src/main/res/values-af-rZA/strings.xml @@ -4,10 +4,15 @@ + Kennisgewings + RileyLink + Datum + %1$.2f U + Herstel RileyLink Konfig diff --git a/pump/omnipod-eros/src/main/res/values-ca-rES/strings.xml b/pump/omnipod-eros/src/main/res/values-ca-rES/strings.xml index bc89093c83..4304ca380e 100644 --- a/pump/omnipod-eros/src/main/res/values-ca-rES/strings.xml +++ b/pump/omnipod-eros/src/main/res/values-ca-rES/strings.xml @@ -1,13 +1,72 @@ + Integració de la bomba per Omnipod Eros (el model antic amb agulla amb tap transparent). Requereix un dispositiu RileyLink amb firmware versió 2.0 o superior. + Notificacions + Mostrar botó \"Registre de pols\" al menú de gestió del pod + Mostrar botó \"Estadístiques RileyLink\" al menú de gestió del pod + Activar registre de canvi de pila a Accions + RileyLink + Habilitat so per avisos de TBR dubtoses + Habilitat so per avisos de SMB dubtosos + Habilitat so per avisos de bolus dubtosos + Historial del pod + Descripció + Font + Data + Tipus: + %1$.2f U + %1$.2f U, CH=%2$.1f g + Basal: %1$.2f U, durada: %2$d minuts + RLBatt: %1$d + Adreça RileyLink no vàlida. + Error de comunicació: ha fallat la verificació de la integritat del missatge + Error de comunicació: s\'ha rebut del pod un paquet no vàlid + Error de comunicació: estat del pod no correcte + Error de comunicació: s\'ha rebut del pod una resposta no vàlida + Error de comunicació: s\'ha rebut del pod un missatge amb un nr. de seqüència no vàlid + Error de comunicació: s\'ha rebut del pod un missatge amb una adreça no vàlida + Error de comunicació: no s\'ha pogut descodificar un missatge del pod + Error de comunicació: error en resincronitzar nonce + Error de comunicació: nonce no sincronitzat + Error de comunicació: no s\'han rebut prou dades des del pod + S\'ha detectat (%1$03d %2$s) un error del pod. Si us plau desactiveu el pod i activeu-ne un de nou + Error de comunicació: el pod ha retornat missatge d\'error + RileyLink no respon + RileyLink interromput + El pod no respon + Error en configurar el perfil basal. El lliurament d\'insulina podria suspendre\'s! Actualitzeu manualment l\'estat del pod des de la pestanya Ominipod i repreneu el lliurament si cal. + Possible error en configurar el perfil basal. El lliurament d\'insulina podria suspendre\'s! Actualitzeu l\'estat del pod des de la pestanya Omnipod i repreneu el lliurament si cal. + Error en configurar el perfil basal. S\'ha aturat el lliurament d\'insulina! Repreneu-lo manualment des de la pestanya Omnipod. + Possible error en cancel·lar basal temporal. Actualitzeu manualment l\'estat del pod des de la pestanya Omnipod. + Possible error en establir basal temporal. Si hi havia una basal temporal activa, pot haver estat cancel·lada. Actualitzeu manualment l\'estat del pod des de la pestanya Omnipod. + Possible error en establir basal temporal. Si hi havia una basal temporal activa, pot haver estat cancel·lada. Actualitzeu manualment l\'estat del pod des de la pestanya Omnipod. + La durada de la TBR ha de ser major que zero i múltiple de %1$s minuts. + Error en configurar la hora. El lliurament d\'insulina podria suspendre\'s! Actualitzeu manualment l\'estat del pod des de la pestanya Ominipod i repreneu el lliurament si cal. + Error en configurar la hora. S\'ha aturat el lliurament d\'insulina! Repreneu-lo manualment des de la pestanya Omnipod. + Error en llegir el registre de pols + Error en el canvi d\'hora automàtic al pod. Haurieu de sincronitzar l\'hora a la pestanya Omnipod. + Operació no possible.\n\n Heu de configurar la bomba Omnipod abans de fer servir aquesta operació. + No s\'ha pogut verificar si el bolus ha estat lliurat. Verifiqueu manualment que el pod està lliurant bolus escoltant els clics. Si esteu segurs que el bolus no s\'ha lliurat, haurieu d\'eliminar manualment el registre de bolus a Tractaments, fins i tot si ara feu \'Cancel·lar bolus\'! + No s\'ha pogut verificar si el bolus SMB (%1$.2f U) ha estat lliurat. Si esteu segurs que el bolus no s\'ha lliurat, haurieu d\'eliminar manualment el registre de SMB a Tractaments + Hi ha una basal temporal en curs al pod, però AAPS no n\'és conscient. Si us plau cancel·leu la basal temporal manualment. + Estadístiques RileyLink + Esperant la connexió a RileyLink… + Restablir configuració RileyLink + Llegir registre de pols + Llegint registre de pols… + Registre de pols + Registre de pols (copiat al porta-retalls) + Empleneu un nou pod amb prou insulina per 3 dies.\n\nDurant el procés d\'emplenament el pod hauria de pitar dues vegades. Això indica que s\'ha inserit la quantitat mínima de 80U. Assegureu-vos de buidar completament la jeringa, fins i tot després d\'haver escoltat els dos bips.\n\nDesprés d\'emplenar el pod, premeu Següent.\n\nNota:no retireu el tap de l\'agulla en aquest moment.\nNota:poseu el RileyLink en posició vertical i a prop del pod. + Intentant emparellar amb el nou pod i encebar-lo.\n\nUn cop finalitzi el procés d\'inicialització, podeu prémer Següent\n\nNota:poseu el RileyLink en posició vertical i situeu-hi el pod a pocs centímetres. + indeterminat diff --git a/pump/omnipod-eros/src/main/res/values-el-rGR/strings.xml b/pump/omnipod-eros/src/main/res/values-el-rGR/strings.xml index bc89093c83..6b7516135a 100644 --- a/pump/omnipod-eros/src/main/res/values-el-rGR/strings.xml +++ b/pump/omnipod-eros/src/main/res/values-el-rGR/strings.xml @@ -4,10 +4,16 @@ + Ειδοποιήσεις + RileyLink + Περιγραφή + Ημερομηνία + %1$.2f U + Επαναφορά Ρυθμίσεων RileyLink diff --git a/pump/omnipod-eros/src/main/res/values-hr-rHR/strings.xml b/pump/omnipod-eros/src/main/res/values-hr-rHR/strings.xml index bc89093c83..49376df755 100644 --- a/pump/omnipod-eros/src/main/res/values-hr-rHR/strings.xml +++ b/pump/omnipod-eros/src/main/res/values-hr-rHR/strings.xml @@ -5,9 +5,11 @@ + Tip: + Resetirajte konfiguraciju RileyLink diff --git a/pump/omnipod-eros/src/main/res/values-hu-rHU/strings.xml b/pump/omnipod-eros/src/main/res/values-hu-rHU/strings.xml index bc89093c83..5e0af9bb6e 100644 --- a/pump/omnipod-eros/src/main/res/values-hu-rHU/strings.xml +++ b/pump/omnipod-eros/src/main/res/values-hu-rHU/strings.xml @@ -4,10 +4,13 @@ + RileyLink + %1$.2f E + RileyLink beállítás törlése diff --git a/pump/omnipod-eros/src/main/res/values-pt-rBR/strings.xml b/pump/omnipod-eros/src/main/res/values-pt-rBR/strings.xml index e597b2df01..de8d69ede4 100644 --- a/pump/omnipod-eros/src/main/res/values-pt-rBR/strings.xml +++ b/pump/omnipod-eros/src/main/res/values-pt-rBR/strings.xml @@ -1,17 +1,72 @@ + Integração da bomba para o Omnipod Eros (o modelo mais antigo com uma tampa transparente de agulha). Requer um dispositivo RileyLink com pelo menos a versão firmware 2.0. + Notificações + Mostrar botão de pulso Log no menu de gerenciamento do Pod + Mostrar estatísticas do botão RileyLink no menu de gerenciamento do Pod + Habilitar o log de mudança de bateria em Ações + RileyLink + Sons para notificações incertas de taxa basal temporária ativados + Sons para notificações incertas de SMB ativados + Sons para notificações incertas de bolus ativados + Histórico do Pod + Descrição + Fonte + Data + Tipo: + %1$.2f U + %1$.2f U, Carboidratos=%2$.1f g + Taxa: %1$.2f U, duração: %2$d minutos + RLBatt: %1$d + Endereço RileyLink inválido. + Comunicação falhou: falha na verificação de integridade das mensagens + Comunicação falhou: recebido um pacote inválido do Pod + Comunicação falhou: o Pod está em estado errado + Comunicação falhou: recebida uma resposta inválida do Pod + Comunicação falhou: recebida uma mensagem com sequência numérica inválida do Pod + Comunicação falhou: recebida uma mensagem com endereço inválido do Pod + Comunicação falhou: não conseguiu decodificar mensagem do Pod + Comunicação falhou: falha em uma única ressincronização + Comunicação falhou: uma única vez fora de sincronização + Comunicação falhou: não há dados suficientes recebidos do Pod + Foi detectada uma falha do Pod (%1$03d %2$s). Por favor, desative seu Pod e ative um novo + Comunicação falhou: o Pod retornou uma resposta de erro + Nenhuma resposta do RileyLink + RileyLink interrompido + Nenhuma resposta do Pod + Configuração do perfil basal falhou. A entrega pode ser suspensa! Por favor atualize manualmente o status do Pod da aba Omnipod e retome a entrega, se necessário. + Configuração do perfil basal pode ter falhado. A administração pode estar suspensa! Por favor atualize manualmente o status do Pod da aba Omnipod e retome a administração se necessário. + Configuração do perfil basal falhou. A administração foi suspensa! Por favor retome manualmente a administração na aba Omnipod. O cancelamento do basal temporário pode ter falhado. Por favor, atualize manualmente o status do Pod na aba Omnipod. Falha ao configurar basal temporário. Se um basal temporário estava sendo executado, pode ter sido cancelado. Por favor, atualize manualmente o status do Pod na aba Omnipod. Configuração de basal temporário pode ter falhado. Se um basal temporário estava sendo executado, ele foi cancelado. Por favor, atualize manualmente o status do Pod na aba Omnipod. Duração da TBT precisa ser maior que zero e múltipla de %1$s minutos. + Configuração do perfil basal pode ter falhado. A administração pode estar suspensa! Por favor atualize manualmente o status do Pod da aba Omnipod e retome a administração se necessário. + Falha na configuração. A entrega está suspensa! Por favor retome manualmente a aplicação na aba Omnipod. + Falha ao ler o Pulse Log + Falha ao trocar automaticamente o horário no Pod. Você deve sincronizar manualmente o horário na aba Omnipod. + Esta operação não é possível.\n\nVocê primeiro precisa configurar o Omnipod para depois realizar a operação. + Não foi possível verificar se o bolus foi bem sucedido. Por favor, verifique manualmente se o seu Pod está administrando bolus ouvindo cliques. Se você tem certeza de que o bolus não conseguiu, você deve apagar manualmente a entrada de bolus dos tratamentos, mesmo se você clicar em \'Cancelar bolus\' agora! + Não foi possível verificar se o bolus SMB (%1$.2f U) foi bem sucedido. Se você tem certeza de que o Bolus não foi bem sucedido, você deve excluir manualmente a entrada SMB de Tratamentos. + Uma basal temporária está sendo executada no Pod, mas o AAPS não está ciente desta basal temporária. Por favor cancele sua basal temporária manualmente. + Status do RileyLink + Aguardando RileyLink conectar... + Redefinir configuração RileyLink + Ler Log do Pulso + Lendo Pulse Log... + Pulse Log + Pulse Log (copiado para área de transferência) + Preencha um novo Pod com insulina suficiente para 3 dias.\n\nEscute dois bips do Pod durante o processo de preenchimento. Eles indicam que a quantidade mínima de 80U foi inserida. Certifique-se de esvaziar completamente a seringa de preenchimento, mesmo depois de ouvir os dois bips.\n\nDepois de preencher o Pod, por favor, pressione Próximo.\n\nNota: não remova a proteção da agulha do Pod neste momento.\nNota: por favor, coloque o RileyLink em uma posição vertical e coloque o Pod a poucos centímetros de distância dele. + Tentando emparelhar com o novo Pod e purgá-lo.\n\nQuando o processo de inicialização for concluído com sucesso, pode pressionar Próximo.\n\nNota: por favor, posicione o RileyLink na posição vertical e coloque o Pod a alguns centímetros de distância dele. + incerto diff --git a/pump/pump-common/src/main/res/values-af-rZA/strings.xml b/pump/pump-common/src/main/res/values-af-rZA/strings.xml index 555b0265bf..b83741f98f 100644 --- a/pump/pump-common/src/main/res/values-af-rZA/strings.xml +++ b/pump/pump-common/src/main/res/values-af-rZA/strings.xml @@ -1,12 +1,55 @@ + Operasie nie ondersteun deur pomp en/of drywer. Operasie nog nie ondersteun deur pomp. + OK + Pomp Reeks Nommer + Nooit gekontak nie + Besig om te wek + Fout met kommunikasie + Te lank op kommunikasie gewag + Pomp onbereikbaar + Ongeldige konfigirasie + Aktief + Slaap + Basale + Konfigurasies + Kennisgewings + Statistiek + Onbekend + Alle + Boluses + Prima + Alarms + Glukose + Ander + Skan + Staak + Verkose + Skandeer + Skandering voltooi + Skaderings fout: %1$d + Nooit + Verwyder + Bluetooth afgeskakel + Geen Bluetooth Toestel + Pomp onbereikbaar + Verkeerde Maks Bolus gestel op Pomp(moet %1$.2f wees). + Verkeerde Maks Basale op Pomp (moet %1$.2f %1$.2f wees),. + + %1$d dae + %1$d dae + + + %1$d uur + %1$d ure + diff --git a/pump/pump-common/src/main/res/values-bg-rBG/strings.xml b/pump/pump-common/src/main/res/values-bg-rBG/strings.xml index 6d8edea0a3..f36b9672ab 100644 --- a/pump/pump-common/src/main/res/values-bg-rBG/strings.xml +++ b/pump/pump-common/src/main/res/values-bg-rBG/strings.xml @@ -4,7 +4,10 @@ Помпата не поддържа тази операция. Операцията не се поддържа от помпата (ВСЕ ОЩЕ). ОК + Сериен номер на помпа + %1$.2fЕ / %2$.2fЕ доставени + Никога не сме се свързвали Събуждане Грешка в комуникацията Изтече времето за връзка @@ -12,6 +15,8 @@ Грешна конфигурация Активна Спинка си + Под не е инициализиран + Прекратено Базали Конфигурации @@ -23,11 +28,27 @@ Пълнене Аларми Кръвна захар + Друго + Сканирай + Спри + Избрано + Сканиране + Завършено сканиране + Грешка при сканиране: %1$d + Никога + Изтрий + Bluetooth е изключен + Няма Bluetooth адаптер + Помпата е недостъпна + Базалните профили/настройки не са позволен в помпата. Включванете го от настройките на помпата. + Грешен максимален болус в помпата ( трябвба да е %1$.2f). + Грешен макс мазал в помпата (трябва да е %1$.2f). + Тип: %1$d ден %1$d дни diff --git a/pump/pump-common/src/main/res/values-ca-rES/strings.xml b/pump/pump-common/src/main/res/values-ca-rES/strings.xml index 9c30e430ff..2a0ebc70be 100644 --- a/pump/pump-common/src/main/res/values-ca-rES/strings.xml +++ b/pump/pump-common/src/main/res/values-ca-rES/strings.xml @@ -3,7 +3,11 @@ Operació no compatible amb la bomba i/o controlador. Operació no compatible ENCARA amb la bomba. + OK + Número de sèrie bomba + %1$.2f U / %2$.2f U lliurades + Mai contactada Iniciant Error de comunicació Temps d\'espera excedit en la comunicació @@ -11,6 +15,7 @@ Configuració no vàlida Activa En suspens + En pausa Basals Configuracions @@ -21,11 +26,28 @@ Bolus Encebaments Alarmes + Glucèmia + Altres + Escanejar + Aturar + Seleccionat + Escanejant + Escaneig finalitzat + Error d\'escaneig: %1$d + Mai + Eliminar + Bluetooth desactivat + No hi ha adaptador Bluetooth + Bomba no accessible + Perfils de basal configurats no activats a la bomba. Activeu-los a la bomba. + Bolus màx. erroni configurat a la bomba (ha de ser %1$.2f). + Basal màx. errònia configurada a la bomba (ha de ser %1$.2f). + Tipus: %1$d dia %1$d dies diff --git a/pump/pump-common/src/main/res/values-da-rDK/strings.xml b/pump/pump-common/src/main/res/values-da-rDK/strings.xml index 3fb031c1f9..91a4e2a8cc 100644 --- a/pump/pump-common/src/main/res/values-da-rDK/strings.xml +++ b/pump/pump-common/src/main/res/values-da-rDK/strings.xml @@ -5,6 +5,7 @@ Operationen er ikke understøttet af pumpen ENDNU. OK Pumpe Serienummer + %1$.2f IE / %2$.2f IE leveret Aldrig kontaktet Vågner diff --git a/pump/pump-common/src/main/res/values-el-rGR/strings.xml b/pump/pump-common/src/main/res/values-el-rGR/strings.xml index 11a7c88fb4..d7de5e5a37 100644 --- a/pump/pump-common/src/main/res/values-el-rGR/strings.xml +++ b/pump/pump-common/src/main/res/values-el-rGR/strings.xml @@ -1,12 +1,55 @@ + Η λειτουργία δεν υποστηρίζεται από την αντλία ή/και οδηγό. Η λειτουργία δεν υποστηρίζεται ΑΚΟΜΑ από την αντλία. + ΟΚ + Σειριακός Αριθμός Αντλίας + Ποτέ δεν επικοινωνήσατε + Ξύπνημα + Σφάλμα με επικοινωνία + Λήξη χρόνου επικοινωνίας + Η αντλία δεν είναι διαθέσιμη + Μη έγκυρη παραμετροποίηση + Ενεργή + Sleeping + Βασικοί + Ρύθμιση παραμέτρων + Ειδοποιήσεις + Στατιστικά + Άγνωστα + Όλα + Bolus + Πλήρωση + Συναγερμοί + Γλυκόζη + Άλλο + Scan + Stop + Επιλεγμένο + Σάρωση + Η σάρωση ολοκληρώθηκε + Λάθος σάρωσης: %1$d + Ποτέ + Μετακίνηση + Bluetooth απενεργοποιημένο + Δεν υπάρχει προσαρμογέας Bluetooth + Η αντλία δεν είναι διαθέσιμη + Λάθος μέγιστο bolus ορίστηκε στην αντλία (πρέπει να είναι %1$.2f). + Λάθος μέγιστο Βασικού ορίστηκε στην αντλία (πρέπει να είναι %1$.2f). + + %1$d ημέρες + %1$d ημέρες + + + %1$d hour + %1$d ώρες + diff --git a/pump/pump-common/src/main/res/values-ga-rIE/strings.xml b/pump/pump-common/src/main/res/values-ga-rIE/strings.xml index 33c77af761..6bf78d23ab 100644 --- a/pump/pump-common/src/main/res/values-ga-rIE/strings.xml +++ b/pump/pump-common/src/main/res/values-ga-rIE/strings.xml @@ -1,8 +1,15 @@ + Ceart go leor + Gníomhach + Bunaidhi + Ar fad + Bólasi + Aláraim + Glúcóis diff --git a/pump/pump-common/src/main/res/values-hr-rHR/strings.xml b/pump/pump-common/src/main/res/values-hr-rHR/strings.xml index 33c77af761..cd61470ff6 100644 --- a/pump/pump-common/src/main/res/values-hr-rHR/strings.xml +++ b/pump/pump-common/src/main/res/values-hr-rHR/strings.xml @@ -1,11 +1,56 @@ + Serijski broj pumpe + Pumpa nedostupna + Nije inicijalizirano + Inicijalizirano + Šifriranje komunikacije + Spremno + Zauzet + Suspendiran + Izvršavanje naredbe + Svi + Bolusi + Osnova + Ostalo + Svi događaji + Događaji (bez statistike) + Danas + Zadnjih sat vremena + Zadnja 3 sata + Zadnjih 6 sati + Zadnjih 12 sati + Zadnja 2 dana + Zadnja 4 dana + Prošli tjedan + Prošli mjesec + Pretraži + Zaustavi + Odabrano + Pretraživanje + Skeniranje završeno + Pogreška skeniranja: %1$d + Nikada + Ukloniti + Bluetooth onemogućen + Nema Bluetooth adaptera + Konfigurirana pumpa nije pronađena + Pumpa nedostupna + Povezivanje s BLE uređajem nije uspjelo + Šifriranje nije uspjelo + Pronađena nepovezana pumpa + Postavka bazalnih profila/uzoraka nije omogućena na pumpi. Uključite ga na pumpi. + Bazalni profil postavljen na pumpi nije točan (mora biti %s). + Na pumpi je postavljen pogrešan tip TBR (mora biti %s). + Pogrešan maksimalni bolus postavljen na pumpi (mora biti %1$.2f). + Pogrešno podešen maksimalni bazal na pumpi (mora biti %1$.2f). + Tip: diff --git a/pump/pump-common/src/main/res/values-hu-rHU/strings.xml b/pump/pump-common/src/main/res/values-hu-rHU/strings.xml index 9453621bea..552a2fc350 100644 --- a/pump/pump-common/src/main/res/values-hu-rHU/strings.xml +++ b/pump/pump-common/src/main/res/values-hu-rHU/strings.xml @@ -1,12 +1,33 @@ + OK + Pumpa sorozatszáma + Pumpa nem elérhető + Bázis + Statisztikák + Glükóz + Egyéb + Keresés + Leállít + Kiválasztott + Keresés + Keresés befejezve + Hiba kereséskor: %1$d + Soha + Eltávolít + Bluetooth kikapcsolva + Nincs Bluetooth adapter + Pumpa nem elérhető + Bázis profilok/sémák beállítás nincs engedélyezve a pumpán. Engedélyezze a pumpán. + Hibás a pumpán beállított Max. Bólus (%1$.2f kell legyen). + Hibás a pumpán beállított Max. Bázis (%1$.2f kell legyen). %1$d nap diff --git a/pump/pump-common/src/main/res/values-ko-rKR/strings.xml b/pump/pump-common/src/main/res/values-ko-rKR/strings.xml index e247034563..75bfce664a 100644 --- a/pump/pump-common/src/main/res/values-ko-rKR/strings.xml +++ b/pump/pump-common/src/main/res/values-ko-rKR/strings.xml @@ -1,14 +1,53 @@ + 펌프 및/또는 드라이버가 작동을 지원하지 않습니다. 펌프에서 지원되지 않는 작동. + + 펌프 일련번호 + %1$.2f U / %2$.2f U 주입됨 + 연결되지 않은 + 시작중 + 연결오류 + 연결시간초과 + 펌프에 연결할 수 없습니다. + 유효하지 않은 설정 + 활성 + 수면 + 중지됨 + Basal + 환경설정 + 알림 + 통계 + 알수없음 + 모든 + Boluses + 교체 + 알람 + 혈당 + 기타 + 스캔하기 + 정지 + 선택됨 + 스캔중 + 스캔 완료 + 스캔 에러: %1$d + 절대 + 삭제 + 블루투스 비활성 + 블루투스 어댑터 없음 + 펌프에 연결할 수 없습니다. + Basal 프로파일/패턴 설정이 펌프에서 활성화되지 않았습니다. 펌프에서 활성화해주세요. + 펌프에 잘못된 최대 Bolus가 설정되었습니다 (%1$.2f 이어야 합니다.). + 펌프에 잘못된 최대 Basal이 설정되었습니다 (%1$.2f 이어야 합니다). + 종류: %1$d 일 diff --git a/pump/pump-common/src/main/res/values-lt-rLT/strings.xml b/pump/pump-common/src/main/res/values-lt-rLT/strings.xml index 84e1d1c00b..0f5bbf7766 100644 --- a/pump/pump-common/src/main/res/values-lt-rLT/strings.xml +++ b/pump/pump-common/src/main/res/values-lt-rLT/strings.xml @@ -4,7 +4,10 @@ Pompa ir/ar jos valdiklis nepalaiko operacijos. Pompa dar nepalaiko operacijos. Gerai + Pompos serijos Nr. + %1$.2f vv iš %2$.2f vv suleista + Niekada nebuvo sujungta Pažadinimas Ryšio klaida Ryšiui skirtas laikas baigėsi @@ -12,6 +15,8 @@ Neteisinga konfigūracija Aktyvi Užmigusi + Nepavyko paleisti + Sustabdyta Bazė Nustatymai @@ -23,11 +28,27 @@ Užpildyti sistemą Aliarmai Gliukozė + Kiti + Skanuoti + Stop + Parinkta + Skanuojama + Skanavimas baigtas + Skanavimo klaida: %1$d + Niekada + Pašalinti + Bluetooth išjungtas + Nėra Bluetooth adapterio + Pompa nepasiekiama + Bazės profilis / nustatymas pompoje nėra įgalintas. Įgalinkite jį pompoje. + Pompoje nustatytas neteisingas Max Bolusas (turi būti %1$.2f). + Pompoje nustatyta neteisinga Maks val. bazė (turi būti %1$.2f). + Tipas: %1$d d. %1$d d. diff --git a/pump/pump-common/src/main/res/values-nl-rNL/strings.xml b/pump/pump-common/src/main/res/values-nl-rNL/strings.xml index acecd97957..ee21e52a83 100644 --- a/pump/pump-common/src/main/res/values-nl-rNL/strings.xml +++ b/pump/pump-common/src/main/res/values-nl-rNL/strings.xml @@ -4,6 +4,8 @@ Bewerking niet ondersteund door pomp en/of driver. Operatie NOG niet ondersteund door de pomp. OK + Serienummer van de pomp + %1$.2f E / %2$.2f E toegediend Nooit verbonden Actief worden @@ -13,6 +15,13 @@ Ongeldige configuratie Actief Slapen + Niet geïnitialiseerd + Geïnitialiseerd + Communicatie wordt versleutelen + Gereed + Bezig + Onderbroken + Commando uitvoeren Basaalstanden Instellingen @@ -24,9 +33,59 @@ Vullen Alarmen Glucose + Basis + Anders + Alle gebeurtenissen + Gebeurtenissen (geen status) + Vandaag + Afgelopen uur + Laatste 3 uur + Laatste 6 uur + Laatste 12 uur + Afgelopen 2 dagen + Afgelopen 4 dagen + Vorige week + Vorige maand + Scannen + Stop + Geselecteerd + Scannen + Scannen voltooid + Scanfout: %1$d + Nooit + Verwijderen + Bluetooth is uitgeschakeld + Geen Bluetooth Adapter + Geconfigureerde pomp niet gevonden + Pomp niet bereikbaar + Verbinding maken met BLE Apparaat mislukt + Versleutelen is mislukt + Niet gekoppelde pomp gevonden + De instelling voor basaalprofielen/schemas is niet ingeschakeld op de pomp. Schakel dit in op de pomp. + Basaal profiel ingesteld op pomp is onjuist (moet %s zijn). + Verkeerd TBR-type ingesteld op pomp (moet %s zijn). + Verkeerde Max Bolus instelling op pomp (moet %1$.2f zijn). + Verkeerde Max Basaal instelling op pomp (moet %1$.2f zijn). + Type: + + %1$d dag + %1$d dagen + + + %1$d uur + %1$d uren + + + %1$d uur geleden + %1$d uur geleden + + + %1$d dag geleden + %1$d dagen geleden + diff --git a/pump/pump-common/src/main/res/values-pl-rPL/strings.xml b/pump/pump-common/src/main/res/values-pl-rPL/strings.xml index b306d45c6e..c30d0aa466 100644 --- a/pump/pump-common/src/main/res/values-pl-rPL/strings.xml +++ b/pump/pump-common/src/main/res/values-pl-rPL/strings.xml @@ -1,14 +1,55 @@ + Operacja nie jest wspierana przez pompę i/lub sterownik pompy. + Operacja nie jest JESZCZE wspierana przez pompę. + OK + Numer seryjny pompy + podano %1$.2f U / %2$.2f U + Nigdy nie połączona + Wybudzanie + Błąd komunikacji + Przekroczony limit czasu połączenia + Pompa nieosiągalna + Nieprawidłowe ustawienia + Aktywna + Uśpiona + Nie zainicjowany + Wstrzymany + Dawki Bazowe + Ustawienia + Powiadomienia + Statystyki + Nieznane + Wszystko + Bolusy Napełnianie + Alarmy + Glukoza + Inne + Dziś + Skanuj + Stop + Wybrany + Skanowanie + Skanowanie zakończono + Błąd skanowania: %1$d + Nigdy + Usuń + Bluetooth wyłączony + Brak modułu Bluetooth + Pompa nieosiągalna + Ustawienia bazy/ wzorców nie są włączone w pompie. Włącz je na pompie. + Ustawiony na pompie typ Bolus Maksymalny jest niewłaściwy (musi być %1$.2f). + Ustawiony na pompie typ Bolus Maksymalny jest niewłaściwy (musi być %1$.2f). + Typ: %1$d dzień %1$d dni diff --git a/pump/pump-common/src/main/res/values-pt-rBR/strings.xml b/pump/pump-common/src/main/res/values-pt-rBR/strings.xml index 770dc80acb..cd7efed068 100644 --- a/pump/pump-common/src/main/res/values-pt-rBR/strings.xml +++ b/pump/pump-common/src/main/res/values-pt-rBR/strings.xml @@ -1,12 +1,91 @@ + Operação não suportada pela Bomba e/ou Controlador. Operação não suportada ainda pela Bomba. + OK + Número de série da Bomba + %1$.2fU / %2$.2fU administrada + Nunca contatado + A acordar + Erro com comunicação + Tempo limite para comunicação + Bomba inacessível + Configuração inválida + Ativo + A dormir + Bomba não inicializada + Inicializado + Comunicação criptografada + Preparado + Ocupado + Suspenso + Executando Comando + Basais + Configurações + Notificações + Estatísticas + Desconhecidos + Todos + Bolus + Purgar/Preencher + Alarmes + Glicose + Base + Outro + Todos os eventos + Eventos (sem Status) + Hoje + Última Hora + Últimas 3 horas + Últimas 6 horas + Últimas 12 horas + Últimos 2 Dias + Últimos 4 dias + Última semana + Último mês + Escanear + Parar + Seleccionado + A procurar + Procura terminada + Erro de Procura: %1$d + Nunca + Remover + Bluetooth desactivado + Nenhum Adaptador Bluetooth + Bomba Configurada Não Encontrada + Bomba inacessível + Falha ao se conectar ao dispositivo BLE + Falha na criptografia + Encontrada bomba não vinculada + A configuração de perfis/padrões da basal não éstá ativada na bomba. Ative-a na bomba. + Perfil Basal definido na bomba está incorreto (deve ser %s). + Tipo de DBT errado definido na bomba (deve ser %s). + Máx. Basal definida na Bomba está incorreta (deve ser %1$.2f). + Máx. Basal definido errado na Bomba (deve ser %1$.2f). + Tipo: + + %1$d dia + %1$d dias + + + %1$d hora + %1$d horas + + + %1$d hora atrás + %1$d horas atrás + + + %1$d dia atrás + %1$d dias atrás + diff --git a/pump/pump-common/src/main/res/values-pt-rPT/strings.xml b/pump/pump-common/src/main/res/values-pt-rPT/strings.xml index 77bc7ca340..ea37e4bfb6 100644 --- a/pump/pump-common/src/main/res/values-pt-rPT/strings.xml +++ b/pump/pump-common/src/main/res/values-pt-rPT/strings.xml @@ -4,7 +4,10 @@ Operação não suportada pela Bomba e/ou Controlador. Operação não suportada ainda pela Bomba. OK + Número de série da Bomba + %1$.2f U / %2$.2f U administrado + Nunca contactado A acordar Erro com comunicação Tempo limite para comunicação @@ -12,6 +15,8 @@ Configuração inválida Activo A dormir + Não inicializado + Suspenso Basais Configurações @@ -23,11 +28,27 @@ Purgar Alarmes Glucose + Outro + Procurar + Parar + Seleccionado + A procurar + Procura terminada + Erro de Procura: %1$d + Nunca + Remover + Bluetooth desactivado + Nenhum Adaptador Bluetooth + Bomba inacessível + A configuração de perfis/padrões de basal não está ativada na bomba. Ative-a na bomba. + Bólus Máximo definido na Bomba está incorreto (deve ser %1$.2f). + Índice Basal máximo definido na Bomba está incorrecto (deve ser %1$.2f). + Tipo: %1$d dia %1$d dias diff --git a/pump/pump-common/src/main/res/values-ro-rRO/strings.xml b/pump/pump-common/src/main/res/values-ro-rRO/strings.xml index 5ef0652d1d..96e855064e 100644 --- a/pump/pump-common/src/main/res/values-ro-rRO/strings.xml +++ b/pump/pump-common/src/main/res/values-ro-rRO/strings.xml @@ -4,7 +4,10 @@ Operațiunea nu este suportată de către pompă și/sau driver. Operațiunea nu este ÎNCĂ suportată de către pompă. OK + Număr serial pompă + %1$.2f U din %2$.2f U livrate + Niciodată contactată Se pornește Eroare de comunicație Comunicația nu a reușit la timp @@ -12,6 +15,8 @@ Configurație invalidă Activă În repaus + Neiniţializat + Suspendat Bazale Configurații @@ -23,11 +28,27 @@ Amorsare Alarme Glicemie + Altul + Scanare + Stop + Selectat + Scanează + Scanare terminată + Eroare la scanare: %1$d + Niciodată + Șterge + Bluetooth dezactivat + Nu există un adaptor Bluetooth + Pompă indisponibilă + Setările de profil/șablon bazale nu sunt activate în pompă. Vă rugăm să le activați din pompă. + Bolus maxim setat incorect în pompă (trebuie să fie %1$.2f). + Bazala maximă setată incorect în pompă (trebuie să fie %1$.2f). + Tip: %1$d zi %1$d zile diff --git a/pump/pump-common/src/main/res/values-sr-rCS/strings.xml b/pump/pump-common/src/main/res/values-sr-rCS/strings.xml index 33c77af761..bc292aa08d 100644 --- a/pump/pump-common/src/main/res/values-sr-rCS/strings.xml +++ b/pump/pump-common/src/main/res/values-sr-rCS/strings.xml @@ -3,6 +3,7 @@ + Ostalo diff --git a/pump/pump-common/src/main/res/values-sv-rSE/strings.xml b/pump/pump-common/src/main/res/values-sv-rSE/strings.xml index 22fbdda8af..fb2d4781fc 100644 --- a/pump/pump-common/src/main/res/values-sv-rSE/strings.xml +++ b/pump/pump-common/src/main/res/values-sv-rSE/strings.xml @@ -4,7 +4,10 @@ Operation stöds inte av pumpen/pumpdrivrutinen. Operationen stöds inte av pumpen ännu. OK + Serienummer på pumpen + %1$.2fU / %2$.2fU levererat + Aldrig ansluten Väcker Kommunikationsfel Kommunikationstimeout @@ -12,6 +15,8 @@ Felaktig konfiguration Aktiv Sover + Inte initierad + Pausad Basaldoser Konfigurationer @@ -23,11 +28,27 @@ Förfyllningar Larm Glukos + Annat + Sök + Stopp + Vald + Söker + Sökning avslutad + Fel vid sökning: %1$d + Aldrig + Ta bort + Bluetooth avstängt + Ingen bluetoothadapter + Pumpen kan inte nås + Basalprofiler är inte aktiverade på pumpen. Aktivera det i pumpens menyer. + Fel max bolus i pumpen (måste vara %1$.2f). + Fel max basal i pumpen (måste vara %1$.2f). + Typ: %1$d dag %1$d dagar diff --git a/pump/pump-common/src/main/res/values-zh-rCN/strings.xml b/pump/pump-common/src/main/res/values-zh-rCN/strings.xml index 33c77af761..412817da28 100644 --- a/pump/pump-common/src/main/res/values-zh-rCN/strings.xml +++ b/pump/pump-common/src/main/res/values-zh-rCN/strings.xml @@ -1,11 +1,87 @@ + 泵和/或驱动程序不支持此操作。 + 泵暂不支持此操作。 + OK + 泵序列号 + %1$.2f U / %2$.2f U 已输注 + 从未连接 + 唤醒中 + 通信出错 + 通信超时 + 泵无法连接 + 无效配置 + 启用 + 休眠 + 尚未初始化 + 已初始化 + 正在加密通信 + 就绪 + 忙碌 + 挂起 + 正在执行指令 + 基础率 + 配置 + 通知 + 统计信息 + 未知 + 全部 + 大剂量 + 充盈 + 告警 + 血糖 + 基础信息 + 其他 + 所有 + 事件 (无统计) + 今天 + 上个小时 + 过去3小时 + 过去6小时 + 过去12小时 + 过去2天 + 过去4天 + 过去一周 + 上个月 + 扫描 + 停止 + 已选中 + 扫描中 + 扫描完成 + 扫描错误: %1$d + 从未 + 删除 + 蓝牙已禁用 + 未找到蓝牙适配器 + 未找到已配置的泵 + 泵无法连接 + BLE设备无法连接 + 加密失败 + 找不到绑定的泵 + 泵上未启用基础率设置。请启用。 + 泵上设置的基础率配置错误 (应当为 %s)。 + 在泵上设置了错误的临时基础率类型 (必须是 %s) 。 + 泵上设置的最大大剂量错误 (应当为 %1$.2f)。 + 泵上设置的最大基础率错误 (应当为 %1$.2f)。 + 类型: + + %1$d 天 + + + %1$d 小时 + + + %1$d 小时前 + + + %1$d 天前 + diff --git a/pump/rileylink/src/main/res/values-af-rZA/strings.xml b/pump/rileylink/src/main/res/values-af-rZA/strings.xml index 1f34355deb..4a0fcf8e96 100644 --- a/pump/rileylink/src/main/res/values-af-rZA/strings.xml +++ b/pump/rileylink/src/main/res/values-af-rZA/strings.xml @@ -2,6 +2,15 @@ + Skan + Staak + Verkose + RileyLink Skan + Skandeer + Skandering voltooi + Skaderings fout: %1$d + Nooit + Verwyder Instellings Geskiedenis @@ -9,7 +18,14 @@ Pomp Status RileyLink Instellings RileyLink + Naam: + %1$d%% + Verbindingstatus: + Verbindingsfout: Toestel + Toestel Tipe: + Pomp Reeks Nommer: + Pomp Frekwensie: Bluetooth Inisiasie… Bluetooth Fout @@ -18,14 +34,26 @@ RileyLink inisiasie… RileyLink Fout Probleel om met pomp te praat + Gekoppel Toestel is nie RileyLink RileyLink onverkry Bluetooth afgeskakel Geen Bluetooth Toestel Opstel het gefaal + Pomp onbereikbaar Pod onbereikbaar Medtronic Pomp + Ja + Nee + + %1$d dae + %1$d dae + + + %1$d uur + %1$d ure + diff --git a/pump/rileylink/src/main/res/values-bg-rBG/strings.xml b/pump/rileylink/src/main/res/values-bg-rBG/strings.xml index 39677d33e8..8361505987 100644 --- a/pump/rileylink/src/main/res/values-bg-rBG/strings.xml +++ b/pump/rileylink/src/main/res/values-bg-rBG/strings.xml @@ -77,4 +77,5 @@ Използвай сканиране Сканирай преди да се свържеш с OrangeLink, това би трябвало да подобри връзката (също може да се използва с други RileyLink клонинги, ако е необходимо) + Конфигурация на RileyLink diff --git a/pump/rileylink/src/main/res/values-ca-rES/strings.xml b/pump/rileylink/src/main/res/values-ca-rES/strings.xml index 0a73dfc845..ee0390e607 100644 --- a/pump/rileylink/src/main/res/values-ca-rES/strings.xml +++ b/pump/rileylink/src/main/res/values-ca-rES/strings.xml @@ -2,9 +2,77 @@ + Escanejar + Aturar + Seleccionat + Escaneig RileyLink + Escanejant + Escaneig finalitzat + Error d\'escaneig: %1$d + Mai + RileyLink seleccionat actualment + Eliminar + Esteu segurs que voleu eliminar el vostre RileyLink? + Eliminar RileyLink + Cap RileyLink seleccionat + Configuració + Històric + Estat RileyLink + Estat bomba + Configuració RileyLink + RileyLink + Adreça: + Nom: + Nivell de la bateria: + %1$d%% + Estat de la connexió: + Error de connexió: + Dispositiu + Tipus de dispositiu: + Model dispositiu configurat: + Model dispositiu connectat: + Darrera freqüència utilitzada: + Últim contacte dispositiu: + Versió del firmware: + BLE113: %1$s\nCC110: %2$s + Número de sèrie bomba: + Freqüència bomba: + %1$.2f MHz + Inicialitzant Bluetooth… + Error de Bluetooth + Bluetooth a punt + No iniciat + Inicialitzant RileyLink… + Error de RileyLink + Posant a punt RileyLink i bomba + Problema en connectar amb la bomba + Connectat + RileyLink a punt + El dispositiu no és un RileyLink + RileyLink no accessible + Bluetooth desactivat + No hi ha adaptador Bluetooth + Error en la posada a punt + Bomba no accessible + Pod no accessible + Bomba Medtronic + Omnipod (Eros) + + No + Mostrar nivell de batería reportat per OrangeLink/EmaLink/DiaLink + NO funciona amb el RileyLink original. Pot ser que no funcioni amb alternatives a RileyLink. + + %1$d dia + %1$d dies + + + %1$d hora + %1$d hores + + Configuració RileyLink diff --git a/pump/rileylink/src/main/res/values-el-rGR/strings.xml b/pump/rileylink/src/main/res/values-el-rGR/strings.xml index ddeeee81ec..5744e2c8de 100644 --- a/pump/rileylink/src/main/res/values-el-rGR/strings.xml +++ b/pump/rileylink/src/main/res/values-el-rGR/strings.xml @@ -2,6 +2,15 @@ + Scan + Stop + Επιλεγμένο + RileyLink Scan + Σάρωση + Η σάρωση ολοκληρώθηκε + Λάθος σάρωσης: %1$d + Ποτέ + Διαγραφή Ρυθμίσεις Ιστορικό @@ -9,7 +18,14 @@ Κατάσταση Αντλίας Ρυθμίσεις RileyLink RileyLink + Όνομα: + %1$d%% + Κατάσταση Σύνδεσης: + Σφάλμα σύνδεσης: Συσκευή + Τύπος Συσκευής: + Σειριακός Αριθμός Αντλίας: + Συχνότητα Αντλίας: Επαναφορά Bluetooth… Σφάλμα Bluetooth @@ -19,14 +35,26 @@ RileyLink Σφάλμα Συντονισμός RileyLink και Αντλίας Πρόβλημα σύνδεσης με την Αντλία + Συνδέθηκε Η συσκευή δεν είναι RileyLink Το RileyLink μη προσπελάσιμο Bluetooth απενεργοποιημένο Δεν υπάρχει προσαρμογέας Bluetooth TuneUp απέτυχε + Η αντλία δεν είναι διαθέσιμη Το Pod δεν είναι διαθέσιμο Αντλία Medtronic + Ναι + Όχι + + %1$d ημέρες + %1$d ημέρες + + + %1$d hour + %1$d ώρες + diff --git a/pump/rileylink/src/main/res/values-hr-rHR/strings.xml b/pump/rileylink/src/main/res/values-hr-rHR/strings.xml index 0a73dfc845..aec4a4100f 100644 --- a/pump/rileylink/src/main/res/values-hr-rHR/strings.xml +++ b/pump/rileylink/src/main/res/values-hr-rHR/strings.xml @@ -2,9 +2,23 @@ + Pretraži + Zaustavi + Odabrano + Pretraživanje + Skeniranje završeno + Pogreška skeniranja: %1$d + Nikada + Ukloniti + Postavke + Serijski broj pumpe: + Frekventno područje pumpe: + Bluetooth onemogućen + Nema Bluetooth adaptera + Pumpa nedostupna diff --git a/pump/rileylink/src/main/res/values-hu-rHU/strings.xml b/pump/rileylink/src/main/res/values-hu-rHU/strings.xml index 0a73dfc845..6bc5448eee 100644 --- a/pump/rileylink/src/main/res/values-hu-rHU/strings.xml +++ b/pump/rileylink/src/main/res/values-hu-rHU/strings.xml @@ -2,9 +2,79 @@ + Keresés + Leállít + Kiválasztott + RileyLink keresése + Keresés + Keresés befejezve + Hiba kereséskor: %1$d + Soha + Jelenleg kiválasztott RileyLink + Eltávolít + Biztosan el akarja távolítani a RileyLink-et? + RileyLink eltávolítása + Nincs RileyLink kiválasztva + Beállítások + Előzmények + RileyLink állapot + Pumpa állapot + RileyLink beállítások + RileyLink + Cím: + Név: + Töltöttségi szint: + %1$d%% + Kapcsolat állapota: + Kapcsolódási hiba: + Eszköz + Eszköz típusa: + Beállított eszköz model: + Kapcsolódott eszköz model: + Utoljára használt frekvencia: + Utoljára kapcsolódott eszköz: + Firmware verzió: + BLE113: %1$s\nCC110: %2$s + Fw: %1$s\nHw: %2$s + Pumpa sorozatszáma: + Pumpa frekvencia: + %1$.2f MHz + Bluetooth inicializálása… + Bluetooth hiba + Bluetooth készen áll + Nincs elindítva + RileyLink inicializálása… + RileyLink hiba + RileyLink és pumpa hangolása + Hiba pumpához kapcsolódáskor + Kapcsolódva + RileyLink készen áll + Eszköz nem RileyLink + RileyLink nem elérhető + Bluetooth kikapcsolva + Nincs Bluetooth adapter + Hangolás sikertelen + Pumpa nem elérhető + Pod nem elérhető + Medtronic pumpa + Omnipod (Eros) + Igen + Nem + OrangeLink/EmaLink töltöttségének megjelenítése + NEM MŰKÖDIK az eredeti RileyLink-el. Lehet nem működik bizonyos RileyLink alternatívákkal. + + %1$d nap + %1$d nap + + + %1$d óra + %1$d óra + + Keresés használata + Keresés indítása OrangeLink-hez kapcsolódás előtt, ez segíthet a kapcsolódásban (RileyLink alternatívákkal is használható, ha szükséges) diff --git a/pump/rileylink/src/main/res/values-ko-rKR/strings.xml b/pump/rileylink/src/main/res/values-ko-rKR/strings.xml index e6ed20e16c..3d015363c2 100644 --- a/pump/rileylink/src/main/res/values-ko-rKR/strings.xml +++ b/pump/rileylink/src/main/res/values-ko-rKR/strings.xml @@ -72,4 +72,5 @@ %1$d 시간 + RileyLink 의 구성 diff --git a/pump/rileylink/src/main/res/values-lt-rLT/strings.xml b/pump/rileylink/src/main/res/values-lt-rLT/strings.xml index c049b0ead2..ea4d800cc7 100644 --- a/pump/rileylink/src/main/res/values-lt-rLT/strings.xml +++ b/pump/rileylink/src/main/res/values-lt-rLT/strings.xml @@ -81,4 +81,5 @@ Atlikti skanavimą Prieš suporuodami su OrangeLink, naudokite skanavimą, tai turėtų pagerinti ryšio kokybę (jei reikia, galite jį naudoti ir kituose RileyLink klonuose) + RileyLink konfigūravimas diff --git a/pump/rileylink/src/main/res/values-pl-rPL/strings.xml b/pump/rileylink/src/main/res/values-pl-rPL/strings.xml index 8c7fc24deb..a96b231e97 100644 --- a/pump/rileylink/src/main/res/values-pl-rPL/strings.xml +++ b/pump/rileylink/src/main/res/values-pl-rPL/strings.xml @@ -81,4 +81,5 @@ Użyj skanowania Skanuj przed połączeniem z OrangeLink, to powinno poprawić jakość połączeń (w razie potrzeby można używać z innymi klonami RileyLink) + Konfiguracja RileyLink diff --git a/pump/rileylink/src/main/res/values-pt-rBR/strings.xml b/pump/rileylink/src/main/res/values-pt-rBR/strings.xml index 731fc4104b..1e3b7b53d9 100644 --- a/pump/rileylink/src/main/res/values-pt-rBR/strings.xml +++ b/pump/rileylink/src/main/res/values-pt-rBR/strings.xml @@ -2,6 +2,19 @@ + Escanear + Parar + Seleccionado + Procura RileyLink + A procurar + Procura terminada + Erro de Procura: %1$d + Nunca + RileyLink selecionado atualmente + Remover + Tem certeza que deseja remover o RileyLink? + Remover RileyLink + Nenhum RileyLink selecionado Definições Histórico @@ -9,7 +22,22 @@ Estado da Bomba Configurações do RileyLink RileyLink + Endereço: + Nome: + Nível de Bateria: + %1$d%% + Estado de Ligação: + Erro de Ligação: Dispositivo + Tipo de dispositivo: + Dispositivo modelo configurado: + Dispositivo modelo conectado: + Frequência da Última Utilização: + Último contato do dispositivo: + Versão do firmware: + Número de série da Bomba: + Frequência da Bomba: + %1$.1f MHz A iniciar o Bluetooth... Erro de Bluetooth @@ -20,14 +48,32 @@ Configurando RileyLink e a Bomba Problema ao ligar à Bomba Ligado + RileyLink pronto Dispositivo não é RileyLink RileyLink inacessível Bluetooth desactivado Nenhum Adaptador Bluetooth TuneUp Falhou + Bomba inacessível Pod inacessível Bomba Medtronic + Omnipod (Eros) + Sim + Não + Mostrar o nível da bateria reportada por OrangeLink/EmaLink/DiaLink + Não funciona com o RileyLink original. Pode não funcionar com outros RileyLink alternativos. + + %1$d dia + %1$d dias + + + %1$d hora + %1$d horas + + Usar escaneamento + Escanear antes de se conectar ao OrangeLink. Isto deve melhorar as conexões (também pode ser usado com outros clones do RileyLink, se necessário) + Configurações do RileyLink diff --git a/pump/rileylink/src/main/res/values-pt-rPT/strings.xml b/pump/rileylink/src/main/res/values-pt-rPT/strings.xml index 7ba7f9c42f..7bbef2830f 100644 --- a/pump/rileylink/src/main/res/values-pt-rPT/strings.xml +++ b/pump/rileylink/src/main/res/values-pt-rPT/strings.xml @@ -73,4 +73,5 @@ %1$d hora %1$d horas + Configuração RileyLink diff --git a/pump/rileylink/src/main/res/values-ro-rRO/strings.xml b/pump/rileylink/src/main/res/values-ro-rRO/strings.xml index d1f8132375..6731326895 100644 --- a/pump/rileylink/src/main/res/values-ro-rRO/strings.xml +++ b/pump/rileylink/src/main/res/values-ro-rRO/strings.xml @@ -79,4 +79,5 @@ Folosește Scanarea Scanează înainte de conectarea la OrangeLink, ar trebui să îmbunătăţească conexiunile (poate fi utilizat, de asemenea, cu alte clone RileyLink, dacă este necesar) + Configurare RileyLink diff --git a/pump/rileylink/src/main/res/values-sv-rSE/strings.xml b/pump/rileylink/src/main/res/values-sv-rSE/strings.xml index c084d21174..160e306fc4 100644 --- a/pump/rileylink/src/main/res/values-sv-rSE/strings.xml +++ b/pump/rileylink/src/main/res/values-sv-rSE/strings.xml @@ -77,4 +77,5 @@ Använd sökning Gör en sökning innan du ansluter till OrangeLink. Det bör förbättra anslutningarna (kan även användas med andra RileyLink-kloner om det behövs) + Konfiguration av Riley Link diff --git a/ui/src/main/res/values-af-rZA/strings.xml b/ui/src/main/res/values-af-rZA/strings.xml index f6ef331c8f..6a05ddd430 100644 --- a/ui/src/main/res/values-af-rZA/strings.xml +++ b/ui/src/main/res/values-af-rZA/strings.xml @@ -6,4 +6,5 @@ Begin hipo TT Tyd verskil min + diff --git a/ui/src/main/res/values-bg-rBG/strings.xml b/ui/src/main/res/values-bg-rBG/strings.xml index 23dc87c145..70ceb81aae 100644 --- a/ui/src/main/res/values-bg-rBG/strings.xml +++ b/ui/src/main/res/values-bg-rBG/strings.xml @@ -1,10 +1,15 @@ Няма избрано действие, нищо няма да се изпълни + Приложено ограничение! + Приложено ограничение на болус + Приложено ограничение на въглехидрати + Вр.цел Старт на вр.цел за физ. активност Старт на вр. цел за Eating soon Старт на вр. цел при хипо времево отместване мин Напомни за болус по-късно + diff --git a/ui/src/main/res/values-ca-rES/strings.xml b/ui/src/main/res/values-ca-rES/strings.xml index 86efe6ff86..d96b5b0f1b 100644 --- a/ui/src/main/res/values-ca-rES/strings.xml +++ b/ui/src/main/res/values-ca-rES/strings.xml @@ -6,4 +6,5 @@ Iniciar OT: Hipo Decalatge horari min + diff --git a/ui/src/main/res/values-cs-rCZ/strings.xml b/ui/src/main/res/values-cs-rCZ/strings.xml index fe1f60711a..59b15635ba 100644 --- a/ui/src/main/res/values-cs-rCZ/strings.xml +++ b/ui/src/main/res/values-cs-rCZ/strings.xml @@ -13,4 +13,7 @@ min Upozornit později na bolus nastavit připomenutí + + Konfigurovat průhlednost + Widget AAPS diff --git a/ui/src/main/res/values-da-rDK/strings.xml b/ui/src/main/res/values-da-rDK/strings.xml index a8bebf5ec1..992193d509 100644 --- a/ui/src/main/res/values-da-rDK/strings.xml +++ b/ui/src/main/res/values-da-rDK/strings.xml @@ -9,4 +9,6 @@ min. Påmind om at bolus senere Indstil påmindelse + + AAPS widget diff --git a/ui/src/main/res/values-de-rDE/strings.xml b/ui/src/main/res/values-de-rDE/strings.xml index acefcde665..defed97f12 100644 --- a/ui/src/main/res/values-de-rDE/strings.xml +++ b/ui/src/main/res/values-de-rDE/strings.xml @@ -9,4 +9,5 @@ Min. Später an Bolus erinnern Erinnerung einstellen + diff --git a/ui/src/main/res/values-el-rGR/strings.xml b/ui/src/main/res/values-el-rGR/strings.xml index cd02ed9df4..287c17fa59 100644 --- a/ui/src/main/res/values-el-rGR/strings.xml +++ b/ui/src/main/res/values-el-rGR/strings.xml @@ -6,4 +6,5 @@ Εκκίνηση TT Υπογλυκαιμίας Χρονική μετατόπιση min + diff --git a/ui/src/main/res/values-es-rES/strings.xml b/ui/src/main/res/values-es-rES/strings.xml index 63daaa7e1c..6d8c15840d 100644 --- a/ui/src/main/res/values-es-rES/strings.xml +++ b/ui/src/main/res/values-es-rES/strings.xml @@ -9,4 +9,6 @@ min Recordar ejecutar el bolo más tarde establecer recordatorio + + Widget de AAPS diff --git a/ui/src/main/res/values-fr-rFR/strings.xml b/ui/src/main/res/values-fr-rFR/strings.xml index fd728208ac..c658454975 100644 --- a/ui/src/main/res/values-fr-rFR/strings.xml +++ b/ui/src/main/res/values-fr-rFR/strings.xml @@ -13,4 +13,7 @@ min Rappel du bolus plus tard définir un rappel + + Configurer l’opacité + Widget AAPS diff --git a/ui/src/main/res/values-ga-rIE/strings.xml b/ui/src/main/res/values-ga-rIE/strings.xml index 8299f50396..6f878a981a 100644 --- a/ui/src/main/res/values-ga-rIE/strings.xml +++ b/ui/src/main/res/values-ga-rIE/strings.xml @@ -1,4 +1,5 @@ nóim + diff --git a/ui/src/main/res/values-hr-rHR/strings.xml b/ui/src/main/res/values-hr-rHR/strings.xml index 3ea04e700d..8e7b1dcc99 100644 --- a/ui/src/main/res/values-hr-rHR/strings.xml +++ b/ui/src/main/res/values-hr-rHR/strings.xml @@ -1,2 +1,4 @@ - + + + diff --git a/ui/src/main/res/values-hu-rHU/strings.xml b/ui/src/main/res/values-hu-rHU/strings.xml index 3ea04e700d..8e7b1dcc99 100644 --- a/ui/src/main/res/values-hu-rHU/strings.xml +++ b/ui/src/main/res/values-hu-rHU/strings.xml @@ -1,2 +1,4 @@ - + + + diff --git a/ui/src/main/res/values-it-rIT/strings.xml b/ui/src/main/res/values-it-rIT/strings.xml index 211466ace7..c6b26be67b 100644 --- a/ui/src/main/res/values-it-rIT/strings.xml +++ b/ui/src/main/res/values-it-rIT/strings.xml @@ -9,4 +9,6 @@ min Ricorda di fare il bolo imposta promemoria + + AAPS widget diff --git a/ui/src/main/res/values-iw-rIL/strings.xml b/ui/src/main/res/values-iw-rIL/strings.xml index a19b2c1cf9..4ea2d10cdd 100644 --- a/ui/src/main/res/values-iw-rIL/strings.xml +++ b/ui/src/main/res/values-iw-rIL/strings.xml @@ -9,4 +9,5 @@ דק\' תזכורת להזרקת בולוס אח\"כ קביעת תזכורת + diff --git a/ui/src/main/res/values-ko-rKR/strings.xml b/ui/src/main/res/values-ko-rKR/strings.xml index cd54bbae3f..9ac8122536 100644 --- a/ui/src/main/res/values-ko-rKR/strings.xml +++ b/ui/src/main/res/values-ko-rKR/strings.xml @@ -6,4 +6,5 @@ 저혈당 임시목표 시작 시간 이동 + diff --git a/ui/src/main/res/values-lt-rLT/strings.xml b/ui/src/main/res/values-lt-rLT/strings.xml index de3664f8c6..ac87c8a127 100644 --- a/ui/src/main/res/values-lt-rLT/strings.xml +++ b/ui/src/main/res/values-lt-rLT/strings.xml @@ -8,4 +8,5 @@ min. Priminti apie bolusą vėliau nustatyti priminimą + diff --git a/ui/src/main/res/values-nl-rNL/strings.xml b/ui/src/main/res/values-nl-rNL/strings.xml index 294fe8eb74..6ca0fd8c10 100644 --- a/ui/src/main/res/values-nl-rNL/strings.xml +++ b/ui/src/main/res/values-nl-rNL/strings.xml @@ -9,4 +9,5 @@ min Herinner later te bolussen herinnering instellen + diff --git a/ui/src/main/res/values-no-rNO/strings.xml b/ui/src/main/res/values-no-rNO/strings.xml index 02f55de263..61f8de7890 100644 --- a/ui/src/main/res/values-no-rNO/strings.xml +++ b/ui/src/main/res/values-no-rNO/strings.xml @@ -1,6 +1,10 @@ Ingen handling valgt. Ingenting endres + Begrensning benyttet! + Bolus-begrensning utført + Karbohydrat-begrensning utført + TT Dialog avbrutt Start Trening TT Start Spise snart TT @@ -9,4 +13,7 @@ min Påminnelse til å gi bolus senere angi påminnelse + + Konfigurer gjennomsiktighet + AAPS widget diff --git a/ui/src/main/res/values-pl-rPL/strings.xml b/ui/src/main/res/values-pl-rPL/strings.xml index 855e83f919..b57595d07f 100644 --- a/ui/src/main/res/values-pl-rPL/strings.xml +++ b/ui/src/main/res/values-pl-rPL/strings.xml @@ -7,4 +7,5 @@ Przesunięcie czasu min Przypomnij o bolusie + diff --git a/ui/src/main/res/values-pt-rBR/strings.xml b/ui/src/main/res/values-pt-rBR/strings.xml index a81fc28800..733dd6093c 100644 --- a/ui/src/main/res/values-pt-rBR/strings.xml +++ b/ui/src/main/res/values-pt-rBR/strings.xml @@ -8,4 +8,6 @@ Fuso horário min definir lembrete + + Widget do AAPS diff --git a/ui/src/main/res/values-pt-rPT/strings.xml b/ui/src/main/res/values-pt-rPT/strings.xml index 178e7d64f2..597a306e14 100644 --- a/ui/src/main/res/values-pt-rPT/strings.xml +++ b/ui/src/main/res/values-pt-rPT/strings.xml @@ -7,4 +7,5 @@ Fuso horário min Lembrete para bólus mais tarde + diff --git a/ui/src/main/res/values-ro-rRO/strings.xml b/ui/src/main/res/values-ro-rRO/strings.xml index 4779b9598b..b77418f24f 100644 --- a/ui/src/main/res/values-ro-rRO/strings.xml +++ b/ui/src/main/res/values-ro-rRO/strings.xml @@ -7,4 +7,5 @@ Decalaj min Amintește-mi sa fac bolus mai târziu + diff --git a/ui/src/main/res/values-ru-rRU/strings.xml b/ui/src/main/res/values-ru-rRU/strings.xml index 905fbb5465..ff3bb45dd4 100644 --- a/ui/src/main/res/values-ru-rRU/strings.xml +++ b/ui/src/main/res/values-ru-rRU/strings.xml @@ -1,6 +1,10 @@ Действие не выбрано, ничего не произойдет + применено ограничение! + применено ограничение болюса + применено ограничение углеводов + TT Диалог отменен Включить временную цель TT Нагрузка Включить временную цель TT Ожидаемый прием пищи @@ -9,4 +13,7 @@ мин Напомнить о болюсе позже установить напоминание + + Настроить прозрачность + Виджет AAPS diff --git a/ui/src/main/res/values-sk-rSK/strings.xml b/ui/src/main/res/values-sk-rSK/strings.xml index 654c988433..fce45a31de 100644 --- a/ui/src/main/res/values-sk-rSK/strings.xml +++ b/ui/src/main/res/values-sk-rSK/strings.xml @@ -13,4 +13,7 @@ min Upozorniť na bolus neskôr nastaviť pripomienku + + Konfigurovať priehľadnosť + AAPS widget diff --git a/ui/src/main/res/values-sr-rCS/strings.xml b/ui/src/main/res/values-sr-rCS/strings.xml index 3ea04e700d..8e7b1dcc99 100644 --- a/ui/src/main/res/values-sr-rCS/strings.xml +++ b/ui/src/main/res/values-sr-rCS/strings.xml @@ -1,2 +1,4 @@ - + + + diff --git a/ui/src/main/res/values-sv-rSE/strings.xml b/ui/src/main/res/values-sv-rSE/strings.xml index 8f6b907a8d..4507410dac 100644 --- a/ui/src/main/res/values-sv-rSE/strings.xml +++ b/ui/src/main/res/values-sv-rSE/strings.xml @@ -8,4 +8,5 @@ min Påminn om bolus senare ställ in påminnelse + diff --git a/ui/src/main/res/values-tr-rTR/strings.xml b/ui/src/main/res/values-tr-rTR/strings.xml index c2dbc4ada8..3c86aa00cd 100644 --- a/ui/src/main/res/values-tr-rTR/strings.xml +++ b/ui/src/main/res/values-tr-rTR/strings.xml @@ -13,4 +13,6 @@ dk. Bolusu daha sonra hatırlat hatırlatıcıyı kur + + AAPS widget diff --git a/ui/src/main/res/values-zh-rCN/strings.xml b/ui/src/main/res/values-zh-rCN/strings.xml index cc169f13ba..27c157a18a 100644 --- a/ui/src/main/res/values-zh-rCN/strings.xml +++ b/ui/src/main/res/values-zh-rCN/strings.xml @@ -9,4 +9,5 @@ 分钟 稍后提醒输注大剂量 设置提醒 + diff --git a/wear/src/main/res/values-bg-rBG/strings.xml b/wear/src/main/res/values-bg-rBG/strings.xml index e92a91fcdc..50725e730d 100644 --- a/wear/src/main/res/values-bg-rBG/strings.xml +++ b/wear/src/main/res/values-bg-rBG/strings.xml @@ -2,6 +2,14 @@ AAPS AAPS + AAPS + AAPS(голям) + AAPS(Графика) + AAPS(без рафика) + AAPS(Кръгъл) + AAPS(Самолет) + AAPS(Steampunk) + AAPS (DigitalStyle) Няма данни! Стари данни! От %1$s @@ -50,9 +58,14 @@ Допълнителни действия при почукване Unicode кодиране Версия: + Настройки на Watchface Погледнете в конфигурацията, моля. Врем цел + Калкулатор + Калк + Болус Болус + въглехидрати Настройки Статус Ре-синхр. @@ -60,17 +73,28 @@ Без Стандартен Меню + Продължителност + Целeва КЗ: + Ниска + Висока + въглехидрати + % от профила + Старт [min] + Прод [h] + Инсулин Шаблон 1 Шаблон 2 Шаблон 3 Неограничено кол ПОТВЪРДИ отместване + Болус Болус прогрес натиснете за отмяна СПРИ БОЛУС Помпа Режим на APS - Loop + Смяна на профил TDD ВХ IOB @@ -111,4 +135,11 @@ AAPS Прогрес на болуса Безшумно Прогрес на болуса и отказ Прогрес на болуса и отказ с по-малко вибрации + Изкл + Хипоглекимия + Физ.активност + Друго + Откажи + Без + --Е From f8a8e90d7bf47a087eaa7a332e9b2ef471186f45 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 3 Nov 2022 13:33:22 +0100 Subject: [PATCH 77/77] ConstraintChecker -> ConstriantsImpl -> implementation module --- .../nightscout/androidaps/MainActivity.kt | 4 +- .../nightscout/androidaps/di/AppModule.kt | 12 +- .../androidaps/dialogs/ExtendedBolusDialog.kt | 4 +- .../androidaps/dialogs/FillDialog.kt | 4 +- .../androidaps/dialogs/InsulinDialog.kt | 4 +- .../androidaps/dialogs/LoopDialog.kt | 4 +- .../androidaps/dialogs/TempBasalDialog.kt | 4 +- .../androidaps/dialogs/TempTargetDialog.kt | 4 +- .../androidaps/dialogs/TreatmentDialog.kt | 4 +- .../androidaps/dialogs/WizardDialog.kt | 4 +- .../androidaps/plugins/aps/loop/LoopPlugin.kt | 4 +- .../openAPSAMA/DetermineBasalAdapterAMAJS.kt | 4 +- .../aps/openAPSAMA/OpenAPSAMAPlugin.kt | 4 +- .../openAPSSMB/DetermineBasalAdapterSMBJS.kt | 4 +- .../aps/openAPSSMB/OpenAPSSMBPlugin.kt | 3 +- .../DetermineBasalAdapterSMBDynamicISFJS.kt | 4 +- .../OpenAPSSMBDynamicISFPlugin.kt | 4 +- ...plementation.kt => ProfileFunctionImpl.kt} | 2 +- .../objectives/objectives/Objective6.kt | 5 +- .../constraints/safety/SafetyPlugin.kt | 4 +- .../general/overview/OverviewFragment.kt | 4 +- .../wear/wearintegration/DataHandlerMobile.kt | 4 +- .../androidaps/utils/wizard/BolusWizard.kt | 4 +- .../interfaces/ConstraintsCheckerTest.kt | 6 +- .../plugins/aps/loop/LoopPluginTest.kt | 4 +- .../constraints/safety/SafetyPluginTest.kt | 8 +- .../utils/wizard/BolusWizardTest.kt | 4 +- .../general/automation/AutomationPlugin.kt | 4 +- .../androidaps/interfaces/Constraints.kt | 45 +++-- .../androidaps/plugins/aps/loop/APSResult.kt | 11 +- .../plugins/aps/loop/APSResultTest.kt | 162 +++++++++++++++--- .../constraints/ConstraintsImpl.kt | 55 +----- .../queue/CommandQueueImplementation.kt | 4 +- .../implementation/BolusTimerImplTest.kt | 4 +- .../implementation/CarbTimerImplTest.kt | 4 +- .../queue/CommandQueueImplementationTest.kt | 6 +- .../implementation/queue/QueueThreadTest.kt | 4 +- .../smsCommunicator/SmsCommunicatorPlugin.kt | 4 +- .../SmsCommunicatorPluginTest.kt | 4 +- .../danaRKorean/DanaRKoreanPlugin.kt | 4 +- .../services/DanaRKoreanExecutionService.java | 4 +- .../androidaps/danaRv2/DanaRv2Plugin.java | 14 +- .../androidaps/danar/AbstractDanaRPlugin.java | 15 +- .../androidaps/danar/DanaRPlugin.java | 26 +-- .../androidaps/danar/comm/MessageBase.kt | 4 +- .../plugins/pump/danaR/DanaRPluginTest.kt | 4 +- .../plugins/pump/danaR/comm/DanaRTestBase.kt | 4 +- .../pump/danaRKorean/DanaRKoreanPluginTest.kt | 4 +- .../plugins/pump/danaRv2/DanaRv2PluginTest.kt | 4 +- .../androidaps/danars/DanaRSPlugin.kt | 4 +- .../DanaRSPacketBolusSetStepBolusStart.kt | 4 +- .../danars/services/DanaRSService.kt | 4 +- .../androidaps/danars/DanaRSPluginTest.kt | 4 +- .../danars/comm/DanaRsMessageHashTableTest.kt | 4 +- .../DanaRsPacketBolusSetStepBolusStartTest.kt | 4 +- ...naRsPacketNotifyDeliveryRateDisplayTest.kt | 4 +- .../androidaps/diaconn/DiaconnG8Plugin.kt | 4 +- .../diaconn/service/DiaconnG8Service.kt | 4 +- .../info/nightscout/ui/dialogs/CarbsDialog.kt | 4 +- .../java/info/nightscout/ui/widget/Widget.kt | 4 +- 60 files changed, 325 insertions(+), 229 deletions(-) rename app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/{ProfileFunctionImplementation.kt => ProfileFunctionImpl.kt} (99%) rename core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt => implementation/src/main/java/info/nightscout/implementation/constraints/ConstraintsImpl.kt (76%) diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index 90e09659e2..d3d2bfcd7a 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -40,7 +40,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus @@ -78,7 +78,7 @@ class MainActivity : NoSplashAppCompatActivity() { @Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var iconsProvider: IconsProvider - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var signatureVerifierPlugin: SignatureVerifierPlugin @Inject lateinit var config: Config @Inject lateinit var uel: UserEntryLogger diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt index d8da3f08b6..a7dab3c4a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt @@ -19,6 +19,7 @@ import info.nightscout.androidaps.interfaces.CarbTimer import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.ConfigBuilder +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.interfaces.DataSyncSelector import info.nightscout.androidaps.interfaces.IconsProvider import info.nightscout.androidaps.interfaces.ImportExportPrefs @@ -36,7 +37,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.PluginStore -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImpl import info.nightscout.androidaps.plugins.general.autotune.AutotunePlugin import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider @@ -60,6 +61,7 @@ import info.nightscout.implementation.BolusTimerImpl import info.nightscout.implementation.CarbTimerImpl import info.nightscout.implementation.LocalAlertUtilsImpl import info.nightscout.implementation.XDripBroadcastImpl +import info.nightscout.implementation.constraints.ConstraintsImpl import info.nightscout.implementation.queue.CommandQueueImplementation import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.shared.logging.AAPSLogger @@ -108,11 +110,14 @@ open class AppModule { ActivePlugin, repository: AppRepository, dateUtil: DateUtil, config: Config, hardLimits: HardLimits, aapsSchedulers: AapsSchedulers, fabricPrivacy: FabricPrivacy, deviceStatusData: DeviceStatusData ): ProfileFunction = - ProfileFunctionImplementation( + ProfileFunctionImpl( aapsLogger, sp, rxBus, rh, activePlugin, repository, dateUtil, config, hardLimits, aapsSchedulers, fabricPrivacy, deviceStatusData ) + @Provides + @Singleton + internal fun provideConstraints(activePlugin: ActivePlugin): Constraints = ConstraintsImpl(activePlugin) @Module interface AppBindings { @@ -130,8 +135,7 @@ open class AppModule { @Binds fun bindAutotuneInterface(autotunePlugin: AutotunePlugin): Autotune @Binds fun bindIobCobCalculatorInterface(iobCobCalculatorPlugin: IobCobCalculatorPlugin): IobCobCalculator @Binds fun bindSmsCommunicatorInterface(smsCommunicatorPlugin: SmsCommunicatorPlugin): SmsCommunicator - @Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector - + @Binds fun bindDataSyncSelectorInterface(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector @Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync @Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast @Binds fun bindCarbTimerInterface(carbTimer: CarbTimerImpl): CarbTimer diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt index 8df008ed23..452e9606e5 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt @@ -18,7 +18,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.ToastUtils @@ -36,7 +36,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { @Inject lateinit var ctx: Context @Inject lateinit var rh: ResourceHelper - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var uel: UserEntryLogger diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index e9820377d9..f9e0848e9b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -22,7 +22,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper @@ -40,7 +40,7 @@ import kotlin.math.abs class FillDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var rh: ResourceHelper @Inject lateinit var ctx: Context @Inject lateinit var commandQueue: CommandQueue diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index d25fff10ed..0f8dafe47c 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -21,7 +21,7 @@ import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog @@ -41,7 +41,7 @@ import kotlin.math.max class InsulinDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var rh: ResourceHelper @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileFunction: ProfileFunction diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt index 4820917e38..d04fcb3105 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt @@ -37,7 +37,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DateUtil @@ -65,7 +65,7 @@ class LoopDialog : DaggerDialogFragment() { @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var loop: Loop @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var configBuilder: ConfigBuilder @Inject lateinit var uel: UserEntryLogger diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt index c44370bad9..6e07438101 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt @@ -14,7 +14,7 @@ import info.nightscout.androidaps.databinding.DialogTempbasalBinding import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.ToastUtils @@ -30,7 +30,7 @@ import kotlin.math.abs class TempBasalDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var rh: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var activePlugin: ActivePlugin diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt index 60609fe12d..de278cb854 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt @@ -24,7 +24,7 @@ import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.ToastUtils @@ -41,7 +41,7 @@ import javax.inject.Inject class TempTargetDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var rh: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var defaultValueHelper: DefaultValueHelper diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index 2f01d661f0..2424be5d47 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -23,7 +23,7 @@ import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper @@ -42,7 +42,7 @@ import kotlin.math.abs class TreatmentDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var rh: ResourceHelper @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var commandQueue: CommandQueue diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index ac8adc39d3..7918dffd31 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -31,7 +31,7 @@ import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.valueToUnits import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS @@ -53,7 +53,7 @@ class WizardDialog : DaggerDialogFragment() { @Inject lateinit var injector: HasAndroidInjector @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsSchedulers: AapsSchedulers - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var ctx: Context @Inject lateinit var sp: SP @Inject lateinit var rxBus: RxBus diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt index bf57ff5d7b..d361f31b77 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt @@ -55,7 +55,7 @@ import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification @@ -87,7 +87,7 @@ class LoopPlugin @Inject constructor( private val rxBus: RxBus, private val sp: SP, config: Config, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, rh: ResourceHelper, private val profileFunction: ProfileFunction, private val context: Context, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt index 184b2b2bd3..08ad43aa41 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt @@ -18,7 +18,7 @@ import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.shared.sharedPreferences.SP import org.json.JSONArray @@ -37,7 +37,7 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader private val injector: HasAndroidInjector @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculator: IobCobCalculator diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt index 99a6325cc1..a658026409 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt @@ -23,7 +23,7 @@ import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.utils.DateUtil @@ -43,7 +43,7 @@ class OpenAPSAMAPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBus, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, rh: ResourceHelper, private val profileFunction: ProfileFunction, private val context: Context, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt index c23f14d54a..aac146196b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt @@ -13,7 +13,7 @@ import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.ScriptReader -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.shared.SafeParse import info.nightscout.androidaps.interfaces.ResourceHelper @@ -31,7 +31,7 @@ import javax.inject.Inject class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) : DetermineBasalAdapterInterface { @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var sp: SP @Inject lateinit var rh: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt index 5256342edf..d69750e7a9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt @@ -26,7 +26,6 @@ import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.utils.DateUtil @@ -45,7 +44,7 @@ class OpenAPSSMBPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBus, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, rh: ResourceHelper, private val profileFunction: ProfileFunction, val context: Context, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/DetermineBasalAdapterSMBDynamicISFJS.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/DetermineBasalAdapterSMBDynamicISFJS.kt index 45e22db183..6f62428a7e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/DetermineBasalAdapterSMBDynamicISFJS.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/DetermineBasalAdapterSMBDynamicISFJS.kt @@ -18,7 +18,7 @@ import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.interfaces.ResourceHelper @@ -42,7 +42,7 @@ import kotlin.math.ln class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) : DetermineBasalAdapterInterface { @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var sp: SP @Inject lateinit var rh: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt index ea2d85eeaa..176cfe3089 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt @@ -12,7 +12,7 @@ import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.HardLimits @@ -30,7 +30,7 @@ class OpenAPSSMBDynamicISFPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, rxBus: RxBus, - constraintChecker: ConstraintChecker, + constraintChecker: Constraints, rh: ResourceHelper, profileFunction: ProfileFunction, context: Context, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImpl.kt similarity index 99% rename from app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt rename to app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImpl.kt index bdb8bcf411..dc79e8df30 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImpl.kt @@ -27,7 +27,7 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class ProfileFunctionImplementation @Inject constructor( +class ProfileFunctionImpl @Inject constructor( private val aapsLogger: AAPSLogger, private val sp: SP, private val rxBus: RxBus, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective6.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective6.kt index dd10f4a33d..e15e5279a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective6.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective6.kt @@ -2,8 +2,7 @@ package info.nightscout.androidaps.plugins.constraints.objectives.objectives import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R -import info.nightscout.androidaps.interfaces.Constraint -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin import info.nightscout.androidaps.utils.T import javax.inject.Inject @@ -11,7 +10,7 @@ import javax.inject.Inject @Suppress("SpellCheckingInspection") class Objective6(injector: HasAndroidInjector) : Objective(injector, "maxiob", R.string.objectives_maxiob_objective, R.string.objectives_maxiob_gate) { - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var safetyPlugin: SafetyPlugin init { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt index 4f4a835e9f..30a2f47603 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDynamicISFPlugin import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin @@ -34,7 +34,7 @@ class SafetyPlugin @Inject constructor( rh: ResourceHelper, private val sp: SP, private val rxBus: RxBus, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, private val openAPSAMAPlugin: OpenAPSAMAPlugin, private val openAPSSMBPlugin: OpenAPSSMBPlugin, private val openAPSSMBDynamicISFPlugin: OpenAPSSMBDynamicISFPlugin, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index ccb34fabba..dd7735c1e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -73,7 +73,7 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus @@ -126,7 +126,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList @Inject lateinit var rh: ResourceHelper @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileFunction: ProfileFunction - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var statusLightHandler: StatusLightHandler @Inject lateinit var nsDeviceStatus: NSDeviceStatus @Inject lateinit var loop: Loop diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index cd4169347b..19fa03887b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -23,7 +23,7 @@ import info.nightscout.androidaps.extensions.valueToUnitsString import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider @@ -72,7 +72,7 @@ class DataHandlerMobile @Inject constructor( private val defaultValueHelper: DefaultValueHelper, private val trendCalculator: TrendCalculator, private val dateUtil: DateUtil, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, private val uel: UserEntryLogger, private val activePlugin: ActivePlugin, private val commandQueue: CommandQueue, diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt index 3ca74ce899..0f0aa7211d 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt @@ -35,7 +35,7 @@ import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.queue.Callback @@ -64,7 +64,7 @@ class BolusWizard @Inject constructor( @Inject lateinit var rxBus: RxBus @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var loop: Loop diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt index ee67c07b13..a352343466 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt @@ -15,7 +15,6 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDynamicISFPlugin -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin @@ -32,6 +31,7 @@ import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl +import info.nightscout.implementation.constraints.ConstraintsImpl import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before @@ -64,7 +64,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { private lateinit var danaPump: DanaPump private lateinit var insightDbHelper: InsightDbHelper - private lateinit var constraintChecker: ConstraintChecker + private lateinit var constraintChecker: ConstraintsImpl private lateinit var safetyPlugin: SafetyPlugin private lateinit var objectivesPlugin: ObjectivesPlugin private lateinit var comboPlugin: ComboPlugin @@ -123,7 +123,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { //SafetyPlugin `when`(activePlugin.activePump).thenReturn(virtualPumpPlugin) - constraintChecker = ConstraintChecker(activePlugin) + constraintChecker = ConstraintsImpl(activePlugin) val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt index 6914c34e49..df4af5b255 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/LoopPluginTest.kt @@ -18,7 +18,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.receivers.ReceiverStatusStore @@ -35,7 +35,7 @@ class LoopPluginTest : TestBase() { @Mock lateinit var sp: SP private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger) - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var rh: ResourceHelper @Mock lateinit var profileFunction: ProfileFunction @Mock lateinit var context: Context diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt index da0e9b7187..39ca5fb51d 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt @@ -12,7 +12,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDynamicISFPlugin -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin import info.nightscout.androidaps.plugins.source.GlimpPlugin @@ -28,7 +28,7 @@ import org.mockito.Mockito.`when` class SafetyPluginTest : TestBaseWithProfile() { @Mock lateinit var sp: SP - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin @Mock lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin @Mock lateinit var openAPSSMBDynamicISFPlugin: OpenAPSSMBDynamicISFPlugin @@ -103,7 +103,7 @@ class SafetyPluginTest : TestBaseWithProfile() { @Test fun notEnabledSMBInPreferencesDisablesSMB() { `when`(sp.getBoolean(R.string.key_use_smb, false)).thenReturn(false) - `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true)) + `when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(true)) var c = Constraint(true) c = safetyPlugin.isSMBModeEnabled(c) Assert.assertTrue(c.getReasons(aapsLogger).contains("SMB disabled in preferences")) @@ -112,7 +112,7 @@ class SafetyPluginTest : TestBaseWithProfile() { @Test fun openLoopPreventsSMB() { `when`(sp.getBoolean(R.string.key_use_smb, false)).thenReturn(true) - `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(false)) + `when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(false)) var c = Constraint(true) c = safetyPlugin.isSMBModeEnabled(c) Assert.assertTrue(c.getReasons(aapsLogger).contains("SMB not allowed in open loop mode")) diff --git a/app/src/test/java/info/nightscout/androidaps/utils/wizard/BolusWizardTest.kt b/app/src/test/java/info/nightscout/androidaps/utils/wizard/BolusWizardTest.kt index 97872fc3d2..0e0d8bcb84 100644 --- a/app/src/test/java/info/nightscout/androidaps/utils/wizard/BolusWizardTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/utils/wizard/BolusWizardTest.kt @@ -8,7 +8,7 @@ import info.nightscout.androidaps.data.IobTotal import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin @@ -27,7 +27,7 @@ class BolusWizardTest : TestBase() { @Mock lateinit var rh: ResourceHelper @Mock lateinit var profileFunction: ProfileFunction - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var context: Context @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var commandQueue: CommandQueue diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt index c7710432f7..fc67a6e217 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt @@ -14,7 +14,7 @@ import info.nightscout.androidaps.events.EventNetworkChange import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.automation.actions.* import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui @@ -47,7 +47,7 @@ class AutomationPlugin @Inject constructor( private val fabricPrivacy: FabricPrivacy, private val loop: Loop, private val rxBus: RxBus, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, aapsLogger: AAPSLogger, private val aapsSchedulers: AapsSchedulers, private val config: Config, diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/Constraints.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/Constraints.kt index 709b4c037b..6f6137c5a2 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/Constraints.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/Constraints.kt @@ -1,31 +1,56 @@ package info.nightscout.androidaps.interfaces +import info.nightscout.androidaps.Constants + /** * Constraints interface * * Every function has a param from previous chained call * Function can limit the value even more and add another reason of restriction * - * see [info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker] + * see [info.nightscout.implementation.constraints.ConstraintsImpl] * which iterates over all registered plugins with [Constraints] implemented * * @return updated parameter */ interface Constraints { - fun isLoopInvocationAllowed(value: Constraint): Constraint = value - fun isClosedLoopAllowed(value: Constraint): Constraint = value - fun isLgsAllowed(value: Constraint): Constraint = value - fun isAutosensModeEnabled(value: Constraint): Constraint = value - fun isSMBModeEnabled(value: Constraint): Constraint = value - fun isUAMEnabled(value: Constraint): Constraint = value - fun isAdvancedFilteringEnabled(value: Constraint): Constraint = value - fun isSuperBolusEnabled(value: Constraint): Constraint = value + fun isLoopInvocationAllowed(value: Constraint = Constraint(true)): Constraint = value + fun isClosedLoopAllowed(value: Constraint = Constraint(true)): Constraint = value + fun isLgsAllowed(value: Constraint = Constraint(true)): Constraint = value + fun isAutosensModeEnabled(value: Constraint = Constraint(true)): Constraint = value + fun isSMBModeEnabled(value: Constraint = Constraint(true)): Constraint = value + fun isUAMEnabled(value: Constraint = Constraint(true)): Constraint = value + fun isAdvancedFilteringEnabled(value: Constraint = Constraint(true)): Constraint = value + fun isSuperBolusEnabled(value: Constraint = Constraint(true)): Constraint = value + fun isAutomationEnabled(value: Constraint = Constraint(true)): Constraint = value fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint = absoluteRate fun applyBasalPercentConstraints(percentRate: Constraint, profile: Profile): Constraint = percentRate fun applyBolusConstraints(insulin: Constraint): Constraint = insulin fun applyExtendedBolusConstraints(insulin: Constraint): Constraint = insulin fun applyCarbsConstraints(carbs: Constraint): Constraint = carbs fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = maxIob - fun isAutomationEnabled(value: Constraint): Constraint = value + + /* + * Determine max values by walking through all constraints + */ + fun getMaxBasalAllowed(profile: Profile): Constraint = + applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile) + + fun getMaxBasalPercentAllowed(profile: Profile): Constraint = + applyBasalPercentConstraints(Constraint(Constants.REALLYHIGHPERCENTBASALRATE), profile) + + fun getMaxBolusAllowed(): Constraint = + applyBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS)) + + fun getMaxExtendedBolusAllowed(): Constraint = + applyExtendedBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS)) + + fun getMaxCarbsAllowed(): Constraint = + applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS)) + + fun getMaxIOBAllowed(): Constraint = + applyMaxIOBConstraints(Constraint(Constants.REALLYHIGHIOB)) + + } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt index c96b0b405b..010dea9225 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt @@ -9,20 +9,19 @@ import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.convertedToPercent import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpDescription -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper.fromHtml -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import org.json.JSONException import org.json.JSONObject -import java.util.* import javax.inject.Inject import kotlin.math.abs import kotlin.math.max @@ -34,7 +33,7 @@ import kotlin.math.max open class APSResult @Inject constructor(val injector: HasAndroidInjector) { @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var sp: SP @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var iobCobCalculator: IobCobCalculator diff --git a/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt index b2ed11b65e..c26ab637af 100644 --- a/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt @@ -5,8 +5,8 @@ import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.database.entities.TemporaryBasal import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.interfaces.IobCobCalculator -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble import org.junit.Assert @@ -18,7 +18,7 @@ import org.mockito.Mockito.`when` class APSResultTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraints: Constraints @Mock lateinit var iobCobCalculator: IobCobCalculator private val injector = HasAndroidInjector { AndroidInjector { } } @@ -31,7 +31,7 @@ class APSResultTest : TestBaseWithProfile() { val apsResult = APSResult { AndroidInjector { } } .also { it.aapsLogger = aapsLogger - it.constraintChecker = constraintChecker + it.constraintChecker = constraints it.sp = sp it.activePlugin = activePluginProvider it.iobCobCalculator = iobCobCalculator @@ -66,36 +66,92 @@ class APSResultTest : TestBaseWithProfile() { Assert.assertEquals(false, apsResult.isChangeRequested) // request equal temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 70.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 70.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(70).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) // request zero temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 10.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 10.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(0).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) // request high temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 190.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 190.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(200).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) // request slightly different temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 70.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 70.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(80).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) // request different temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 70.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 70.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(120).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) // it should work with absolute temps too // request different temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 1.0, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 1.0, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(100).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 2.0, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 2.0, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).percent(50).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) @@ -111,39 +167,103 @@ class APSResultTest : TestBaseWithProfile() { Assert.assertEquals(false, apsResult.isChangeRequested) // request equal temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 2.0, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 2.0, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(2.0).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 200.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 200.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(2.0).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) // request zero temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 0.1, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 0.1, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(0.0).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) // request high temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 34.9, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 34.9, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(35.0).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) // request slightly different temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 1.1, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 1.1, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(1.2).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) // request different temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 1.1, duration = 30, isAbsolute = true, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 1.1, + duration = 30, + isAbsolute = true, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(1.5).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) // it should work with percent temps too // request different temp - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 110.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 110.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(1.1).duration(30) Assert.assertEquals(false, apsResult.isChangeRequested) - `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(TemporaryBasal(timestamp = 0, rate = 200.0, duration = 30, isAbsolute = false, type = TemporaryBasal.Type.NORMAL)) + `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn( + TemporaryBasal( + timestamp = 0, + rate = 200.0, + duration = 30, + isAbsolute = false, + type = TemporaryBasal.Type.NORMAL + ) + ) apsResult.tempBasalRequested(true).rate(0.5).duration(30) Assert.assertEquals(true, apsResult.isChangeRequested) } @@ -152,7 +272,7 @@ class APSResultTest : TestBaseWithProfile() { val apsResult = APSResult { AndroidInjector { } } .also { it.aapsLogger = aapsLogger - it.constraintChecker = constraintChecker + it.constraintChecker = constraints it.sp = sp it.activePlugin = activePluginProvider it.iobCobCalculator = iobCobCalculator @@ -169,7 +289,7 @@ class APSResultTest : TestBaseWithProfile() { val apsResult = APSResult { AndroidInjector { } } .also { it.aapsLogger = aapsLogger - it.constraintChecker = constraintChecker + it.constraintChecker = constraints it.sp = sp it.activePlugin = activePluginProvider it.iobCobCalculator = iobCobCalculator @@ -184,7 +304,7 @@ class APSResultTest : TestBaseWithProfile() { @Before fun prepare() { - `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(closedLoopEnabled) + `when`(constraints.isClosedLoopAllowed(anyObject())).thenReturn(closedLoopEnabled) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) `when`(sp.getDouble(ArgumentMatchers.anyInt(), ArgumentMatchers.anyDouble())).thenReturn(30.0) `when`(profileFunction.getProfile()).thenReturn(validProfile) diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt b/implementation/src/main/java/info/nightscout/implementation/constraints/ConstraintsImpl.kt similarity index 76% rename from core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt rename to implementation/src/main/java/info/nightscout/implementation/constraints/ConstraintsImpl.kt index 0aa41d107e..5d0557798d 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt +++ b/implementation/src/main/java/info/nightscout/implementation/constraints/ConstraintsImpl.kt @@ -1,63 +1,14 @@ -package info.nightscout.androidaps.plugins.configBuilder +package info.nightscout.implementation.constraints -import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.annotations.OpenForTesting -import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraints -import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.Profile import javax.inject.Inject import javax.inject.Singleton -@OpenForTesting @Singleton -class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlugin) : Constraints { - - fun isLoopInvocationAllowed(): Constraint = - isLoopInvocationAllowed(Constraint(true)) - - fun isClosedLoopAllowed(): Constraint = - isClosedLoopAllowed(Constraint(true)) - - fun isLgsAllowed(): Constraint = - isLgsAllowed(Constraint(true)) - - fun isAutosensModeEnabled(): Constraint = - isAutosensModeEnabled(Constraint(true)) - - fun isSMBModeEnabled(): Constraint = - isSMBModeEnabled(Constraint(true)) - - fun isUAMEnabled(): Constraint = - isUAMEnabled(Constraint(true)) - - fun isAdvancedFilteringEnabled(): Constraint = - isAdvancedFilteringEnabled(Constraint(true)) - - fun isSuperBolusEnabled(): Constraint = - isSuperBolusEnabled(Constraint(true)) - - fun getMaxBasalAllowed(profile: Profile): Constraint = - applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile) - - fun getMaxBasalPercentAllowed(profile: Profile): Constraint = - applyBasalPercentConstraints(Constraint(Constants.REALLYHIGHPERCENTBASALRATE), profile) - - fun getMaxBolusAllowed(): Constraint = - applyBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS)) - - fun getMaxExtendedBolusAllowed(): Constraint = - applyExtendedBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS)) - - fun getMaxCarbsAllowed(): Constraint = - applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS)) - - fun getMaxIOBAllowed(): Constraint = - applyMaxIOBConstraints(Constraint(Constants.REALLYHIGHIOB)) - - fun isAutomationEnabled(): Constraint = - isAutomationEnabled(Constraint(true)) +class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin) : Constraints { override fun isLoopInvocationAllowed(value: Constraint): Constraint { val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) diff --git a/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt index 65177e94b9..999f62acc8 100644 --- a/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt @@ -31,7 +31,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification @@ -82,7 +82,7 @@ class CommandQueueImplementation @Inject constructor( private val rxBus: RxBus, private val aapsSchedulers: AapsSchedulers, private val rh: ResourceHelper, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, private val profileFunction: ProfileFunction, private val activePlugin: ActivePlugin, private val context: Context, diff --git a/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt b/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt index a5cfb3c152..78211c0604 100644 --- a/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/BolusTimerImplTest.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger import info.nightscout.androidaps.services.LocationServiceHelper @@ -33,7 +33,7 @@ class BolusTimerImplTest : TestBase() { @Mock lateinit var fabricPrivacy: FabricPrivacy @Mock lateinit var loop: Loop @Mock lateinit var rxBus: RxBus - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var config: Config @Mock lateinit var locationServiceHelper: LocationServiceHelper @Mock lateinit var activePlugin: ActivePlugin diff --git a/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt b/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt index a6923ad2ee..be03ee5c88 100644 --- a/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/CarbTimerImplTest.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger import info.nightscout.androidaps.services.LocationServiceHelper @@ -35,7 +35,7 @@ class CarbTimerImplTest : TestBase() { @Mock lateinit var fabricPrivacy: FabricPrivacy @Mock lateinit var loop: Loop @Mock lateinit var rxBus: RxBus - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var config: Config @Mock lateinit var locationServiceHelper: LocationServiceHelper @Mock lateinit var activePlugin: ActivePlugin diff --git a/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt index 5324fdf01b..8688ae5089 100644 --- a/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt @@ -17,11 +17,11 @@ import info.nightscout.androidaps.interfaces.AndroidPermission import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.queue.commands.CustomCommand @@ -47,7 +47,7 @@ import java.util.Calendar class CommandQueueImplementationTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var sp: SP @Mock lateinit var powerManager: PowerManager @@ -62,7 +62,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { rxBus: RxBus, aapsSchedulers: AapsSchedulers, rh: ResourceHelper, - constraintChecker: ConstraintChecker, + constraintChecker: Constraints, profileFunction: ProfileFunction, activePlugin: ActivePlugin, context: Context, diff --git a/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt index 7329abdfcd..ac8db35717 100644 --- a/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt @@ -14,7 +14,7 @@ import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.queue.commands.Command import info.nightscout.implementation.R import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute @@ -28,7 +28,7 @@ import org.mockito.Mockito class QueueThreadTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var sp: SP @Mock lateinit var powerManager: PowerManager diff --git a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index 7ff8da4c91..dc7e6d803b 100644 --- a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -34,7 +34,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui @@ -71,7 +71,7 @@ class SmsCommunicatorPlugin @Inject constructor( private val smsManager: SmsManager?, private val aapsSchedulers: AapsSchedulers, private val sp: SP, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, private val rxBus: RxBus, private val profileFunction: ProfileFunction, private val fabricPrivacy: FabricPrivacy, diff --git a/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt index 0975a57510..b9083fcf9b 100644 --- a/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt @@ -18,7 +18,7 @@ import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTe import info.nightscout.androidaps.database.transactions.Transaction import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore @@ -47,7 +47,7 @@ import org.mockito.invocation.InvocationOnMock class SmsCommunicatorPluginTest : TestBaseWithProfile() { @Mock lateinit var sp: SP - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var loop: Loop diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt index 88609dbc9b..e5d6e3ddfd 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt @@ -19,7 +19,7 @@ import info.nightscout.androidaps.interfaces.PumpSync.TemporaryBasalType import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.utils.DateUtil @@ -42,7 +42,7 @@ class DanaRKoreanPlugin @Inject constructor( rxBus: RxBus, private val context: Context, rh: ResourceHelper, - constraintChecker: ConstraintChecker, + constraintChecker: Constraints, activePlugin: ActivePlugin, sp: SP, commandQueue: CommandQueue, diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java index 75c5ec5079..1327d5aa85 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java @@ -37,6 +37,7 @@ import info.nightscout.androidaps.danar.comm.MsgSettingShippingInfo; import info.nightscout.androidaps.danar.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; +import info.nightscout.androidaps.interfaces.Constraints; import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.dialogs.BolusProgressDialog; @@ -50,7 +51,6 @@ import info.nightscout.androidaps.interfaces.PumpSync; import info.nightscout.shared.logging.AAPSLogger; import info.nightscout.shared.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; @@ -64,7 +64,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { @Inject AAPSLogger aapsLogger; @Inject RxBus rxBus; @Inject ResourceHelper rh; - @Inject ConstraintChecker constraintChecker; + @Inject Constraints constraintChecker; @Inject DanaPump danaPump; @Inject DanaRPlugin danaRPlugin; @Inject DanaRKoreanPlugin danaRKoreanPlugin; diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java index 40e9688199..3bd6c48967 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java @@ -17,17 +17,16 @@ import info.nightscout.androidaps.danaRv2.services.DanaRv2ExecutionService; import info.nightscout.androidaps.danar.AbstractDanaRPlugin; import info.nightscout.androidaps.danar.R; import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.interfaces.ActivePlugin; import info.nightscout.androidaps.interfaces.CommandQueue; import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.Constraints; +import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.interfaces.PumpSync; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage; @@ -36,8 +35,9 @@ import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.Round; import info.nightscout.androidaps.utils.T; -import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.utils.rx.AapsSchedulers; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; import io.reactivex.rxjava3.disposables.CompositeDisposable; @@ -48,7 +48,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { private final AAPSLogger aapsLogger; private final Context context; private final ResourceHelper rh; - private final ConstraintChecker constraintChecker; + private final Constraints constraintChecker; private final DetailedBolusInfoStorage detailedBolusInfoStorage; private final TemporaryBasalStorage temporaryBasalStorage; private final FabricPrivacy fabricPrivacy; @@ -63,7 +63,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { RxBus rxBus, Context context, ResourceHelper rh, - ConstraintChecker constraintChecker, + Constraints constraintChecker, ActivePlugin activePlugin, SP sp, CommandQueue commandQueue, diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java index 881eda371f..1be361b923 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java @@ -10,7 +10,6 @@ import info.nightscout.androidaps.dana.DanaFragment; import info.nightscout.androidaps.dana.DanaPump; import info.nightscout.androidaps.dana.comm.RecordTypes; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; -import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventPreferenceChange; @@ -22,23 +21,23 @@ import info.nightscout.androidaps.interfaces.Constraints; import info.nightscout.androidaps.interfaces.Dana; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.interfaces.Pump; +import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpPluginBase; import info.nightscout.androidaps.interfaces.PumpSync; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.common.ManufacturerType; -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.Round; -import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.utils.rx.AapsSchedulers; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; import io.reactivex.rxjava3.disposables.CompositeDisposable; @@ -55,7 +54,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump protected PumpDescription pumpDescription = new PumpDescription(); protected DanaPump danaPump; - protected ConstraintChecker constraintChecker; + protected Constraints constraintChecker; protected RxBus rxBus; protected ActivePlugin activePlugin; protected SP sp; @@ -67,7 +66,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump HasAndroidInjector injector, DanaPump danaPump, ResourceHelper rh, - ConstraintChecker constraintChecker, + Constraints constraintChecker, AAPSLogger aapsLogger, AapsSchedulers aapsSchedulers, CommandQueue commandQueue, diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java index 883572425e..bf86382b95 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java @@ -21,20 +21,20 @@ import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.ActivePlugin; import info.nightscout.androidaps.interfaces.CommandQueue; import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.Constraints; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.interfaces.PumpSync; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; +import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.Round; -import info.nightscout.androidaps.interfaces.ResourceHelper; import info.nightscout.androidaps.utils.rx.AapsSchedulers; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; import info.nightscout.shared.sharedPreferences.SP; import io.reactivex.rxjava3.disposables.CompositeDisposable; @@ -45,7 +45,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { private final AAPSLogger aapsLogger; private final Context context; private final ResourceHelper rh; - private final ConstraintChecker constraintChecker; + private final Constraints constraints; private final FabricPrivacy fabricPrivacy; @Inject @@ -56,7 +56,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { RxBus rxBus, Context context, ResourceHelper rh, - ConstraintChecker constraintChecker, + Constraints constraints, ActivePlugin activePlugin, SP sp, CommandQueue commandQueue, @@ -65,11 +65,11 @@ public class DanaRPlugin extends AbstractDanaRPlugin { FabricPrivacy fabricPrivacy, PumpSync pumpSync ) { - super(injector, danaPump, rh, constraintChecker, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil, pumpSync); + super(injector, danaPump, rh, constraints, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil, pumpSync); this.aapsLogger = aapsLogger; this.context = context; this.rh = rh; - this.constraintChecker = constraintChecker; + this.constraints = constraints; this.fabricPrivacy = fabricPrivacy; useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false); @@ -159,7 +159,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { @NonNull @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { - detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); + detailedBolusInfo.insulin = constraints.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.getId()); boolean connectionOK = false; @@ -207,7 +207,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { //This should not be needed while using queue because connection should be done before calling this PumpEnactResult result = new PumpEnactResult(getInjector()); - absoluteRate = constraintChecker.applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); + absoluteRate = constraints.applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d && absoluteRate >= 0.10d; final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d; @@ -217,8 +217,8 @@ public class DanaRPlugin extends AbstractDanaRPlugin { int percentRate = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue(); // Any basal less than 0.10u/h will be dumped once per hour, not every 4 minutes. So if it's less than .10u/h, set a zero temp. if (absoluteRate < 0.10d) percentRate = 0; - if (percentRate < 100) percentRate = (int) Round.INSTANCE.ceilTo((double) percentRate, 10d); - else percentRate = (int) Round.INSTANCE.floorTo((double) percentRate, 10d); + if (percentRate < 100) percentRate = (int) Round.INSTANCE.ceilTo(percentRate, 10d); + else percentRate = (int) Round.INSTANCE.floorTo(percentRate, 10d); if (percentRate > getPumpDescription().getMaxTempPercent()) { percentRate = getPumpDescription().getMaxTempPercent(); } @@ -286,7 +286,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { int durationInHalfHours = Math.max(durationInMinutes / 30, 1); // We keep current basal running so need to sub current basal double extendedRateToSet = absoluteRate - getBaseBasalRate(); - extendedRateToSet = constraintChecker.applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value(); + extendedRateToSet = constraints.applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value(); // needs to be rounded to 0.1 extendedRateToSet = Round.INSTANCE.roundTo(extendedRateToSet, pumpDescription.getExtendedBolusStep() * 2); // *2 because of half hours diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt index 491bb0b040..c59a6d7889 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt @@ -12,7 +12,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.ConfigBuilder import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage import info.nightscout.androidaps.utils.CRC.getCrc16 @@ -46,7 +46,7 @@ open class MessageBase(injector: HasAndroidInjector) { @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Inject lateinit var temporaryBasalStorage: TemporaryBasalStorage - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var pumpSync: PumpSync @Inject lateinit var danaHistoryRecordDao: DanaHistoryRecordDao diff --git a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt index 16bbb9112c..e56c04020d 100644 --- a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt +++ b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/DanaRPluginTest.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before @@ -21,7 +21,7 @@ import org.mockito.Mockito.`when` class DanaRPluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var sp: SP @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var pumpSync: PumpSync diff --git a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt index 2f198bafb4..98f0b9c7ea 100644 --- a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt +++ b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/DanaRTestBase.kt @@ -16,7 +16,7 @@ import info.nightscout.androidaps.interfaces.ConfigBuilder import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.interfaces.ResourceHelper @@ -41,7 +41,7 @@ open class DanaRTestBase : TestBase() { @Mock lateinit var configBuilder: ConfigBuilder @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var pumpSync: PumpSync @Mock lateinit var danaHistoryRecordDao: DanaHistoryRecordDao diff --git a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt index 6db1382b3a..5cb2260983 100644 --- a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt +++ b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRKorean/DanaRKoreanPluginTest.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before @@ -21,7 +21,7 @@ import org.mockito.Mockito.`when` class DanaRKoreanPluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var sp: SP @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var pumpSync: PumpSync diff --git a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt index c0fc30ac73..bd7e61a7fa 100644 --- a/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt +++ b/pump/danar/src/test/java/info/nightscout/androidaps/plugins/pump/danaRv2/DanaRv2PluginTest.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage import info.nightscout.shared.sharedPreferences.SP @@ -22,7 +22,7 @@ import org.mockito.Mockito.`when` class DanaRv2PluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var sp: SP @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage diff --git a/pump/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt index 964fe05fb8..e7fdd5e579 100644 --- a/pump/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt +++ b/pump/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt @@ -24,7 +24,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.common.ManufacturerType -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress @@ -54,7 +54,7 @@ class DanaRSPlugin @Inject constructor( private val rxBus: RxBus, private val context: Context, rh: ResourceHelper, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, private val profileFunction: ProfileFunction, private val sp: SP, commandQueue: CommandQueue, diff --git a/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt index 4e9dab3a54..14e84ac302 100644 --- a/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt +++ b/pump/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt @@ -3,7 +3,7 @@ package info.nightscout.androidaps.danars.comm import dagger.android.HasAndroidInjector import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.shared.logging.LTag -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.danars.encryption.BleEncryption import javax.inject.Inject @@ -15,7 +15,7 @@ class DanaRSPacketBolusSetStepBolusStart( ) : DanaRSPacket(injector) { @Inject lateinit var danaPump: DanaPump - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints init { opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_START diff --git a/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt b/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt index 994a56b43e..b17b6d8f74 100644 --- a/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt +++ b/pump/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt @@ -29,7 +29,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.general.overview.notifications.Notification @@ -65,7 +65,7 @@ class DanaRSService : DaggerService() { @Inject lateinit var danaRSPlugin: DanaRSPlugin @Inject lateinit var danaPump: DanaPump @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var activityNames: ActivityNames @Inject lateinit var bleComm: BLEComm @Inject lateinit var fabricPrivacy: FabricPrivacy diff --git a/pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt index 550484e1e7..6dbc566fd5 100644 --- a/pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt +++ b/pump/danars/src/test/java/info/nightscout/androidaps/danars/DanaRSPluginTest.kt @@ -7,7 +7,7 @@ import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage import org.junit.Assert @@ -21,7 +21,7 @@ import org.mockito.Mockito class DanaRSPluginTest : DanaRSTestBase() { @Mock lateinit var context: Context - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage diff --git a/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt index 4fc446bd31..bf0e31b6a4 100644 --- a/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt +++ b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsMessageHashTableTest.kt @@ -7,7 +7,7 @@ import info.nightscout.androidaps.danars.DanaRSTestBase import info.nightscout.androidaps.danars.encryption.BleEncryption import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Constraint -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import org.junit.Assert import org.junit.Test import org.mockito.Mock @@ -16,7 +16,7 @@ import org.mockito.Mockito.`when` class DanaRsMessageHashTableTest : DanaRSTestBase() { @Mock lateinit var activePlugin: ActivePlugin - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints private val packetInjector = HasAndroidInjector { AndroidInjector { diff --git a/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt index ab385d84f3..cfdd79d1b2 100644 --- a/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt +++ b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt @@ -8,7 +8,7 @@ import info.nightscout.androidaps.danars.DanaRSTestBase import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage import org.junit.Assert @@ -19,7 +19,7 @@ import org.mockito.Mockito class DanaRsPacketBolusSetStepBolusStartTest : DanaRSTestBase() { - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var context: Context @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage diff --git a/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt index 61f6ac97a0..bf58a52435 100644 --- a/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt +++ b/pump/danars/src/test/java/info/nightscout/androidaps/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt @@ -8,7 +8,7 @@ import info.nightscout.androidaps.danars.DanaRSTestBase import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage @@ -22,7 +22,7 @@ import org.mockito.Mockito.`when` class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() { @Mock lateinit var activePlugin: ActivePlugin - @Mock lateinit var constraintChecker: ConstraintChecker + @Mock lateinit var constraintChecker: Constraints @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var context: Context @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage diff --git a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt index d6f144209b..b86b17a8dd 100644 --- a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt +++ b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/DiaconnG8Plugin.kt @@ -20,7 +20,7 @@ import info.nightscout.androidaps.extensions.plannedRemainingMinutes import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.common.ManufacturerType -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification @@ -51,7 +51,7 @@ class DiaconnG8Plugin @Inject constructor( private val rxBus: RxBus, private val context: Context, rh: ResourceHelper, - private val constraintChecker: ConstraintChecker, + private val constraintChecker: Constraints, private val profileFunction: ProfileFunction, private val sp: SP, commandQueue: CommandQueue, diff --git a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt index 1dd284d41c..4a1fa6dd66 100644 --- a/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt +++ b/pump/diaconn/src/main/java/info/nightscout/androidaps/diaconn/service/DiaconnG8Service.kt @@ -59,7 +59,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.general.overview.notifications.Notification @@ -96,7 +96,7 @@ class DiaconnG8Service : DaggerService() { @Inject lateinit var diaconnG8Plugin: DiaconnG8Plugin @Inject lateinit var diaconnG8Pump: DiaconnG8Pump @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Inject lateinit var bleCommonService: BLECommonService @Inject lateinit var fabricPrivacy: FabricPrivacy diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt index 2bae95c60c..2dbe5511ad 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt @@ -28,7 +28,7 @@ import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DecimalFormatter @@ -54,7 +54,7 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var ctx: Context @Inject lateinit var rh: ResourceHelper - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculator: IobCobCalculator diff --git a/ui/src/main/java/info/nightscout/ui/widget/Widget.kt b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt index 195a1f88a3..2cdef86ef5 100644 --- a/ui/src/main/java/info/nightscout/ui/widget/Widget.kt +++ b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt @@ -29,7 +29,7 @@ import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.VariableSensitivityResult -import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.plugins.general.overview.OverviewData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.utils.DateUtil @@ -60,7 +60,7 @@ class Widget : AppWidgetProvider() { @Inject lateinit var loop: Loop @Inject lateinit var config: Config @Inject lateinit var sp: SP - @Inject lateinit var constraintChecker: ConstraintChecker + @Inject lateinit var constraintChecker: Constraints companion object { // This object doesn't behave like singleton,