├── DoseMathTests ├── es.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── ru.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── Base.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── fr.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── nb.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── nl.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── pl.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── de.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── it.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── zh-Hans.lproj │ ├── InfoPlist.strings │ └── Localizable.strings ├── Fixtures │ ├── recommend_temp_basal_flat_and_high.json │ ├── recommend_temp_basal_no_change_glucose.json │ ├── recommend_temp_basal_correct_low_at_min.json │ ├── recommend_temp_basal_start_high_end_low.json │ ├── recommend_temp_basal_start_low_end_in_range.json │ ├── recommend_temp_basal_dropping_then_rising.json │ ├── recommend_temp_basal_high_and_falling.json │ ├── recommend_temp_basal_high_and_rising.json │ ├── recommend_temp_basal_in_range_and_rising.json │ ├── recommend_temp_basal_start_high_end_in_range.json │ ├── recommend_temp_basal_start_low_end_high.json │ ├── recommend_temp_basal_very_low_end_in_range.json │ ├── recommend_temp_basal_start_very_low_end_high.json │ ├── far_future_high_bg_forecast.json │ └── read_selected_basal_profile.json └── Info.plist ├── Loop ├── de.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── fr.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── it.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── nb.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── nl.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── pl.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── zh-Hans.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── es.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── ru.lproj │ ├── LaunchScreen.strings │ └── InfoPlist.strings ├── Assets.xcassets │ ├── Contents.json │ ├── bolus.imageset │ │ ├── bolus.pdf │ │ └── Contents.json │ ├── carbs.imageset │ │ ├── Meal.pdf │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Icon-76.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small-60.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── App Store Copy@2x.png │ │ ├── Icon-Small-40@2x.png │ │ ├── Icon-Small-60@2x.png │ │ ├── Icon-Small@2x-1.png │ │ ├── Icon-Small-40@2x-1.png │ │ ├── Icon-Notification-20.png │ │ ├── Icon-Notification-40.png │ │ ├── Icon-Notification-41.png │ │ └── Icon-Notification-42.png │ ├── Pre-Meal.imageset │ │ ├── Pre-Meal.pdf │ │ └── Contents.json │ ├── settings.imageset │ │ ├── settings.png │ │ ├── settings@2x.png │ │ ├── settings@3x.png │ │ ├── settings_compact@2x.png │ │ ├── settings_compact@3x.png │ │ └── Contents.json │ ├── workout.imageset │ │ ├── workout.pdf │ │ └── Contents.json │ ├── Uploading.imageset │ │ ├── Uploading.pdf │ │ └── Contents.json │ ├── workout-selected.imageset │ │ ├── workout-selected.pdf │ │ └── Contents.json │ └── Pre-Meal Selected.imageset │ │ ├── Pre-Meal Selected.pdf │ │ └── Contents.json ├── Models │ ├── Result.swift │ ├── LoopSettings+Loop.swift │ ├── WatchContext+LoopKit.swift │ ├── StatusExtensionContext+LoopKit.swift │ ├── AbsorptionTimeType+CarbKit.swift │ ├── Locked.swift │ ├── GlucoseEffectVelocity.swift │ ├── ServiceAuthentication │ │ └── MLabService.swift │ └── NetBasal.swift ├── RemoteSettings-template.plist ├── Views │ ├── TextFieldTableViewCell.swift │ ├── HUDViewTableViewCell.swift │ ├── TitleSubtitleTextFieldTableViewCell.swift │ ├── CircleMaskView.swift │ ├── HeaderValuesTableViewCell.swift │ ├── ChartTableViewCell.swift │ ├── TitleSubtitleTableViewCell.swift │ └── PredictionInputEffectTableViewCell.swift ├── Extensions │ ├── UITableViewCell.swift │ ├── Data.swift │ ├── CaseCountable.swift │ ├── ChartColorPalette+Loop.swift │ ├── StateColorPalette.swift │ ├── ChartSettings+Loop.swift │ ├── MealBolusNightscoutTreatment.swift │ ├── UIColor+Loop.swift │ ├── CollectionType+Loop.swift │ ├── NewPumpEvent.swift │ └── UIImage.swift ├── View Controllers │ ├── CarbEntryTableViewController.swift │ ├── CarbEntryEditTableViewController.swift │ ├── InsulinDeliveryTableViewController.swift │ ├── TextFieldTableViewController.swift │ └── GlucoseThresholdTableViewController.swift ├── Loop.entitlements ├── Managers │ ├── DiagnosticLogger+LoopKit.swift │ ├── KeychainManager+Loop.swift │ ├── CGMManager.swift │ ├── PumpManager.swift │ └── RemoteDataManager.swift └── Base.lproj │ └── InfoPlist.strings ├── Loop Status Extension ├── ru.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── Base.lproj │ └── InfoPlist.strings ├── nb.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── nl.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── pl.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── de.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── es.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── fr.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── it.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── zh-Hans.lproj │ ├── InfoPlist.strings │ └── MainInterface.strings ├── Loop Status Extension.entitlements ├── StateColorPalette.swift ├── UIColor+Widget.swift └── Info.plist ├── LoopTests ├── de.lproj │ └── InfoPlist.strings ├── es.lproj │ └── InfoPlist.strings ├── fr.lproj │ └── InfoPlist.strings ├── it.lproj │ └── InfoPlist.strings ├── nb.lproj │ └── InfoPlist.strings ├── nl.lproj │ └── InfoPlist.strings ├── pl.lproj │ └── InfoPlist.strings ├── ru.lproj │ └── InfoPlist.strings ├── zh-Hans.lproj │ └── InfoPlist.strings └── Info.plist ├── LoopUI ├── Assets.xcassets │ ├── Contents.json │ ├── battery │ │ ├── Contents.json │ │ ├── battery.imageset │ │ │ ├── battery.pdf │ │ │ └── Contents.json │ │ └── battery_mask.imageset │ │ │ ├── battery_mask.pdf │ │ │ └── Contents.json │ └── reservoir │ │ ├── Contents.json │ │ ├── reservoir.imageset │ │ ├── reservoir.pdf │ │ └── Contents.json │ │ └── reservoir_mask.imageset │ │ ├── reservoir_mask.pdf │ │ └── Contents.json ├── nb.lproj │ └── InfoPlist.strings ├── nl.lproj │ └── InfoPlist.strings ├── pl.lproj │ └── InfoPlist.strings ├── Base.lproj │ └── InfoPlist.strings ├── de.lproj │ └── InfoPlist.strings ├── es.lproj │ └── InfoPlist.strings ├── fr.lproj │ └── InfoPlist.strings ├── it.lproj │ └── InfoPlist.strings ├── ru.lproj │ └── InfoPlist.strings ├── zh-Hans.lproj │ └── InfoPlist.strings ├── Views │ ├── BaseHUDView.swift │ ├── BatteryLevelHUDView.swift │ ├── LevelHUDView.swift │ └── ChartContainerView.swift ├── LoopUI.h ├── Models │ ├── StateColorPalette.swift │ ├── ChartColorPalette.swift │ ├── ChartLineModel.swift │ └── ChartAxisValueDoubleUnit.swift ├── Common │ └── LocalizedString.swift ├── Extensions │ └── CGPoint.swift └── Info.plist ├── WatchApp ├── Assets.xcassets │ ├── Contents.json │ ├── loop │ │ ├── Contents.json │ │ ├── loop_aging.imageset │ │ │ ├── loop-aging@38mm.png │ │ │ ├── loop-aging@42mm.png │ │ │ └── Contents.json │ │ ├── loop_fresh.imageset │ │ │ ├── loop-fresh@38mm.png │ │ │ ├── loop-fresh@42mm.png │ │ │ └── Contents.json │ │ ├── loop_stale.imageset │ │ │ ├── loop-stale@38mm.png │ │ │ ├── loop-stale@42mm.png │ │ │ └── Contents.json │ │ └── loop_unknown.imageset │ │ │ ├── loop-unknown@38mm.png │ │ │ ├── loop-unknown@42mm.png │ │ │ └── Contents.json │ ├── Graph menu icons │ │ ├── Contents.json │ │ ├── 1-hour-graph-38mm.png │ │ ├── 1-hour-graph-42mm.png │ │ ├── 2-hour-graph-38mm.png │ │ ├── 2-hour-graph-42mm.png │ │ ├── 3-hour-graph-38mm.png │ │ ├── 3-hour-graph-42mm.png │ │ ├── 1-hour-graph.imageset │ │ │ ├── 1-hour-graph-38mm.png │ │ │ ├── 1-hour-graph-42mm.png │ │ │ └── Contents.json │ │ ├── 2-hour-graph.imageset │ │ │ ├── 2-hour-graph-38mm.png │ │ │ ├── 2-hour-graph-42mm.png │ │ │ └── Contents.json │ │ └── 3-hour-graph.imageset │ │ │ ├── 3-hour-graph-38mm.png │ │ │ ├── 3-hour-graph-42mm.png │ │ │ └── Contents.json │ ├── carbs.imageset │ │ ├── Carb Icon 42mm.pdf │ │ ├── Carbs icon 38mm.png │ │ └── Contents.json │ ├── workout.imageset │ │ ├── Workout 38mm.png │ │ ├── Workout 42mm.pdf │ │ └── Contents.json │ ├── bolus.imageset │ │ ├── Bolus Icon 42mm.pdf │ │ ├── Bolus icon 38mm.png │ │ └── Contents.json │ ├── pre-meal.imageset │ │ ├── Pre-Meal 38mm.png │ │ ├── Pre-Meal 42mm.pdf │ │ └── Contents.json │ └── AppIcon.appiconset │ │ ├── Icon-App-Store-1024.png │ │ ├── Icon-AppleWatch-24x24@2x.png │ │ ├── Icon-AppleWatch-40x40@2x.png │ │ ├── Icon-AppleWatch-44x44@2x.png │ │ ├── Icon-AppleWatch-86x86@2x.png │ │ ├── Icon-AppleWatch-98x98@2x.png │ │ ├── Icon-AppleWatch-100x100@2x.png │ │ ├── Icon-AppleWatch-216x216@2x.png │ │ ├── Icon-AppleWatch-27.5x27.5@2x.png │ │ ├── Icon-AppleWatch-Companion-29x29@2x.png │ │ └── Icon-AppleWatch-Companion-29x29@3x.png ├── de.lproj │ └── InfoPlist.strings ├── es.lproj │ └── InfoPlist.strings ├── fr.lproj │ └── InfoPlist.strings ├── it.lproj │ └── InfoPlist.strings ├── nb.lproj │ └── InfoPlist.strings ├── nl.lproj │ └── InfoPlist.strings ├── pl.lproj │ └── InfoPlist.strings ├── ru.lproj │ └── InfoPlist.strings ├── Base.lproj │ └── InfoPlist.strings ├── zh-Hans.lproj │ └── InfoPlist.strings └── Info.plist ├── Documentation ├── Changing the app icon.png ├── Screenshots │ ├── Phone Bolus.png │ ├── Watch Bolus.png │ ├── Watch Menu.png │ ├── Phone Graphs.png │ ├── Watch Carb Entry.png │ ├── Watch Complication.png │ ├── Phone Notification Battery.png │ ├── Watch Notification Battery.png │ ├── Watch Notification Reservoir.png │ ├── Phone Notification Loop Failure.png │ ├── Phone Notification Bolus Failure.png │ └── Watch Notification Bolus Failure.png ├── User Icons │ └── LoopingPump.png ├── Changing the display name.png └── Assigning a bundle identifier.png ├── WatchApp Extension ├── Assets.xcassets │ ├── Contents.json │ └── Complication.complicationset │ │ ├── Modular.imageset │ │ ├── Icon-Complication-26x26@2x.png │ │ ├── Icon-Complication-29x29@2x.png │ │ ├── Icon-Complication-32x32@2x.png │ │ └── Contents.json │ │ ├── Circular.imageset │ │ ├── Icon-Complication-16x16@2x.png │ │ ├── Icon-Complication-18x18@2x.png │ │ └── Contents.json │ │ ├── Graphic Bezel.imageset │ │ ├── Icon-AppleWatch-42x42@2x.png │ │ ├── Icon-AppleWatch-47x47@2x.png │ │ └── Contents.json │ │ ├── Utilitarian.imageset │ │ ├── Icon-Complication-20x20@2x.png │ │ ├── Icon-Complication-22x22@2x.png │ │ ├── Icon-Complication-25x25@2x.png │ │ └── Contents.json │ │ ├── Graphic Circular.imageset │ │ ├── Icon-AppleWatch-42x42@2x.png │ │ ├── Icon-AppleWatch-47x47@2x.png │ │ └── Contents.json │ │ ├── Graphic Corner.imageset │ │ ├── Icon-Complication-20x20@2x.png │ │ ├── Icon-Complication-22x22@2x.png │ │ └── Contents.json │ │ ├── Graphic Large Rectangular.imageset │ │ └── Contents.json │ │ ├── Extra Large.imageset │ │ └── Contents.json │ │ └── Contents.json ├── Base.lproj │ ├── InfoPlist.strings │ └── ckcomplication.strings ├── nb.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── nl.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── pl.lproj │ ├── InfoPlist.strings │ └── ckcomplication.strings ├── de.lproj │ ├── InfoPlist.strings │ └── ckcomplication.strings ├── es.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── fr.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── it.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── ru.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── zh-Hans.lproj │ ├── InfoPlist.strings │ ├── ckcomplication.strings │ └── Localizable.strings ├── Extensions │ ├── WatchApp Extension-Bridging-Header.h │ ├── GlucoseStore.swift │ ├── Date.swift │ ├── IdentifiableClass.swift │ ├── CLKTextProvider+Compound.h │ ├── WKAlertAction.swift │ ├── WKInterfaceImage.swift │ ├── CGRect.swift │ ├── INRelevantShortcutStore+Loop.swift │ ├── WatchContext+WatchApp.swift │ ├── NSUserDefaults+WatchApp.swift │ └── CLKTextProvider+Compound.m ├── WatchApp Extension.entitlements ├── Controllers │ └── NotificationController.swift └── PushNotificationPayload.apns ├── Common ├── en.lproj │ └── Intents.strings ├── it.lproj │ └── Intents.strings ├── ru.lproj │ └── Intents.strings ├── es.lproj │ └── Intents.strings ├── Extensions │ ├── NewCarbEntryIntent+Loop.swift │ ├── NibLoadable.swift │ ├── IdentifiableClass.swift │ ├── Double.swift │ ├── UserDefaults+CGM.swift │ ├── NSTimeInterval.swift │ ├── UIColor.swift │ ├── SampleValue.swift │ ├── NSUserDefaults+StatusExtension.swift │ ├── NSUserActivity.swift │ ├── NSBundle.swift │ └── PersistenceController.swift └── Models │ ├── Insulin │ └── WalshInsulinModel.swift │ ├── LoopSettingsUserInfo.swift │ ├── GlucoseBackfillRequestUserInfo.swift │ ├── GlucoseThreshold.swift │ ├── SetBolusUserInfo.swift │ └── BolusSuggestionUserInfo.swift ├── Loop.xcodeproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── Cartfile ├── Cartfile.resolved ├── Loop.xcconfig ├── .travis.yml └── .github └── ISSUE_TEMPLATE └── bug_report.md /DoseMathTests/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /DoseMathTests/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Loop/de.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop/fr.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop/it.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop/nb.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop/nl.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop/pl.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop Status Extension/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Loop/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Loop/es.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /Loop/ru.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /DoseMathTests/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /DoseMathTests/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /DoseMathTests/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /DoseMathTests/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /DoseMathTests/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* No Localized Strings */ 2 | -------------------------------------------------------------------------------- /LoopTests/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /DoseMathTests/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /DoseMathTests/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /LoopTests/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /DoseMathTests/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/battery/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/reservoir/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Documentation/Changing the app icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Changing the app icon.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Phone Bolus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Phone Bolus.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Bolus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Bolus.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Menu.png -------------------------------------------------------------------------------- /Documentation/User Icons/LoopingPump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/User Icons/LoopingPump.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Documentation/Changing the display name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Changing the display name.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Phone Graphs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Phone Graphs.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Carb Entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Carb Entry.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/bolus.imageset/bolus.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/bolus.imageset/bolus.pdf -------------------------------------------------------------------------------- /Loop/Assets.xcassets/carbs.imageset/Meal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/carbs.imageset/Meal.pdf -------------------------------------------------------------------------------- /Documentation/Assigning a bundle identifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Assigning a bundle identifier.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Complication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Complication.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Pre-Meal.imageset/Pre-Meal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/Pre-Meal.imageset/Pre-Meal.pdf -------------------------------------------------------------------------------- /Loop/Assets.xcassets/settings.imageset/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/settings.imageset/settings.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/workout.imageset/workout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/workout.imageset/workout.pdf -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Uploading.imageset/Uploading.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/Uploading.imageset/Uploading.pdf -------------------------------------------------------------------------------- /Documentation/Screenshots/Phone Notification Battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Phone Notification Battery.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Notification Battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Notification Battery.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/settings.imageset/settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/settings.imageset/settings@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/settings.imageset/settings@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/settings.imageset/settings@3x.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Notification Reservoir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Notification Reservoir.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-60.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /LoopUI/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/carbs.imageset/Carb Icon 42mm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/carbs.imageset/Carb Icon 42mm.pdf -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/workout.imageset/Workout 38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/workout.imageset/Workout 38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/workout.imageset/Workout 42mm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/workout.imageset/Workout 42mm.pdf -------------------------------------------------------------------------------- /WatchApp/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Documentation/Screenshots/Phone Notification Loop Failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Phone Notification Loop Failure.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/App Store Copy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/App Store Copy@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-60@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/battery/battery.imageset/battery.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/LoopUI/Assets.xcassets/battery/battery.imageset/battery.pdf -------------------------------------------------------------------------------- /LoopUI/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /LoopUI/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/bolus.imageset/Bolus Icon 42mm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/bolus.imageset/Bolus Icon 42mm.pdf -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/bolus.imageset/Bolus icon 38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/bolus.imageset/Bolus icon 38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/carbs.imageset/Carbs icon 38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/carbs.imageset/Carbs icon 38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 42mm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 42mm.pdf -------------------------------------------------------------------------------- /WatchApp/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Documentation/Screenshots/Phone Notification Bolus Failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Phone Notification Bolus Failure.png -------------------------------------------------------------------------------- /Documentation/Screenshots/Watch Notification Bolus Failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Documentation/Screenshots/Watch Notification Bolus Failure.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x-1.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/settings.imageset/settings_compact@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/settings.imageset/settings_compact@2x.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/settings.imageset/settings_compact@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/settings.imageset/settings_compact@3x.png -------------------------------------------------------------------------------- /LoopUI/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "LoopUI"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph-38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph-38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph-42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph-42mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph-38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph-38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph-42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph-42mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph-38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph-38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph-42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph-42mm.png -------------------------------------------------------------------------------- /Loop Status Extension/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-20.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-40.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-41.png -------------------------------------------------------------------------------- /Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/AppIcon.appiconset/Icon-Notification-42.png -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/reservoir/reservoir.imageset/reservoir.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/LoopUI/Assets.xcassets/reservoir/reservoir.imageset/reservoir.pdf -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_flat_and_high.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 200}, 3 | {"date": "2015-07-19T22:00:00", "amount": 200}, 4 | ] 5 | -------------------------------------------------------------------------------- /Loop Status Extension/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/workout-selected.imageset/workout-selected.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/workout-selected.imageset/workout-selected.pdf -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-App-Store-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-App-Store-1024.png -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_no_change_glucose.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T20:00:00", "amount": 100}, 3 | {"date": "2015-07-19T20:30:00", "amount": 100} 4 | ] 5 | -------------------------------------------------------------------------------- /Loop Status Extension/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Pre-Meal Selected.imageset/Pre-Meal Selected.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/Loop/Assets.xcassets/Pre-Meal Selected.imageset/Pre-Meal Selected.pdf -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/battery/battery_mask.imageset/battery_mask.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/LoopUI/Assets.xcassets/battery/battery_mask.imageset/battery_mask.pdf -------------------------------------------------------------------------------- /WatchApp Extension/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* (No Comment) */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* (No Comment) */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_aging.imageset/loop-aging@38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_aging.imageset/loop-aging@38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_aging.imageset/loop-aging@42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_aging.imageset/loop-aging@42mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_fresh.imageset/loop-fresh@38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_fresh.imageset/loop-fresh@38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_fresh.imageset/loop-fresh@42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_fresh.imageset/loop-fresh@42mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_stale.imageset/loop-stale@38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_stale.imageset/loop-stale@38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_stale.imageset/loop-stale@42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_stale.imageset/loop-stale@42mm.png -------------------------------------------------------------------------------- /WatchApp Extension/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-24x24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-24x24@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-40x40@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-44x44@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-44x44@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-86x86@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-86x86@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-98x98@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-98x98@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_unknown.imageset/loop-unknown@38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_unknown.imageset/loop-unknown@38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_unknown.imageset/loop-unknown@42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/loop/loop_unknown.imageset/loop-unknown@42mm.png -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/reservoir/reservoir_mask.imageset/reservoir_mask.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/LoopUI/Assets.xcassets/reservoir/reservoir_mask.imageset/reservoir_mask.pdf -------------------------------------------------------------------------------- /WatchApp Extension/de.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 2 | "UtilitarianLargeFlat" = "%@%@ %@"; 3 | 4 | -------------------------------------------------------------------------------- /WatchApp Extension/it.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 2 | "UtilitarianLargeFlat" = "%@%@ %@"; 3 | 4 | -------------------------------------------------------------------------------- /WatchApp Extension/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "WatchApp Extension"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-100x100@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-100x100@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-216x216@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-216x216@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-27.5x27.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-27.5x27.5@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/zh-Hans.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 2 | "UtilitarianLargeFlat" = "%@%@ %@"; 3 | 4 | -------------------------------------------------------------------------------- /WatchApp Extension/es.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 2 | "UtilitarianLargeFlat" = "UtilitarianLargeFlat"; 3 | 4 | -------------------------------------------------------------------------------- /WatchApp Extension/ru.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 2 | "UtilitarianLargeFlat" = "UtilitarianLargeFlat"; 3 | 4 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-Companion-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-Companion-29x29@2x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-Companion-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/AppIcon.appiconset/Icon-AppleWatch-Companion-29x29@3x.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph.imageset/1-hour-graph-38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph.imageset/1-hour-graph-38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph.imageset/1-hour-graph-42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph.imageset/1-hour-graph-42mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph.imageset/2-hour-graph-38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph.imageset/2-hour-graph-38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph.imageset/2-hour-graph-42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph.imageset/2-hour-graph-42mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph.imageset/3-hour-graph-38mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph.imageset/3-hour-graph-38mm.png -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph.imageset/3-hour-graph-42mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph.imageset/3-hour-graph-42mm.png -------------------------------------------------------------------------------- /Common/en.lproj/Intents.strings: -------------------------------------------------------------------------------- 1 | /* INIntentTitle */ 2 | "80eo5o" = "Add Carb Entry"; 3 | 4 | /* INIntentParameterCombinationTitle */ 5 | "OcNxIj" = "Add Carb Entry"; 6 | 7 | /* INIntentDescription */ 8 | "yc02Yq" = ""; 9 | -------------------------------------------------------------------------------- /Common/it.lproj/Intents.strings: -------------------------------------------------------------------------------- 1 | /* INIntentTitle */ 2 | "80eo5o" = "Add Carb Entry"; 3 | 4 | /* INIntentParameterCombinationTitle */ 5 | "OcNxIj" = "Add Carb Entry"; 6 | 7 | /* INIntentDescription */ 8 | "yc02Yq" = ""; 9 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/WatchApp Extension-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "CLKTextProvider+Compound.h" 6 | -------------------------------------------------------------------------------- /Loop.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Common/ru.lproj/Intents.strings: -------------------------------------------------------------------------------- 1 | /* INIntentTitle */ 2 | "80eo5o" = "Добавить запись углеводов"; 3 | 4 | /* INIntentParameterCombinationTitle */ 5 | "OcNxIj" = "Добавить запись углеводов"; 6 | 7 | /* INIntentDescription */ 8 | "yc02Yq" = ""; 9 | -------------------------------------------------------------------------------- /Loop/Models/Result.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Result.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | 9 | enum Result { 10 | case success(T) 11 | case failure(Error) 12 | } 13 | -------------------------------------------------------------------------------- /Loop/RemoteSettings-template.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Common/es.lproj/Intents.strings: -------------------------------------------------------------------------------- 1 | /* INIntentTitle */ 2 | "80eo5o" = "Agregar entrada de carbohidratos"; 3 | 4 | /* INIntentParameterCombinationTitle */ 5 | "OcNxIj" = "Agregar entrada de carbohidratos"; 6 | 7 | /* INIntentDescription */ 8 | "yc02Yq" = ""; 9 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Icon-Complication-26x26@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Icon-Complication-26x26@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Icon-Complication-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Icon-Complication-29x29@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Icon-Complication-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Icon-Complication-32x32@2x.png -------------------------------------------------------------------------------- /Loop/Views/TextFieldTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextFieldTableViewCell.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopKitUI 9 | 10 | 11 | extension TextFieldTableViewCell: NibLoadable { } 12 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Icon-Complication-16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Icon-Complication-16x16@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Icon-Complication-18x18@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Icon-Complication-18x18@2x.png -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/battery/battery_mask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "battery_mask.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Icon-AppleWatch-42x42@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Icon-AppleWatch-42x42@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Icon-AppleWatch-47x47@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Icon-AppleWatch-47x47@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Icon-Complication-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Icon-Complication-20x20@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Icon-Complication-22x22@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Icon-Complication-22x22@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Icon-Complication-25x25@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Icon-Complication-25x25@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Icon-AppleWatch-42x42@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Icon-AppleWatch-42x42@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Icon-AppleWatch-47x47@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Icon-AppleWatch-47x47@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Icon-Complication-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Icon-Complication-20x20@2x.png -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Icon-Complication-22x22@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyoung1024/Loop/HEAD/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Icon-Complication-22x22@2x.png -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/reservoir/reservoir_mask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "reservoir_mask.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Loop Status Extension/nb.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "Omsider 92 mg/dL"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 E"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/pl.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 3 | "9iF-xY-Bh4.text" = "docelowo 92 mg/dL"; 4 | 5 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 6 | "UPi-dG-yYD.text" = "IOB 1.0 J"; 7 | -------------------------------------------------------------------------------- /Loop Status Extension/de.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "Schließlich 92 mg/dL"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 E"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/es.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "Eventualmente 92 mg/dL"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 U"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/fr.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "Éventuellement 92 mg/dL"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 U"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/nl.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "Uiteindelijk 92 mg/dL"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 E"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/zh-Hans.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "最终血糖为92 毫克/分升"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 单位"; 6 | 7 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Loop Status Extension/it.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "probabile glic. 92 mg/dL"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 U"; 6 | 7 | -------------------------------------------------------------------------------- /Loop Status Extension/ru.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ 2 | "9iF-xY-Bh4.text" = "в конечном итоге 92 мг/дл"; 3 | 4 | /* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ 5 | "UPi-dG-yYD.text" = "IOB 1.0 ед"; 6 | 7 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | 2 | github "LoopKit/LoopKit" ~> 2.2 3 | github "LoopKit/CGMBLEKit" == 3.0 4 | github "ps2/SwiftCharts" "hotfix-xcode10.2" 5 | github "LoopKit/dexcom-share-client-swift" == 1.0 6 | github "LoopKit/G4ShareSpy" == 1.0 7 | github "ps2/rileylink_ios" ~> 2.1 8 | github "LoopKit/Amplitude-iOS" "decreepify" 9 | -------------------------------------------------------------------------------- /Loop/Extensions/UITableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 5/22/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension UITableViewCell: IdentifiableClass { } 13 | -------------------------------------------------------------------------------- /Loop/Views/HUDViewTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDViewTableViewCell.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import LoopUI 10 | 11 | class HUDViewTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet var hudView: HUDView! 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Common/Extensions/NewCarbEntryIntent+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NewCarbEntryIntent+Loop.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | @available(iOS 12.0, watchOSApplicationExtension 5.0, *) 11 | extension NewCarbEntryIntent: IdentifiableClass { } 12 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_correct_low_at_min.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 100}, 3 | {"date": "2015-07-19T18:30:00", "amount": 90}, 4 | {"date": "2015-07-19T19:00:00", "amount": 85}, 5 | {"date": "2015-07-19T19:30:00", "amount": 90}, 6 | {"date": "2015-07-19T20:00:00", "amount": 100} 7 | ] -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_start_high_end_low.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 200}, 3 | {"date": "2015-07-19T18:30:00", "amount": 160}, 4 | {"date": "2015-07-19T19:00:00", "amount": 120}, 5 | {"date": "2015-07-19T19:30:00", "amount": 80}, 6 | {"date": "2015-07-19T20:00:00", "amount": 60} 7 | ] -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_start_low_end_in_range.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 60}, 3 | {"date": "2015-07-19T18:30:00", "amount": 70}, 4 | {"date": "2015-07-19T19:00:00", "amount": 80}, 5 | {"date": "2015-07-19T19:30:00", "amount": 90}, 6 | {"date": "2015-07-19T20:00:00", "amount": 100} 7 | ] -------------------------------------------------------------------------------- /Loop/Assets.xcassets/bolus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bolus.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /Loop/Assets.xcassets/carbs.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Meal.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_dropping_then_rising.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 90}, 3 | {"date": "2015-07-19T19:00:00", "amount": 80}, 4 | {"date": "2015-07-19T20:00:00", "amount": 100}, 5 | {"date": "2015-07-19T21:00:00", "amount": 160}, 6 | {"date": "2015-07-19T22:00:00", "amount": 200} 7 | ] 8 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_high_and_falling.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 240}, 3 | {"date": "2015-07-19T19:00:00", "amount": 220}, 4 | {"date": "2015-07-19T20:00:00", "amount": 200}, 5 | {"date": "2015-07-19T21:00:00", "amount": 160}, 6 | {"date": "2015-07-19T22:00:00", "amount": 124} 7 | ] 8 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_high_and_rising.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 140}, 3 | {"date": "2015-07-19T19:00:00", "amount": 150}, 4 | {"date": "2015-07-19T20:00:00", "amount": 160}, 5 | {"date": "2015-07-19T21:00:00", "amount": 170}, 6 | {"date": "2015-07-19T22:00:00", "amount": 180} 7 | ] 8 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_in_range_and_rising.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 90}, 3 | {"date": "2015-07-19T19:00:00", "amount": 100}, 4 | {"date": "2015-07-19T20:00:00", "amount": 110}, 5 | {"date": "2015-07-19T21:00:00", "amount": 120}, 6 | {"date": "2015-07-19T22:00:00", "amount": 125} 7 | ] 8 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_start_high_end_in_range.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 200}, 3 | {"date": "2015-07-19T18:30:00", "amount": 180}, 4 | {"date": "2015-07-19T19:00:00", "amount": 150}, 5 | {"date": "2015-07-19T19:30:00", "amount": 120}, 6 | {"date": "2015-07-19T20:00:00", "amount": 100} 7 | ] -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_start_low_end_high.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 60}, 3 | {"date": "2015-07-19T19:00:00", "amount": 80}, 4 | {"date": "2015-07-19T20:00:00", "amount": 120}, 5 | {"date": "2015-07-19T21:00:00", "amount": 160}, 6 | {"date": "2015-07-19T22:00:00", "amount": 200} 7 | ] 8 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_very_low_end_in_range.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 60}, 3 | {"date": "2015-07-19T18:30:00", "amount": 50}, 4 | {"date": "2015-07-19T19:00:00", "amount": 60}, 5 | {"date": "2015-07-19T19:30:00", "amount": 70}, 6 | {"date": "2015-07-19T20:00:00", "amount": 100} 7 | ] 8 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/recommend_temp_basal_start_very_low_end_high.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T18:00:00", "amount": 40}, 3 | {"date": "2015-07-19T18:30:00", "amount": 50}, 4 | {"date": "2015-07-19T19:00:00", "amount": 80}, 5 | {"date": "2015-07-19T19:30:00", "amount": 160}, 6 | {"date": "2015-07-19T20:00:00", "amount": 200} 7 | ] 8 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Pre-Meal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Pre-Meal.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Uploading.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Uploading.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/battery/battery.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "battery.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } -------------------------------------------------------------------------------- /LoopUI/Assets.xcassets/reservoir/reservoir.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "reservoir.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } -------------------------------------------------------------------------------- /Loop/Assets.xcassets/Pre-Meal Selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Pre-Meal Selected.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /Loop/View Controllers/CarbEntryTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarbEntryTableViewController.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/11/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import LoopKitUI 10 | 11 | 12 | extension CarbEntryTableViewController: IdentifiableClass { 13 | } 14 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/GlucoseStore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GlucoseStore.swift 3 | // WatchApp Extension 4 | // 5 | // Created by Bharat Mediratta on 6/26/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | import WatchConnectivity 12 | 13 | extension GlucoseStore { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "LoopKit/Amplitude-iOS" "2137d5fd44bf630ed33e1e72d7af6d8f8612f270" 2 | github "LoopKit/CGMBLEKit" "v3.0" 3 | github "LoopKit/G4ShareSpy" "v1.0" 4 | github "LoopKit/LoopKit" "v2.2.2" 5 | github "LoopKit/dexcom-share-client-swift" "v1.0" 6 | github "ps2/SwiftCharts" "cc8c401171d5ccb638ec6c87f6c410ee31fa774d" 7 | github "ps2/rileylink_ios" "v2.1.1" 8 | -------------------------------------------------------------------------------- /Loop/View Controllers/CarbEntryEditTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarbEntryEditTableViewController.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/25/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import LoopKitUI 10 | 11 | 12 | extension CarbEntryEditViewController: IdentifiableClass { 13 | } 14 | -------------------------------------------------------------------------------- /WatchApp Extension/nb.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* 2 | ckcomplication.strings 3 | Loop 4 | 5 | Created by Nate Racklyeft on 9/18/16. 6 | Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | */ 8 | 9 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 10 | "UtilitarianLargeFlat" = "%@%@ %@"; 11 | -------------------------------------------------------------------------------- /WatchApp Extension/nl.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* 2 | ckcomplication.strings 3 | Loop 4 | 5 | Created by Nate Racklyeft on 9/18/16. 6 | Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | */ 8 | 9 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 10 | "UtilitarianLargeFlat" = "%@%@ %@"; 11 | -------------------------------------------------------------------------------- /WatchApp Extension/pl.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* 2 | ckcomplication.strings 3 | Loop 4 | 5 | Created by Nate Racklyeft on 9/18/16. 6 | Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | */ 8 | 9 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 10 | "UtilitarianLargeFlat" = "%@%@ %@"; 11 | -------------------------------------------------------------------------------- /Loop/View Controllers/InsulinDeliveryTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InsulinDeliveryTableViewController.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/11/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import LoopKitUI 10 | 11 | 12 | extension InsulinDeliveryTableViewController: IdentifiableClass { 13 | } 14 | -------------------------------------------------------------------------------- /Loop/Extensions/Data.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/27/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Data { 13 | var hexadecimalString: String { 14 | return map { String(format: "%02hhx", $0) }.joined() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Loop/Views/TitleSubtitleTextFieldTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TitleSubtitleTextFieldTableViewCell.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | class TitleSubtitleTextFieldTableViewCell: PredictionInputEffectTableViewCell { 11 | 12 | @IBOutlet weak var textField: UITextField! 13 | 14 | } 15 | -------------------------------------------------------------------------------- /WatchApp Extension/fr.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* 2 | ckcomplication.strings 3 | Loop 4 | 5 | Created by Nate Racklyeft on 9/18/16. 6 | Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | */ 8 | 9 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 10 | "UtilitarianLargeFlat" = "%@%@ %@"; 11 | 12 | 13 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/workout.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "workout.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template", 14 | "preserves-vector-representation" : true 15 | } 16 | } -------------------------------------------------------------------------------- /Loop Status Extension/Loop Status Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | $(APP_GROUP_IDENTIFIER) 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Loop/Views/CircleMaskView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircleMaskView.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | class CircleMaskView: UIView { 11 | 12 | override func layoutSubviews() { 13 | super.layoutSubviews() 14 | 15 | self.layer.cornerRadius = self.frame.height / 2 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Loop.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // Loop.xcconfig 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 9/3/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | // This is automatically disambiguated by development team, but you may choose to change this to 10 | // support running multiple apps simultaneously. 11 | MAIN_APP_BUNDLE_IDENTIFIER = com.${DEVELOPMENT_TEAM}.loopkit 12 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/workout-selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "workout-selected.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template", 14 | "preserves-vector-representation" : true 15 | } 16 | } -------------------------------------------------------------------------------- /LoopUI/Views/BaseHUDView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDView.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 5/1/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class BaseHUDView: UIView { 12 | 13 | @IBOutlet weak var caption: UILabel! { 14 | didSet { 15 | caption?.text = "—" 16 | } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /WatchApp Extension/WatchApp Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.healthkit 6 | 7 | com.apple.developer.healthkit.access 8 | 9 | com.apple.developer.siri 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Loop/Loop.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.healthkit 6 | 7 | com.apple.developer.siri 8 | 9 | com.apple.security.application-groups 10 | 11 | $(APP_GROUP_IDENTIFIER) 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Common/Extensions/NibLoadable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NibLoadable.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 7/2/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | protocol NibLoadable: IdentifiableClass { 13 | static func nib() -> UINib 14 | } 15 | 16 | 17 | extension NibLoadable { 18 | static func nib() -> UINib { 19 | return UINib(nibName: className, bundle: Bundle(for: self)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Loop/Models/LoopSettings+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoopSettings+Loop.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | 9 | // MARK: - Static configuration 10 | extension LoopSettings { 11 | var enabledEffects: PredictionInputEffect { 12 | var inputs = PredictionInputEffect.all 13 | if !retrospectiveCorrectionEnabled { 14 | inputs.remove(.retrospection) 15 | } 16 | return inputs 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Loop/Views/HeaderValuesTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderValuesTableViewCell.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | class HeaderValuesTableViewCell: UITableViewCell { 11 | 12 | @IBOutlet weak var COBValueLabel: UILabel! 13 | 14 | @IBOutlet weak var COBDateLabel: UILabel! 15 | 16 | @IBOutlet weak var totalValueLabel: UILabel! 17 | 18 | @IBOutlet weak var totalDateLabel: UILabel! 19 | } 20 | -------------------------------------------------------------------------------- /Loop/Extensions/CaseCountable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CaseCountable.swift 3 | // Loop 4 | // 5 | // Created by Pete Schwamb on 1/1/17. 6 | // Copyright © 2017 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | protocol CaseCountable: RawRepresentable {} 10 | 11 | extension CaseCountable where RawValue == Int { 12 | static var count: Int { 13 | var i: RawValue = 0 14 | while let new = Self(rawValue: i) { i = new.rawValue.advanced(by: 1) } 15 | return i 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Loop/Extensions/ChartColorPalette+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartColorPalette+Loop.swift 3 | // Loop 4 | // 5 | // Created by Bharat Mediratta on 4/1/17. 6 | // Copyright © 2017 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import LoopUI 10 | 11 | 12 | extension ChartColorPalette { 13 | static var `default`: ChartColorPalette { 14 | return ChartColorPalette(axisLine: .axisLineColor, axisLabel: .axisLabelColor, grid: .gridColor, glucoseTint: .glucoseTintColor, doseTint: .doseTintColor) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/Date.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Date.swift 3 | // WatchApp Extension 4 | // 5 | // Created by Bharat Mediratta on 6/26/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Date { 13 | static var earliestGlucoseCutoff: Date { 14 | return Date(timeIntervalSinceNow: .hours(-3)) 15 | } 16 | 17 | static var staleGlucoseCutoff: Date { 18 | return Date(timeIntervalSinceNow: .minutes(-5)) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Common/Extensions/IdentifiableClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IdentifiableClass.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 5/22/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | protocol IdentifiableClass: class { 13 | static var className: String { get } 14 | } 15 | 16 | 17 | extension IdentifiableClass { 18 | static var className: String { 19 | return NSStringFromClass(self).components(separatedBy: ".").last! 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/IdentifiableClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IdentifiableClass.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 2/9/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | protocol IdentifiableClass: class { 13 | static var className: String { get } 14 | } 15 | 16 | 17 | extension IdentifiableClass { 18 | static var className: String { 19 | return NSStringFromClass(self).components(separatedBy: ".").last! 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Loop/Extensions/StateColorPalette.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StateColorPalette.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopUI 9 | 10 | extension StateColorPalette { 11 | static let loopStatus = StateColorPalette(unknown: .unknownColor, normal: .freshColor, warning: .agingColor, error: .staleColor) 12 | 13 | static let cgmStatus = loopStatus 14 | 15 | static let pumpStatus = StateColorPalette(unknown: .unknownColor, normal: .pumpStatusNormal, warning: .agingColor, error: .staleColor) 16 | } 17 | -------------------------------------------------------------------------------- /Loop Status Extension/StateColorPalette.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StateColorPalette.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopUI 9 | 10 | extension StateColorPalette { 11 | static let loopStatus = StateColorPalette(unknown: .unknownColor, normal: .freshColor, warning: .agingColor, error: .staleColor) 12 | 13 | static let cgmStatus = loopStatus 14 | 15 | static let pumpStatus = StateColorPalette(unknown: .unknownColor, normal: .pumpStatusNormal, warning: .agingColor, error: .staleColor) 16 | } 17 | -------------------------------------------------------------------------------- /LoopUI/LoopUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoopUI.h 3 | // LoopUI 4 | // 5 | // Created by Bharat Mediratta on 12/11/16. 6 | // Copyright © 2016 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for LoopUI. 12 | FOUNDATION_EXPORT double LoopUIVersionNumber; 13 | 14 | //! Project version string for LoopUI. 15 | FOUNDATION_EXPORT const unsigned char LoopUIVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Loop/Models/WatchContext+LoopKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WatchContext+LoopKit.swift 3 | // Loop 4 | // 5 | // Created by Nathan Racklyeft on 5/29/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import HealthKit 11 | import LoopKit 12 | 13 | extension WatchContext { 14 | convenience init(glucose: GlucoseValue?, glucoseUnit: HKUnit?) { 15 | self.init() 16 | 17 | self.glucose = glucose?.quantity 18 | self.glucoseDate = glucose?.startDate 19 | self.preferredGlucoseUnit = glucoseUnit 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/CLKTextProvider+Compound.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLKTextProvider+Compound.h 3 | // Loop 4 | // 5 | // Created by Michael Pangburn on 10/27/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | #define CLKTextProvider_Compound_h 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface CLKTextProvider (Compound) 16 | 17 | + (CLKTextProvider *)textProviderByJoiningTextProviders: (NSArray *)textProviders separator:(NSString *) separator; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Loop/Models/StatusExtensionContext+LoopKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatusExtensionContext+LoopKit.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopKit 9 | 10 | 11 | extension NetBasalContext { 12 | var tempBasal: DoseEntry? { 13 | guard rate != 0 else { 14 | return nil 15 | } 16 | 17 | return DoseEntry( 18 | type: .tempBasal, 19 | startDate: start, 20 | endDate: end, 21 | value: rate, 22 | unit: .unitsPerHour 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/WKAlertAction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WKAlertAction.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/20/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import WatchKit 11 | 12 | 13 | extension WKAlertAction { 14 | static func dismissAction() -> Self { 15 | return self.init( 16 | title: NSLocalizedString("Dismiss", comment: "The action button title to dismiss an error message"), 17 | style: .cancel, 18 | handler: { } 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Loop/Extensions/ChartSettings+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartSettings+Loop.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import SwiftCharts 9 | 10 | 11 | extension ChartSettings { 12 | static var `default`: ChartSettings { 13 | var settings = ChartSettings() 14 | settings.top = 12 15 | settings.bottom = 0 16 | settings.trailing = 8 17 | settings.axisTitleLabelsToLabelsSpacing = 0 18 | settings.labelsToAxisSpacingX = 6 19 | settings.clipInnerFrame = false 20 | return settings 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/WKInterfaceImage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WKInterfaceImage.swift 3 | // Loop 4 | // 5 | // Created by Nathan Racklyeft on 5/29/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | 11 | enum LoopImage: String { 12 | case fresh 13 | case aging 14 | case stale 15 | case unknown 16 | 17 | var imageName: String { 18 | return "loop_\(rawValue)" 19 | } 20 | } 21 | 22 | 23 | extension WKInterfaceImage { 24 | func setLoopImage(_ loopImage: LoopImage) { 25 | setImageNamed(loopImage.imageName) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Common/Extensions/Double.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Double.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | extension FloatingPoint { 12 | func floored(to increment: Self) -> Self { 13 | if increment == 0 { 14 | return self 15 | } 16 | 17 | return floor(self / increment) * increment 18 | } 19 | 20 | func ceiled(to increment: Self) -> Self { 21 | if increment == 0 { 22 | return self 23 | } 24 | 25 | return ceil(self / increment) * increment 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /WatchApp Extension/Base.lproj/ckcomplication.strings: -------------------------------------------------------------------------------- 1 | /* 2 | ckcomplication.strings 3 | Loop 4 | 5 | Created by Nate Racklyeft on 9/18/16. 6 | Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | */ 8 | 9 | /* The complication template example glucose and trend string */ 10 | "120↘︎" = "120↘︎"; 11 | 12 | /* The complication template example glucose string */ 13 | "120" = "120"; 14 | 15 | /* The complication template example time string */ 16 | "3MIN" = "3MIN"; 17 | 18 | /* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ 19 | "UtilitarianLargeFlat" = "%@%@ %@"; 20 | -------------------------------------------------------------------------------- /Common/Extensions/UserDefaults+CGM.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserDefaults+CGM.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import LoopKit 10 | 11 | 12 | extension UserDefaults { 13 | private enum Key: String { 14 | case cgmManagerState = "com.loopkit.Loop.CGMManagerState" 15 | } 16 | 17 | var cgmManagerState: CGMManager.RawStateValue? { 18 | get { 19 | return dictionary(forKey: Key.cgmManagerState.rawValue) 20 | } 21 | set { 22 | set(newValue, forKey: Key.cgmManagerState.rawValue) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Loop/Models/AbsorptionTimeType+CarbKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AbsorptionTimeType+CarbKit.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 1/24/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import LoopKit 10 | 11 | 12 | extension AbsorptionTimeType { 13 | func absorptionTimeFromDefaults(_ defaults: CarbStore.DefaultAbsorptionTimes) -> TimeInterval { 14 | switch self { 15 | case .fast: 16 | return defaults.fast 17 | case .medium: 18 | return defaults.medium 19 | case .slow: 20 | return defaults.slow 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">161" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "scale" : "2x", 16 | "screen-width" : ">145" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "scale" : "2x", 21 | "screen-width" : ">183" 22 | } 23 | ], 24 | "info" : { 25 | "version" : 1, 26 | "author" : "xcode" 27 | } 28 | } -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/CGRect.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGRect.swift 3 | // WatchApp Extension 4 | // 5 | // Created by Michael Pangburn on 10/17/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import CoreGraphics 10 | 11 | 12 | extension CGRect { 13 | func alignedToScreenScale(_ screenScale: CGFloat) -> CGRect { 14 | let factor = 1 / screenScale 15 | 16 | return CGRect( 17 | x: origin.x.floored(to: factor), 18 | y: origin.y.floored(to: factor), 19 | width: size.width.ceiled(to: factor), 20 | height: size.height.ceiled(to: factor) 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LoopUI/Models/StateColorPalette.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StateColorPalette.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | /// A collection of colors for displaying state 12 | public struct StateColorPalette { 13 | public let unknown: UIColor 14 | public let normal: UIColor 15 | public let warning: UIColor 16 | public let error: UIColor 17 | 18 | public init(unknown: UIColor, normal: UIColor, warning: UIColor, error: UIColor) { 19 | self.unknown = unknown 20 | self.normal = normal 21 | self.warning = warning 22 | self.error = error 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Loop/Managers/DiagnosticLogger+LoopKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DiagnosticLogger+LoopKit.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/25/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import HealthKit 11 | import LoopKit 12 | 13 | 14 | extension DiagnosticLogger { 15 | func addError(_ message: String, fromSource source: String) { 16 | let message = [ 17 | "message": message 18 | ] 19 | 20 | forCategory(source).error(message) 21 | } 22 | 23 | func addError(_ message: Error, fromSource source: String) { 24 | forCategory(source).error(message) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Loop/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "蓝牙用于与胰岛素泵和连续血糖监测设备进行通信"; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "使用人脸解锁来确认输注胰岛素剂量"; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "数据库中的膳食数据用于确定葡萄糖影响。健康数据库中的葡萄糖数据用于绘图和动量计算。"; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "在应用程序和手表中输入的碳水化合物膳食数据存储在健康数据库中。从CGM检索的葡萄糖数据安全地存储在HealthKit中。"; 18 | 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode10 3 | # xcode_sdk: iphonesimulator11 4 | # xcode_project: Loop.xcodeproj 5 | # xcode_scheme: Loop 6 | before_script: 7 | - set -o pipefail && xcodebuild -project Loop.xcodeproj -target Cartfile 8 | script: 9 | # Build the app target 10 | - set -o pipefail && xcodebuild -project Loop.xcodeproj -scheme Loop build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO | xcpretty 11 | # Run the test target 12 | - set -o pipefail && xcodebuild -project Loop.xcodeproj -scheme LoopTests -destination 'name=iPhone SE' test | xcpretty 13 | - set -o pipefail && xcodebuild -project Loop.xcodeproj -scheme DoseMathTests -destination 'name=iPhone SE' test | xcpretty 14 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/1-hour-graph.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "1-hour-graph-38mm.png", 6 | "screen-width" : "<=145", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "watch", 11 | "scale" : "2x", 12 | "screen-width" : ">161" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "filename" : "1-hour-graph-42mm.png", 17 | "screen-width" : ">145", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "idiom" : "watch", 22 | "scale" : "2x", 23 | "screen-width" : ">183" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/2-hour-graph.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "2-hour-graph-38mm.png", 6 | "screen-width" : "<=145", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "watch", 11 | "scale" : "2x", 12 | "screen-width" : ">161" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "filename" : "2-hour-graph-42mm.png", 17 | "screen-width" : ">145", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "idiom" : "watch", 22 | "scale" : "2x", 23 | "screen-width" : ">183" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/Graph menu icons/3-hour-graph.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "3-hour-graph-38mm.png", 6 | "screen-width" : "<=145", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "watch", 11 | "scale" : "2x", 12 | "screen-width" : ">161" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "filename" : "3-hour-graph-42mm.png", 17 | "screen-width" : ">145", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "idiom" : "watch", 22 | "scale" : "2x", 23 | "screen-width" : ">183" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /Loop/Views/ChartTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartTableViewCell.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 2/19/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import LoopUI 11 | 12 | 13 | final class ChartTableViewCell: UITableViewCell { 14 | 15 | @IBOutlet weak var chartContentView: ChartContainerView! 16 | 17 | @IBOutlet weak var titleLabel: UILabel? 18 | 19 | @IBOutlet weak var subtitleLabel: UILabel? 20 | 21 | override func prepareForReuse() { 22 | super.prepareForReuse() 23 | 24 | chartContentView.chartGenerator = nil 25 | } 26 | 27 | func reloadChart() { 28 | chartContentView.reloadChart() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Loop/Extensions/MealBolusNightscoutTreatment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NightscoutTreatment.swift 3 | // Loop 4 | // 5 | // Created by Pete Schwamb on 10/7/16. 6 | // Copyright © 2016 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | import NightscoutUploadKit 12 | import HealthKit 13 | 14 | extension MealBolusNightscoutTreatment { 15 | public convenience init(carbEntry: StoredCarbEntry) { 16 | let carbGrams = carbEntry.quantity.doubleValue(for: HKUnit.gram()) 17 | self.init(timestamp: carbEntry.startDate, enteredBy: "loop://\(UIDevice.current.name)", id: carbEntry.externalID, carbs: lround(carbGrams), absorptionTime: carbEntry.absorptionTime, foodType: carbEntry.foodType) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LoopUI/Common/LocalizedString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocalizedString.swift 3 | // LoopUI 4 | // 5 | // Created by Kathryn DiSimone on 8/15/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | private class FrameworkBundle { 12 | static let main = Bundle(for: FrameworkBundle.self) 13 | } 14 | 15 | func LocalizedString(_ key: String, tableName: String? = nil, value: String? = nil, comment: String) -> String { 16 | if let value = value { 17 | return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment) 18 | } else { 19 | return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, comment: comment) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Icon-Complication-16x16@2x.png", 6 | "screen-width" : "<=145", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "watch", 11 | "filename" : "Icon-Complication-18x18@2x.png", 12 | "screen-width" : ">161", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "scale" : "2x", 18 | "screen-width" : ">145" 19 | }, 20 | { 21 | "idiom" : "watch", 22 | "scale" : "2x", 23 | "screen-width" : ">183" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Icon-AppleWatch-42x42@2x.png", 11 | "screen-width" : ">161", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "filename" : "Icon-AppleWatch-47x47@2x.png", 22 | "screen-width" : ">183", 23 | "scale" : "2x" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Icon-AppleWatch-42x42@2x.png", 11 | "screen-width" : ">161", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "filename" : "Icon-AppleWatch-47x47@2x.png", 22 | "screen-width" : ">183", 23 | "scale" : "2x" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Icon-Complication-20x20@2x.png", 11 | "screen-width" : ">161", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "filename" : "Icon-Complication-22x22@2x.png", 22 | "screen-width" : ">183", 23 | "scale" : "2x" 24 | } 25 | ], 26 | "info" : { 27 | "version" : 1, 28 | "author" : "xcode" 29 | } 30 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_aging.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "loop-aging@42mm.png", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "loop-aging@38mm.png", 11 | "screen-width" : "<=145", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">161" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "scale" : "2x", 22 | "screen-width" : ">145" 23 | }, 24 | { 25 | "idiom" : "watch", 26 | "scale" : "2x", 27 | "screen-width" : ">183" 28 | } 29 | ], 30 | "info" : { 31 | "version" : 1, 32 | "author" : "xcode" 33 | } 34 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_fresh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "loop-fresh@42mm.png", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "loop-fresh@38mm.png", 11 | "screen-width" : "<=145", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">161" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "scale" : "2x", 22 | "screen-width" : ">145" 23 | }, 24 | { 25 | "idiom" : "watch", 26 | "scale" : "2x", 27 | "screen-width" : ">183" 28 | } 29 | ], 30 | "info" : { 31 | "version" : 1, 32 | "author" : "xcode" 33 | } 34 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_stale.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "loop-stale@42mm.png", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "loop-stale@38mm.png", 11 | "screen-width" : "<=145", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">161" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "scale" : "2x", 22 | "screen-width" : ">145" 23 | }, 24 | { 25 | "idiom" : "watch", 26 | "scale" : "2x", 27 | "screen-width" : ">183" 28 | } 29 | ], 30 | "info" : { 31 | "version" : 1, 32 | "author" : "xcode" 33 | } 34 | } -------------------------------------------------------------------------------- /Loop/View Controllers/TextFieldTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextFieldTableViewController.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 7/31/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import LoopKitUI 10 | import HealthKit 11 | 12 | 13 | /// Convenience static constructors used to contain common configuration 14 | extension TextFieldTableViewController { 15 | typealias T = TextFieldTableViewController 16 | 17 | private static let valueNumberFormatter: NumberFormatter = { 18 | let formatter = NumberFormatter() 19 | 20 | formatter.numberStyle = .decimal 21 | formatter.minimumFractionDigits = 0 22 | formatter.maximumFractionDigits = 2 23 | 24 | return formatter 25 | }() 26 | } 27 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/loop/loop_unknown.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "loop-unknown@42mm.png", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "loop-unknown@38mm.png", 11 | "screen-width" : "<=145", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "idiom" : "watch", 16 | "scale" : "2x", 17 | "screen-width" : ">161" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "scale" : "2x", 22 | "screen-width" : ">145" 23 | }, 24 | { 25 | "idiom" : "watch", 26 | "scale" : "2x", 27 | "screen-width" : ">183" 28 | } 29 | ], 30 | "info" : { 31 | "version" : 1, 32 | "author" : "xcode" 33 | } 34 | } -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/far_future_high_bg_forecast.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "2015-07-19T16:30:00", "amount": 90}, 3 | {"date": "2015-07-19T17:00:00", "amount": 90}, 4 | {"date": "2015-07-19T17:30:00", "amount": 90}, 5 | {"date": "2015-07-19T18:00:00", "amount": 90}, 6 | {"date": "2015-07-19T18:30:00", "amount": 95}, 7 | {"date": "2015-07-19T19:00:00", "amount": 100}, 8 | {"date": "2015-07-19T19:30:00", "amount": 105}, 9 | {"date": "2015-07-19T20:00:00", "amount": 110}, 10 | {"date": "2015-07-19T20:30:00", "amount": 115}, 11 | {"date": "2015-07-19T21:00:00", "amount": 118}, 12 | {"date": "2015-07-19T21:30:00", "amount": 120}, 13 | {"date": "2015-07-19T21:30:00", "amount": 140}, 14 | {"date": "2015-07-19T21:30:00", "amount": 160}, 15 | {"date": "2015-07-19T21:30:00", "amount": 180} 16 | ] 17 | -------------------------------------------------------------------------------- /Loop/Extensions/UIColor+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Loop.swift 3 | // Loop 4 | // 5 | // Created by Nathan Racklyeft on 1/23/16. 6 | // Copyright © 2016 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension UIColor { 13 | @nonobjc static let axisLabelColor = secondaryLabelColor 14 | 15 | @nonobjc static let axisLineColor = UIColor.clear 16 | 17 | @nonobjc static let doseTintColor = UIColor.HIGOrangeColor() 18 | 19 | @nonobjc static let freshColor = UIColor.HIGGreenColor() 20 | 21 | @nonobjc static let glucoseTintColor = UIColor(red: 0 / 255, green: 176 / 255, blue: 255 / 255, alpha: 1) 22 | 23 | @nonobjc static let gridColor = UIColor(white: 193 / 255, alpha: 1) 24 | 25 | @nonobjc static let pumpStatusNormal = secondaryLabelColor 26 | } 27 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Icon-Complication-26x26@2x.png", 6 | "screen-width" : "<=145", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "watch", 11 | "filename" : "Icon-Complication-29x29@2x.png", 12 | "screen-width" : ">161", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "scale" : "2x", 18 | "screen-width" : ">145" 19 | }, 20 | { 21 | "idiom" : "watch", 22 | "filename" : "Icon-Complication-32x32@2x.png", 23 | "screen-width" : ">183", 24 | "scale" : "2x" 25 | } 26 | ], 27 | "info" : { 28 | "version" : 1, 29 | "author" : "xcode" 30 | } 31 | } -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Icon-Complication-20x20@2x.png", 6 | "screen-width" : "<=145", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "watch", 11 | "filename" : "Icon-Complication-22x22@2x.png", 12 | "screen-width" : ">161", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "scale" : "2x", 18 | "screen-width" : ">145" 19 | }, 20 | { 21 | "idiom" : "watch", 22 | "filename" : "Icon-Complication-25x25@2x.png", 23 | "screen-width" : ">183", 24 | "scale" : "2x" 25 | } 26 | ], 27 | "info" : { 28 | "version" : 1, 29 | "author" : "xcode" 30 | } 31 | } -------------------------------------------------------------------------------- /LoopUI/Extensions/CGPoint.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGPoint.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 2/29/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension CGPoint { 13 | /** 14 | Rounds the coordinates to whole-pixel values 15 | 16 | - parameter scale: The display scale to use. Defaults to the main screen scale. 17 | */ 18 | mutating func makeIntegralInPlaceWithDisplayScale(_ scale: CGFloat = 0) { 19 | var scale = scale 20 | 21 | // It's possible for scale values retrieved from traitCollection objects to be 0. 22 | if scale == 0 { 23 | scale = UIScreen.main.scale 24 | } 25 | x = round(x * scale) / scale 26 | y = round(y * scale) / scale 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LoopUI/Models/ChartColorPalette.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartColorPalette.swift 3 | // Loop 4 | // 5 | // Created by Bharat Mediratta on 3/29/17. 6 | // Copyright © 2017 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /// A palette of colors for displaying charts 12 | public struct ChartColorPalette { 13 | public let axisLine: UIColor 14 | public let axisLabel: UIColor 15 | public let grid: UIColor 16 | public let glucoseTint: UIColor 17 | public let doseTint: UIColor 18 | 19 | public init(axisLine: UIColor, axisLabel: UIColor, grid: UIColor, glucoseTint: UIColor, doseTint: UIColor) { 20 | self.axisLine = axisLine 21 | self.axisLabel = axisLabel 22 | self.grid = grid 23 | self.glucoseTint = glucoseTint 24 | self.doseTint = doseTint 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DoseMathTests/Fixtures/read_selected_basal_profile.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "i": 0, 4 | "start": "00:00:00", 5 | "rate": 0.9, 6 | "minutes": 0 7 | }, 8 | { 9 | "i": 1, 10 | "start": "04:00:00", 11 | "rate": 0.925, 12 | "minutes": 240 13 | }, 14 | { 15 | "i": 2, 16 | "start": "07:00:00", 17 | "rate": 0.85, 18 | "minutes": 420 19 | }, 20 | { 21 | "i": 3, 22 | "start": "10:00:00", 23 | "rate": 0.85, 24 | "minutes": 600 25 | }, 26 | { 27 | "i": 4, 28 | "start": "12:00:00", 29 | "rate": 0.75, 30 | "minutes": 720 31 | }, 32 | { 33 | "i": 5, 34 | "start": "15:00:00", 35 | "rate": 0.8, 36 | "minutes": 900 37 | }, 38 | { 39 | "i": 6, 40 | "start": "22:00:00", 41 | "rate": 0.9, 42 | "minutes": 1320 43 | } 44 | ] -------------------------------------------------------------------------------- /LoopTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.9.5 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /DoseMathTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.9.5 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LoopUI/Models/ChartLineModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartLineModel.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import SwiftCharts 9 | 10 | 11 | extension ChartLineModel { 12 | /// Creates a model configured with the dashed prediction line style 13 | /// 14 | /// - Parameters: 15 | /// - points: The points to construct the line 16 | /// - color: The line color 17 | /// - width: The line width 18 | /// - Returns: A new line model 19 | static func predictionLine(points: [T], color: UIColor, width: CGFloat) -> ChartLineModel { 20 | // TODO: Bug in ChartPointsLineLayer requires a non-zero animation to draw the dash pattern 21 | return self.init(chartPoints: points, lineColor: color, lineWidth: width, animDuration: 0.0001, animDelay: 0, dashPattern: [6, 5]) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LoopUI/Models/ChartAxisValueDoubleUnit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartAxisValueDoubleUnit.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 7/16/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftCharts 11 | 12 | 13 | public final class ChartAxisValueDoubleUnit: ChartAxisValueDouble { 14 | let unitString: String 15 | 16 | public init(_ double: Double, unitString: String, formatter: NumberFormatter) { 17 | self.unitString = unitString 18 | 19 | super.init(double, formatter: formatter) 20 | } 21 | 22 | init(_ double: Double, unitString: String) { 23 | self.unitString = unitString 24 | 25 | super.init(double) 26 | } 27 | 28 | override public var description: String { 29 | return formatter.string(from: scalar, unit: unitString) ?? "" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /WatchApp Extension/Controllers/NotificationController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationController.swift 3 | // WatchApp Extension 4 | // 5 | // Created by Nathan Racklyeft on 8/29/15. 6 | // Copyright © 2015 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import Foundation 11 | import UserNotifications 12 | 13 | 14 | final class NotificationController: WKUserNotificationInterfaceController { 15 | 16 | override init() { 17 | super.init() 18 | } 19 | 20 | override func willActivate() { 21 | super.willActivate() 22 | } 23 | 24 | override func didDeactivate() { 25 | super.didDeactivate() 26 | } 27 | 28 | override func didReceive(_ notification: UNNotification, withCompletion completionHandler: @escaping (WKUserNotificationInterfaceType) -> Void) { 29 | completionHandler(.default) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Loop/nb.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Bluetooth brukes til å kommunisere med insulinpumpe og kontinuerlige glukosemonitorer."; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Face ID brukes til å autentisere insulin bolus."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Matdata fra Health-databasen brukes til å bestemme blodsukkereffekt. Blodsukkerdata hentes fra HealthKit for opptegning og analyse."; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Angitte karbohydrater i matdataene som tastes inn i appen blir lagret i Health-databasen."; 18 | 19 | -------------------------------------------------------------------------------- /LoopUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | LoopUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.9.5 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LoopUI/Views/BatteryLevelHUDView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatteryLevelHUDView.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 5/2/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | public final class BatteryLevelHUDView: LevelHUDView { 13 | 14 | private lazy var numberFormatter: NumberFormatter = { 15 | let formatter = NumberFormatter() 16 | formatter.numberStyle = .percent 17 | 18 | return formatter 19 | }() 20 | 21 | public var batteryLevel: Double? { 22 | didSet { 23 | if let value = batteryLevel, let level = numberFormatter.string(from: value) { 24 | caption.text = level 25 | accessibilityValue = level 26 | } else { 27 | caption.text = nil 28 | } 29 | 30 | level = batteryLevel 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /WatchApp Extension/PushNotificationPayload.apns: -------------------------------------------------------------------------------- 1 | { 2 | "aps": { 3 | "alert": { 4 | "body": "RileyLink timed out. Check your pump before retrying.", 5 | "title": "Bolus", 6 | "subtitle": "3.5 U bolus failed" 7 | }, 8 | "category": "bolusFailure" 9 | }, 10 | 11 | "WatchKit Simulator Actions": [ 12 | { 13 | "title": "Retry", 14 | "identifier": "retryBolus" 15 | } 16 | ], 17 | 18 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." 19 | } 20 | -------------------------------------------------------------------------------- /Common/Extensions/NSTimeInterval.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSTimeInterval.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 1/9/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension TimeInterval { 13 | static func seconds(_ seconds: Double) -> TimeInterval { 14 | return seconds 15 | } 16 | 17 | static func minutes(_ minutes: Double) -> TimeInterval { 18 | return TimeInterval(minutes: minutes) 19 | } 20 | 21 | static func hours(_ hours: Double) -> TimeInterval { 22 | return TimeInterval(hours: hours) 23 | } 24 | 25 | init(minutes: Double) { 26 | self.init(minutes * 60) 27 | } 28 | 29 | init(hours: Double) { 30 | self.init(minutes: hours * 60) 31 | } 32 | 33 | var minutes: Double { 34 | return self / 60.0 35 | } 36 | 37 | var hours: Double { 38 | return minutes / 60.0 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/INRelevantShortcutStore+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // INRelevantShortcutStore+Loop.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import Intents 9 | import os.log 10 | 11 | 12 | @available(watchOSApplicationExtension 5.0, *) 13 | extension INRelevantShortcutStore { 14 | func registerShortcuts() { 15 | var shortcuts = [INRelevantShortcut]() 16 | 17 | let shortcut = INShortcut(userActivity: .forDidAddCarbEntryOnWatch()) 18 | let relevance = INRelevantShortcut(shortcut: shortcut) 19 | relevance.shortcutRole = .action 20 | relevance.relevanceProviders = [] 21 | 22 | shortcuts.append(relevance) 23 | 24 | setRelevantShortcuts(shortcuts) { (error) in 25 | if let error = error { 26 | os_log(.error, "Error specifying shortcuts: %{public}@", String(describing: error)) 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Loop/Assets.xcassets/settings.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "settings.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "settings@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "settings@3x.png", 16 | "scale" : "3x" 17 | }, 18 | { 19 | "idiom" : "universal", 20 | "scale" : "1x", 21 | "height-class" : "compact" 22 | }, 23 | { 24 | "idiom" : "universal", 25 | "filename" : "settings_compact@2x.png", 26 | "height-class" : "compact", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "idiom" : "universal", 31 | "filename" : "settings_compact@3x.png", 32 | "height-class" : "compact", 33 | "scale" : "3x" 34 | } 35 | ], 36 | "info" : { 37 | "version" : 1, 38 | "author" : "xcode" 39 | } 40 | } -------------------------------------------------------------------------------- /Loop/Extensions/CollectionType+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionType.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 2/21/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | 12 | 13 | public extension Sequence where Element: TimelineValue { 14 | /// Returns the closest element index in the sorted sequence prior to the specified date 15 | /// 16 | /// - parameter date: The date to use in the search 17 | /// 18 | /// - returns: The closest index, if any exist before the specified date 19 | func closestIndexPriorToDate(_ date: Date) -> Int? { 20 | var closestIndex: Int? 21 | 22 | for (index, value) in self.enumerated() { 23 | if value.startDate <= date { 24 | closestIndex = index 25 | } else { 26 | break 27 | } 28 | } 29 | 30 | return closestIndex 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Common/Extensions/UIColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 1/23/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension UIColor { 13 | @nonobjc static var tintColor: UIColor? = nil 14 | 15 | @nonobjc static let secondaryLabelColor = UIColor.HIGGrayColor() 16 | 17 | @nonobjc static let cellBackgroundColor = UIColor(white: 239 / 255, alpha: 1) 18 | 19 | @nonobjc static let IOBTintColor = UIColor.HIGOrangeColor() 20 | 21 | @nonobjc static let COBTintColor = UIColor(red: 99 / 255, green: 218 / 255, blue: 56 / 255, alpha: 1) 22 | 23 | @nonobjc static let agingColor = UIColor.HIGYellowColor() 24 | 25 | @nonobjc static let staleColor = UIColor.HIGRedColor() 26 | 27 | @nonobjc static let unknownColor = UIColor(red: 198 / 255, green: 199 / 255, blue: 201 / 255, alpha: 1) 28 | 29 | static let delete = UIColor.HIGRedColor() 30 | } 31 | -------------------------------------------------------------------------------- /Common/Extensions/SampleValue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleValue.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import HealthKit 9 | import LoopKit 10 | 11 | 12 | extension Collection where Element == SampleValue { 13 | /// O(n) 14 | var quantityRange: Range? { 15 | var lowest: HKQuantity? 16 | var highest: HKQuantity? 17 | 18 | for sample in self { 19 | if let l = lowest { 20 | lowest = Swift.min(l, sample.quantity) 21 | } else { 22 | lowest = sample.quantity 23 | } 24 | 25 | if let h = highest { 26 | highest = Swift.max(h, sample.quantity) 27 | } else { 28 | highest = sample.quantity 29 | } 30 | } 31 | 32 | guard let l = lowest, let h = highest else { 33 | return nil 34 | } 35 | 36 | return l.. { 12 | private var lock = os_unfair_lock() 13 | private var _value: T 14 | 15 | init(_ value: T) { 16 | os_unfair_lock_lock(&lock) 17 | defer { os_unfair_lock_unlock(&lock) } 18 | _value = value 19 | } 20 | 21 | var value: T { 22 | get { 23 | os_unfair_lock_lock(&lock) 24 | defer { os_unfair_lock_unlock(&lock) } 25 | return _value 26 | } 27 | set { 28 | os_unfair_lock_lock(&lock) 29 | defer { os_unfair_lock_unlock(&lock) } 30 | _value = newValue 31 | } 32 | } 33 | 34 | func mutate(_ changes: (_ value: inout T) -> Void) -> T { 35 | os_unfair_lock_lock(&lock) 36 | defer { os_unfair_lock_unlock(&lock) } 37 | changes(&_value) 38 | return _value 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Loop/it.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Il Bluetooth viene utilizzato per comunicare con il microinfusore e i dispositivi CGM."; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Face ID viene utilizzato per autenticare il bolo."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "I dati sui pasti dal database Salute vengono utilizzati per determinare gli effetti del glucosio. I dati del glucosio del database Salute vengono utilizzati per il calcolo del grafico della glicemia."; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "I dati sui carboidrati inseriti nell'app e sull'orologio sono memorizzati nel database Salute. I dati relativi al glucosio recuperati dal CGM vengono memorizzati in modo sicuro in Salute."; 18 | 19 | -------------------------------------------------------------------------------- /Loop/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Bluetooth wordt gebruikt om te communiceren met de insuline pomp en de continue glucose meter."; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Face ID wordt gebruikt om de insuline bolus te verifiëren."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Voedsel informatie van de Gezondheid database wordt gebruikt om de glucose impact te bepalen. Glucose data van de Gezondheid database wordt gebruikt voor de tijdslijn en momentberekening"; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Koolhydraten van de maaltijd die worden ingevoerd in de app op de apple watch worden opgeslagen in de Gezondheid database. Glucose gegevens ontvangen van de CGM wordt veilig opgeslagen in Gezondheid."; 18 | 19 | -------------------------------------------------------------------------------- /Loop/pl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Bluetooth jest używany do komunikacji z pompą i urządzeniami ciągłego monitoringu glukozy."; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Face ID jest używane do autoryzacji podaży bolusa."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Dane o posiłkach z bazy aplikacji Zdrowie będą używane do określenia ich wpływu na poziom cukru. Informacje o poziomie cukru z bazy danych aplikacji Zdrowie są używane do narysowania wykresu oraz obliczenia przewidywanego poziomu cukru."; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Posiłek węglowodanowy wprowadzony w aplikacji i na zegarku oraz dane o poziomie cukru pobrane z ciągłego monitoringu glukozy są bezpiecznie przechowywane w aplikacji Zdrowie."; 18 | -------------------------------------------------------------------------------- /Common/Models/Insulin/WalshInsulinModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WalshInsulinModel.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopKit 9 | 10 | 11 | extension WalshInsulinModel: RawRepresentable { 12 | public typealias RawValue = [String: Any] 13 | 14 | public init?(rawValue: RawValue) { 15 | guard let duration = rawValue["actionDuration"] as? TimeInterval else { 16 | return nil 17 | } 18 | 19 | self.init(actionDuration: duration) 20 | } 21 | 22 | public var rawValue: [String : Any] { 23 | return ["actionDuration": self.actionDuration] 24 | } 25 | } 26 | 27 | 28 | // MARK: - Localization 29 | extension WalshInsulinModel { 30 | var title: String { 31 | return NSLocalizedString("Walsh", comment: "Title of insulin model setting") 32 | } 33 | 34 | var subtitle: String { 35 | return NSLocalizedString("The legacy model used by Loop, allowing customization of action duration.", comment: "Subtitle description of Walsh insulin model setting") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Loop/Views/PredictionInputEffectTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PredictionInputEffectTableViewCell.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 9/4/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PredictionInputEffectTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var titleLabel: UILabel! 14 | 15 | @IBOutlet weak var subtitleLabel: UILabel! 16 | 17 | override func layoutSubviews() { 18 | super.layoutSubviews() 19 | 20 | contentView.layoutMargins.left = separatorInset.left 21 | contentView.layoutMargins.right = separatorInset.left 22 | } 23 | 24 | var enabled: Bool = true { 25 | didSet { 26 | if enabled { 27 | titleLabel.textColor = UIColor.darkText 28 | subtitleLabel.textColor = UIColor.darkText 29 | } else { 30 | titleLabel.textColor = UIColor.secondaryLabelColor 31 | subtitleLabel.textColor = UIColor.secondaryLabelColor 32 | } 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Loop/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Bluetooth wird verwendet, um mit Insulinpumpen und kontinuierlichen Blutzuckermessgeräten zu kommunizieren"; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Face ID wird benutzt, um einen Insulin-Bolus zu authentifizieren."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Mahlzeit-Daten aus der HealthKit-Datenbank werden verwendet, um Blutzuckereffekte zu bestimmen. Blutzuckerdaten aus der HealthKit-Datenbank werden für die Grafik- und Impulsberechnung verwendet."; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Die in der App und auf der Uhr eingegebenen Kohlenhydratmengen werden in der Health-Datenbank gespeichert. Blutzuckerdaten, die vom CGM abgerufen werden, werden sicher in HealthKit gespeichert."; 18 | 19 | -------------------------------------------------------------------------------- /Loop/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Блутус применяется для коммуникации с инсулиновой помпой и устройствами непрерывного мониторинга СК"; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Идентификатор Face ID применяется для авторизации болюса инсулина"; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Данные о пище из базы данных Здоровье используются для определения влияния на гликемию. Данные гликемии из базы данных Здоровье используются для графического отображения и вычисления скорости изменений"; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Данные об углеводах в приложении и на смарт-часах хранятся в базе данных Здоровье. Данные о гликемии полученные от систем непрерывного мониторинга хранятся в безопасности в Комплексе Здоровья HealthKit "; 18 | 19 | -------------------------------------------------------------------------------- /Common/Models/LoopSettingsUserInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoopSettingsUserInfo.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | 9 | struct LoopSettingsUserInfo { 10 | let settings: LoopSettings 11 | } 12 | 13 | 14 | extension LoopSettingsUserInfo: RawRepresentable { 15 | typealias RawValue = [String: Any] 16 | 17 | static let name = "LoopSettingsUserInfo" 18 | static let version = 1 19 | 20 | init?(rawValue: RawValue) { 21 | guard rawValue["v"] as? Int == LoopSettingsUserInfo.version, 22 | rawValue["name"] as? String == LoopSettingsUserInfo.name, 23 | let settingsRaw = rawValue["s"] as? LoopSettings.RawValue, 24 | let settings = LoopSettings(rawValue: settingsRaw) 25 | else { 26 | return nil 27 | } 28 | 29 | self.settings = settings 30 | } 31 | 32 | var rawValue: RawValue { 33 | return [ 34 | "v": LoopSettingsUserInfo.version, 35 | "name": LoopSettingsUserInfo.name, 36 | "s": settings.rawValue 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Common/Models/GlucoseBackfillRequestUserInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GlucoseBackfillRequestUserInfo.swift 3 | // Loop 4 | // 5 | // Created by Bharat Mediratta on 6/21/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct GlucoseBackfillRequestUserInfo { 12 | let version = 1 13 | let startDate: Date 14 | } 15 | 16 | extension GlucoseBackfillRequestUserInfo: RawRepresentable { 17 | typealias RawValue = [String: Any] 18 | 19 | static let name = "GlucoseBackfillRequestUserInfo" 20 | 21 | init?(rawValue: RawValue) { 22 | guard 23 | rawValue["v"] as? Int == version, 24 | rawValue["name"] as? String == GlucoseBackfillRequestUserInfo.name, 25 | let startDate = rawValue["sd"] as? Date 26 | else { 27 | return nil 28 | } 29 | 30 | self.startDate = startDate 31 | } 32 | 33 | var rawValue: RawValue { 34 | return [ 35 | "v": version, 36 | "name": GlucoseBackfillRequestUserInfo.name, 37 | "sd": startDate 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Common/Models/GlucoseThreshold.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GlucoseThreshold.swift 3 | // Loop 4 | // 5 | // Created by Pete Schwamb on 1/1/17. 6 | // Copyright © 2017 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import HealthKit 11 | 12 | struct GlucoseThreshold: Equatable, RawRepresentable { 13 | typealias RawValue = [String: Any] 14 | 15 | let value: Double 16 | let unit: HKUnit 17 | 18 | public var quantity: HKQuantity { 19 | return HKQuantity(unit: unit, doubleValue: value) 20 | } 21 | 22 | public init(unit: HKUnit, value: Double) { 23 | self.value = value 24 | self.unit = unit 25 | } 26 | 27 | init?(rawValue: RawValue) { 28 | guard let unitsStr = rawValue["units"] as? String, let value = rawValue["value"] as? Double else { 29 | return nil 30 | } 31 | self.unit = HKUnit(from: unitsStr) 32 | self.value = value 33 | } 34 | 35 | var rawValue: RawValue { 36 | return [ 37 | "value": value, 38 | "units": unit.unitString 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Loop/Models/GlucoseEffectVelocity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GlucoseEffectVelocity.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import HealthKit 9 | import LoopKit 10 | 11 | 12 | extension GlucoseEffectVelocity: RawRepresentable { 13 | public typealias RawValue = [String: Any] 14 | 15 | static let unit = HKUnit.milligramsPerDeciliter.unitDivided(by: .minute()) 16 | 17 | public init?(rawValue: RawValue) { 18 | guard let startDate = rawValue["startDate"] as? Date, 19 | let doubleValue = rawValue["doubleValue"] as? Double 20 | else { 21 | return nil 22 | } 23 | 24 | self.init( 25 | startDate: startDate, 26 | endDate: rawValue["endDate"] as? Date ?? startDate, 27 | quantity: HKQuantity(unit: type(of: self).unit, doubleValue: doubleValue) 28 | ) 29 | } 30 | 31 | public var rawValue: RawValue { 32 | return [ 33 | "startDate": startDate, 34 | "endDate": endDate, 35 | "doubleValue": quantity.doubleValue(for: type(of: self).unit) 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Loop/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Bluetooth se utiliza para las comunicaciones con la microinfusora y los dispositivos de monitoreo continuo de glucosa."; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "Se utiliza reconocimiento facial para autenticar el bolo de insulina."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Datos de alimentos de la base de datos de Salud se utiliza para determinar los efectos en el nivel de glucosa. Datos de glucosa de la bsase de datos de Salud se utilizan para graficar y determinar cálculos de momento."; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Datos de alimentos ingresados en la aplicación y en el reloj son almacenados en la base de datos de Salud. Los datos de glucosa extraídos del monitor continuo de glucosa se almacenan de manera segura en Kit de Salud."; 18 | 19 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/NSUserDefaults+WatchApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSUserDefaults.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/29/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension UserDefaults { 13 | private enum Key: String { 14 | case StartOnChartPage = "com.loudnate.Naterade.StartOnChartPage" 15 | case VisibleDuration = "com.loudnate.Naterade.VisibleDuration" 16 | } 17 | 18 | var startOnChartPage: Bool { 19 | get { 20 | return object(forKey: Key.StartOnChartPage.rawValue) as? Bool ?? false 21 | } 22 | set { 23 | set(newValue, forKey: Key.StartOnChartPage.rawValue) 24 | } 25 | } 26 | 27 | var visibleDuration: TimeInterval { 28 | get { 29 | if let value = object(forKey: Key.VisibleDuration.rawValue) as? TimeInterval { 30 | return value 31 | } 32 | return TimeInterval (hours: 6) 33 | } 34 | set { 35 | set(newValue.rawValue, forKey: Key.VisibleDuration.rawValue) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Loop/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "Loop"; 3 | 4 | /* Bundle name */ 5 | "CFBundleName" = "$(PRODUCT_NAME)"; 6 | 7 | /* Privacy - Bluetooth Peripheral Usage Description */ 8 | "NSBluetoothPeripheralUsageDescription" = "Bluetooth est utilisé pour communiquer avec la pompe à insuline et les dispositifs de surveillance continue du glucose."; 9 | 10 | /* Privacy - Face ID Usage Description */ 11 | "NSFaceIDUsageDescription" = "ID de visage est utilisé pour authentifier le bolus d'insuline."; 12 | 13 | /* Privacy - Health Share Usage Description */ 14 | "NSHealthShareUsageDescription" = "Les données sur les repas provenant de la base de données Health sont utilisées pour déterminer les effets du glucose. Les données sur la glycémie de la base de données Health sont utilisées pour le calcul graphique et le calcul du momentum."; 15 | 16 | /* Privacy - Health Update Usage Description */ 17 | "NSHealthUpdateUsageDescription" = "Les données sur les repas glucidiques saisies dans l'application et sur la montre sont stockées dans la base de données Health. Les données de glucose extraites du CGM sont stockées de manière sécurisée dans HealthKit."; 18 | 19 | -------------------------------------------------------------------------------- /Loop/Managers/KeychainManager+Loop.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainManager+Loop.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 6/26/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | 12 | 13 | private let NightscoutAccount = "NightscoutAPI" 14 | 15 | 16 | extension KeychainManager { 17 | func setNightscoutURL(_ url: URL?, secret: String?) { 18 | let credentials: InternetCredentials? 19 | 20 | if let url = url, let secret = secret { 21 | credentials = InternetCredentials(username: NightscoutAccount, password: secret, url: url) 22 | } else { 23 | credentials = nil 24 | } 25 | 26 | do { 27 | try replaceInternetCredentials(credentials, forAccount: NightscoutAccount) 28 | } catch { 29 | } 30 | } 31 | 32 | func getNightscoutCredentials() -> (url: URL, secret: String)? { 33 | do { 34 | let credentials = try getInternetCredentials(account: NightscoutAccount) 35 | 36 | return (url: credentials.url, secret: credentials.password) 37 | } catch { 38 | return nil 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Loop/Models/ServiceAuthentication/MLabService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // mLabService.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 7/3/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | 12 | 13 | private let mLabAPIHost = URL(string: "https://api.mongolab.com/api/1/databases")! 14 | 15 | 16 | extension KeychainManager { 17 | func setMLabDatabaseName(_ databaseName: String?, APIKey: String?) throws { 18 | let credentials: InternetCredentials? 19 | 20 | if let username = databaseName, let password = APIKey { 21 | credentials = InternetCredentials(username: username, password: password, url: mLabAPIHost) 22 | } else { 23 | credentials = nil 24 | } 25 | 26 | try replaceInternetCredentials(credentials, forURL: mLabAPIHost) 27 | } 28 | 29 | func getMLabCredentials() -> (databaseName: String, APIKey: String)? { 30 | do { 31 | let credentials = try getInternetCredentials(url: mLabAPIHost) 32 | 33 | return (databaseName: credentials.username, APIKey: credentials.password) 34 | } catch { 35 | return nil 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DoseMathTests/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "当前血糖%1$@低于纠正目标."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "克"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "毫克/分升"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "毫摩尔/升"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "未来%1$@时间的血糖为%2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "预计血糖%1$@低于低血糖暂停阈值"; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "单位"; 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report to help us improve Loop 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. I.e. what you see vs what you expect to see. 9 | 10 | **Attach an Issue Report** 11 | Tap the Loop settings icon on the bottom of the screen, then tap Issue Report and attach it to this ticket. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Phone** 27 | - Hardware: [e.g. iPhone XS] 28 | - OS Version: [e.g. iOS 12.0.1] 29 | 30 | **Loop Version** 31 | - Version Number: [e.g. 1.9.2] 32 | - Repo: [LoopKit/Loop, Katie, etc] 33 | 34 | **CGM** 35 | - Device: [e.g. Dexcom G6] 36 | - Manager app: [e.g. Dexcom App, Spike] 37 | 38 | **Pump** 39 | - Manufacturer: [e.g. Medtronic] 40 | - Model: [e.g. 723] 41 | - Firmware version: [e.g. 2.3A 1.1 0B 0B] 42 | 43 | **Additional context** 44 | Add any other context about the problem here. 45 | -------------------------------------------------------------------------------- /Loop/Managers/CGMManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGMManager.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopKit 9 | import CGMBLEKit 10 | import G4ShareSpy 11 | import ShareClient 12 | 13 | 14 | let allCGMManagers: [CGMManager.Type] = [ 15 | G6CGMManager.self, 16 | G5CGMManager.self, 17 | G4CGMManager.self, 18 | ShareClientManager.self, 19 | ] 20 | 21 | 22 | private let managersByIdentifier: [String: CGMManager.Type] = allCGMManagers.reduce(into: [:]) { (map, Type) in 23 | map[Type.managerIdentifier] = Type 24 | } 25 | 26 | 27 | func CGMManagerFromRawValue(_ rawValue: [String: Any]) -> CGMManager? { 28 | guard let managerIdentifier = rawValue["managerIdentifier"] as? String, 29 | let rawState = rawValue["state"] as? CGMManager.RawStateValue, 30 | let Manager = managersByIdentifier[managerIdentifier] 31 | else { 32 | return nil 33 | } 34 | 35 | return Manager.init(rawState: rawState) 36 | } 37 | 38 | 39 | extension CGMManager { 40 | var rawValue: [String: Any] { 41 | return [ 42 | "managerIdentifier": type(of: self).managerIdentifier, 43 | "state": self.rawState 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /WatchApp Extension/Assets.xcassets/Complication.complicationset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Circular.imageset", 6 | "role" : "circular" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Extra Large.imageset", 11 | "role" : "extra-large" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "filename" : "Graphic Bezel.imageset", 16 | "role" : "graphic-bezel" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "filename" : "Graphic Circular.imageset", 21 | "role" : "graphic-circular" 22 | }, 23 | { 24 | "idiom" : "watch", 25 | "filename" : "Graphic Corner.imageset", 26 | "role" : "graphic-corner" 27 | }, 28 | { 29 | "idiom" : "watch", 30 | "filename" : "Graphic Large Rectangular.imageset", 31 | "role" : "graphic-large-rectangular" 32 | }, 33 | { 34 | "idiom" : "watch", 35 | "filename" : "Modular.imageset", 36 | "role" : "modular" 37 | }, 38 | { 39 | "idiom" : "watch", 40 | "filename" : "Utilitarian.imageset", 41 | "role" : "utilitarian" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Common/Extensions/NSUserActivity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSUserActivity.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | extension NSUserActivity { 12 | /// Activity of viewing the current status of the Loop 13 | static let viewLoopStatusActivityType = "ViewLoopStatus" 14 | 15 | class func forViewLoopStatus() -> NSUserActivity { 16 | return NSUserActivity(activityType: viewLoopStatusActivityType) 17 | } 18 | 19 | static let didAddCarbEntryOnWatchActivityType = "com.loopkit.Loop.AddCarbEntryOnWatch" 20 | 21 | class func forDidAddCarbEntryOnWatch() -> NSUserActivity { 22 | let activity = NSUserActivity(activityType: didAddCarbEntryOnWatchActivityType) 23 | activity.isEligibleForSearch = true 24 | activity.isEligibleForHandoff = false 25 | activity.isEligibleForPublicIndexing = false 26 | if #available(iOS 12.0, watchOSApplicationExtension 5.0, *) { 27 | activity.isEligibleForPrediction = true 28 | } 29 | activity.requiredUserInfoKeys = [] 30 | activity.title = NSLocalizedString("Add Carb Entry", comment: "Title of the user activity for adding carbs") 31 | return activity 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/workout.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Workout 42mm.pdf" 6 | }, 7 | { 8 | "idiom" : "watch", 9 | "screen-width" : "<=145" 10 | }, 11 | { 12 | "idiom" : "watch", 13 | "screen-width" : ">161" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "screen-width" : ">183" 22 | }, 23 | { 24 | "idiom" : "watch", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "idiom" : "watch", 29 | "filename" : "Workout 38mm.png", 30 | "screen-width" : "<=145", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "watch", 35 | "scale" : "2x", 36 | "screen-width" : ">161" 37 | }, 38 | { 39 | "idiom" : "watch", 40 | "scale" : "2x", 41 | "screen-width" : ">145" 42 | }, 43 | { 44 | "idiom" : "watch", 45 | "scale" : "2x", 46 | "screen-width" : ">183" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | }, 53 | "properties" : { 54 | "template-rendering-intent" : "template", 55 | "auto-scaling" : "auto" 56 | } 57 | } -------------------------------------------------------------------------------- /Loop Status Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | MainAppBundleIdentifier 8 | $(MAIN_APP_BUNDLE_IDENTIFIER) 9 | CFBundleDisplayName 10 | Loop 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | XPC! 21 | CFBundleShortVersionString 22 | 1.9.5 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | AppGroupIdentifier 26 | $(APP_GROUP_IDENTIFIER) 27 | NSExtension 28 | 29 | NSExtensionMainStoryboard 30 | MainInterface 31 | NSExtensionPointIdentifier 32 | com.apple.widget-extension 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/bolus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Bolus Icon 42mm.pdf" 6 | }, 7 | { 8 | "idiom" : "watch", 9 | "screen-width" : "<=145" 10 | }, 11 | { 12 | "idiom" : "watch", 13 | "screen-width" : ">161" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "screen-width" : ">183" 22 | }, 23 | { 24 | "idiom" : "watch", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "idiom" : "watch", 29 | "filename" : "Bolus icon 38mm.png", 30 | "screen-width" : "<=145", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "watch", 35 | "scale" : "2x", 36 | "screen-width" : ">161" 37 | }, 38 | { 39 | "idiom" : "watch", 40 | "scale" : "2x", 41 | "screen-width" : ">145" 42 | }, 43 | { 44 | "idiom" : "watch", 45 | "scale" : "2x", 46 | "screen-width" : ">183" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | }, 53 | "properties" : { 54 | "template-rendering-intent" : "template", 55 | "auto-scaling" : "auto" 56 | } 57 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/carbs.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Carb Icon 42mm.pdf" 6 | }, 7 | { 8 | "idiom" : "watch", 9 | "screen-width" : "<=145" 10 | }, 11 | { 12 | "idiom" : "watch", 13 | "screen-width" : ">161" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "screen-width" : ">183" 22 | }, 23 | { 24 | "idiom" : "watch", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "idiom" : "watch", 29 | "filename" : "Carbs icon 38mm.png", 30 | "screen-width" : "<=145", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "watch", 35 | "scale" : "2x", 36 | "screen-width" : ">161" 37 | }, 38 | { 39 | "idiom" : "watch", 40 | "scale" : "2x", 41 | "screen-width" : ">145" 42 | }, 43 | { 44 | "idiom" : "watch", 45 | "scale" : "2x", 46 | "screen-width" : ">183" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | }, 53 | "properties" : { 54 | "template-rendering-intent" : "template", 55 | "auto-scaling" : "auto" 56 | } 57 | } -------------------------------------------------------------------------------- /WatchApp/Assets.xcassets/pre-meal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Pre-Meal 42mm.pdf" 6 | }, 7 | { 8 | "idiom" : "watch", 9 | "screen-width" : "<=145" 10 | }, 11 | { 12 | "idiom" : "watch", 13 | "screen-width" : ">161" 14 | }, 15 | { 16 | "idiom" : "watch", 17 | "screen-width" : ">145" 18 | }, 19 | { 20 | "idiom" : "watch", 21 | "screen-width" : ">183" 22 | }, 23 | { 24 | "idiom" : "watch", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "idiom" : "watch", 29 | "filename" : "Pre-Meal 38mm.png", 30 | "screen-width" : "<=145", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "watch", 35 | "scale" : "2x", 36 | "screen-width" : ">161" 37 | }, 38 | { 39 | "idiom" : "watch", 40 | "scale" : "2x", 41 | "screen-width" : ">145" 42 | }, 43 | { 44 | "idiom" : "watch", 45 | "scale" : "2x", 46 | "screen-width" : ">183" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | }, 53 | "properties" : { 54 | "template-rendering-intent" : "template", 55 | "auto-scaling" : "auto" 56 | } 57 | } -------------------------------------------------------------------------------- /Loop/Extensions/NewPumpEvent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NewPumpEvent.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopKit 9 | 10 | 11 | extension NewPumpEvent { 12 | 13 | /* 14 | It takes a MM pump about 40s to deliver 1 Unit while bolusing 15 | See: http://www.healthline.com/diabetesmine/ask-dmine-speed-insulin-pumps#3 16 | */ 17 | private static let deliveryUnitsPerMinute = 1.5 18 | 19 | /// Constructs a pump event placeholder representing a bolus just enacted. 20 | /// 21 | /// - Parameters: 22 | /// - units: The units of insulin requested 23 | /// - date: The date the bolus was enacted 24 | static func enactedBolus(units: Double, at date: Date) -> NewPumpEvent { 25 | let dose = DoseEntry( 26 | type: .bolus, 27 | startDate: date, 28 | endDate: date.addingTimeInterval(.minutes(units / NewPumpEvent.deliveryUnitsPerMinute)), 29 | value: units, 30 | unit: .units 31 | ) 32 | 33 | return self.init( 34 | date: date, 35 | dose: dose, 36 | isMutable: true, 37 | raw: Data(), // This can be empty, as mutable events aren't persisted 38 | title: "" 39 | ) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DoseMathTests/Base.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "U"; 27 | -------------------------------------------------------------------------------- /DoseMathTests/pl.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Obecny cukier jest %1$@ poniżej poziomu korekcji."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Przewidywany cukier o %1$@ wyniesie %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Przewidywany poziom cukru %1$@ jest poniżej progu wstrzymania."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "J"; 27 | -------------------------------------------------------------------------------- /Loop/Managers/PumpManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PumpManager.swift 3 | // Loop 4 | // 5 | // Copyright © 2018 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import LoopKit 10 | import MinimedKit 11 | 12 | 13 | let allPumpManagers: [PumpManager.Type] = [ 14 | MinimedPumpManager.self 15 | ] 16 | 17 | private let managersByIdentifier: [String: PumpManager.Type] = allPumpManagers.reduce(into: [:]) { (map, Type) in 18 | map[Type.managerIdentifier] = Type 19 | } 20 | 21 | func PumpManagerTypeFromRawValue(_ rawValue: [String: Any]) -> PumpManager.Type? { 22 | guard let managerIdentifier = rawValue["managerIdentifier"] as? String else { 23 | return nil 24 | } 25 | 26 | return managersByIdentifier[managerIdentifier] 27 | } 28 | 29 | func PumpManagerFromRawValue(_ rawValue: [String: Any]) -> PumpManager? { 30 | guard let rawState = rawValue["state"] as? PumpManager.RawStateValue, 31 | let Manager = PumpManagerTypeFromRawValue(rawValue) 32 | else { 33 | return nil 34 | } 35 | 36 | return Manager.init(rawState: rawState) 37 | } 38 | 39 | extension PumpManager { 40 | var rawValue: [String: Any] { 41 | return [ 42 | "managerIdentifier": type(of: self).managerIdentifier, 43 | "state": self.rawState 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Loop/Managers/RemoteDataManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RemoteDataManager.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 6/29/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | import NightscoutUploadKit 12 | 13 | 14 | final class RemoteDataManager { 15 | 16 | weak var delegate: RemoteDataManagerDelegate? 17 | 18 | var nightscoutService: NightscoutService { 19 | didSet { 20 | keychain.setNightscoutURL(nightscoutService.siteURL, secret: nightscoutService.APISecret) 21 | UIDevice.current.isBatteryMonitoringEnabled = true 22 | delegate?.remoteDataManagerDidUpdateServices(self) 23 | } 24 | } 25 | 26 | private let keychain = KeychainManager() 27 | 28 | init() { 29 | if let (siteURL, APISecret) = keychain.getNightscoutCredentials() { 30 | nightscoutService = NightscoutService(siteURL: siteURL, APISecret: APISecret) 31 | UIDevice.current.isBatteryMonitoringEnabled = true 32 | } else { 33 | nightscoutService = NightscoutService(siteURL: nil, APISecret: nil) 34 | } 35 | } 36 | } 37 | 38 | 39 | protocol RemoteDataManagerDelegate: class { 40 | func remoteDataManagerDidUpdateServices(_ dataManager: RemoteDataManager) 41 | } 42 | -------------------------------------------------------------------------------- /WatchApp Extension/Extensions/CLKTextProvider+Compound.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLKTextProvider+Compound.m 3 | // WatchApp Extension 4 | // 5 | // Created by Michael Pangburn on 10/27/18. 6 | // Copyright © 2018 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | #import "CLKTextProvider+Compound.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | // CLKTextProvider.textProviderWithFormat (compound text provider creation) is unavailable in Swift. 14 | // c.f. https://crunchybagel.com/using-multicolour-clktextprovider-in-swift-in-watchos-5/ 15 | @implementation CLKTextProvider (Compound) 16 | 17 | + (CLKTextProvider *)textProviderByJoiningTextProviders: (NSArray *)textProviders separator:(NSString *) separator { 18 | 19 | NSString *formatString = @"%@%@"; 20 | 21 | if (separator.length > 0) { 22 | formatString = [NSString stringWithFormat:@"%@%@%@", @"%@", separator, @"%@"]; 23 | } 24 | 25 | CLKTextProvider *firstItem = textProviders.firstObject; 26 | 27 | for (NSInteger index = 1; index < textProviders.count; index++) { 28 | CLKTextProvider *secondItem = [textProviders objectAtIndex: index]; 29 | firstItem = [CLKTextProvider textProviderWithFormat:formatString, firstItem, secondItem]; 30 | } 31 | 32 | return firstItem; 33 | } 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /DoseMathTests/nb.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Nåværende blodsukker på %1$@ er under målområde."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Forventet blodsukker om %1$@ er %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet blodsukker %1$@ er under innstillingen for insulinstopp."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "E"; 27 | 28 | -------------------------------------------------------------------------------- /DoseMathTests/fr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Glycémie actuelle %1$@ sous la plage de correction."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Glycémie de %2$@ prédite pour %1$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Prédiction de la glycémie à %1$@ sous le seuil de suspension défini."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "U"; 27 | 28 | -------------------------------------------------------------------------------- /Common/Models/SetBolusUserInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SetBolusUserInfo.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/20/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | struct SetBolusUserInfo { 13 | let value: Double 14 | let startDate: Date 15 | 16 | init(value: Double, startDate: Date) { 17 | self.value = value 18 | self.startDate = startDate 19 | } 20 | } 21 | 22 | 23 | extension SetBolusUserInfo: RawRepresentable { 24 | typealias RawValue = [String: Any] 25 | 26 | static let version = 1 27 | static let name = "SetBolusUserInfo" 28 | 29 | init?(rawValue: RawValue) { 30 | guard rawValue["v"] as? Int == type(of: self).version && 31 | rawValue["name"] as? String == SetBolusUserInfo.name, 32 | let value = rawValue["bv"] as? Double, 33 | let startDate = rawValue["sd"] as? Date else 34 | { 35 | return nil 36 | } 37 | 38 | self.value = value 39 | self.startDate = startDate 40 | } 41 | 42 | var rawValue: RawValue { 43 | return [ 44 | "v": type(of: self).version, 45 | "name": SetBolusUserInfo.name, 46 | "bv": value, 47 | "sd": startDate 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Common/Extensions/NSBundle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 7/28/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Bundle { 13 | var shortVersionString: String { 14 | return object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String 15 | } 16 | 17 | var bundleDisplayName: String { 18 | return object(forInfoDictionaryKey: "CFBundleDisplayName") as! String 19 | } 20 | 21 | var localizedNameAndVersion: String { 22 | return String(format: NSLocalizedString("%1$@ v%2$@", comment: "The format string for the app name and version number. (1: bundle name)(2: bundle version)"), bundleDisplayName, shortVersionString) 23 | } 24 | 25 | private var mainAppBundleIdentifier: String? { 26 | return object(forInfoDictionaryKey: "MainAppBundleIdentifier") as? String 27 | } 28 | 29 | var appGroupSuiteName: String { 30 | return object(forInfoDictionaryKey: "AppGroupIdentifier") as! String 31 | } 32 | 33 | var mainAppUrl: URL? { 34 | if let mainAppBundleIdentifier = mainAppBundleIdentifier { 35 | return URL(string: "\(mainAppBundleIdentifier)://") 36 | } else { 37 | return nil 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /DoseMathTests/es.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Glucosa actual de %1$@ está debajo del rango correctivo."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Glucosa proyectada en %1$@ es %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Glucosa proyectada de %1$@ se encuentra debajo de tu nivel de suspensión."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "U"; 27 | 28 | -------------------------------------------------------------------------------- /DoseMathTests/nl.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Huidige glucose van %1$@ is onder het correctie bereik."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "gr"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Voorspelde glucose van %1$@ is %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Voorspelde glucose van %1$@ is onder het onderbreken van basaal instelling."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "E"; 27 | 28 | -------------------------------------------------------------------------------- /DoseMathTests/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = " Текущая гликемия %1$@ ниже диапазона коррекции"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "г"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "мг/дл"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "ммоль/л"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Предсказываемая гликемия в %1$@ - %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Предсказываемая гликемия %1$@ ниже установленного вами порога приостановки помпы"; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "ед"; 27 | 28 | -------------------------------------------------------------------------------- /WatchApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Loop 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.9.5 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | $(MAIN_APP_BUNDLE_IDENTIFIER) 32 | WKWatchKitApp 33 | 34 | NSUserActivityTypes 35 | 36 | com.loopkit.Loop.AddCarbEntryOnWatch 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /DoseMathTests/it.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "La glicemia corrente %1$@ é al di sotto dell'intervallo glicemico selezionato."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dL"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/L"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "La glicemia prevista a %1$@ è %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "La glicemia prevista %1$@ è inferiore al valore glicemico previsto per la sospensione dell'erogazione."; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "U"; 27 | 28 | -------------------------------------------------------------------------------- /DoseMathTests/de.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ 2 | "Current glucose of %1$@ is below correction range." = "Der aktuelle Blutzucker von %1$@ liegt unterhalb des Korrekturbereiches."; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The short unit display string for grams */ 8 | "g" = "g"; 9 | 10 | /* The short unit display string for milligrams of glucose per decilter */ 11 | "mg/dL" = "mg/dl"; 12 | 13 | /* The short unit display string for millimoles of glucose per liter */ 14 | "mmol/L" = "mmol/l"; 15 | 16 | /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ 17 | "Predicted glucose at %1$@ is %2$@." = "Der vorhergesagte Blutzucker um %1$@ ist %2$@."; 18 | 19 | /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ 20 | "Predicted glucose of %1$@ is below your suspend threshold setting." = "Der vorhergesagte Blutzucker von %1$@ liegt unterhalb des eingestellten Schwellwertes zur Unterbrechung der Basalrate. "; 21 | 22 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 23 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 24 | 25 | /* The short unit display string for international units of insulin */ 26 | "U" = "IE"; 27 | -------------------------------------------------------------------------------- /LoopUI/Views/LevelHUDView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LevelHUDView.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 2/4/17. 6 | // Copyright © 2017 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class LevelHUDView: BaseHUDView { 12 | 13 | @IBOutlet private weak var levelMaskView: LevelMaskView! 14 | 15 | override public func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | updateColor() 19 | 20 | accessibilityValue = LocalizedString("Unknown", comment: "Accessibility value for an unknown value") 21 | } 22 | 23 | public var stateColors: StateColorPalette? { 24 | didSet { 25 | updateColor() 26 | } 27 | } 28 | 29 | private func updateColor() { 30 | levelMaskView.tintColor = nil 31 | 32 | switch level { 33 | case .none: 34 | tintColor = stateColors?.unknown 35 | case let x? where x > 0.25: 36 | tintColor = stateColors?.normal 37 | case let x? where x > 0.10: 38 | tintColor = stateColors?.normal 39 | levelMaskView.tintColor = stateColors?.warning 40 | default: 41 | tintColor = stateColors?.error 42 | } 43 | } 44 | 45 | internal var level: Double? { 46 | didSet { 47 | levelMaskView.value = level ?? 1.0 48 | updateColor() 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /Loop/Models/NetBasal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetBasal.swift 3 | // Loop 4 | // 5 | // Created by Bharat Mediratta on 12/7/16. 6 | // Copyright © 2016 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import LoopKit 11 | 12 | 13 | struct NetBasal { 14 | let rate: Double 15 | let percent: Double 16 | let start: Date 17 | let end: Date 18 | 19 | init(lastTempBasal: DoseEntry?, maxBasal: Double?, scheduledBasal: AbsoluteScheduleValue) { 20 | if let lastTempBasal = lastTempBasal, lastTempBasal.endDate > Date(), let maxBasal = maxBasal { 21 | rate = lastTempBasal.unitsPerHour - scheduledBasal.value 22 | start = lastTempBasal.startDate 23 | end = lastTempBasal.endDate 24 | 25 | if rate < 0 { 26 | percent = rate / scheduledBasal.value 27 | } else { 28 | percent = rate / (maxBasal - scheduledBasal.value) 29 | } 30 | } else { 31 | rate = 0 32 | percent = 0 33 | 34 | if let lastTempBasal = lastTempBasal, lastTempBasal.endDate > scheduledBasal.startDate { 35 | start = lastTempBasal.endDate 36 | end = scheduledBasal.endDate 37 | } else { 38 | start = scheduledBasal.startDate 39 | end = scheduledBasal.endDate 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LoopUI/Views/ChartContainerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartContainerView.swift 3 | // Loop 4 | // 5 | // Created by Nate Racklyeft on 9/14/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class ChartContainerView: UIView { 12 | 13 | override public func layoutSubviews() { 14 | super.layoutSubviews() 15 | 16 | if chartView == nil || chartView!.frame != bounds { 17 | // 50 is the smallest height in which we should attempt to redraw a chart. 18 | // Smaller sizes might be requested mid-animation, so ignore them. 19 | if bounds.height > 50 { 20 | chartView = chartGenerator?(bounds) 21 | } 22 | } else if chartView!.superview == nil { 23 | addSubview(chartView!) 24 | } 25 | } 26 | 27 | public func reloadChart() { 28 | chartView = nil 29 | setNeedsLayout() 30 | } 31 | 32 | public var chartGenerator: ((CGRect) -> UIView?)? { 33 | didSet { 34 | chartView = nil 35 | setNeedsLayout() 36 | } 37 | } 38 | 39 | private var chartView: UIView? { 40 | didSet { 41 | if let view = oldValue { 42 | view.removeFromSuperview() 43 | } 44 | 45 | if let view = chartView { 46 | self.addSubview(view) 47 | } 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /WatchApp Extension/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "Болюс не состоялся"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "Пропустить"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "г"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "Убедитесь, что ваш iPhone поблизости и повторите попытку"; 17 | 18 | /* The short unit display string for millimoles of glucose per liter */ 19 | "mmol/L" = "ммоль/л"; 20 | 21 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 22 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 23 | 24 | /* The label and value showing the recommended bolus */ 25 | "Rec: %@ U" = "Рекомендовано: %@ ед"; 26 | 27 | /* The title of the alert controller displayed after a carb entry send attempt fails 28 | The title of the alert controller displayed after a glucose range override send attempt fails */ 29 | "Send Failed" = "Ошибка отправки"; 30 | 31 | /* The short unit display string for international units of insulin */ 32 | "U" = "ед"; 33 | 34 | -------------------------------------------------------------------------------- /Common/Models/BolusSuggestionUserInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BolusSuggestionUserInfo.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 3/20/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | struct BolusSuggestionUserInfo: RawRepresentable { 13 | let recommendedBolus: Double? 14 | var maxBolus: Double? 15 | 16 | init(recommendedBolus: Double?, maxBolus: Double? = nil) { 17 | self.recommendedBolus = recommendedBolus 18 | self.maxBolus = maxBolus 19 | } 20 | 21 | // MARK: - RawRepresentable 22 | typealias RawValue = [String: Any] 23 | 24 | static let version = 1 25 | static let name = "BolusSuggestionUserInfo" 26 | 27 | init?(rawValue: RawValue) { 28 | guard rawValue["v"] as? Int == type(of: self).version && rawValue["name"] as? String == BolusSuggestionUserInfo.name, 29 | let recommendedBolus = rawValue["br"] as? Double else 30 | { 31 | return nil 32 | } 33 | 34 | self.recommendedBolus = recommendedBolus 35 | self.maxBolus = rawValue["mb"] as? Double 36 | } 37 | 38 | var rawValue: RawValue { 39 | var raw: RawValue = [ 40 | "v": type(of: self).version, 41 | "name": BolusSuggestionUserInfo.name, 42 | ] 43 | 44 | raw["br"] = recommendedBolus 45 | raw["mb"] = maxBolus 46 | 47 | return raw 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /WatchApp Extension/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "大剂量输注失败"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "忽略"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "克"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "请确保苹果手机接近设备并重试"; 17 | 18 | /* The short unit display string for milligrams of glucose per decilter */ 19 | "mg/dL" = "毫克/分升"; 20 | 21 | /* The short unit display string for millimoles of glucose per liter */ 22 | "mmol/L" = "毫摩尔/升"; 23 | 24 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 25 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 26 | 27 | /* The label and value showing the recommended bolus */ 28 | "Rec: %@ U" = "推荐: %@ 单位"; 29 | 30 | /* The title of the alert controller displayed after a carb entry send attempt fails 31 | The title of the alert controller displayed after a glucose range override send attempt fails */ 32 | "Send Failed" = "发送失败"; 33 | 34 | /* The short unit display string for international units of insulin */ 35 | "U" = "单位"; 36 | 37 | -------------------------------------------------------------------------------- /Loop/Extensions/UIImage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage.swift 3 | // Naterade 4 | // 5 | // Created by Nathan Racklyeft on 5/7/16. 6 | // Copyright © 2016 Nathan Racklyeft. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension UIImage { 13 | private static func imageSuffixForLevel(_ level: Double?) -> String { 14 | let suffix: String 15 | 16 | switch level { 17 | case 0?: 18 | suffix = "0" 19 | case let x? where x <= 0.25: 20 | suffix = "25" 21 | case let x? where x <= 0.5: 22 | suffix = "50" 23 | case let x? where x <= 0.75: 24 | suffix = "75" 25 | case let x? where x <= 1: 26 | suffix = "100" 27 | default: 28 | suffix = "unknown" 29 | } 30 | 31 | return suffix 32 | } 33 | 34 | static func batteryHUDImageWithLevel(_ level: Double?) -> UIImage? { 35 | return UIImage(named: "battery_\(imageSuffixForLevel(level))") 36 | } 37 | 38 | static func reservoirHUDImageWithLevel(_ level: Double?) -> UIImage? { 39 | return UIImage(named: "reservoir_\(imageSuffixForLevel(level))") 40 | } 41 | 42 | static func preMealImage(selected: Bool) -> UIImage? { 43 | return UIImage(named: selected ? "Pre-Meal Selected" : "Pre-Meal") 44 | } 45 | 46 | static func workoutImage(selected: Bool) -> UIImage? { 47 | return UIImage(named: selected ? "workout-selected" : "workout") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Loop/View Controllers/GlucoseThresholdTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GlucoseThresholdTableViewController.swift 3 | // Loop 4 | // 5 | // Created by Pete Schwamb on 1/1/17. 6 | // Copyright © 2017 LoopKit Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | import LoopKitUI 13 | import HealthKit 14 | 15 | 16 | final class GlucoseThresholdTableViewController: TextFieldTableViewController { 17 | 18 | public let glucoseUnit: HKUnit 19 | 20 | init(threshold: Double?, glucoseUnit: HKUnit) { 21 | self.glucoseUnit = glucoseUnit 22 | 23 | super.init(style: .grouped) 24 | 25 | placeholder = NSLocalizedString("Enter suspend threshold", comment: "The placeholder text instructing users to enter a suspend treshold") 26 | keyboardType = .decimalPad 27 | contextHelp = NSLocalizedString("When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour.", comment: "Explanation of suspend threshold") 28 | 29 | unit = glucoseUnit.localizedShortUnitString 30 | 31 | if let threshold = threshold { 32 | value = NumberFormatter.glucoseFormatter(for: glucoseUnit).string(from: threshold) 33 | } 34 | 35 | } 36 | 37 | required init?(coder aDecoder: NSCoder) { 38 | fatalError("init(coder:) has not been implemented") 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /WatchApp Extension/it.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "Bolo Fallito"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "Rimuovere"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "g"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "Assicurati che il tuo iPhone sia vicino e riprova"; 17 | 18 | /* The short unit display string for milligrams of glucose per decilter */ 19 | "mg/dL" = "mg/dL"; 20 | 21 | /* The short unit display string for millimoles of glucose per liter */ 22 | "mmol/L" = "mmol/L"; 23 | 24 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 25 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 26 | 27 | /* The label and value showing the recommended bolus */ 28 | "Rec: %@ U" = "Rec: %@ U"; 29 | 30 | /* The title of the alert controller displayed after a carb entry send attempt fails 31 | The title of the alert controller displayed after a glucose range override send attempt fails */ 32 | "Send Failed" = "Invio Fallito"; 33 | 34 | /* The short unit display string for international units of insulin */ 35 | "U" = "U"; 36 | 37 | -------------------------------------------------------------------------------- /Common/Extensions/PersistenceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PersistenceController.swift 3 | // Loop 4 | // 5 | // Copyright © 2017 LoopKit Authors. All rights reserved. 6 | // 7 | 8 | import LoopKit 9 | 10 | 11 | extension PersistenceController { 12 | class func controllerInAppGroupDirectory() -> PersistenceController { 13 | let appGroup = Bundle.main.appGroupSuiteName 14 | guard let directoryURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else { 15 | assertionFailure("Could not get a container directory URL. Please ensure App Groups are set up correctly in entitlements.") 16 | return self.init(directoryURL: URL(fileURLWithPath: "/")) 17 | } 18 | 19 | let isReadOnly = Bundle.main.bundleURL.pathExtension == "appex" 20 | 21 | return self.init(directoryURL: directoryURL.appendingPathComponent("com.loopkit.LoopKit", isDirectory: true), isReadOnly: isReadOnly) 22 | } 23 | 24 | class func controllerInLocalDirectory() -> PersistenceController { 25 | guard let directoryURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else { 26 | fatalError("Could not access the document directory of the current process") 27 | } 28 | 29 | let isReadOnly = Bundle.main.bundleURL.pathExtension == "appex" 30 | 31 | return self.init(directoryURL: directoryURL.appendingPathComponent("com.loopkit.LoopKit"), isReadOnly: isReadOnly) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WatchApp Extension/nb.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "Bolus mislyktes"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "Avskjedige"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "g"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "Pass på at iPhone er i nærheten, og prøv igjen"; 17 | 18 | /* The short unit display string for milligrams of glucose per decilter */ 19 | "mg/dL" = "mg/dL"; 20 | 21 | /* The short unit display string for millimoles of glucose per liter */ 22 | "mmol/L" = "mmol/L"; 23 | 24 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 25 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 26 | 27 | /* The label and value showing the recommended bolus */ 28 | "Rec: %@ U" = "Rec: %@ E"; 29 | 30 | /* The title of the alert controller displayed after a carb entry send attempt fails 31 | The title of the alert controller displayed after a glucose range override send attempt fails */ 32 | "Send Failed" = "Send mislyktes"; 33 | 34 | /* The short unit display string for international units of insulin */ 35 | "U" = "E"; 36 | 37 | -------------------------------------------------------------------------------- /WatchApp Extension/es.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "Bolo Falló"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "Ignorar"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "g"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "Asegúrate que tu iPhone se encuentre cerca e inténtalo de nuevo"; 17 | 18 | /* The short unit display string for milligrams of glucose per decilter */ 19 | "mg/dL" = "mg/dL"; 20 | 21 | /* The short unit display string for millimoles of glucose per liter */ 22 | "mmol/L" = "mmol/L"; 23 | 24 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 25 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 26 | 27 | /* The label and value showing the recommended bolus */ 28 | "Rec: %@ U" = "Rec: %@ U"; 29 | 30 | /* The title of the alert controller displayed after a carb entry send attempt fails 31 | The title of the alert controller displayed after a glucose range override send attempt fails */ 32 | "Send Failed" = "Envío Falló"; 33 | 34 | /* The short unit display string for international units of insulin */ 35 | "U" = "U"; 36 | 37 | -------------------------------------------------------------------------------- /WatchApp Extension/fr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "Bolus Échoué"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "Rejeter"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "g"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "Assurez-vous que votre iPhone est à proximité et réessayez"; 17 | 18 | /* The short unit display string for milligrams of glucose per decilter */ 19 | "mg/dL" = "mg/dL"; 20 | 21 | /* The short unit display string for millimoles of glucose per liter */ 22 | "mmol/L" = "mmol/L"; 23 | 24 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 25 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 26 | 27 | /* The label and value showing the recommended bolus */ 28 | "Rec: %@ U" = "Rec: %@ U"; 29 | 30 | /* The title of the alert controller displayed after a carb entry send attempt fails 31 | The title of the alert controller displayed after a glucose range override send attempt fails */ 32 | "Send Failed" = "Echec de l'envoi"; 33 | 34 | /* The short unit display string for international units of insulin */ 35 | "U" = "U"; 36 | 37 | -------------------------------------------------------------------------------- /WatchApp Extension/nl.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* The title of the alert controller displayed after a bolus attempt fails */ 2 | "Bolus Failed" = "Bolus mislukt"; 3 | 4 | /* The short unit display string for decibles */ 5 | "dB" = "dB"; 6 | 7 | /* The action button title to dismiss an error message */ 8 | "Dismiss" = "Verwerp"; 9 | 10 | /* The short unit display string for grams */ 11 | "g" = "gr"; 12 | 13 | /* The recovery message displayed after a bolus attempt fails 14 | The recovery message displayed after a carb entry send attempt fails 15 | The recovery message displayed after a glucose range override send attempt fails */ 16 | "Make sure your iPhone is nearby and try again" = "Zorg dat je iPhone in de buurt is en probeer opnieuw"; 17 | 18 | /* The short unit display string for milligrams of glucose per decilter */ 19 | "mg/dL" = "mg/dL"; 20 | 21 | /* The short unit display string for millimoles of glucose per liter */ 22 | "mmol/L" = "mmol/L"; 23 | 24 | /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ 25 | "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; 26 | 27 | /* The label and value showing the recommended bolus */ 28 | "Rec: %@ U" = "Voorgesteld: %@ E"; 29 | 30 | /* The title of the alert controller displayed after a carb entry send attempt fails 31 | The title of the alert controller displayed after a glucose range override send attempt fails */ 32 | "Send Failed" = "Versturen mislukt"; 33 | 34 | /* The short unit display string for international units of insulin */ 35 | "U" = "E"; 36 | 37 | --------------------------------------------------------------------------------