From 27e31e2ab10a8a7305ada44878db1c9dfe680bad Mon Sep 17 00:00:00 2001 From: JHubi1 Date: Fri, 7 Aug 2026 23:26:12 +0200 Subject: [PATCH] ChatDB, complete UI, formatting, everything else --- .vscode/launch.json | 22 + analysis_options.yaml | 5 +- android/app/build.gradle.kts | 18 +- android/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/settings.gradle.kts | 4 +- ...SansCode-Italic-VariableFont_MONO,wght.ttf | Bin 0 -> 281920 bytes .../GoogleSansCode-VariableFont_MONO,wght.ttf | Bin 0 -> 132884 bytes devtools_options.yaml | 3 +- lib/l10n/app_de.arb | 56 +- lib/l10n/app_en.arb | 384 +- lib/l10n/gen/app_localizations.dart | 306 +- lib/l10n/gen/app_localizations_de.dart | 195 +- lib/l10n/gen/app_localizations_en.dart | 224 +- lib/l10n/gen/app_localizations_fa.dart | 149 +- lib/l10n/gen/app_localizations_it.dart | 150 +- lib/l10n/gen/app_localizations_tr.dart | 150 +- lib/l10n/gen/app_localizations_zh.dart | 148 +- lib/main.dart | 220 +- lib/main.gr.dart | 224 + lib/screens/chat.dart | 520 + lib/screens/main.dart | 897 +- lib/screens/settings.dart | 1620 +- lib/screens/settings/about.dart | 249 +- lib/screens/settings/behavior.dart | 173 +- lib/screens/settings/export.dart | 417 +- lib/screens/settings/interface.dart | 810 +- lib/screens/settings/voice.dart | 634 +- lib/screens/voice.dart | 561 +- lib/screens/welcome.dart | 147 +- lib/services/chat.dart | 750 +- lib/services/chat_database/chat_database.dart | 58 + .../chat_database/chat_database.g.dart | 998 ++ lib/services/clients.dart | 13 +- lib/services/curves.dart | 50 + lib/services/error.dart | 106 +- lib/services/haptic.dart | 15 +- lib/services/host.dart | 142 + lib/services/markdown.dart | 551 +- lib/services/model.dart | 225 +- lib/services/preferences.dart | 24 +- lib/services/responsive.dart | 164 +- lib/services/services.dart | 12 + lib/services/theme.dart | 51 +- lib/util/extensions.dart | 26 + lib/widgets/alert_dialog_child.dart | 344 + lib/widgets/alpha_beta.dart | 107 + lib/widgets/child_size_notifier.dart | 35 + .../hero_text_flight_shuttle_builder.dart | 6 +- lib/widgets/list_tile_slide.dart | 8 +- lib/widgets/list_tile_switch.dart | 34 +- lib/widgets/model_adder.dart | 551 + lib/widgets/model_selector.dart | 454 + .../sized_circular_progress_indicator.dart | 76 + lib/widgets/two_state_widget.dart | 128 + lib/worker/desktop.dart | 85 +- lib/worker/sender.dart | 175 +- lib/worker/setter.dart | 951 +- lib/worker/update.dart | 117 +- pubspec.lock | 552 +- pubspec.yaml | 39 +- scripts/build.dart | 42 +- test/functions.dart | 4 +- test/widget_test.dart | 33 +- {tools => tool}/base64.dart | 0 {tools => tool}/logid.dart | 2 +- untranslated_messages.json | 150 +- web/drift_worker.js | 13271 ++++++++++++++++ web/index.html | 2 +- web/sqlite3.wasm | Bin 0 -> 744131 bytes windows/flutter/generated_plugins.cmake | 1 + 71 files changed, 24608 insertions(+), 4036 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 assets/fonts/GoogleSansCode-Italic-VariableFont_MONO,wght.ttf create mode 100644 assets/fonts/GoogleSansCode-VariableFont_MONO,wght.ttf create mode 100644 lib/main.gr.dart create mode 100644 lib/screens/chat.dart create mode 100644 lib/services/chat_database/chat_database.dart create mode 100644 lib/services/chat_database/chat_database.g.dart create mode 100644 lib/services/curves.dart create mode 100644 lib/services/host.dart create mode 100644 lib/services/services.dart create mode 100644 lib/util/extensions.dart create mode 100644 lib/widgets/alert_dialog_child.dart create mode 100644 lib/widgets/alpha_beta.dart create mode 100644 lib/widgets/child_size_notifier.dart create mode 100644 lib/widgets/model_adder.dart create mode 100644 lib/widgets/model_selector.dart create mode 100644 lib/widgets/sized_circular_progress_indicator.dart create mode 100644 lib/widgets/two_state_widget.dart rename {tools => tool}/base64.dart (100%) rename {tools => tool}/logid.dart (96%) create mode 100644 web/drift_worker.js create mode 100644 web/sqlite3.wasm diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bc77ead --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "ollama-app", + "request": "launch", + "type": "dart", + }, + { + "name": "ollama-app (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "ollama-app (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml index 5c5ed34..c72735d 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -16,19 +16,18 @@ linter: - avoid_multiple_declarations_per_line - eol_at_end_of_file - leading_newlines_in_multiline_strings + - no_wildcard_variable_uses + - prefer_final_locals - unnecessary_breaks - - unnecessary_final - unnecessary_lambdas - unnecessary_parenthesis # Async, Errors, Null Safety - avoid_catching_errors - - avoid_null_checks_in_equality_operators - avoid_void_async - cancel_subscriptions - cast_nullable_to_non_nullable - unnecessary_await_in_return - - use_if_null_to_convert_nulls_to_bools - use_to_and_as_if_applicable # Usage Patterns diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 88fe025..1ffc3ab 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -3,7 +3,6 @@ import java.io.FileInputStream plugins { id("com.android.application") - id("kotlin-android") // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id("dev.flutter.flutter-gradle-plugin") } @@ -17,15 +16,11 @@ if (keystorePropertiesFile.exists()) { android { namespace = "com.freakurl.apps.ollama" compileSdk = flutter.compileSdkVersion - ndkVersion = "27.0.12077973" // flutter.ndkVersion + ndkVersion = "28.2.13676358" // flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - kotlinOptions { - jvmTarget = JavaVersion.VERSION_11.toString() + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } defaultConfig { @@ -54,6 +49,13 @@ android { } } +kotlin { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} + + flutter { source = "../.." } diff --git a/android/gradle.properties b/android/gradle.properties index f018a61..475a628 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,7 @@ org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true +# This builtInKotlin flag was added automatically by Flutter migrator +android.builtInKotlin=false +# This newDsl flag was added automatically by Flutter migrator +android.newDsl=false diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index afa1e8e..f587a47 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-all.zip diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index 11662c3..da20e6d 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "2.1.0" apply false + id("com.android.application") version "8.11.1" apply false + id("org.jetbrains.kotlin.android") version "2.2.20" apply false } include(":app") diff --git a/assets/fonts/GoogleSansCode-Italic-VariableFont_MONO,wght.ttf b/assets/fonts/GoogleSansCode-Italic-VariableFont_MONO,wght.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d07eaf94997c94813528c90703b456947b5e96cb GIT binary patch literal 281920 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 rt#z)}727m%Wv)d1QRY3#X*iv3I|bl^V#-c3Ek literal 0 HcmV?d00001 diff --git a/assets/fonts/GoogleSansCode-VariableFont_MONO,wght.ttf b/assets/fonts/GoogleSansCode-VariableFont_MONO,wght.ttf new file mode 100644 index 0000000000000000000000000000000000000000..58583b96a9ea8f099508995610c5d1ccd6fe9cd4 GIT binary patch literal 132884 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Ƿ}%+9+sHh&Fr<@@#E{cvMJSw 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 literal 0 HcmV?d00001 diff --git a/devtools_options.yaml b/devtools_options.yaml index 4dcfde9..2c00e5e 100644 --- a/devtools_options.yaml +++ b/devtools_options.yaml @@ -1,4 +1,5 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states extensions: - - shared_preferences: true \ No newline at end of file + - shared_preferences: true + - drift: true \ No newline at end of file diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 9308bcd..55297f6 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1,10 +1,12 @@ { "@@locale": "de", - "appTitle": "Ollama", + "appTitle": "{env, select, short{Ollama} integrated{{title} - Ollama App} other{Ollama App}}", "optionNewChat": "Neuer Chat", "optionSettings": "Einstellungen", "optionInstallPwa": "Webapp installieren", - "optionNoChatFound": "Keine Chats gefunden", + "optionNoChatFound": "Keine Chats", + "optionNoChatFoundSearch": "Keinen Chat gefunden für Suche ‚{query}‘", + "optionSearchChats": "Chats durchsuchen", "tipPrefix": "Tipp: ", "tip0": "Bearbeite Nachrichten durch langes Tippen", "tip1": "Lösche Nachrichten durch Doppeltippen", @@ -15,37 +17,32 @@ "renameChat": "Umbenennen", "takeImage": "Bild Aufnehmen", "uploadImage": "Bild Hochladen", - "notAValidImage": "Kein gültiges Bild", - "imageOnlyConversation": "Nur Bild Unterhaltung", - "messageInputPlaceholder": "Nachricht", - "tooltipAttachment": "Anhang hinzufügen", + "messageInputPlaceholder": "{model} fragen", + "messageInputPlaceholderModelPlaceholder": "Modell", + "tooltipMessageOptions": "Nachrichtenoptionen", "tooltipSend": "Senden", - "tooltipSave": "Speichern", - "tooltipLetAIThink": "Lass KI denken", + "tooltipLetAIThink": "Mit {model} generieren", "tooltipAddHostHeaders": "Host-Header festlegen", "tooltipReset": "Aktuellen Chat zurücksetzen", "tooltipOptions": "Optionen anzeigen", "noModelSelected": "Kein Modell ausgewählt", - "noHostSelected": "Kein Host ausgewählt, öffne zum Auswählen die Einstellungen", - "noSelectedModel": "", + "noHostSelected": "Kein Host ausgewählt, öffne zum Auswählen die Einstellungen.", + "noSelectedModel": "", "newChatTitle": "Unbenannter Chat", - "modelDialogAddModel": "Hinzufügen", - "modelDialogAddPromptTitle": "Neues Modell hinzufügen", - "modelDialogAddPromptDescription": "Das kann entweder ein normaler Name (z.B. 'llama3') oder Name und Tag (z.B. 'llama3:70b') sein.", - "modelDialogAddPromptAlreadyExists": "Modell existiert bereits", - "modelDialogAddPromptInvalid": "Ungültiger Modellname", - "modelDialogAddAllowanceTitle": "Proxy erlauben", - "modelDialogAddAllowanceDescription": "Ollama App muss überprüfen, ob das eingegebene Modell gültig ist. Dafür senden wir normalerweise eine Webanfrage an die Ollama-Modellliste und überprüfen den Statuscode, aber da gerade der Webclient verwendet wird, können wir das nicht direkt tun. Stattdessen sendet die App die Anfrage an eine andere API, gehostet von JHubi1, um dies für uns zu überprüfen.\nDies ist eine einmalige Anfrage und wird nur gesendet, wenn du ein neues Modell hinzufügst.\nIhre IP-Adresse wird mit der Anfrage gesendet und kann bis zu zehn Minuten gespeichert werden, um Spamming mit potenziell schädlichen Absichten zu verhindern.\nWenn du zustimmst, wird deine Auswahl für die Zukunft gespeichert; wenn nicht, wird nichts gesendet und das Modell wird nicht hinzugefügt.", - "modelDialogAddAllowanceAllow": "Erlauben", - "modelDialogAddAllowanceDeny": "Ablehnen", - "modelDialogAddAssuranceTitle": "{model} hinzufügen?", - "modelDialogAddAssuranceDescription": "Durch Drücken von 'Hinzufügen' wird das Modell '{model}' direkt vom Ollama-Server auf deinen Host heruntergeladen.\nJe nach Internetverbindung kann dies eine Weile dauern. Der Vorgang kann nicht abgebrochen werden.\nWenn die App während des Downloads geschlossen wird, wird der Download fortgesetzt, wenn du den Namen erneut in den Modelldialog eingibst.", - "modelDialogAddAssuranceAdd": "Hinzufügen", - "modelDialogAddAssuranceCancel": "Abbrechen", - "modelDialogAddDownloadPercentLoading": "lade Fortschritt", - "modelDialogAddDownloadPercent": "Download bei {percent}%", + "learnMore": "Mehr erfahren", + "modelDialogAdd": "Hinzufügen", + "modelDialogAddPromptTitle": "Modell hinzufügen", + "modelDialogAddPromptDescription": "Das kann entweder ein normaler Name (z.B. „llama3“) oder ein Name zusammen mit einem Tag (z.B. „llama3:70b“) sein.", "modelDialogAddCurrently": "Wird gerade heruntergeladen:", "modelDialogAddPromptAlreadyExists": "Modell existiert bereits.", + "modelDialogAddPromptInvalid": "Ungültiger Modellname.", + "modelDialogAddPromptNotFound": "Das Modell konnte auf dem Server nicht gefunden werden. Bitte überprüfe die Schreibweise und versuche es erneut.", + "modelDialogAddPromptNetworkError": "Netzwerkfehler beim Überprüfen des Modells. Bitte überprüfe deine Verbindung und versuche es erneut.", + "modelDialogAddPromptCorruptionError": "Die API hat „EOF“ zurückgegeben; dein Server wurde wahrscheinlich neu gestartet, während das Modell zuvor heruntergeladen wurde.", + "modelDialogAddPromptCorruptionErrorSolution": "Alternativ kannst du den folgenden Befehl direkt auf deinem Linux-Host ausführen:\nWenn du eine neue Fehlermeldung siehst, versuche den Befehl mit „sudo“ davor auszuführen.", + "modelDialogAddCancelTitle": "Download abbrechen?", + "modelDialogAddCancelConfirm": "Abbrechen", + "modelDialogAddCancelHide": "Ausblenden", "modelDialogAddDownloadFailed": "Getrennt, versuche es erneut", - "modelDialogAddDownloadSuccess": "Download erfolgreich", + "modelDialogAddDownloadSuccess": "Download erfolgreich. Als aktuelles Modell festlegen.", "deleteDialogTitle": "Chat löschen", "deleteDialogDescription": "Bist du sicher, dass du fortfahren möchtest? Dies wird alle Erinnerungen dieses Chats löschen und kann nicht rückgängig gemacht werden.\nUm diesen Dialog zu deaktivieren, besuche die Einstellungen.", "deleteDialogDelete": "Löschen", @@ -73,12 +70,11 @@ "settingsExperimentalDeprecatedDescription": "Diese Funktion ist veraltet und wird in einer zukünftigen Version entfernt werden.\nEs funktioniert möglicherweise nicht wie beabsichtigt oder erwartet. Benutzung auf eigenes Gefahr.", "settingsExperimentalDeprecatedFeature": "Veraltete Funktion, halte, um mehr zu erfahren", "settingsHost": "Host", + "settingsHostMissing": "Kein Host festgelegt", "settingsHostValid": "Gültiger Host", "settingsHostChecking": "Host wird Überprüft", - "settingsHostInvalid": "Fehler: {type, select, url{Ungültige URL} host{Ungültiger Host} timeout{Request Fehlgeschlagen. Server Fehler} ratelimit{Zu viele Anfragen} other{Request Fehlgeschlagen}}", - "settingsHostHeaderTitle": "Host-Header festlegen", - "settingsHostHeaderInvalid": "Der eingegebene Text ist kein gültiges Header-JSON-Objekt", - "settingsHostInvalidDetailed": "{type, select, url{Die eingegebene URL ist ungültig. Es handelt sich nicht um ein standardisiertes URL-Format.} other{Der eingegebene Host ist ungültig. Er kann nicht erreicht werden. Bitte überprüfe den Host und versuche es erneut.}}", + "settingsHostInvalid": "{type, select, invalidUrl{Ungültige URL} unreachable{Host nicht erreichbar} undetectable{Host kein Ollama-Server} timeout{Verbindung abgelaufen} outdated{Veraltete Ollama-Version} other{Ungültiger Host}}", + "settingsHostInvalidDetailed": "{type, select, invalidUrl{Die eingegebene URL hat kein gültiges Format.} unreachable{Der Host ist ungültig oder nicht erreichbar, möglicherweise aufgrund einer falschen Adresse oder eines Netzwerkproblems.} undetectable{Der Host ist erreichbar, antwortet aber nicht wie von Ollama App erwartet.\nEr ist möglicherweise kein Ollama-Server. Bist du sicher, dass du ihn richtig eingegeben hast?} timeout{Der Host konnte nicht rechtzeitig erreicht werden.\nVersuche, den Timeout-Multiplikator in den Oberflächen-Einstellungen zu erhöhen.} outdated{Der Host verwendet eine Ollama-Version, die mit dieser App nicht kompatibel ist.\nBitte aktualisiere sowohl den Host als auch diese App, wenn möglich.} other{Der eingegebene Host ist ungültig.}}", "settingsSystemMessage": "Systemnachricht", "settingsUseSystem": "Systemnachricht verwenden", "settingsUseSystemDescription": "Deaktiviere das Setzen der obigen Systemnachricht und benutze stattdessen die des Modells. Kann nützlich für Modelle mit Model-Files sein", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 50b6ad7..63eb52d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,8 +1,24 @@ { "@@locale": "en", - "appTitle": "Ollama", + "appTitle": "{env, select, short{Ollama} integrated{{title} - Ollama App} other{Ollama App}}", "@appTitle": { - "description": "Title of the application", + "description": "Title of the application. Should stay untranslated in most cases", + "context": "app:sidebar", + "placeholders": { + "env": { + "type": "String", + "description": "The environment the app is running in. Can be 'short' on mobile platforms, 'integrated' on web if the app is currently displaying a page, or 'other' in every other case.", + "example": "integrated" + }, + "title": { + "type": "String", + "description": "Title of the chat or settings page currently visible, if visible" + } + } + }, + "learnMore": "Learn more", + "@learnMore": { + "description": "Text displayed for learn more button", "context": "app:sidebar" }, "optionNewChat": "New Chat", @@ -20,9 +36,35 @@ "description": "Text displayed for install PWA option", "context": "app:sidebar" }, - "optionNoChatFound": "No chats found", + "optionNoChatFound": "No chats", "@optionNoChatFound": { - "description": "Text displayed when no chats are found", + "description": "Text displayed when there are no chats", + "context": "app:sidebar" + }, + "optionNoChatFoundSearch": "No chats found for ‘{query}’", + "@optionNoChatFoundSearch": { + "description": "Text displayed when no chats are found for the search query", + "context": "app:sidebar", + "placeholders": { + "query": { + "type": "String", + "description": "The search query that returned no results" + } + } + }, + "optionSearchChats": "Search through chats", + "@optionSearchChats": { + "description": "Placeholder for search chats input", + "context": "app:sidebar" + }, + "optionChatDetails": "Chat details", + "@optionChatDetails": { + "description": "Text displayed as title for chat details sidebar", + "context": "app:sidebar" + }, + "optionChatDetailsNoChat": "No chat selected", + "@optionChatDetailsNoChat": { + "description": "Text displayed when no chat is selected in the chat details sidebar", "context": "app:sidebar" }, "tipPrefix": "Tip: ", @@ -65,34 +107,100 @@ "description": "Text displayed for rename chat option", "context": "app:sidebar" }, - "takeImage": "Take Image", + "takeImage": "Camera", "@takeImage": { "description": "Text displayed for take image button", "context": "app:chat:attachment" }, - "uploadImage": "Upload Image", + "uploadImage": "Gallery", "@uploadImage": { "description": "Text displayed for image upload button", "context": "app:chat:attachment" }, - "notAValidImage": "Not a valid image", - "@notAValidImage": { - "description": "Text displayed when an image is not valid", - "context": "app:chat:attachment" + "newChatGreeting1": "What’s on your mind, {user}?", + "@newChatGreeting1": { + "description": "First greeting displayed in a new chat", + "context": "app:chat:greeting", + "placeholders": { + "user": { + "type": "String", + "description": "Name of the user. If unavailable, 'user' will be used instead.", + "example": "User" + } + } }, - "imageOnlyConversation": "Image Only Conversation", - "@imageOnlyConversation": { - "description": "Title, if 'Generate Title' is executed on a conversation with no text messages", - "context": "app:chat:title" + "newChatGreeting2": "Good to see you, {user}.", + "@newChatGreeting2": { + "description": "Second greeting displayed in a new chat", + "context": "app:chat:greeting", + "placeholders": { + "user": { + "type": "String", + "description": "Name of the user. If unavailable, 'user' will be used instead.", + "example": "User" + } + } }, - "messageInputPlaceholder": "Message", + "newChatGreeting3": "What can I do for you, {user}?", + "@newChatGreeting3": { + "description": "Third greeting displayed in a new chat", + "context": "app:chat:greeting", + "placeholders": { + "user": { + "type": "String", + "description": "Name of the user. If unavailable, 'user' will be used instead.", + "example": "User" + } + } + }, + "newChatGreeting4": "How can I help you today, {user}?", + "@newChatGreeting4": { + "description": "Fourth greeting displayed in a new chat", + "context": "app:chat:greeting", + "placeholders": { + "user": { + "type": "String", + "description": "Name of the user. If unavailable, 'user' will be used instead.", + "example": "User" + } + } + }, + "newChatGreeting5": "What would you like to talk about, {user}?", + "@newChatGreeting5": { + "description": "Fifth greeting displayed in a new chat", + "context": "app:chat:greeting", + "placeholders": { + "user": { + "type": "String", + "description": "Name of the user. If unavailable, 'user' will be used instead.", + "example": "User" + } + } + }, + "newChatGreetingNameFallback": "user", + "@newChatGreetingNameFallback": { + "description": "Fallback name for the user if no name is set", + "context": "app:chat:greeting" + }, + "messageInputPlaceholder": "Ask {model}", "@messageInputPlaceholder": { "description": "Placeholder text for message input", + "context": "app:chat:input", + "placeholders": { + "model": { + "type": "String", + "description": "Friendly name of the model without its tag, so 'gemma3' or 'gpt-oss' for example" + } + } + }, + "messageInputPlaceholderModelPlaceholder": "model", + "@messageInputPlaceholderModelPlaceholder": { + "description": "Model name used in 'messageInputPlaceholder' if no model is available, should fit into capitalization and context", "context": "app:chat:input" }, - "tooltipAttachment": "Add attachment", - "@tooltipAttachment": { - "description": "Tooltip for attachment button", + "tooltipMessageOptions": "Message options", + "@tooltipMessageOptions": { + "description": "Tooltip for message options button; options here being attachments, etc.", "context": "app:chat:tooltips" }, "tooltipSend": "Send", @@ -100,14 +208,20 @@ "description": "Tooltip for send button", "context": "app:chat:tooltips" }, - "tooltipSave": "Save", - "@tooltipSave": { - "description": "Tooltip for save button", - "context": "app:chat:tooltips" - }, - "tooltipLetAIThink": "Let AI think", + "tooltipLetAIThink": "Generate with {model}", "@tooltipLetAIThink": { - "description": "Tooltip for let AI think button", + "description": "Tooltip for generate with model button", + "context": "app:chat:tooltips", + "placeholders": { + "model": { + "type": "String", + "description": "Friendly name of the model without its tag, so 'gemma3' or 'gpt-oss' for example" + } + } + }, + "tooltipAddHostHeaders": "Add host headers", + "@tooltipAddHostHeaders": { + "description": "Tooltip for add host headers button", "context": "app:chat:tooltips" }, "tooltipReset": "Reset current chat", @@ -125,120 +239,97 @@ "description": "Text displayed when no model is selected", "context": "app:chat" }, - "noHostSelected": "No host selected, open settings to set one", + "noHostSelected": "No host selected, open settings to set one.", "@noHostSelected": { "description": "Text displayed when no host is selected", "context": "app:chat" }, - "noSelectedModel": "", + "noSelectedModel": "", "@noSelectedModel": { - "description": "Text displayed when no model is selected", + "description": "Text displayed when no model is selected. Should be lower case even if the language would capitalize it, to fit better into the app's design.", "context": "app:chat" }, - "newChatTitle": "Unnamed Chat", + "newChatTitle": "Untitled Chat", "@newChatTitle": { "description": "Title of a new chat", "context": "app:chat:title" }, - "modelDialogAddModel": "Add", - "@modelDialogAddModel": { + "modelDialogTitle": "Select a model", + "@modelDialogTitle": { + "description": "Title of the model selection dialog", + "context": "app:modelDialog" + }, + "modelDialogAdd": "Add", + "@modelDialogAdd": { "description": "Text displayed for add model button", "context": "app:modelDialog" }, - "modelDialogAddPromptTitle": "Add new model", + "modelDialogRefresh": "Refresh", + "@modelDialogRefresh": { + "description": "Text displayed for refresh models button", + "context": "app:modelDialog" + }, + "modelDialogAddPromptTitle": "Add model", "@modelDialogAddPromptTitle": { "description": "Title of the add model dialog", "context": "app:modelDialog" }, - "modelDialogAddPromptDescription": "This can either be a normal name (e.g. 'llama3') or a name and tag (e.g. 'llama3:70b').", + "modelDialogAddPromptDescription": "This can either be a normal name (e.g. “llama3”) or a name together with a tag (e.g. “llama3:70b”).", "@modelDialogAddPromptDescription": { "description": "Description of the add model dialog", "context": "app:modelDialog" }, - "modelDialogAddPromptAlreadyExists": "Model already exists", + "modelDialogAddCurrently": "Currently downloading:", + "@modelDialogAddCurrently": { + "description": "Text displayed when there are currently downloading models", + "context": "app:modelDialog" + }, + "modelDialogAddPromptAlreadyExists": "Model already exists. Try refreshing if it was deleted.", "@modelDialogAddPromptAlreadyExists": { "description": "Text displayed when the model already exists", "context": "app:modelDialog" }, - "modelDialogAddPromptInvalid": "Invalid model name", + "modelDialogAddPromptInvalid": "Couldn’t read your model name correctly. Please check the spelling and try again.", "@modelDialogAddPromptInvalid": { "description": "Text displayed when the model name is invalid", "context": "app:modelDialog" }, - "modelDialogAddAllowanceTitle": "Allow Proxy", - "@modelDialogAddAllowanceTitle": { - "description": "Title of the allow proxy dialog", + "modelDialogAddPromptNotFound": "Couldn’t find your model on the server. Please check the spelling and try again.", + "@modelDialogAddPromptNotFound": { + "description": "Text displayed when the model could not be found", "context": "app:modelDialog" }, - "modelDialogAddAllowanceDescription": "Ollama App must check if the entered model is valid. To do that, we normally send a web request to the Ollama model list and check the status code, but because you're using the web client, we can't do that directly. Instead, the app will send the request to a different API, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potentially harmful intentions.\nIf you accept, your selection will be remembered for the future; if not, nothing will be sent and the model won't be added.", - "@modelDialogAddAllowanceDescription": { - "description": "Description of the allow proxy dialog", + "modelDialogAddPromptNetworkError": "Network error while checking model. Please check your connection and try again.", + "@modelDialogAddPromptNetworkError": { + "description": "Text displayed when there was a network error while checking the model", "context": "app:modelDialog" }, - "modelDialogAddAllowanceAllow": "Allow", - "@modelDialogAddAllowanceAllow": { - "description": "Text displayed for allow button, should be capitalized", + "modelDialogAddPromptCorruptionError": "The API returned “EOF”; your server was likely restarted while downloading the model previously.", + "@modelDialogAddPromptCorruptionError": { + "description": "Text displayed when the model is corrupted on the server", "context": "app:modelDialog" }, - "modelDialogAddAllowanceDeny": "Deny", - "@modelDialogAddAllowanceDeny": { - "description": "Text displayed for deny button, should be capitalized", + "modelDialogAddPromptCorruptionErrorSolution": "Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.", + "@modelDialogAddPromptCorruptionErrorSolution": { + "description": "Text displayed as solution for the corrupted model error", "context": "app:modelDialog" }, - "modelDialogAddAssuranceTitle": "Add {model}?", - "@modelDialogAddAssuranceTitle": { - "description": "Title of the add model assurance dialog", - "context": "app:modelDialog", - "placeholders": { - "model": { - "type": "String", - "description": "Name of the model to be added" - } - } - }, - "modelDialogAddAssuranceDescription": "Pressing 'Add' will download the model '{model}' directly from the Ollama server to your host.\nThis can take a while depending on your internet connection. The action cannot be canceled.\nIf the app is closed during the download, it will resume if you enter the name into the model dialog again.", - "@modelDialogAddAssuranceDescription": { - "description": "Description of the add model assurance dialog", - "context": "app:modelDialog", - "placeholders": { - "model": { - "type": "String", - "description": "Name of the model to be added" - } - } - }, - "modelDialogAddAssuranceAdd": "Add", - "@modelDialogAddAssuranceAdd": { - "description": "Text displayed for add button, should be capitalized", + "modelDialogAddCancelTitle": "Cancel download?", + "@modelDialogAddCancelTitle": { + "description": "Title of the cancel download dialog", "context": "app:modelDialog" }, - "modelDialogAddAssuranceCancel": "Cancel", - "@modelDialogAddAssuranceCancel": { - "description": "Text displayed for cancel button, should be capitalized", + "modelDialogAddCancelConfirm": "Cancel", + "@modelDialogAddCancelConfirm": { + "description": "Text displayed for cancel download button", "context": "app:modelDialog" }, - "modelDialogAddDownloadPercentLoading": "loading progress", - "@modelDialogAddDownloadPercentLoading": { - "description": "Text displayed while loading the download progress", - "context": "app:modelDialog:download" + "modelDialogAddCancelHide": "Hide", + "@modelDialogAddCancelHide": { + "description": "Text displayed for hide button in cancel download dialog. Hide in the sense of 'hide this dialog'", + "context": "app:modelDialog" }, - "modelDialogAddDownloadPercent": "download at {percent}%", - "@modelDialogAddDownloadPercent": { - "description": "Text displayed while downloading a model", - "context": "app:modelDialog:download", - "placeholders": { - "percent": { - "type": "String", - "description": "Percentage of the download" - } - } - }, - "modelDialogAddDownloadFailed": "Disconnected, try again", - "@modelDialogAddDownloadFailed": { - "description": "Text displayed when the download of a model fails", - "context": "app:modelDialog:download" - }, - "modelDialogAddDownloadSuccess": "Download successful", + "modelDialogAddDownloadSuccess": "Download successful. Set as current model.", "@modelDialogAddDownloadSuccess": { "description": "Text displayed when the download of a model is successful", "context": "app:modelDialog:download" @@ -298,6 +389,16 @@ "description": "Title of the edit message dialog", "context": "app:editMessageDialog" }, + "settingsTitleOverview": "Overview", + "@settingsTitleOverview": { + "description": "Title of the overview settings section", + "context": "app:settings" + }, + "settingsDescriptionOverview": "General settings regarding your host.", + "@settingsDescriptionOverview": { + "description": "Description of the overview settings section", + "context": "app:settings" + }, "settingsTitleBehavior": "Behavior", "@settingsTitleBehavior": { "description": "Title of the behavior settings section", @@ -348,17 +449,12 @@ "description": "Description of the about settings section", "context": "app:settings" }, - "settingsSavedAutomatically": "Settings are saved automatically", - "@settingsSavedAutomatically": { - "description": "Text displayed when settings are saved automatically", - "context": "app:settings" - }, "settingsExperimentalAlpha": "alpha", "@settingsExperimentalAlpha": { "description": "Text displayed when a feature is in alpha phase", "context": "app:settings" }, - "settingsExperimentalAlphaDescription": "This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.", + "settingsExperimentalAlphaDescription": "This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or connected services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.", "@settingsExperimentalAlphaDescription": { "description": "Description of the alpha feature", "context": "app:settings" @@ -373,7 +469,7 @@ "description": "Text displayed when a feature is in beta", "context": "app:settings" }, - "settingsExperimentalBetaDescription": "This feature is in beta and may not work as intended or expected.\nLess severe issues may or may not occur. Damage shouldn't be critical.\nUse at your own risk.", + "settingsExperimentalBetaDescription": "This feature is in beta and may not work as intended or expected.\nLess severe issues may or may not occur. Damage shouldn’t be critical.\nUse at your own risk.", "@settingsExperimentalBetaDescription": { "description": "Description of the beta feature", "context": "app:settings" @@ -403,6 +499,11 @@ "description": "Text displayed as description for host input", "context": "app:settings:host" }, + "settingsHostMissing": "No host set", + "@settingsHostMissing": { + "description": "Text displayed when no host is set", + "context": "app:settings:host" + }, "settingsHostValid": "Valid Host", "@settingsHostValid": { "description": "Text displayed when the host is valid", @@ -413,40 +514,57 @@ "description": "Text displayed when the host is being checked", "context": "app:settings:host" }, - "settingsHostInvalid": "Issue: {type, select, url{Invalid URL} host{Invalid Host} timeout{Request failed. Server issues} ratelimit{Too many requests} other{Request Failed}}", + "settingsHostInvalid": "{type, select, invalidUrl{Invalid URL} unreachable{Host unreachable} undetectable{Host not an Ollama server} timeout{Connection timed out} outdated{Outdated Ollama version} other{Invalid host}}", "@settingsHostInvalid": { - "description": "Text displayed when the host is invalid", + "description": "Short title displayed when the host is invalid", "context": "app:settings:host", "placeholders": { "type": { "type": "String", - "description": "Type of the issue, either 'url', 'host', 'timeout', 'ratelimit' or 'other' (preferably 'host')" + "description": "Type of the issue, either 'invalidUrl', 'unreachable', 'undetectable', 'timeout' or 'outdated'. See `lib/services/host.dart` for more information." } } }, - "tooltipAddHostHeaders": "Add host headers", - "@tooltipAddHostHeaders": { - "description": "Tooltip for add host headers button", - "context": "app:settings:host" - }, - "settingsHostHeaderTitle": "Set host header", - "@settingsHostHeaderTitle": { - "description": "Text displayed as description for host header input", - "context": "app:settings:host" - }, - "settingsHostHeaderInvalid": "The entered text isn't a valid header JSON object", - "@settingsHostHeaderInvalid": { - "description": "Text displayed when the host header is invalid", - "context": "app:settings:host" - }, - "settingsHostInvalidDetailed": "{type, select, url{The URL you entered is invalid. It isn't in a standardized URL format.} other{The host you entered is invalid. It cannot be reached. Please check the host and try again.}}", + "settingsHostInvalidDetailed": "{type, select, invalidUrl{The URL you entered isn’t in a valid format.} unreachable{The host is invalid or unreachable, possibly due to a wrong address or network issue.} undetectable{The host is reachable but doesn’t respond as expected by Ollama App.\nIt may not be an Ollama server. Are you sure you entered it correctly?} timeout{The host couldn’t be reached in time.\nTry increasing the timeout multiplier in interface settings.} outdated{The host is running an Ollama version incompatible with this app.\nPlease update both the host and this app, if possible.} other{The host you entered is invalid.}}", "@settingsHostInvalidDetailed": { - "description": "Text displayed when the host is invalid", + "description": "Detailed text displayed when the host is invalid", "context": "app:settings:host", "placeholders": { "type": { "type": "String", - "description": "Type of the issue, either 'url' or 'other' (preferably 'host')" + "description": "Type of the issue, either 'invalidUrl', 'unreachable', 'undetectable', 'timeout' or 'outdated'. See `lib/services/host.dart` for more information." + } + } + }, + "settingsHostHeaderHeaderName": "Header", + "@settingsHostHeaderHeaderName": { + "description": "Text displayed as description for host header name input", + "context": "app:settings:host" + }, + "settingsHostHeaderHeaderValue": "Value", + "@settingsHostHeaderHeaderValue": { + "description": "Text displayed as description for host header value input", + "context": "app:settings:host" + }, + "settingsHostHeaderUnsupported": "The header “{header}” may not be supported.", + "@settingsHostHeaderUnsupported": { + "description": "Text displayed when a host header is unsupported", + "context": "app:settings:host", + "placeholders": { + "header": { + "type": "String", + "description": "The name of the unsupported header" + } + } + }, + "settingsHostHeaderDuplicate": "The header “{header}” is already set.", + "@settingsHostHeaderDuplicate": { + "description": "Text displayed when a host header is a duplicate", + "context": "app:settings:host", + "placeholders": { + "header": { + "type": "String", + "description": "The name of the duplicate header" } } }, @@ -460,7 +578,7 @@ "description": "Text displayed as description for use system message toggle", "context": "app:settings:behavior" }, - "settingsUseSystemDescription": "Disables setting the system message above and uses the one from the model's Modelfile instead. Can be useful for models with model files.", + "settingsUseSystemDescription": "Disables setting the system message above and uses the one from the model’s Modelfile instead. Can be useful for models with model files.", "@settingsUseSystemDescription": { "description": "Description of the use system message toggle", "context": "app:settings:behavior" @@ -525,7 +643,7 @@ "description": "Text displayed as description for keep model loaded always toggle", "context": "app:settings:interface:keepModelLoaded" }, - "settingsKeepModelLoadedNever": "Don't keep model loaded", + "settingsKeepModelLoadedNever": "Don’t keep model loaded", "@settingsKeepModelLoadedNever": { "description": "Text displayed as description for don't keep model loaded toggle", "context": "app:settings:interface:keepModelLoaded" @@ -606,7 +724,7 @@ "description": "Description of the temporary fixes section", "context": "app:settings:interface:temporaryFixes" }, - "settingsTemporaryFixesInstructions": "Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.", + "settingsTemporaryFixesInstructions": "Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey should not be considered final or judged as such. Issues might occur.", "@settingsTemporaryFixesInstructions": { "description": "Instructions and warnings for the temporary fixes", "context": "app:settings:interface:temporaryFixes" @@ -616,7 +734,7 @@ "description": "Text displayed when no fixes are available", "context": "app:settings:interface:temporaryFixes" }, - "settingsVoicePermissionLoading": "Loading voice permissions ...", + "settingsVoicePermissionLoading": "Loading voice permissions...", "@settingsVoicePermissionLoading": { "description": "Text displayed while loading voice permissions", "context": "app:settings:voice" @@ -706,12 +824,12 @@ "description": "Text displayed when chats are imported successfully", "context": "app:settings:export" }, - "settingsExportInfo": "These options allow you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or back up your chat history", + "settingsExportInfo": "These options allow you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or back up your chat history.", "@settingsExportInfo": { "description": "Information displayed for export and import options", "context": "app:settings:export" }, - "settingsExportWarning": "Multiple chat histories won't be merged! You'll lose your current chat history if you import a new one.", + "settingsExportWarning": "Multiple chat histories won’t be merged! You’ll lose your current chat history if you import a new one.", "@settingsExportWarning": { "description": "Warning displayed for export and import options", "context": "app:settings:export" @@ -721,7 +839,7 @@ "description": "Text displayed as description for check for updates button", "context": "app:settings:info" }, - "settingsUpdateChecking": "Checking for updates ...", + "settingsUpdateChecking": "Checking for updates...", "@settingsUpdateChecking": { "description": "Text displayed while looking for updates", "context": "app:settings:info" @@ -742,7 +860,7 @@ } } }, - "settingsUpdateRateLimit": "Can't check, API rate limit exceeded", + "settingsUpdateRateLimit": "Can’t check, API rate limit exceeded", "@settingsUpdateRateLimit": { "description": "Text displayed when the API rate limit is exceeded", "context": "app:settings:info" @@ -777,7 +895,7 @@ "description": "Text displayed for cancel button, should be capitalized", "context": "app:settings:info" }, - "settingsCheckForUpdates": "Check for updates on open", + "settingsCheckForUpdates": "Check for updates on startup", "@settingsCheckForUpdates": { "description": "Text displayed as description for check for updates toggle", "context": "app:settings:info" diff --git a/lib/l10n/gen/app_localizations.dart b/lib/l10n/gen/app_localizations.dart index 073285e..abe8d0a 100644 --- a/lib/l10n/gen/app_localizations.dart +++ b/lib/l10n/gen/app_localizations.dart @@ -106,11 +106,17 @@ abstract class AppLocalizations { Locale('zh'), ]; - /// Title of the application + /// Title of the application. Should stay untranslated in most cases /// /// In en, this message translates to: - /// **'Ollama'** - String get appTitle; + /// **'{env, select, short{Ollama} integrated{{title} - Ollama App} other{Ollama App}}'** + String appTitle(String env, String title); + + /// Text displayed for learn more button + /// + /// In en, this message translates to: + /// **'Learn more'** + String get learnMore; /// Text displayed for new chat option /// @@ -130,12 +136,36 @@ abstract class AppLocalizations { /// **'Install Webapp'** String get optionInstallPwa; - /// Text displayed when no chats are found + /// Text displayed when there are no chats /// /// In en, this message translates to: - /// **'No chats found'** + /// **'No chats'** String get optionNoChatFound; + /// Text displayed when no chats are found for the search query + /// + /// In en, this message translates to: + /// **'No chats found for ‘{query}’'** + String optionNoChatFoundSearch(String query); + + /// Placeholder for search chats input + /// + /// In en, this message translates to: + /// **'Search through chats'** + String get optionSearchChats; + + /// Text displayed as title for chat details sidebar + /// + /// In en, this message translates to: + /// **'Chat details'** + String get optionChatDetails; + + /// Text displayed when no chat is selected in the chat details sidebar + /// + /// In en, this message translates to: + /// **'No chat selected'** + String get optionChatDetailsNoChat; + /// Prefix for tips /// /// In en, this message translates to: @@ -187,38 +217,68 @@ abstract class AppLocalizations { /// Text displayed for take image button /// /// In en, this message translates to: - /// **'Take Image'** + /// **'Camera'** String get takeImage; /// Text displayed for image upload button /// /// In en, this message translates to: - /// **'Upload Image'** + /// **'Gallery'** String get uploadImage; - /// Text displayed when an image is not valid + /// First greeting displayed in a new chat /// /// In en, this message translates to: - /// **'Not a valid image'** - String get notAValidImage; + /// **'What’s on your mind, {user}?'** + String newChatGreeting1(String user); - /// Title, if 'Generate Title' is executed on a conversation with no text messages + /// Second greeting displayed in a new chat /// /// In en, this message translates to: - /// **'Image Only Conversation'** - String get imageOnlyConversation; + /// **'Good to see you, {user}.'** + String newChatGreeting2(String user); + + /// Third greeting displayed in a new chat + /// + /// In en, this message translates to: + /// **'What can I do for you, {user}?'** + String newChatGreeting3(String user); + + /// Fourth greeting displayed in a new chat + /// + /// In en, this message translates to: + /// **'How can I help you today, {user}?'** + String newChatGreeting4(String user); + + /// Fifth greeting displayed in a new chat + /// + /// In en, this message translates to: + /// **'What would you like to talk about, {user}?'** + String newChatGreeting5(String user); + + /// Fallback name for the user if no name is set + /// + /// In en, this message translates to: + /// **'user'** + String get newChatGreetingNameFallback; /// Placeholder text for message input /// /// In en, this message translates to: - /// **'Message'** - String get messageInputPlaceholder; + /// **'Ask {model}'** + String messageInputPlaceholder(String model); - /// Tooltip for attachment button + /// Model name used in 'messageInputPlaceholder' if no model is available, should fit into capitalization and context /// /// In en, this message translates to: - /// **'Add attachment'** - String get tooltipAttachment; + /// **'model'** + String get messageInputPlaceholderModelPlaceholder; + + /// Tooltip for message options button; options here being attachments, etc. + /// + /// In en, this message translates to: + /// **'Message options'** + String get tooltipMessageOptions; /// Tooltip for send button /// @@ -226,17 +286,17 @@ abstract class AppLocalizations { /// **'Send'** String get tooltipSend; - /// Tooltip for save button + /// Tooltip for generate with model button /// /// In en, this message translates to: - /// **'Save'** - String get tooltipSave; + /// **'Generate with {model}'** + String tooltipLetAIThink(String model); - /// Tooltip for let AI think button + /// Tooltip for add host headers button /// /// In en, this message translates to: - /// **'Let AI think'** - String get tooltipLetAIThink; + /// **'Add host headers'** + String get tooltipAddHostHeaders; /// Tooltip for reset button /// @@ -259,121 +319,115 @@ abstract class AppLocalizations { /// Text displayed when no host is selected /// /// In en, this message translates to: - /// **'No host selected, open settings to set one'** + /// **'No host selected, open settings to set one.'** String get noHostSelected; - /// Text displayed when no model is selected + /// Text displayed when no model is selected. Should be lower case even if the language would capitalize it, to fit better into the app's design. /// /// In en, this message translates to: - /// **''** + /// **''** String get noSelectedModel; /// Title of a new chat /// /// In en, this message translates to: - /// **'Unnamed Chat'** + /// **'Untitled Chat'** String get newChatTitle; + /// Title of the model selection dialog + /// + /// In en, this message translates to: + /// **'Select a model'** + String get modelDialogTitle; + /// Text displayed for add model button /// /// In en, this message translates to: /// **'Add'** - String get modelDialogAddModel; + String get modelDialogAdd; + + /// Text displayed for refresh models button + /// + /// In en, this message translates to: + /// **'Refresh'** + String get modelDialogRefresh; /// Title of the add model dialog /// /// In en, this message translates to: - /// **'Add new model'** + /// **'Add model'** String get modelDialogAddPromptTitle; /// Description of the add model dialog /// /// In en, this message translates to: - /// **'This can either be a normal name (e.g. \'llama3\') or a name and tag (e.g. \'llama3:70b\').'** + /// **'This can either be a normal name (e.g. “llama3”) or a name together with a tag (e.g. “llama3:70b”).'** String get modelDialogAddPromptDescription; + /// Text displayed when there are currently downloading models + /// + /// In en, this message translates to: + /// **'Currently downloading:'** + String get modelDialogAddCurrently; + /// Text displayed when the model already exists /// /// In en, this message translates to: - /// **'Model already exists'** + /// **'Model already exists. Try refreshing if it was deleted.'** String get modelDialogAddPromptAlreadyExists; /// Text displayed when the model name is invalid /// /// In en, this message translates to: - /// **'Invalid model name'** + /// **'Couldn’t read your model name correctly. Please check the spelling and try again.'** String get modelDialogAddPromptInvalid; - /// Title of the allow proxy dialog + /// Text displayed when the model could not be found /// /// In en, this message translates to: - /// **'Allow Proxy'** - String get modelDialogAddAllowanceTitle; + /// **'Couldn’t find your model on the server. Please check the spelling and try again.'** + String get modelDialogAddPromptNotFound; - /// Description of the allow proxy dialog + /// Text displayed when there was a network error while checking the model /// /// In en, this message translates to: - /// **'Ollama App must check if the entered model is valid. To do that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different API, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potentially harmful intentions.\nIf you accept, your selection will be remembered for the future; if not, nothing will be sent and the model won\'t be added.'** - String get modelDialogAddAllowanceDescription; + /// **'Network error while checking model. Please check your connection and try again.'** + String get modelDialogAddPromptNetworkError; - /// Text displayed for allow button, should be capitalized + /// Text displayed when the model is corrupted on the server /// /// In en, this message translates to: - /// **'Allow'** - String get modelDialogAddAllowanceAllow; + /// **'The API returned “EOF”; your server was likely restarted while downloading the model previously.'** + String get modelDialogAddPromptCorruptionError; - /// Text displayed for deny button, should be capitalized + /// Text displayed as solution for the corrupted model error /// /// In en, this message translates to: - /// **'Deny'** - String get modelDialogAddAllowanceDeny; + /// **'Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.'** + String get modelDialogAddPromptCorruptionErrorSolution; - /// Title of the add model assurance dialog + /// Title of the cancel download dialog /// /// In en, this message translates to: - /// **'Add {model}?'** - String modelDialogAddAssuranceTitle(String model); + /// **'Cancel download?'** + String get modelDialogAddCancelTitle; - /// Description of the add model assurance dialog - /// - /// In en, this message translates to: - /// **'Pressing \'Add\' will download the model \'{model}\' directly from the Ollama server to your host.\nThis can take a while depending on your internet connection. The action cannot be canceled.\nIf the app is closed during the download, it will resume if you enter the name into the model dialog again.'** - String modelDialogAddAssuranceDescription(String model); - - /// Text displayed for add button, should be capitalized - /// - /// In en, this message translates to: - /// **'Add'** - String get modelDialogAddAssuranceAdd; - - /// Text displayed for cancel button, should be capitalized + /// Text displayed for cancel download button /// /// In en, this message translates to: /// **'Cancel'** - String get modelDialogAddAssuranceCancel; + String get modelDialogAddCancelConfirm; - /// Text displayed while loading the download progress + /// Text displayed for hide button in cancel download dialog. Hide in the sense of 'hide this dialog' /// /// In en, this message translates to: - /// **'loading progress'** - String get modelDialogAddDownloadPercentLoading; - - /// Text displayed while downloading a model - /// - /// In en, this message translates to: - /// **'download at {percent}%'** - String modelDialogAddDownloadPercent(String percent); - - /// Text displayed when the download of a model fails - /// - /// In en, this message translates to: - /// **'Disconnected, try again'** - String get modelDialogAddDownloadFailed; + /// **'Hide'** + String get modelDialogAddCancelHide; /// Text displayed when the download of a model is successful /// /// In en, this message translates to: - /// **'Download successful'** + /// **'Download successful. Set as current model.'** String get modelDialogAddDownloadSuccess; /// Title of the delete dialog @@ -442,6 +496,18 @@ abstract class AppLocalizations { /// **'Edit message'** String get dialogEditMessageTitle; + /// Title of the overview settings section + /// + /// In en, this message translates to: + /// **'Overview'** + String get settingsTitleOverview; + + /// Description of the overview settings section + /// + /// In en, this message translates to: + /// **'General settings regarding your host.'** + String get settingsDescriptionOverview; + /// Title of the behavior settings section /// /// In en, this message translates to: @@ -502,12 +568,6 @@ abstract class AppLocalizations { /// **'Check for updates and learn more about Ollama App.'** String get settingsDescriptionAbout; - /// Text displayed when settings are saved automatically - /// - /// In en, this message translates to: - /// **'Settings are saved automatically'** - String get settingsSavedAutomatically; - /// Text displayed when a feature is in alpha phase /// /// In en, this message translates to: @@ -517,7 +577,7 @@ abstract class AppLocalizations { /// Description of the alpha feature /// /// In en, this message translates to: - /// **'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.'** + /// **'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or connected services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.'** String get settingsExperimentalAlphaDescription; /// Text displayed when a feature is in alpha @@ -535,7 +595,7 @@ abstract class AppLocalizations { /// Description of the beta feature /// /// In en, this message translates to: - /// **'This feature is in beta and may not work as intended or expected.\nLess severe issues may or may not occur. Damage shouldn\'t be critical.\nUse at your own risk.'** + /// **'This feature is in beta and may not work as intended or expected.\nLess severe issues may or may not occur. Damage shouldn’t be critical.\nUse at your own risk.'** String get settingsExperimentalBetaDescription; /// Text displayed when a feature is in beta @@ -568,6 +628,12 @@ abstract class AppLocalizations { /// **'Host'** String get settingsHost; + /// Text displayed when no host is set + /// + /// In en, this message translates to: + /// **'No host set'** + String get settingsHostMissing; + /// Text displayed when the host is valid /// /// In en, this message translates to: @@ -580,36 +646,42 @@ abstract class AppLocalizations { /// **'Checking Host'** String get settingsHostChecking; - /// Text displayed when the host is invalid + /// Short title displayed when the host is invalid /// /// In en, this message translates to: - /// **'Issue: {type, select, url{Invalid URL} host{Invalid Host} timeout{Request failed. Server issues} ratelimit{Too many requests} other{Request Failed}}'** + /// **'{type, select, invalidUrl{Invalid URL} unreachable{Host unreachable} undetectable{Host not an Ollama server} timeout{Connection timed out} outdated{Outdated Ollama version} other{Invalid host}}'** String settingsHostInvalid(String type); - /// Tooltip for add host headers button + /// Detailed text displayed when the host is invalid /// /// In en, this message translates to: - /// **'Add host headers'** - String get tooltipAddHostHeaders; - - /// Text displayed as description for host header input - /// - /// In en, this message translates to: - /// **'Set host header'** - String get settingsHostHeaderTitle; - - /// Text displayed when the host header is invalid - /// - /// In en, this message translates to: - /// **'The entered text isn\'t a valid header JSON object'** - String get settingsHostHeaderInvalid; - - /// Text displayed when the host is invalid - /// - /// In en, this message translates to: - /// **'{type, select, url{The URL you entered is invalid. It isn\'t in a standardized URL format.} other{The host you entered is invalid. It cannot be reached. Please check the host and try again.}}'** + /// **'{type, select, invalidUrl{The URL you entered isn’t in a valid format.} unreachable{The host is invalid or unreachable, possibly due to a wrong address or network issue.} undetectable{The host is reachable but doesn’t respond as expected by Ollama App.\nIt may not be an Ollama server. Are you sure you entered it correctly?} timeout{The host couldn’t be reached in time.\nTry increasing the timeout multiplier in interface settings.} outdated{The host is running an Ollama version incompatible with this app.\nPlease update both the host and this app, if possible.} other{The host you entered is invalid.}}'** String settingsHostInvalidDetailed(String type); + /// Text displayed as description for host header name input + /// + /// In en, this message translates to: + /// **'Header'** + String get settingsHostHeaderHeaderName; + + /// Text displayed as description for host header value input + /// + /// In en, this message translates to: + /// **'Value'** + String get settingsHostHeaderHeaderValue; + + /// Text displayed when a host header is unsupported + /// + /// In en, this message translates to: + /// **'The header “{header}” may not be supported.'** + String settingsHostHeaderUnsupported(String header); + + /// Text displayed when a host header is a duplicate + /// + /// In en, this message translates to: + /// **'The header “{header}” is already set.'** + String settingsHostHeaderDuplicate(String header); + /// Text displayed as description for system message input /// /// In en, this message translates to: @@ -625,7 +697,7 @@ abstract class AppLocalizations { /// Description of the use system message toggle /// /// In en, this message translates to: - /// **'Disables setting the system message above and uses the one from the model\'s Modelfile instead. Can be useful for models with model files.'** + /// **'Disables setting the system message above and uses the one from the model’s Modelfile instead. Can be useful for models with model files.'** String get settingsUseSystemDescription; /// Text displayed as description for disable markdown toggle @@ -703,7 +775,7 @@ abstract class AppLocalizations { /// Text displayed as description for don't keep model loaded toggle /// /// In en, this message translates to: - /// **'Don\'t keep model loaded'** + /// **'Don’t keep model loaded'** String get settingsKeepModelLoadedNever; /// Text displayed as description for keep model loaded for toggle @@ -793,7 +865,7 @@ abstract class AppLocalizations { /// Instructions and warnings for the temporary fixes /// /// In en, this message translates to: - /// **'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.'** + /// **'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey should not be considered final or judged as such. Issues might occur.'** String get settingsTemporaryFixesInstructions; /// Text displayed when no fixes are available @@ -805,7 +877,7 @@ abstract class AppLocalizations { /// Text displayed while loading voice permissions /// /// In en, this message translates to: - /// **'Loading voice permissions ...'** + /// **'Loading voice permissions...'** String get settingsVoicePermissionLoading; /// Text displayed when text-to-speech is not supported @@ -913,13 +985,13 @@ abstract class AppLocalizations { /// Information displayed for export and import options /// /// In en, this message translates to: - /// **'These options allow you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or back up your chat history'** + /// **'These options allow you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or back up your chat history.'** String get settingsExportInfo; /// Warning displayed for export and import options /// /// In en, this message translates to: - /// **'Multiple chat histories won\'t be merged! You\'ll lose your current chat history if you import a new one.'** + /// **'Multiple chat histories won’t be merged! You’ll lose your current chat history if you import a new one.'** String get settingsExportWarning; /// Text displayed as description for check for updates button @@ -931,7 +1003,7 @@ abstract class AppLocalizations { /// Text displayed while looking for updates /// /// In en, this message translates to: - /// **'Checking for updates ...'** + /// **'Checking for updates...'** String get settingsUpdateChecking; /// Text displayed when the app is up to date @@ -949,7 +1021,7 @@ abstract class AppLocalizations { /// Text displayed when the API rate limit is exceeded /// /// In en, this message translates to: - /// **'Can\'t check, API rate limit exceeded'** + /// **'Can’t check, API rate limit exceeded'** String get settingsUpdateRateLimit; /// Text displayed when an issue occurs while checking for updates @@ -991,7 +1063,7 @@ abstract class AppLocalizations { /// Text displayed as description for check for updates toggle /// /// In en, this message translates to: - /// **'Check for updates on open'** + /// **'Check for updates on startup'** String get settingsCheckForUpdates; /// Text displayed as description for GitHub button diff --git a/lib/l10n/gen/app_localizations_de.dart b/lib/l10n/gen/app_localizations_de.dart index 606409f..3bc0f00 100644 --- a/lib/l10n/gen/app_localizations_de.dart +++ b/lib/l10n/gen/app_localizations_de.dart @@ -9,7 +9,17 @@ class AppLocalizationsDe extends AppLocalizations { AppLocalizationsDe([String locale = 'de']) : super(locale); @override - String get appTitle => 'Ollama'; + String appTitle(String env, String title) { + String _temp0 = intl.Intl.selectLogic(env, { + 'short': 'Ollama', + 'integrated': '$title - Ollama App', + 'other': 'Ollama App', + }); + return '$_temp0'; + } + + @override + String get learnMore => 'Mehr erfahren'; @override String get optionNewChat => 'Neuer Chat'; @@ -21,7 +31,21 @@ class AppLocalizationsDe extends AppLocalizations { String get optionInstallPwa => 'Webapp installieren'; @override - String get optionNoChatFound => 'Keine Chats gefunden'; + String get optionNoChatFound => 'Keine Chats'; + + @override + String optionNoChatFoundSearch(String query) { + return 'Keinen Chat gefunden für Suche ‚$query‘'; + } + + @override + String get optionSearchChats => 'Chats durchsuchen'; + + @override + String get optionChatDetails => 'Chat details'; + + @override + String get optionChatDetailsNoChat => 'No chat selected'; @override String get tipPrefix => 'Tipp: '; @@ -54,25 +78,54 @@ class AppLocalizationsDe extends AppLocalizations { String get uploadImage => 'Bild Hochladen'; @override - String get notAValidImage => 'Kein gültiges Bild'; + String newChatGreeting1(String user) { + return 'What’s on your mind, $user?'; + } @override - String get imageOnlyConversation => 'Nur Bild Unterhaltung'; + String newChatGreeting2(String user) { + return 'Good to see you, $user.'; + } @override - String get messageInputPlaceholder => 'Nachricht'; + String newChatGreeting3(String user) { + return 'What can I do for you, $user?'; + } @override - String get tooltipAttachment => 'Anhang hinzufügen'; + String newChatGreeting4(String user) { + return 'How can I help you today, $user?'; + } + + @override + String newChatGreeting5(String user) { + return 'What would you like to talk about, $user?'; + } + + @override + String get newChatGreetingNameFallback => 'user'; + + @override + String messageInputPlaceholder(String model) { + return '$model fragen'; + } + + @override + String get messageInputPlaceholderModelPlaceholder => 'Modell'; + + @override + String get tooltipMessageOptions => 'Nachrichtenoptionen'; @override String get tooltipSend => 'Senden'; @override - String get tooltipSave => 'Speichern'; + String tooltipLetAIThink(String model) { + return 'Mit $model generieren'; + } @override - String get tooltipLetAIThink => 'Lass KI denken'; + String get tooltipAddHostHeaders => 'Host-Header festlegen'; @override String get tooltipReset => 'Aktuellen Chat zurücksetzen'; @@ -85,72 +138,67 @@ class AppLocalizationsDe extends AppLocalizations { @override String get noHostSelected => - 'Kein Host ausgewählt, öffne zum Auswählen die Einstellungen'; + 'Kein Host ausgewählt, öffne zum Auswählen die Einstellungen.'; @override - String get noSelectedModel => ''; + String get noSelectedModel => ''; @override String get newChatTitle => 'Unbenannter Chat'; @override - String get modelDialogAddModel => 'Hinzufügen'; + String get modelDialogTitle => 'Select a model'; @override - String get modelDialogAddPromptTitle => 'Neues Modell hinzufügen'; + String get modelDialogAdd => 'Hinzufügen'; + + @override + String get modelDialogRefresh => 'Refresh'; + + @override + String get modelDialogAddPromptTitle => 'Modell hinzufügen'; @override String get modelDialogAddPromptDescription => - 'Das kann entweder ein normaler Name (z.B. \'llama3\') oder Name und Tag (z.B. \'llama3:70b\') sein.'; + 'Das kann entweder ein normaler Name (z.B. „llama3“) oder ein Name zusammen mit einem Tag (z.B. „llama3:70b“) sein.'; @override - String get modelDialogAddPromptAlreadyExists => 'Modell existiert bereits'; + String get modelDialogAddCurrently => 'Wird gerade heruntergeladen:'; @override - String get modelDialogAddPromptInvalid => 'Ungültiger Modellname'; + String get modelDialogAddPromptAlreadyExists => 'Modell existiert bereits.'; @override - String get modelDialogAddAllowanceTitle => 'Proxy erlauben'; + String get modelDialogAddPromptInvalid => 'Ungültiger Modellname.'; @override - String get modelDialogAddAllowanceDescription => - 'Ollama App muss überprüfen, ob das eingegebene Modell gültig ist. Dafür senden wir normalerweise eine Webanfrage an die Ollama-Modellliste und überprüfen den Statuscode, aber da gerade der Webclient verwendet wird, können wir das nicht direkt tun. Stattdessen sendet die App die Anfrage an eine andere API, gehostet von JHubi1, um dies für uns zu überprüfen.\nDies ist eine einmalige Anfrage und wird nur gesendet, wenn du ein neues Modell hinzufügst.\nIhre IP-Adresse wird mit der Anfrage gesendet und kann bis zu zehn Minuten gespeichert werden, um Spamming mit potenziell schädlichen Absichten zu verhindern.\nWenn du zustimmst, wird deine Auswahl für die Zukunft gespeichert; wenn nicht, wird nichts gesendet und das Modell wird nicht hinzugefügt.'; + String get modelDialogAddPromptNotFound => + 'Das Modell konnte auf dem Server nicht gefunden werden. Bitte überprüfe die Schreibweise und versuche es erneut.'; @override - String get modelDialogAddAllowanceAllow => 'Erlauben'; + String get modelDialogAddPromptNetworkError => + 'Netzwerkfehler beim Überprüfen des Modells. Bitte überprüfe deine Verbindung und versuche es erneut.'; @override - String get modelDialogAddAllowanceDeny => 'Ablehnen'; + String get modelDialogAddPromptCorruptionError => + 'Die API hat „EOF“ zurückgegeben; dein Server wurde wahrscheinlich neu gestartet, während das Modell zuvor heruntergeladen wurde.'; @override - String modelDialogAddAssuranceTitle(String model) { - return '$model hinzufügen?'; - } + String get modelDialogAddPromptCorruptionErrorSolution => + 'Alternativ kannst du den folgenden Befehl direkt auf deinem Linux-Host ausführen:\nWenn du eine neue Fehlermeldung siehst, versuche den Befehl mit „sudo“ davor auszuführen.'; @override - String modelDialogAddAssuranceDescription(String model) { - return 'Durch Drücken von \'Hinzufügen\' wird das Modell \'$model\' direkt vom Ollama-Server auf deinen Host heruntergeladen.\nJe nach Internetverbindung kann dies eine Weile dauern. Der Vorgang kann nicht abgebrochen werden.\nWenn die App während des Downloads geschlossen wird, wird der Download fortgesetzt, wenn du den Namen erneut in den Modelldialog eingibst.'; - } + String get modelDialogAddCancelTitle => 'Download abbrechen?'; @override - String get modelDialogAddAssuranceAdd => 'Hinzufügen'; + String get modelDialogAddCancelConfirm => 'Abbrechen'; @override - String get modelDialogAddAssuranceCancel => 'Abbrechen'; + String get modelDialogAddCancelHide => 'Ausblenden'; @override - String get modelDialogAddDownloadPercentLoading => 'lade Fortschritt'; - - @override - String modelDialogAddDownloadPercent(String percent) { - return 'Download bei $percent%'; - } - - @override - String get modelDialogAddDownloadFailed => 'Getrennt, versuche es erneut'; - - @override - String get modelDialogAddDownloadSuccess => 'Download erfolgreich'; + String get modelDialogAddDownloadSuccess => + 'Download erfolgreich. Als aktuelles Modell festlegen.'; @override String get deleteDialogTitle => 'Chat löschen'; @@ -186,6 +234,13 @@ class AppLocalizationsDe extends AppLocalizations { @override String get dialogEditMessageTitle => 'Nachricht bearbeiten'; + @override + String get settingsTitleOverview => 'Overview'; + + @override + String get settingsDescriptionOverview => + 'General settings regarding your host.'; + @override String get settingsTitleBehavior => 'Verhalten'; @@ -221,10 +276,6 @@ class AppLocalizationsDe extends AppLocalizations { String get settingsDescriptionAbout => 'Suche nach Updates und erfahre mehr über Ollama App.'; - @override - String get settingsSavedAutomatically => - 'Einstellungen werden automatisch gespeichert'; - @override String get settingsExperimentalAlpha => 'alpha'; @@ -261,6 +312,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get settingsHost => 'Host'; + @override + String get settingsHostMissing => 'Kein Host festgelegt'; + @override String get settingsHostValid => 'Gültiger Host'; @@ -270,36 +324,49 @@ class AppLocalizationsDe extends AppLocalizations { @override String settingsHostInvalid(String type) { String _temp0 = intl.Intl.selectLogic(type, { - 'url': 'Ungültige URL', - 'host': 'Ungültiger Host', - 'timeout': 'Request Fehlgeschlagen. Server Fehler', - 'ratelimit': 'Zu viele Anfragen', - 'other': 'Request Fehlgeschlagen', + 'invalidUrl': 'Ungültige URL', + 'unreachable': 'Host nicht erreichbar', + 'undetectable': 'Host kein Ollama-Server', + 'timeout': 'Verbindung abgelaufen', + 'outdated': 'Veraltete Ollama-Version', + 'other': 'Ungültiger Host', }); - return 'Fehler: $_temp0'; + return '$_temp0'; } - @override - String get tooltipAddHostHeaders => 'Host-Header festlegen'; - - @override - String get settingsHostHeaderTitle => 'Host-Header festlegen'; - - @override - String get settingsHostHeaderInvalid => - 'Der eingegebene Text ist kein gültiges Header-JSON-Objekt'; - @override String settingsHostInvalidDetailed(String type) { String _temp0 = intl.Intl.selectLogic(type, { - 'url': - 'Die eingegebene URL ist ungültig. Es handelt sich nicht um ein standardisiertes URL-Format.', - 'other': - 'Der eingegebene Host ist ungültig. Er kann nicht erreicht werden. Bitte überprüfe den Host und versuche es erneut.', + 'invalidUrl': 'Die eingegebene URL hat kein gültiges Format.', + 'unreachable': + 'Der Host ist ungültig oder nicht erreichbar, möglicherweise aufgrund einer falschen Adresse oder eines Netzwerkproblems.', + 'undetectable': + 'Der Host ist erreichbar, antwortet aber nicht wie von Ollama App erwartet.\nEr ist möglicherweise kein Ollama-Server. Bist du sicher, dass du ihn richtig eingegeben hast?', + 'timeout': + 'Der Host konnte nicht rechtzeitig erreicht werden.\nVersuche, den Timeout-Multiplikator in den Oberflächen-Einstellungen zu erhöhen.', + 'outdated': + 'Der Host verwendet eine Ollama-Version, die mit dieser App nicht kompatibel ist.\nBitte aktualisiere sowohl den Host als auch diese App, wenn möglich.', + 'other': 'Der eingegebene Host ist ungültig.', }); return '$_temp0'; } + @override + String get settingsHostHeaderHeaderName => 'Header'; + + @override + String get settingsHostHeaderHeaderValue => 'Value'; + + @override + String settingsHostHeaderUnsupported(String header) { + return 'The header “$header” may not be supported.'; + } + + @override + String settingsHostHeaderDuplicate(String header) { + return 'The header “$header” is already set.'; + } + @override String get settingsSystemMessage => 'Systemnachricht'; diff --git a/lib/l10n/gen/app_localizations_en.dart b/lib/l10n/gen/app_localizations_en.dart index 9a1ab3d..e22d30d 100644 --- a/lib/l10n/gen/app_localizations_en.dart +++ b/lib/l10n/gen/app_localizations_en.dart @@ -9,7 +9,17 @@ class AppLocalizationsEn extends AppLocalizations { AppLocalizationsEn([String locale = 'en']) : super(locale); @override - String get appTitle => 'Ollama'; + String appTitle(String env, String title) { + String _temp0 = intl.Intl.selectLogic(env, { + 'short': 'Ollama', + 'integrated': '$title - Ollama App', + 'other': 'Ollama App', + }); + return '$_temp0'; + } + + @override + String get learnMore => 'Learn more'; @override String get optionNewChat => 'New Chat'; @@ -21,7 +31,21 @@ class AppLocalizationsEn extends AppLocalizations { String get optionInstallPwa => 'Install Webapp'; @override - String get optionNoChatFound => 'No chats found'; + String get optionNoChatFound => 'No chats'; + + @override + String optionNoChatFoundSearch(String query) { + return 'No chats found for ‘$query’'; + } + + @override + String get optionSearchChats => 'Search through chats'; + + @override + String get optionChatDetails => 'Chat details'; + + @override + String get optionChatDetailsNoChat => 'No chat selected'; @override String get tipPrefix => 'Tip: '; @@ -48,31 +72,60 @@ class AppLocalizationsEn extends AppLocalizations { String get renameChat => 'Rename'; @override - String get takeImage => 'Take Image'; + String get takeImage => 'Camera'; @override - String get uploadImage => 'Upload Image'; + String get uploadImage => 'Gallery'; @override - String get notAValidImage => 'Not a valid image'; + String newChatGreeting1(String user) { + return 'What’s on your mind, $user?'; + } @override - String get imageOnlyConversation => 'Image Only Conversation'; + String newChatGreeting2(String user) { + return 'Good to see you, $user.'; + } @override - String get messageInputPlaceholder => 'Message'; + String newChatGreeting3(String user) { + return 'What can I do for you, $user?'; + } @override - String get tooltipAttachment => 'Add attachment'; + String newChatGreeting4(String user) { + return 'How can I help you today, $user?'; + } + + @override + String newChatGreeting5(String user) { + return 'What would you like to talk about, $user?'; + } + + @override + String get newChatGreetingNameFallback => 'user'; + + @override + String messageInputPlaceholder(String model) { + return 'Ask $model'; + } + + @override + String get messageInputPlaceholderModelPlaceholder => 'model'; + + @override + String get tooltipMessageOptions => 'Message options'; @override String get tooltipSend => 'Send'; @override - String get tooltipSave => 'Save'; + String tooltipLetAIThink(String model) { + return 'Generate with $model'; + } @override - String get tooltipLetAIThink => 'Let AI think'; + String get tooltipAddHostHeaders => 'Add host headers'; @override String get tooltipReset => 'Reset current chat'; @@ -84,72 +137,69 @@ class AppLocalizationsEn extends AppLocalizations { String get noModelSelected => 'No model selected'; @override - String get noHostSelected => 'No host selected, open settings to set one'; + String get noHostSelected => 'No host selected, open settings to set one.'; @override - String get noSelectedModel => ''; + String get noSelectedModel => ''; @override - String get newChatTitle => 'Unnamed Chat'; + String get newChatTitle => 'Untitled Chat'; @override - String get modelDialogAddModel => 'Add'; + String get modelDialogTitle => 'Select a model'; @override - String get modelDialogAddPromptTitle => 'Add new model'; + String get modelDialogAdd => 'Add'; + + @override + String get modelDialogRefresh => 'Refresh'; + + @override + String get modelDialogAddPromptTitle => 'Add model'; @override String get modelDialogAddPromptDescription => - 'This can either be a normal name (e.g. \'llama3\') or a name and tag (e.g. \'llama3:70b\').'; + 'This can either be a normal name (e.g. “llama3”) or a name together with a tag (e.g. “llama3:70b”).'; @override - String get modelDialogAddPromptAlreadyExists => 'Model already exists'; + String get modelDialogAddCurrently => 'Currently downloading:'; @override - String get modelDialogAddPromptInvalid => 'Invalid model name'; + String get modelDialogAddPromptAlreadyExists => + 'Model already exists. Try refreshing if it was deleted.'; @override - String get modelDialogAddAllowanceTitle => 'Allow Proxy'; + String get modelDialogAddPromptInvalid => + 'Couldn’t read your model name correctly. Please check the spelling and try again.'; @override - String get modelDialogAddAllowanceDescription => - 'Ollama App must check if the entered model is valid. To do that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different API, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potentially harmful intentions.\nIf you accept, your selection will be remembered for the future; if not, nothing will be sent and the model won\'t be added.'; + String get modelDialogAddPromptNotFound => + 'Couldn’t find your model on the server. Please check the spelling and try again.'; @override - String get modelDialogAddAllowanceAllow => 'Allow'; + String get modelDialogAddPromptNetworkError => + 'Network error while checking model. Please check your connection and try again.'; @override - String get modelDialogAddAllowanceDeny => 'Deny'; + String get modelDialogAddPromptCorruptionError => + 'The API returned “EOF”; your server was likely restarted while downloading the model previously.'; @override - String modelDialogAddAssuranceTitle(String model) { - return 'Add $model?'; - } + String get modelDialogAddPromptCorruptionErrorSolution => + 'Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.'; @override - String modelDialogAddAssuranceDescription(String model) { - return 'Pressing \'Add\' will download the model \'$model\' directly from the Ollama server to your host.\nThis can take a while depending on your internet connection. The action cannot be canceled.\nIf the app is closed during the download, it will resume if you enter the name into the model dialog again.'; - } + String get modelDialogAddCancelTitle => 'Cancel download?'; @override - String get modelDialogAddAssuranceAdd => 'Add'; + String get modelDialogAddCancelConfirm => 'Cancel'; @override - String get modelDialogAddAssuranceCancel => 'Cancel'; + String get modelDialogAddCancelHide => 'Hide'; @override - String get modelDialogAddDownloadPercentLoading => 'loading progress'; - - @override - String modelDialogAddDownloadPercent(String percent) { - return 'download at $percent%'; - } - - @override - String get modelDialogAddDownloadFailed => 'Disconnected, try again'; - - @override - String get modelDialogAddDownloadSuccess => 'Download successful'; + String get modelDialogAddDownloadSuccess => + 'Download successful. Set as current model.'; @override String get deleteDialogTitle => 'Delete Chat'; @@ -185,6 +235,13 @@ class AppLocalizationsEn extends AppLocalizations { @override String get dialogEditMessageTitle => 'Edit message'; + @override + String get settingsTitleOverview => 'Overview'; + + @override + String get settingsDescriptionOverview => + 'General settings regarding your host.'; + @override String get settingsTitleBehavior => 'Behavior'; @@ -220,15 +277,12 @@ class AppLocalizationsEn extends AppLocalizations { String get settingsDescriptionAbout => 'Check for updates and learn more about Ollama App.'; - @override - String get settingsSavedAutomatically => 'Settings are saved automatically'; - @override String get settingsExperimentalAlpha => 'alpha'; @override String get settingsExperimentalAlphaDescription => - 'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.'; + 'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or connected services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.'; @override String get settingsExperimentalAlphaFeature => @@ -239,7 +293,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsExperimentalBetaDescription => - 'This feature is in beta and may not work as intended or expected.\nLess severe issues may or may not occur. Damage shouldn\'t be critical.\nUse at your own risk.'; + 'This feature is in beta and may not work as intended or expected.\nLess severe issues may or may not occur. Damage shouldn’t be critical.\nUse at your own risk.'; @override String get settingsExperimentalBetaFeature => @@ -259,6 +313,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsHost => 'Host'; + @override + String get settingsHostMissing => 'No host set'; + @override String get settingsHostValid => 'Valid Host'; @@ -268,36 +325,49 @@ class AppLocalizationsEn extends AppLocalizations { @override String settingsHostInvalid(String type) { String _temp0 = intl.Intl.selectLogic(type, { - 'url': 'Invalid URL', - 'host': 'Invalid Host', - 'timeout': 'Request failed. Server issues', - 'ratelimit': 'Too many requests', - 'other': 'Request Failed', + 'invalidUrl': 'Invalid URL', + 'unreachable': 'Host unreachable', + 'undetectable': 'Host not an Ollama server', + 'timeout': 'Connection timed out', + 'outdated': 'Outdated Ollama version', + 'other': 'Invalid host', }); - return 'Issue: $_temp0'; + return '$_temp0'; } - @override - String get tooltipAddHostHeaders => 'Add host headers'; - - @override - String get settingsHostHeaderTitle => 'Set host header'; - - @override - String get settingsHostHeaderInvalid => - 'The entered text isn\'t a valid header JSON object'; - @override String settingsHostInvalidDetailed(String type) { String _temp0 = intl.Intl.selectLogic(type, { - 'url': - 'The URL you entered is invalid. It isn\'t in a standardized URL format.', - 'other': - 'The host you entered is invalid. It cannot be reached. Please check the host and try again.', + 'invalidUrl': 'The URL you entered isn’t in a valid format.', + 'unreachable': + 'The host is invalid or unreachable, possibly due to a wrong address or network issue.', + 'undetectable': + 'The host is reachable but doesn’t respond as expected by Ollama App.\nIt may not be an Ollama server. Are you sure you entered it correctly?', + 'timeout': + 'The host couldn’t be reached in time.\nTry increasing the timeout multiplier in interface settings.', + 'outdated': + 'The host is running an Ollama version incompatible with this app.\nPlease update both the host and this app, if possible.', + 'other': 'The host you entered is invalid.', }); return '$_temp0'; } + @override + String get settingsHostHeaderHeaderName => 'Header'; + + @override + String get settingsHostHeaderHeaderValue => 'Value'; + + @override + String settingsHostHeaderUnsupported(String header) { + return 'The header “$header” may not be supported.'; + } + + @override + String settingsHostHeaderDuplicate(String header) { + return 'The header “$header” is already set.'; + } + @override String get settingsSystemMessage => 'System message'; @@ -306,7 +376,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsUseSystemDescription => - 'Disables setting the system message above and uses the one from the model\'s Modelfile instead. Can be useful for models with model files.'; + 'Disables setting the system message above and uses the one from the model’s Modelfile instead. Can be useful for models with model files.'; @override String get settingsDisableMarkdown => 'Disable markdown'; @@ -346,7 +416,7 @@ class AppLocalizationsEn extends AppLocalizations { String get settingsKeepModelLoadedAlways => 'Keep model always loaded'; @override - String get settingsKeepModelLoadedNever => 'Don\'t keep model loaded'; + String get settingsKeepModelLoadedNever => 'Don’t keep model loaded'; @override String get settingsKeepModelLoadedFor => @@ -397,13 +467,13 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsTemporaryFixesInstructions => - 'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.'; + 'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey should not be considered final or judged as such. Issues might occur.'; @override String get settingsTemporaryFixesNoFixes => 'No fixes available'; @override - String get settingsVoicePermissionLoading => 'Loading voice permissions ...'; + String get settingsVoicePermissionLoading => 'Loading voice permissions...'; @override String get settingsVoiceTtsNotSupported => 'Text-to-speech not supported'; @@ -460,17 +530,17 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsExportInfo => - 'These options allow you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or back up your chat history'; + 'These options allow you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or back up your chat history.'; @override String get settingsExportWarning => - 'Multiple chat histories won\'t be merged! You\'ll lose your current chat history if you import a new one.'; + 'Multiple chat histories won’t be merged! You’ll lose your current chat history if you import a new one.'; @override String get settingsUpdateCheck => 'Check for updates'; @override - String get settingsUpdateChecking => 'Checking for updates ...'; + String get settingsUpdateChecking => 'Checking for updates...'; @override String get settingsUpdateLatest => 'You are on the latest version'; @@ -481,7 +551,7 @@ class AppLocalizationsEn extends AppLocalizations { } @override - String get settingsUpdateRateLimit => 'Can\'t check, API rate limit exceeded'; + String get settingsUpdateRateLimit => 'Can’t check, API rate limit exceeded'; @override String get settingsUpdateIssue => 'An issue occurred'; @@ -503,7 +573,7 @@ class AppLocalizationsEn extends AppLocalizations { String get settingsUpdateDialogCancel => 'Cancel'; @override - String get settingsCheckForUpdates => 'Check for updates on open'; + String get settingsCheckForUpdates => 'Check for updates on startup'; @override String get settingsGithub => 'GitHub'; diff --git a/lib/l10n/gen/app_localizations_fa.dart b/lib/l10n/gen/app_localizations_fa.dart index efb6df1..5f89a07 100644 --- a/lib/l10n/gen/app_localizations_fa.dart +++ b/lib/l10n/gen/app_localizations_fa.dart @@ -9,7 +9,12 @@ class AppLocalizationsFa extends AppLocalizations { AppLocalizationsFa([String locale = 'fa']) : super(locale); @override - String get appTitle => 'Ollama'; + String appTitle(String env, String title) { + return 'Ollama'; + } + + @override + String get learnMore => 'Learn more'; @override String get optionNewChat => 'New Chat'; @@ -23,6 +28,20 @@ class AppLocalizationsFa extends AppLocalizations { @override String get optionNoChatFound => 'No chats found'; + @override + String optionNoChatFoundSearch(String query) { + return 'No chats found for ‘$query’'; + } + + @override + String get optionSearchChats => 'Search through chats'; + + @override + String get optionChatDetails => 'Chat details'; + + @override + String get optionChatDetailsNoChat => 'No chat selected'; + @override String get tipPrefix => 'Tip: '; @@ -54,25 +73,54 @@ class AppLocalizationsFa extends AppLocalizations { String get uploadImage => 'Upload Image'; @override - String get notAValidImage => 'Not a valid image'; + String newChatGreeting1(String user) { + return 'What’s on your mind, $user?'; + } @override - String get imageOnlyConversation => 'Image Only Conversation'; + String newChatGreeting2(String user) { + return 'Good to see you, $user.'; + } @override - String get messageInputPlaceholder => 'Message'; + String newChatGreeting3(String user) { + return 'What can I do for you, $user?'; + } @override - String get tooltipAttachment => 'Add attachment'; + String newChatGreeting4(String user) { + return 'How can I help you today, $user?'; + } + + @override + String newChatGreeting5(String user) { + return 'What would you like to talk about, $user?'; + } + + @override + String get newChatGreetingNameFallback => 'user'; + + @override + String messageInputPlaceholder(String model) { + return 'Message'; + } + + @override + String get messageInputPlaceholderModelPlaceholder => 'model'; + + @override + String get tooltipMessageOptions => 'Message options'; @override String get tooltipSend => 'Send'; @override - String get tooltipSave => 'Save'; + String tooltipLetAIThink(String model) { + return 'Let AI think'; + } @override - String get tooltipLetAIThink => 'Let AI think'; + String get tooltipAddHostHeaders => 'Add host headers'; @override String get tooltipReset => 'Reset current chat'; @@ -93,7 +141,13 @@ class AppLocalizationsFa extends AppLocalizations { String get newChatTitle => 'Unnamed Chat'; @override - String get modelDialogAddModel => 'Add'; + String get modelDialogTitle => 'Select a model'; + + @override + String get modelDialogAdd => 'Add'; + + @override + String get modelDialogRefresh => 'Refresh'; @override String get modelDialogAddPromptTitle => 'Add new model'; @@ -102,6 +156,9 @@ class AppLocalizationsFa extends AppLocalizations { String get modelDialogAddPromptDescription => 'This can have either be a normal name (e.g. \'llama3\') or name and tag (e.g. \'llama3:70b\').'; + @override + String get modelDialogAddCurrently => 'Currently downloading:'; + @override String get modelDialogAddPromptAlreadyExists => 'Model already exists'; @@ -109,44 +166,29 @@ class AppLocalizationsFa extends AppLocalizations { String get modelDialogAddPromptInvalid => 'Invalid model name'; @override - String get modelDialogAddAllowanceTitle => 'Allow Proxy'; + String get modelDialogAddPromptNotFound => + 'Couldn’t find your model on the server. Please check the spelling and try again.'; @override - String get modelDialogAddAllowanceDescription => - 'Ollama App must check if the entered model is valid. For that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different api, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potential harmful intentions.\nIf you accept, your selection will be remembered in the future; if not, nothing will be sent and the model won\'t be added.'; + String get modelDialogAddPromptNetworkError => + 'Network error while checking model. Please check your connection and try again.'; @override - String get modelDialogAddAllowanceAllow => 'Allow'; + String get modelDialogAddPromptCorruptionError => + 'The API returned “EOF”; your server was likely restarted while downloading the model previously.'; @override - String get modelDialogAddAllowanceDeny => 'Deny'; + String get modelDialogAddPromptCorruptionErrorSolution => + 'Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.'; @override - String modelDialogAddAssuranceTitle(String model) { - return 'Add $model?'; - } + String get modelDialogAddCancelTitle => 'Cancel download?'; @override - String modelDialogAddAssuranceDescription(String model) { - return 'Pressing \'Add\' will download the model \'$model\' directly from the Ollama server to your host.\nThis can take a while depending on your internet connection. The action cannot be canceled.\nIf the app is closed during the download, it\'ll resume if you enter the name into the model dialog again.'; - } + String get modelDialogAddCancelConfirm => 'Cancel'; @override - String get modelDialogAddAssuranceAdd => 'Add'; - - @override - String get modelDialogAddAssuranceCancel => 'Cancel'; - - @override - String get modelDialogAddDownloadPercentLoading => 'loading progress'; - - @override - String modelDialogAddDownloadPercent(String percent) { - return 'download at $percent%'; - } - - @override - String get modelDialogAddDownloadFailed => 'Disconnected, try again'; + String get modelDialogAddCancelHide => 'Hide'; @override String get modelDialogAddDownloadSuccess => 'Download successful'; @@ -185,6 +227,13 @@ class AppLocalizationsFa extends AppLocalizations { @override String get dialogEditMessageTitle => 'Edit message'; + @override + String get settingsTitleOverview => 'Overview'; + + @override + String get settingsDescriptionOverview => + 'General settings regarding your host.'; + @override String get settingsTitleBehavior => 'Behavior'; @@ -220,9 +269,6 @@ class AppLocalizationsFa extends AppLocalizations { String get settingsDescriptionAbout => 'Check for updates and learn more about Ollama App.'; - @override - String get settingsSavedAutomatically => 'Settings are saved automatically'; - @override String get settingsExperimentalAlpha => 'alpha'; @@ -259,6 +305,9 @@ class AppLocalizationsFa extends AppLocalizations { @override String get settingsHost => 'Host'; + @override + String get settingsHostMissing => 'No host set'; + @override String get settingsHostValid => 'Valid Host'; @@ -277,16 +326,6 @@ class AppLocalizationsFa extends AppLocalizations { return 'Issue: $_temp0'; } - @override - String get tooltipAddHostHeaders => 'Add host headers'; - - @override - String get settingsHostHeaderTitle => 'Set host header'; - - @override - String get settingsHostHeaderInvalid => - 'The entered text isn\'t a valid header JSON object'; - @override String settingsHostInvalidDetailed(String type) { String _temp0 = intl.Intl.selectLogic(type, { @@ -298,6 +337,22 @@ class AppLocalizationsFa extends AppLocalizations { return '$_temp0'; } + @override + String get settingsHostHeaderHeaderName => 'Header'; + + @override + String get settingsHostHeaderHeaderValue => 'Value'; + + @override + String settingsHostHeaderUnsupported(String header) { + return 'The header “$header” may not be supported.'; + } + + @override + String settingsHostHeaderDuplicate(String header) { + return 'The header “$header” is already set.'; + } + @override String get settingsSystemMessage => 'System message'; diff --git a/lib/l10n/gen/app_localizations_it.dart b/lib/l10n/gen/app_localizations_it.dart index 5b7c52d..6f7ac0a 100644 --- a/lib/l10n/gen/app_localizations_it.dart +++ b/lib/l10n/gen/app_localizations_it.dart @@ -9,7 +9,12 @@ class AppLocalizationsIt extends AppLocalizations { AppLocalizationsIt([String locale = 'it']) : super(locale); @override - String get appTitle => 'Ollama'; + String appTitle(String env, String title) { + return 'Ollama'; + } + + @override + String get learnMore => 'Learn more'; @override String get optionNewChat => 'Nuova Chat'; @@ -23,6 +28,20 @@ class AppLocalizationsIt extends AppLocalizations { @override String get optionNoChatFound => 'Nessuna Chat trovata'; + @override + String optionNoChatFoundSearch(String query) { + return 'No chats found for ‘$query’'; + } + + @override + String get optionSearchChats => 'Search through chats'; + + @override + String get optionChatDetails => 'Chat details'; + + @override + String get optionChatDetailsNoChat => 'No chat selected'; + @override String get tipPrefix => 'Suggerimento: '; @@ -55,25 +74,54 @@ class AppLocalizationsIt extends AppLocalizations { String get uploadImage => 'Carica immagine'; @override - String get notAValidImage => 'Immagine non valida'; + String newChatGreeting1(String user) { + return 'What’s on your mind, $user?'; + } @override - String get imageOnlyConversation => 'Conversazione di sole immagini'; + String newChatGreeting2(String user) { + return 'Good to see you, $user.'; + } @override - String get messageInputPlaceholder => 'Messaggio'; + String newChatGreeting3(String user) { + return 'What can I do for you, $user?'; + } @override - String get tooltipAttachment => 'Aggiungi allegato'; + String newChatGreeting4(String user) { + return 'How can I help you today, $user?'; + } + + @override + String newChatGreeting5(String user) { + return 'What would you like to talk about, $user?'; + } + + @override + String get newChatGreetingNameFallback => 'user'; + + @override + String messageInputPlaceholder(String model) { + return 'Messaggio'; + } + + @override + String get messageInputPlaceholderModelPlaceholder => 'model'; + + @override + String get tooltipMessageOptions => 'Message options'; @override String get tooltipSend => 'Invia'; @override - String get tooltipSave => 'Salva'; + String tooltipLetAIThink(String model) { + return 'Lasciamo che sia IA a pensare'; + } @override - String get tooltipLetAIThink => 'Lasciamo che sia IA a pensare'; + String get tooltipAddHostHeaders => 'Aggiungi host headers'; @override String get tooltipReset => 'Reimposta la chat corrente'; @@ -95,7 +143,13 @@ class AppLocalizationsIt extends AppLocalizations { String get newChatTitle => 'Chat senza nome'; @override - String get modelDialogAddModel => 'Aggiungi'; + String get modelDialogTitle => 'Select a model'; + + @override + String get modelDialogAdd => 'Add'; + + @override + String get modelDialogRefresh => 'Refresh'; @override String get modelDialogAddPromptTitle => 'Aggiungi nuovo modello'; @@ -104,6 +158,9 @@ class AppLocalizationsIt extends AppLocalizations { String get modelDialogAddPromptDescription => 'Questo può essere un nome normale (ad es. \'llama3\') o nome e tag (ad es. \'llama3:70b\').'; + @override + String get modelDialogAddCurrently => 'Currently downloading:'; + @override String get modelDialogAddPromptAlreadyExists => 'Il modello esiste già'; @@ -111,44 +168,29 @@ class AppLocalizationsIt extends AppLocalizations { String get modelDialogAddPromptInvalid => 'Nome del modello non valido'; @override - String get modelDialogAddAllowanceTitle => 'Abilita Proxy'; + String get modelDialogAddPromptNotFound => + 'Couldn’t find your model on the server. Please check the spelling and try again.'; @override - String get modelDialogAddAllowanceDescription => - 'Ollama App deve controllare se il modello inserito è valido. Per questo, normalmente inviamo una richiesta web alla lista dei modelli Ollama e controlliamo il codice di stato, ma perché stai usando il web client, non possiamo farlo direttamente. Invece, l\'app invierà la richiesta a un altro api, ospitato da JHubi1, per eseguire il controllo.\nQuesta è una richiesta verrà inviata solo quando aggiungi un nuovo modello.\nIl tuo indirizzo IP verrà inviato con la richiesta e potrebbe essere memorizzato per un massimo di dieci minuti per evitare lo spamming con potenziali intenzioni nocive.\nSe accetti, la tua selezione sarà ricordata in futuro; in caso contrario, non verrà inviato nulla e il modello non verrà aggiunto.'; + String get modelDialogAddPromptNetworkError => + 'Network error while checking model. Please check your connection and try again.'; @override - String get modelDialogAddAllowanceAllow => 'Consenti'; + String get modelDialogAddPromptCorruptionError => + 'The API returned “EOF”; your server was likely restarted while downloading the model previously.'; @override - String get modelDialogAddAllowanceDeny => 'Nega'; + String get modelDialogAddPromptCorruptionErrorSolution => + 'Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.'; @override - String modelDialogAddAssuranceTitle(String model) { - return 'Aggiungi $model?'; - } + String get modelDialogAddCancelTitle => 'Cancel download?'; @override - String modelDialogAddAssuranceDescription(String model) { - return 'Premendo \'Aggiungi\' scaricherà il modello \'$model\' direttamente dal server Ollama al tuo host.\nQuesto può richiedere un po\' di tempo a seconda della tua connessione internet. L\'azione non può essere annullata.\nSe l\'app è chiusa durante il download, riprenderà se inserisci di nuovo il nome nella finestra del modello.'; - } + String get modelDialogAddCancelConfirm => 'Cancel'; @override - String get modelDialogAddAssuranceAdd => 'Aggiungi'; - - @override - String get modelDialogAddAssuranceCancel => 'Annulla'; - - @override - String get modelDialogAddDownloadPercentLoading => 'Caricamento in corso'; - - @override - String modelDialogAddDownloadPercent(String percent) { - return 'scarica al $percent%'; - } - - @override - String get modelDialogAddDownloadFailed => 'Disconnesso, riprova'; + String get modelDialogAddCancelHide => 'Hide'; @override String get modelDialogAddDownloadSuccess => @@ -188,6 +230,13 @@ class AppLocalizationsIt extends AppLocalizations { @override String get dialogEditMessageTitle => 'Modifica Messaggio'; + @override + String get settingsTitleOverview => 'Overview'; + + @override + String get settingsDescriptionOverview => + 'General settings regarding your host.'; + @override String get settingsTitleBehavior => 'Comportamento'; @@ -223,10 +272,6 @@ class AppLocalizationsIt extends AppLocalizations { String get settingsDescriptionAbout => 'Controlla gli aggiornamenti e scopri di più su Ollama App.'; - @override - String get settingsSavedAutomatically => - 'Le impostazioni vengono salvate automaticamente'; - @override String get settingsExperimentalAlpha => 'alpha'; @@ -263,6 +308,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get settingsHost => 'Host'; + @override + String get settingsHostMissing => 'No host set'; + @override String get settingsHostValid => 'Host valido'; @@ -281,16 +329,6 @@ class AppLocalizationsIt extends AppLocalizations { return 'Problema: $_temp0'; } - @override - String get tooltipAddHostHeaders => 'Aggiungi host headers'; - - @override - String get settingsHostHeaderTitle => 'Imposta header host'; - - @override - String get settingsHostHeaderInvalid => - 'Il testo immesso non è un valido oggetto JSON'; - @override String settingsHostInvalidDetailed(String type) { String _temp0 = intl.Intl.selectLogic(type, { @@ -302,6 +340,22 @@ class AppLocalizationsIt extends AppLocalizations { return '$_temp0'; } + @override + String get settingsHostHeaderHeaderName => 'Header'; + + @override + String get settingsHostHeaderHeaderValue => 'Value'; + + @override + String settingsHostHeaderUnsupported(String header) { + return 'The header “$header” may not be supported.'; + } + + @override + String settingsHostHeaderDuplicate(String header) { + return 'The header “$header” is already set.'; + } + @override String get settingsSystemMessage => 'Messaggio di sistema'; diff --git a/lib/l10n/gen/app_localizations_tr.dart b/lib/l10n/gen/app_localizations_tr.dart index 2549b11..7c5729f 100644 --- a/lib/l10n/gen/app_localizations_tr.dart +++ b/lib/l10n/gen/app_localizations_tr.dart @@ -9,7 +9,12 @@ class AppLocalizationsTr extends AppLocalizations { AppLocalizationsTr([String locale = 'tr']) : super(locale); @override - String get appTitle => 'Ollama'; + String appTitle(String env, String title) { + return 'Ollama'; + } + + @override + String get learnMore => 'Learn more'; @override String get optionNewChat => 'Yeni Sohbet'; @@ -23,6 +28,20 @@ class AppLocalizationsTr extends AppLocalizations { @override String get optionNoChatFound => 'Sohbet bulunamadı'; + @override + String optionNoChatFoundSearch(String query) { + return 'No chats found for ‘$query’'; + } + + @override + String get optionSearchChats => 'Search through chats'; + + @override + String get optionChatDetails => 'Chat details'; + + @override + String get optionChatDetailsNoChat => 'No chat selected'; + @override String get tipPrefix => 'İpucu: '; @@ -54,25 +73,54 @@ class AppLocalizationsTr extends AppLocalizations { String get uploadImage => 'Görsel Yükle'; @override - String get notAValidImage => 'Geçerli bir görsel değil'; + String newChatGreeting1(String user) { + return 'What’s on your mind, $user?'; + } @override - String get imageOnlyConversation => 'Sadece Görsel İçeren Konuşma'; + String newChatGreeting2(String user) { + return 'Good to see you, $user.'; + } @override - String get messageInputPlaceholder => 'Mesaj'; + String newChatGreeting3(String user) { + return 'What can I do for you, $user?'; + } @override - String get tooltipAttachment => 'Ek ekle'; + String newChatGreeting4(String user) { + return 'How can I help you today, $user?'; + } + + @override + String newChatGreeting5(String user) { + return 'What would you like to talk about, $user?'; + } + + @override + String get newChatGreetingNameFallback => 'user'; + + @override + String messageInputPlaceholder(String model) { + return 'Mesaj'; + } + + @override + String get messageInputPlaceholderModelPlaceholder => 'model'; + + @override + String get tooltipMessageOptions => 'Message options'; @override String get tooltipSend => 'Gönder'; @override - String get tooltipSave => 'Kaydet'; + String tooltipLetAIThink(String model) { + return 'AI\'\'nın düşünmesine izin ver'; + } @override - String get tooltipLetAIThink => 'AI\'\'nın düşünmesine izin ver'; + String get tooltipAddHostHeaders => 'Ana bilgisayar başlıkları ekle'; @override String get tooltipReset => 'Mevcut sohbeti sıfırla'; @@ -94,7 +142,13 @@ class AppLocalizationsTr extends AppLocalizations { String get newChatTitle => 'İsimsiz Sohbet'; @override - String get modelDialogAddModel => 'Ekle'; + String get modelDialogTitle => 'Select a model'; + + @override + String get modelDialogAdd => 'Add'; + + @override + String get modelDialogRefresh => 'Refresh'; @override String get modelDialogAddPromptTitle => 'Yeni model ekle'; @@ -103,6 +157,9 @@ class AppLocalizationsTr extends AppLocalizations { String get modelDialogAddPromptDescription => 'Bu normal bir isim (örneğin \'llama3\') ya da isim ve etiket (örneğin \'llama3:70b\') olabilir.'; + @override + String get modelDialogAddCurrently => 'Currently downloading:'; + @override String get modelDialogAddPromptAlreadyExists => 'Model zaten mevcut'; @@ -110,45 +167,29 @@ class AppLocalizationsTr extends AppLocalizations { String get modelDialogAddPromptInvalid => 'Geçersiz model adı'; @override - String get modelDialogAddAllowanceTitle => 'Proxy\'e İzin Ver'; + String get modelDialogAddPromptNotFound => + 'Couldn’t find your model on the server. Please check the spelling and try again.'; @override - String get modelDialogAddAllowanceDescription => - 'Ollama Uygulaması, girilen modelin geçerli olup olmadığını kontrol etmelidir. Bunun için normalde Ollama model listesine bir web isteği gönderir ve durum kodunu kontrol ederiz, ancak siz web istemcisini kullandığınız için bunu doğrudan yapamayız. Bunun yerine, uygulama bizim için kontrol etmek amacıyla JHubi1 tarafından barındırılan farklı bir API\'ye istek gönderecek. \nBu, yalnızca bir kez yapılan bir istektir ve yalnızca yeni bir model eklediğinizde gönderilecektir. \nIP adresiniz istekle birlikte gönderilecek ve olası zararlı niyetlerle spam yapılmasını önlemek amacıyla on dakikaya kadar saklanabilir. \nKabul ederseniz, seçiminiz gelecekte hatırlanacaktır; kabul etmezseniz, hiçbir şey gönderilmeyecek ve model eklenmeyecektir.'; + String get modelDialogAddPromptNetworkError => + 'Network error while checking model. Please check your connection and try again.'; @override - String get modelDialogAddAllowanceAllow => 'İzin ver'; + String get modelDialogAddPromptCorruptionError => + 'The API returned “EOF”; your server was likely restarted while downloading the model previously.'; @override - String get modelDialogAddAllowanceDeny => 'Reddet'; + String get modelDialogAddPromptCorruptionErrorSolution => + 'Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.'; @override - String modelDialogAddAssuranceTitle(String model) { - return '$model Ekle?'; - } + String get modelDialogAddCancelTitle => 'Cancel download?'; @override - String modelDialogAddAssuranceDescription(String model) { - return '\'Ekle\' tuşuna basmak, \'$model\' modelini doğrudan Ollama sunucusundan bilgisayarınıza indirecektir. İnternet bağlantınıza bağlı olarak bu işlem biraz zaman alabilir. Bu işlem iptal edilemez. Uygulama indirme sırasında kapatılırsa, model adını tekrar model diyaloguna girerseniz indirme işlemi kaldığı yerden devam eder.'; - } + String get modelDialogAddCancelConfirm => 'Cancel'; @override - String get modelDialogAddAssuranceAdd => 'Ekle'; - - @override - String get modelDialogAddAssuranceCancel => 'İptal'; - - @override - String get modelDialogAddDownloadPercentLoading => 'yükleme ilerleme durumu'; - - @override - String modelDialogAddDownloadPercent(String percent) { - return '%$percent oranında indir'; - } - - @override - String get modelDialogAddDownloadFailed => - 'Bağlantı kesildi, yeniden deneyin'; + String get modelDialogAddCancelHide => 'Hide'; @override String get modelDialogAddDownloadSuccess => 'İndirme tamamlandı'; @@ -187,6 +228,13 @@ class AppLocalizationsTr extends AppLocalizations { @override String get dialogEditMessageTitle => 'Mesajı düzenle'; + @override + String get settingsTitleOverview => 'Overview'; + + @override + String get settingsDescriptionOverview => + 'General settings regarding your host.'; + @override String get settingsTitleBehavior => 'Davranış'; @@ -222,9 +270,6 @@ class AppLocalizationsTr extends AppLocalizations { String get settingsDescriptionAbout => 'Güncellemeleri kontrol edin ve Ollama Uygulaması hakkında daha fazla bilgi edinin.'; - @override - String get settingsSavedAutomatically => 'Ayarlar otomatik olarak kaydedilir'; - @override String get settingsExperimentalAlpha => 'alfa'; @@ -261,6 +306,9 @@ class AppLocalizationsTr extends AppLocalizations { @override String get settingsHost => 'Ana bilgisayar'; + @override + String get settingsHostMissing => 'No host set'; + @override String get settingsHostValid => 'Geçerli Ana Bilgisayar'; @@ -279,16 +327,6 @@ class AppLocalizationsTr extends AppLocalizations { return 'Sorun: $_temp0'; } - @override - String get tooltipAddHostHeaders => 'Ana bilgisayar başlıkları ekle'; - - @override - String get settingsHostHeaderTitle => 'Ana bilgisayar başlığını ayarla'; - - @override - String get settingsHostHeaderInvalid => - 'Girilen metin geçerli bir başlık JSON nesnesi değil'; - @override String settingsHostInvalidDetailed(String type) { String _temp0 = intl.Intl.selectLogic(type, { @@ -299,6 +337,22 @@ class AppLocalizationsTr extends AppLocalizations { return '$_temp0'; } + @override + String get settingsHostHeaderHeaderName => 'Header'; + + @override + String get settingsHostHeaderHeaderValue => 'Value'; + + @override + String settingsHostHeaderUnsupported(String header) { + return 'The header “$header” may not be supported.'; + } + + @override + String settingsHostHeaderDuplicate(String header) { + return 'The header “$header” is already set.'; + } + @override String get settingsSystemMessage => 'Sistem mesajı'; diff --git a/lib/l10n/gen/app_localizations_zh.dart b/lib/l10n/gen/app_localizations_zh.dart index ad60958..a4618cb 100644 --- a/lib/l10n/gen/app_localizations_zh.dart +++ b/lib/l10n/gen/app_localizations_zh.dart @@ -9,7 +9,12 @@ class AppLocalizationsZh extends AppLocalizations { AppLocalizationsZh([String locale = 'zh']) : super(locale); @override - String get appTitle => 'Ollama'; + String appTitle(String env, String title) { + return 'Ollama'; + } + + @override + String get learnMore => 'Learn more'; @override String get optionNewChat => '新建聊天'; @@ -23,6 +28,20 @@ class AppLocalizationsZh extends AppLocalizations { @override String get optionNoChatFound => '暂无聊天消息'; + @override + String optionNoChatFoundSearch(String query) { + return 'No chats found for ‘$query’'; + } + + @override + String get optionSearchChats => 'Search through chats'; + + @override + String get optionChatDetails => 'Chat details'; + + @override + String get optionChatDetailsNoChat => 'No chat selected'; + @override String get tipPrefix => '提示: '; @@ -54,25 +73,54 @@ class AppLocalizationsZh extends AppLocalizations { String get uploadImage => '上传图像'; @override - String get notAValidImage => '不是一个有效的图片文件.'; + String newChatGreeting1(String user) { + return 'What’s on your mind, $user?'; + } @override - String get imageOnlyConversation => '仅图片对话'; + String newChatGreeting2(String user) { + return 'Good to see you, $user.'; + } @override - String get messageInputPlaceholder => '消息'; + String newChatGreeting3(String user) { + return 'What can I do for you, $user?'; + } @override - String get tooltipAttachment => '添加附件'; + String newChatGreeting4(String user) { + return 'How can I help you today, $user?'; + } + + @override + String newChatGreeting5(String user) { + return 'What would you like to talk about, $user?'; + } + + @override + String get newChatGreetingNameFallback => 'user'; + + @override + String messageInputPlaceholder(String model) { + return '消息'; + } + + @override + String get messageInputPlaceholderModelPlaceholder => 'model'; + + @override + String get tooltipMessageOptions => 'Message options'; @override String get tooltipSend => '发送'; @override - String get tooltipSave => '保存'; + String tooltipLetAIThink(String model) { + return '让AI思考'; + } @override - String get tooltipLetAIThink => '让AI思考'; + String get tooltipAddHostHeaders => '设置主机请求头'; @override String get tooltipReset => '重置当前聊天'; @@ -93,7 +141,13 @@ class AppLocalizationsZh extends AppLocalizations { String get newChatTitle => '未命名的聊天'; @override - String get modelDialogAddModel => '添加'; + String get modelDialogTitle => 'Select a model'; + + @override + String get modelDialogAdd => 'Add'; + + @override + String get modelDialogRefresh => 'Refresh'; @override String get modelDialogAddPromptTitle => '添加新模型'; @@ -102,6 +156,9 @@ class AppLocalizationsZh extends AppLocalizations { String get modelDialogAddPromptDescription => '可以是一个普通名称(如:\'llama3\'),也可以是名称加标签(如:\'llama3:70b\')。'; + @override + String get modelDialogAddCurrently => 'Currently downloading:'; + @override String get modelDialogAddPromptAlreadyExists => '模型已存在'; @@ -109,44 +166,29 @@ class AppLocalizationsZh extends AppLocalizations { String get modelDialogAddPromptInvalid => '无效的模型名称'; @override - String get modelDialogAddAllowanceTitle => '允许代理服务器'; + String get modelDialogAddPromptNotFound => + 'Couldn’t find your model on the server. Please check the spelling and try again.'; @override - String get modelDialogAddAllowanceDescription => - 'Ollama 应用程序必须检查输入的模型是否有效。 为此,我们通常向Ollama模型列表发送一个网络请求并检查状态。 由于您正在使用 Web 客户端,我们不能直接做到这一点。 因此,应用将把请求发送到另一个由 JHubi 1 部署的api 上进行检查。\n这是一个一次性请求,只有当您添加一个新模型时才会发送。\n您的IP地址将与请求一起发送,可能会被存储长达10分钟,以防止潜在的有害故障。\n如果您接受,您的选择将在将来被记住;如果不接受,将不会发送任何内容,也不会添加模型。'; + String get modelDialogAddPromptNetworkError => + 'Network error while checking model. Please check your connection and try again.'; @override - String get modelDialogAddAllowanceAllow => '允许'; + String get modelDialogAddPromptCorruptionError => + 'The API returned “EOF”; your server was likely restarted while downloading the model previously.'; @override - String get modelDialogAddAllowanceDeny => '拒绝'; + String get modelDialogAddPromptCorruptionErrorSolution => + 'Alternatively, you can run the following command on your Linux host directly:\nIf you see a new error, try running the command with “sudo” placed in front of it.'; @override - String modelDialogAddAssuranceTitle(String model) { - return '添加$model?'; - } + String get modelDialogAddCancelTitle => 'Cancel download?'; @override - String modelDialogAddAssuranceDescription(String model) { - return '按下“添加”将直接从 Ollama 服务器下载模型“$model”到您的主机。\n这可能需要一些时间,取决于您的互联网连接。该操作不能被取消。\n如果在下载过程中关闭应用,当您再次在模型对话框中输入名称,它将恢复之前的下载。'; - } + String get modelDialogAddCancelConfirm => 'Cancel'; @override - String get modelDialogAddAssuranceAdd => '添加'; - - @override - String get modelDialogAddAssuranceCancel => '取消'; - - @override - String get modelDialogAddDownloadPercentLoading => '加载进度'; - - @override - String modelDialogAddDownloadPercent(String percent) { - return '已下载 $percent%'; - } - - @override - String get modelDialogAddDownloadFailed => '连接断开,请重试'; + String get modelDialogAddCancelHide => 'Hide'; @override String get modelDialogAddDownloadSuccess => '下载成功'; @@ -185,6 +227,13 @@ class AppLocalizationsZh extends AppLocalizations { @override String get dialogEditMessageTitle => '编辑消息'; + @override + String get settingsTitleOverview => 'Overview'; + + @override + String get settingsDescriptionOverview => + 'General settings regarding your host.'; + @override String get settingsTitleBehavior => '行为'; @@ -215,9 +264,6 @@ class AppLocalizationsZh extends AppLocalizations { @override String get settingsDescriptionAbout => '检查更新并了解更多关于Ollama App的信息。'; - @override - String get settingsSavedAutomatically => '设置已自动保存'; - @override String get settingsExperimentalAlpha => 'alpha'; @@ -251,6 +297,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get settingsHost => '主机地址'; + @override + String get settingsHostMissing => 'No host set'; + @override String get settingsHostValid => '有效主机地址'; @@ -268,15 +317,6 @@ class AppLocalizationsZh extends AppLocalizations { return '问题:$_temp0'; } - @override - String get tooltipAddHostHeaders => '设置主机请求头'; - - @override - String get settingsHostHeaderTitle => '设置主机请求头'; - - @override - String get settingsHostHeaderInvalid => '输入的文本不是有效的标题 JSON 对象'; - @override String settingsHostInvalidDetailed(String type) { String _temp0 = intl.Intl.selectLogic(type, { @@ -286,6 +326,22 @@ class AppLocalizationsZh extends AppLocalizations { return '$_temp0'; } + @override + String get settingsHostHeaderHeaderName => 'Header'; + + @override + String get settingsHostHeaderHeaderValue => 'Value'; + + @override + String settingsHostHeaderUnsupported(String header) { + return 'The header “$header” may not be supported.'; + } + + @override + String settingsHostHeaderDuplicate(String header) { + return 'The header “$header” is already set.'; + } + @override String get settingsSystemMessage => '系统信息'; diff --git a/lib/main.dart b/lib/main.dart index 5f0b2cd..9de5634 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,81 +1,123 @@ import 'dart:async'; import 'dart:io'; +import 'package:auto_route/auto_route.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart'; +import 'package:dartx/dartx.dart'; import 'package:dynamic_system_colors/dynamic_system_colors.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_chat_types/flutter_chat_types.dart' as types; +import 'package:flutter/material.dart' hide RouteSettings; // import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:flutter_tts/flutter_tts.dart'; +import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy; +import 'package:intl/date_symbol_data_local.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:pwa_install/pwa_install.dart' as pwa; import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/util/legacy_to_async_migration_util.dart'; import 'package:speech_to_text/speech_to_text.dart'; import 'package:universal_html/html.dart' as html; -import 'package:uuid/uuid.dart'; import 'l10n/gen/app_localizations.dart'; -import 'screens/main.dart'; -import 'services/clients.dart'; -import 'services/responsive.dart'; -import 'services/theme.dart'; +import 'main.gr.dart'; +import 'services/services.dart'; // client configuration -// use host or not, if false dialog is shown +/// forces usage of [fixedHost] as the host const bool useHost = false; -// host of ollama, must be accessible from the client, without trailing slash -// ! will always be accepted as valid, even if [useHost] is false + +/// the host used when [useHost] is true; not validated! const String fixedHost = "http://example.com:11434"; -// use model or not, if false selector is shown + +/// forces usage of [fixedModel] as the model const bool useModel = false; -// model name as string, must be valid ollama model! -const String fixedModel = "gemma3"; -// recommended models, shown with a star in model selector -const List recommendedModels = ["gemma3", "llama3.3"]; -// allow opening of settings -const bool allowSettings = true; -// allow multiple chats -const bool allowMultipleChats = true; + +/// the model used when [useModel] is true; not validated! +const String fixedModel = "gemma3:latest"; // client configuration end Completer prefsReady = Completer(); SharedPreferencesWithCache? prefs; -String? host; - -bool chatAllowed = true; -String hoveredChat = ""; - -final user = types.User(id: const Uuid().v4()); -final assistant = types.User(id: const Uuid().v4()); - -bool settingsOpen = false; -bool desktopTitleVisible = true; -bool logoVisible = true; -bool menuVisible = false; -bool sendable = false; -bool updateDetectedOnStart = false; -double sidebarIconSize = 1; - SpeechToText speech = SpeechToText(); FlutterTts voice = FlutterTts(); bool voiceSupported = false; -BuildContext? mainContext; -void Function(void Function())? setGlobalState; -void Function(void Function())? setMainAppState; +Color adaptedSurfaceFromColorScheme(ColorScheme cs) => cs.surface; +Color adaptedOnSurfaceFromColorScheme(ColorScheme cs) => cs.surfaceContainerLow; -void main() { +const kDisabledOpacity = 0.38; + +const kImageLogo = AssetImage("assets/logo512.png"); +const kImageLogoError = AssetImage("assets/logo512error.png"); + +final uuidRegex = RegExp( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", + caseSensitive: false, +); + +@AutoRouterConfig() +class AppRouter extends RootStackRouter { + @override + RouteType get defaultRouteType => const RouteType.material(); + + @override + List get routes => [ + AutoRoute( + page: RouteMain.page, + path: "/", + children: [ + AutoRoute(page: RouteNewChat.page, path: ""), + AutoRoute(page: RouteChat.page, path: "c/:id"), + + AutoRoute( + page: RouteSettingsShell.page, + path: "settings", + children: [ + AutoRoute(page: RouteSettings.page, path: "", initial: true), + AutoRoute(page: RouteSettingsOverview.page, path: "overview"), + + AutoRoute(page: RouteSettingsBehavior.page, path: "behavior"), + AutoRoute(page: RouteSettingsInterface.page, path: "interface"), + AutoRoute(page: RouteSettingsVoice.page, path: "voice"), + AutoRoute(page: RouteSettingsExport.page, path: "export"), + AutoRoute(page: RouteSettingsAbout.page, path: "about"), + ], + ), + ], + ), + RedirectRoute(path: "*", redirectTo: "/"), + ]; +} + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + usePathUrlStrategy(); + + await initializeDateFormatting(null, null); pwa.PWAInstall().setup(); try { HttpOverrides.global = OllamaHttpOverrides(); } catch (_) {} + SharedPreferences.setPrefix("ollama."); + await migrateLegacySharedPreferencesToSharedPreferencesAsyncIfNecessary( + legacySharedPreferencesInstance: await SharedPreferences.getInstance(), + sharedPreferencesAsyncOptions: const SharedPreferencesOptions(), + migrationCompletedKey: "migrationCompleted", + ); + prefs = await SharedPreferencesWithCache.create( + cacheOptions: const SharedPreferencesWithCacheOptions(), + ); + prefsReady.complete(); + Preferences.instance; + + chatDb = ChatDatabase(); + await ChatManager.instance.loadChats(); + runApp(const App()); if (LayoutFeature.desktop()) { @@ -96,6 +138,9 @@ class App extends StatefulWidget { } class _AppState extends State { + final _appRouter = AppRouter(); + Chat? _currentChat; + @override void initState() { super.initState(); @@ -104,17 +149,6 @@ class _AppState extends State { // FlutterDisplayMode.setHighRefreshRate().catchError((_) {}); Future load() async { - SharedPreferences.setPrefix("ollama."); - await migrateLegacySharedPreferencesToSharedPreferencesAsyncIfNecessary( - legacySharedPreferencesInstance: await SharedPreferences.getInstance(), - sharedPreferencesAsyncOptions: const SharedPreferencesOptions(), - migrationCompletedKey: "migrationCompleted", - ); - prefs = await SharedPreferencesWithCache.create( - cacheOptions: const SharedPreferencesWithCacheOptions(), - ); - prefsReady.complete(); - try { if ((await Permission.bluetoothConnect.isGranted) && (await Permission.microphone.isGranted)) { @@ -130,6 +164,34 @@ class _AppState extends State { } load(); + + ChatManager.instance.addListener(onChatUpdate); + WidgetsBinding.instance.addPostFrameCallback((_) { + precacheImage(kImageLogo, context); + precacheImage(kImageLogoError, context); + if (mounted) setState(() {}); + }); + } + + @override + void dispose() { + ChatManager.instance.removeListener(onChatUpdate); + super.dispose(); + } + + void onUpdate() { + if (mounted) setState(() {}); + } + + void onChatUpdate() { + if (ChatManager.instance.currentChat != _currentChat) { + _currentChat?.removeListener(onUpdate); + _currentChat = ChatManager.instance.currentChat; + _currentChat?.addListener(onUpdate); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) setState(() {}); + }); + } } @override @@ -142,15 +204,38 @@ class _AppState extends State { dynamicDark: dynamicDark, ), builder: (themeMode, themeLight, themeDark) { - return MaterialApp( + return MaterialApp.router( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, - onGenerateTitle: (context) => - AppLocalizations.of(context).appTitle, + onGenerateTitle: (context) { + final currentId = _appRouter.currentPath + .split("/") + .where(uuidRegex.hasMatch) + .lastOrNull; + final currentTitle = currentId != null + ? ChatManager.instance.chats + .firstOrNullWhere((chat) => chat.id == currentId) + ?.title ?? + AppLocalizations.of(context).newChatTitle + : null; + + return AppLocalizations.of(context).appTitle(switch (kIsWeb + ? "web" + : Platform.operatingSystem) { + "android" || "ios" => "short", + "web" when (currentTitle != null) => "integrated", + _ => "other", + }, currentTitle ?? ""); + }, theme: themeLight, darkTheme: themeDark, themeMode: themeMode, - home: const ScreenMain(), + routerConfig: _appRouter.config( + navigatorObservers: () => [ + GlobalNavigationObserver(), + HeroController(), + ], + ), ); }, ); @@ -158,3 +243,30 @@ class _AppState extends State { ); } } + +class GlobalNavigationObserver extends NavigatorObserver { + static String? _path; + static String? get path => _path; + + static final StreamController _routerStream = + StreamController.broadcast(); + static Stream get routerStream => _routerStream.stream; + + @override + void didChangeTop(Route topRoute, Route? previousTopRoute) { + super.didChangeTop(topRoute, previousTopRoute); + + var node = topRoute.data; + var path = node?.path ?? ""; + while (node?.parent != null) { + node = node!.parent; + if (node?.path != null && node!.path.isNotEmpty) { + path = "${node.path}/$path"; + } + } + path = "/${path.replaceAll(RegExp(r"(^/+)|(/+$)"), "")}"; + + _path = path; + _routerStream.add(null); + } +} diff --git a/lib/main.gr.dart b/lib/main.gr.dart new file mode 100644 index 0000000..83b8fb9 --- /dev/null +++ b/lib/main.gr.dart @@ -0,0 +1,224 @@ +// dart format width=80 +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// AutoRouterGenerator +// ************************************************************************** + +// ignore_for_file: type=lint +// coverage:ignore-file + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:auto_route/auto_route.dart' as _i4; +import 'package:flutter/material.dart' as _i5; +import 'package:ollama_app/screens/chat.dart' as _i1; +import 'package:ollama_app/screens/main.dart' as _i2; +import 'package:ollama_app/screens/settings.dart' as _i3; + +/// generated route for +/// [_i1.ScreenChat] +class RouteChat extends _i4.PageRouteInfo { + RouteChat({_i5.Key? key, String? chatId, List<_i4.PageRouteInfo>? children}) + : super( + RouteChat.name, + args: RouteChatArgs(key: key, chatId: chatId), + rawPathParams: {'id': chatId}, + initialChildren: children, + ); + + static const String name = 'RouteChat'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + final pathParams = data.inheritedPathParams; + final args = data.argsAs( + orElse: () => RouteChatArgs(chatId: pathParams.optString('id')), + ); + return _i1.ScreenChat(key: args.key, chatId: args.chatId); + }, + ); +} + +class RouteChatArgs { + const RouteChatArgs({this.key, this.chatId}); + + final _i5.Key? key; + + final String? chatId; + + @override + String toString() { + return 'RouteChatArgs{key: $key, chatId: $chatId}'; + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other is! RouteChatArgs) return false; + return key == other.key && chatId == other.chatId; + } + + @override + int get hashCode => key.hashCode ^ chatId.hashCode; +} + +/// generated route for +/// [_i2.ScreenMain] +class RouteMain extends _i4.PageRouteInfo { + const RouteMain({List<_i4.PageRouteInfo>? children}) + : super(RouteMain.name, initialChildren: children); + + static const String name = 'RouteMain'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i2.ScreenMain(); + }, + ); +} + +/// generated route for +/// [_i1.ScreenNewChat] +class RouteNewChat extends _i4.PageRouteInfo { + const RouteNewChat({List<_i4.PageRouteInfo>? children}) + : super(RouteNewChat.name, initialChildren: children); + + static const String name = 'RouteNewChat'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i1.ScreenNewChat(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettings] +class RouteSettings extends _i4.PageRouteInfo { + const RouteSettings({List<_i4.PageRouteInfo>? children}) + : super(RouteSettings.name, initialChildren: children); + + static const String name = 'RouteSettings'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettings(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsAbout] +class RouteSettingsAbout extends _i4.PageRouteInfo { + const RouteSettingsAbout({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsAbout.name, initialChildren: children); + + static const String name = 'RouteSettingsAbout'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsAbout(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsBehavior] +class RouteSettingsBehavior extends _i4.PageRouteInfo { + const RouteSettingsBehavior({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsBehavior.name, initialChildren: children); + + static const String name = 'RouteSettingsBehavior'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsBehavior(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsExport] +class RouteSettingsExport extends _i4.PageRouteInfo { + const RouteSettingsExport({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsExport.name, initialChildren: children); + + static const String name = 'RouteSettingsExport'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsExport(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsInterface] +class RouteSettingsInterface extends _i4.PageRouteInfo { + const RouteSettingsInterface({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsInterface.name, initialChildren: children); + + static const String name = 'RouteSettingsInterface'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsInterface(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsOverview] +class RouteSettingsOverview extends _i4.PageRouteInfo { + const RouteSettingsOverview({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsOverview.name, initialChildren: children); + + static const String name = 'RouteSettingsOverview'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsOverview(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsShell] +class RouteSettingsShell extends _i4.PageRouteInfo { + const RouteSettingsShell({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsShell.name, initialChildren: children); + + static const String name = 'RouteSettingsShell'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsShell(); + }, + ); +} + +/// generated route for +/// [_i3.ScreenSettingsVoice] +class RouteSettingsVoice extends _i4.PageRouteInfo { + const RouteSettingsVoice({List<_i4.PageRouteInfo>? children}) + : super(RouteSettingsVoice.name, initialChildren: children); + + static const String name = 'RouteSettingsVoice'; + + static _i4.PageInfo page = _i4.PageInfo( + name, + builder: (data) { + return const _i3.ScreenSettingsVoice(); + }, + ); +} diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart new file mode 100644 index 0000000..d3c5c3c --- /dev/null +++ b/lib/screens/chat.dart @@ -0,0 +1,520 @@ +import 'dart:convert'; +import 'dart:math' as math; +import 'dart:ui'; + +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:ollama_dart/ollama_dart.dart' as llama; +import 'package:visibility_detector/visibility_detector.dart'; + +import '../l10n/gen/app_localizations.dart'; +import '../main.dart'; +import '../main.gr.dart'; +import '../services/services.dart'; +import '../widgets/two_state_widget.dart'; + +@RoutePage() +class ScreenNewChat extends StatefulWidget { + const ScreenNewChat({super.key}); + + @override + State createState() => _ScreenNewChatState(); +} + +class _ScreenNewChatState extends State { + late int greetingId; + + @override + void initState() { + super.initState(); + ChatManager.instance.addListener(onUpdate); + shuffleGreeting(); + } + + @override + void dispose() { + ChatManager.instance.removeListener(onUpdate); + super.dispose(); + } + + void onUpdate() { + if (ChatManager.instance.currentChatId != null) { + context.router.navigate( + RouteChat(chatId: ChatManager.instance.currentChatId!), + ); + } + } + + void shuffleGreeting() => greetingId = math.Random().nextInt(5) + 1; + + @override + Widget build(BuildContext context) { + final textTheme = TextTheme.of(context); + + final breakpoint = Breakpoint.of(context); + final embeddedNavigation = breakpoint.panesRecommended >= 2; + + final appLocalizations = AppLocalizations.of(context); + final user = + Preferences.instance.user ?? + appLocalizations.newChatGreetingNameFallback; + final greeting = switch (greetingId) { + 1 => appLocalizations.newChatGreeting1(user), + 2 => appLocalizations.newChatGreeting2(user), + 3 => appLocalizations.newChatGreeting3(user), + 4 => appLocalizations.newChatGreeting4(user), + _ => appLocalizations.newChatGreeting5(user), + }; + + return _ChatFrame( + placeSearchBar: !embeddedNavigation, + builder: (context, safeAreaPadding, input) => Padding( + padding: safeAreaPadding, + child: VisibilityDetector( + key: const Key("newChatGreeting"), + onVisibilityChanged: (i) { + if (i.visibleFraction <= 0) { + shuffleGreeting(); + if (mounted) setState(() {}); + } + }, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: Text( + greeting, + style: textTheme.titleLarge, + textAlign: TextAlign.center, + ), + ), + if (input != null) ...[const SizedBox(height: 12), input], + ], + ), + ), + ), + ), + ); + } +} + +@RoutePage() +class ScreenChat extends StatefulWidget { + final String? chatId; + const ScreenChat({super.key, @PathParam("id") this.chatId}); + + @override + State createState() => _ScreenChatState(); +} + +class _ScreenChatState extends State { + Chat? _chat; + + @override + void initState() { + super.initState(); + ChatManager.instance.addListener(onUpdate); + checkChatId(); + } + + @override + void dispose() { + ChatManager.instance.removeListener(onUpdate); + _chat?.removeListener(onUpdate); + super.dispose(); + } + + void onUpdate() { + if (ChatManager.instance.currentChatId != widget.chatId) { + context.router.navigate( + ChatManager.instance.currentChatId != null + ? RouteChat(chatId: ChatManager.instance.currentChatId!) + : const RouteNewChat(), + ); + } + if (mounted) setState(() {}); + } + + @override + void didUpdateWidget(covariant ScreenChat oldWidget) { + super.didUpdateWidget(oldWidget); + checkChatId(); + } + + void checkChatId() { + if ((widget.chatId?.trim() ?? "").isEmpty || + !uuidRegex.hasMatch(widget.chatId!) || + !ChatManager.instance.chats.any((chat) => chat.id == widget.chatId)) { + context.router.navigate(const RouteNewChat()); + } else if (widget.chatId != ChatManager.instance.currentChatId) { + ChatManager.instance.currentChatId = widget.chatId!; + } + + _chat?.removeListener(onUpdate); + _chat = ChatManager.instance.chats + .where((chat) => chat.id == widget.chatId) + .first; + _chat?.addListener(onUpdate); + } + + @override + Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); + final adaptedOnSurface = adaptedOnSurfaceFromColorScheme(colorScheme); + + return _ChatFrame( + builder: (context, safeAreaPadding, input) { + final msg = _chat?.messages + .where((m) => m.sender == .assistant) + .whereType() + .lastOrNull; + return Text( + "${msg?.thinking ?? ""}\n\n${msg?.content ?? ""}\n\n${msg?.stats?.toJson() ?? ""}", + ); + }, + ); + } +} + +class _ChatFrame extends StatelessWidget { + final Widget Function( + BuildContext context, + EdgeInsetsGeometry safeAreaPadding, + Widget? input, + ) + builder; + final bool placeSearchBar; + const _ChatFrame({required this.builder, this.placeSearchBar = true}); + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + final halfSpacing = breakpoint.spacing / 2; + + final input = Hero( + tag: "chatScreenInput", + child: Align( + alignment: AlignmentGeometry.bottomCenter, + child: AnimatedPadding( + duration: ExpressiveCurves.standardSpatial.fastDuration, + curve: ExpressiveCurves.standardEffects.fast, + padding: breakpoint.panesRecommended >= 2 + ? EdgeInsetsGeometry.only( + left: halfSpacing, + right: halfSpacing, + bottom: halfSpacing, + ) + : EdgeInsetsGeometry.only(bottom: breakpoint.spacing), + child: const _ChatInput(), + ), + ), + ); + + final child = builder.call( + context, + EdgeInsetsGeometry.zero, + placeSearchBar ? null : input, + ); + final stack = Stack(children: [child, if (placeSearchBar) input]); + return Center( + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 720 - halfSpacing), + child: SizedBox.expand(child: stack), + ), + ); + } +} + +class _ChatInput extends StatefulWidget { + const _ChatInput(); + + @override + State<_ChatInput> createState() => _ChatInputState(); +} + +class _ChatInputState extends State<_ChatInput> { + late final TextEditingController _controller = TextEditingController(); + late final FocusNode _focusNode = FocusNode( + onKeyEvent: (_, event) { + if (!HardwareKeyboard.instance.isShiftPressed && + event.logicalKey == LogicalKeyboardKey.enter) { + if (event is KeyDownEvent) _submit(); + return KeyEventResult.handled; + } else { + return KeyEventResult.ignored; + } + }, + ); + + Chat? _chat; + + @override + void initState() { + super.initState(); + ModelManager.instance.addListener(onUpdate); + ChatManager.instance.addListener(onChatUpdate); + onChatUpdate(); + } + + @override + void dispose() { + _controller.dispose(); + _focusNode.dispose(); + ModelManager.instance.removeListener(onUpdate); + ChatManager.instance.removeListener(onChatUpdate); + super.dispose(); + } + + void onUpdate() { + if (mounted) setState(() {}); + } + + void onChatUpdate() { + final chat = ChatManager.instance.currentChat; + if (chat != _chat) { + _chat?.removeListener(onUpdate); + _chat = chat; + _chat?.addListener(onUpdate); + } + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) setState(() {}); + }); + } + + Future _submit() async { + final text = _controller.text.trim(); + if (text.isEmpty) return; + + var chat = ChatManager.instance.currentChat; + final isNewChat = chat == null; + if (isNewChat) { + chat = ChatManager.instance.createChat(context: context); + context.router.navigate(RouteChat(chatId: chat.id)); + } + + _controller.clear(); + + await errorGuard( + context, + "N89P97ND", + () async => chat!.send(TextMessage(text, sender: .user)), + errorMessage: errorGuardErrorMessageWithFallbackSingle( + llama.OllamaException, + "Unable to send message", + ), + enableReporting: false, + ); + + if (!mounted || !chat.alive || !isNewChat) return; + await errorGuard( + context, + "A02A05PB", + () async => chat!.generateTitle(context: context, think: true), + errorMessage: errorGuardErrorMessageWithFallbackSingle( + llama.OllamaException, + "Unable to generate chat title", + ), + ); + } + + @override + Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); + final textTheme = TextTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final adaptiveOnSurface = adaptedOnSurfaceFromColorScheme(colorScheme); + + final enabled = ModelManager.instance.currentModel != null; + final opacity = enabled ? 1.0 : kDisabledOpacity; + + Widget enabledWidget({required Widget child}) => IgnorePointer( + ignoring: !enabled, + child: Opacity(opacity: opacity, child: child), + ); + + Padding leadingTrailingPaddingMap(e) => Padding( + padding: const EdgeInsetsGeometry.symmetric(vertical: 8), + child: e, + ); + final leading = [ + enabledWidget( + child: IconButton( + onPressed: () {}, + icon: const Icon(Icons.add_rounded), + ), + ), + ]; + final trailing = [ + TwoStateWidgetManaged( + state: _chat?.completer.isCompleted ?? true, + from: IconButton.outlined( + onPressed: () => _chat?.completer.complete(), + icon: const Icon(Icons.stop_rounded), + ), + to: enabledWidget( + child: IconButton.filled( + onPressed: () {}, + icon: const Icon(Icons.arrow_upward_rounded), + ), + ), + ), + ]; + + return ConstrainedBox( + constraints: const BoxConstraints(minHeight: 56.0), + child: Material( + shadowColor: colorScheme.shadow, + elevation: 1, + shape: RoundedRectangleBorder( + side: BorderSide(color: adaptiveOnSurface, width: 1), + borderRadius: const BorderRadius.all(Radius.circular(56 / 2)), + ), + child: InkWell( + onTap: enabled + ? () { + if (!_focusNode.hasFocus) _focusNode.requestFocus(); + } + : null, + overlayColor: const WidgetStatePropertyAll(Colors.transparent), + customBorder: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(56 / 2)), + ), + mouseCursor: enabled + ? SystemMouseCursors.text + : SystemMouseCursors.basic, + child: Padding( + padding: const EdgeInsetsGeometry.symmetric(horizontal: 8.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + ...leading.map(leadingTrailingPaddingMap), + Expanded( + child: Padding( + padding: const EdgeInsetsGeometry.symmetric( + horizontal: 8.0, + vertical: (56 - 24) / 2, + ), + child: Semantics( + inputType: SemanticsInputType.text, + child: Opacity( + opacity: opacity, + child: TextField( + autofocus: true, + onTapAlwaysCalled: true, + focusNode: _focusNode, + onSubmitted: (value) => _submit(), + controller: _controller, + style: textTheme.bodyLarge?.copyWith( + color: colorScheme.onSurface, + ), + enabled: enabled, + minLines: 1, + maxLines: 9, + decoration: + InputDecoration( + hintText: appLocalizations.messageInputPlaceholder( + Model.nameColoredStatic( + name: ModelManager + .instance + .currentModelName, + context: context, + )?.first.text ?? + appLocalizations + .messageInputPlaceholderModelPlaceholder, + ), + ).applyDefaults( + InputDecorationThemeData( + hintStyle: textTheme.bodyLarge?.copyWith( + color: colorScheme.onSurfaceVariant, + ), + enabledBorder: InputBorder.none, + border: InputBorder.none, + focusedBorder: InputBorder.none, + contentPadding: EdgeInsets.zero, + isDense: true, + ), + ), + textInputAction: TextInputAction.newline, + keyboardType: TextInputType.multiline, + ), + ), + ), + ), + ), + ...trailing.map(leadingTrailingPaddingMap), + ], + ), + ), + ), + ), + ); + } +} + +class ChatDetails extends StatelessWidget { + final VoidCallback? onClose; + final EdgeInsetsGeometry padding; + const ChatDetails({ + super.key, + this.onClose, + this.padding = const EdgeInsetsGeometry.directional( + start: 24, + end: 16, + top: 16, + bottom: 24, + ), + }); + + @override + Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final currentChat = ChatManager.instance.currentChat; + + return Padding( + padding: padding, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Text( + appLocalizations.optionChatDetails, + style: TextStyle( + color: colorScheme.onSurfaceVariant, + fontSize: 22, + ), + ), + ), + const SizedBox(width: 12), + IconButton(onPressed: onClose, icon: const Icon(Icons.close)), + ], + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsetsGeometry.directional(end: 8), + child: SizedBox( + width: double.infinity, + // TODO: implement proper details view + child: SingleChildScrollView( + child: Text( + currentChat != null + ? "${currentChat.title}\n\nstats:\n${JsonEncoder.withIndent(" " * 2).convert(currentChat.messages.whereType().lastOrNull?.stats?.toJson() ?? {})}" + : appLocalizations.optionChatDetailsNoChat, + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/main.dart b/lib/screens/main.dart index 9e54c5d..893966a 100644 --- a/lib/screens/main.dart +++ b/lib/screens/main.dart @@ -1,6 +1,18 @@ -import 'package:flutter/material.dart'; -import 'package:ollama_dart/ollama_dart.dart'; -import 'package:scroll_to_index/scroll_to_index.dart'; +import 'dart:async'; +import 'dart:ui'; + +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart' hide RouteSettings; +import 'package:ollama_dart/ollama_dart.dart' as llama; + +import '../l10n/gen/app_localizations.dart'; +import '../main.dart'; +import '../main.gr.dart'; +import '../services/services.dart'; +import '../widgets/model_selector.dart'; +import '../widgets/two_state_widget.dart'; +import 'chat.dart'; +import 'settings.dart'; // import 'package:flutter_chat_types/flutter_chat_types.dart' as types; // import 'package:flutter_chat_ui/flutter_chat_ui.dart' as chat_ui; @@ -15,12 +27,6 @@ import 'package:scroll_to_index/scroll_to_index.dart'; // import '../l10n/gen/app_localizations.dart'; // import '../main.dart'; -import '../l10n/gen/app_localizations.dart'; -import '../main.dart'; -import '../services/chat.dart'; -import '../services/error.dart'; -import '../services/markdown.dart'; -import '../services/model.dart'; // import '../services/model.dart'; // import '../services/preferences.dart'; // import '../worker/desktop.dart'; @@ -1770,6 +1776,7 @@ import '../services/model.dart'; // } // } +@RoutePage() class ScreenMain extends StatefulWidget { const ScreenMain({super.key}); @@ -1777,42 +1784,64 @@ class ScreenMain extends StatefulWidget { State createState() => _ScreenMainState(); } -class _ScreenMainState extends State { +class _ScreenMainState extends State + with SingleTickerProviderStateMixin { + bool _thirdPaneOpen = false; + + bool isSettingsRoute = false; + late final bool startedAtSettingsRoute; + PageController? _sidebarController; + + final FocusNode _searchBarFocusNode = FocusNode(); + final TextEditingController _searchBarController = TextEditingController(); + + late final AnimationController _searchBarFocusController; + late final CurvedAnimation _searchBarFocusCurved; + + final _modelSelectorKey = GlobalKey(); + @override void initState() { super.initState(); + setIsSettingsRoute(); + startedAtSettingsRoute = isSettingsRoute; - host = "https://raspimainollama.tunler.net"; ChatManager.instance.addListener(onUpdate); ModelManager.instance.addListener(onUpdate); + HostManager.instance.addListener(onUpdate); - prefsReady.future.then((_) async { - if (!mounted) return; + if (HostManager.instance.host != null) { errorGuard( context, "Q3L4Z1X6", - () async { - await ModelManager.instance.loadModels(); - - if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text("Models: ${ModelManager.instance.models.length}"), - ), - ); - }, + () async => ModelManager.instance.loadModels(), errorMessage: errorGuardErrorMessageWithFallbackSingle( - OllamaClientException, + llama.OllamaException, "Unable to load models", ), enableReporting: false, ); + } - await ChatManager.instance.loadChats(); + _searchBarFocusController = AnimationController( + vsync: this, + duration: ExpressiveCurves.expressiveSpatial.fastDuration, + reverseDuration: ExpressiveCurves.expressiveSpatial.fastDuration, + ); + _searchBarFocusCurved = CurvedAnimation( + parent: _searchBarFocusController, + curve: ExpressiveCurves.expressiveSpatial.fast, + reverseCurve: ExpressiveCurves.expressiveSpatial.fast.flipped, + ); + + _searchBarFocusNode.addListener(() { if (!mounted) return; - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar(content: Text("Chats: ${ChatManager.instance.chats.length}")), - // ); + if (_searchBarFocusNode.hasFocus) { + _searchBarFocusController.forward(); + } else { + _searchBarFocusController.reverse(); + } + setState(() {}); }); } @@ -1820,121 +1849,779 @@ class _ScreenMainState extends State { void dispose() { ChatManager.instance.removeListener(onUpdate); ModelManager.instance.removeListener(onUpdate); + HostManager.instance.removeListener(onUpdate); + + _searchBarFocusNode.dispose(); + _searchBarController.dispose(); + _searchBarFocusCurved.dispose(); + _searchBarFocusController.dispose(); + _sidebarController?.dispose(); + super.dispose(); } void onUpdate() { - if (mounted) setState(() {}); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) setState(() {}); + }); } - bool test = false; - double testSlider = 0.5; + void setIsSettingsRoute() { + isSettingsRoute = context.router.currentPath.contains("/settings"); + + var page = isSettingsRoute ? 1 : 0; + if (_sidebarController != null && _sidebarController!.hasClients) { + if (startedAtSettingsRoute) page = page == 0 ? 1 : 0; + _sidebarController!.animateToPage( + page, + duration: ExpressiveCurves.expressiveEffects.slowDuration, + curve: ExpressiveCurves.expressiveEffects.slow, + ); + } else { + _sidebarController = PageController(initialPage: 0); + } + } @override Widget build(BuildContext context) { - return Scaffold( - body: ListView( - children: [ - ...ChatManager.instance.chats.map( - (chat) => ScreenMainChatTile(chat: chat), + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + final textTheme = theme.textTheme; + final appLocalizations = AppLocalizations.of(context); + + final adaptedSurface = adaptedSurfaceFromColorScheme(colorScheme); + final adaptedOnSurface = adaptedOnSurfaceFromColorScheme(colorScheme); + final breakpoint = Breakpoint.of(context); + + final chatsSearched = ChatManager.instance.chats.where((chat) { + final searchTerm = _searchBarController.text.toLowerCase(); + return chat.title.toLowerCase().contains(searchTerm) || + chat.messages.any( + (message) => + message is TextMessage && + message.content.toLowerCase().contains(searchTerm), + ); + }).toList(); + + if (breakpoint != Breakpoint.extraLarge) _thirdPaneOpen = false; + final embeddedNavigation = breakpoint.panesRecommended >= 2; + + final navigationRail = Transform.translate( + offset: const Offset(0, -8), + child: _ScreenMainNavigationBarWide( + adaptedSurface: adaptedSurface, + isSettingsRoute: isSettingsRoute, + onDestinationSelected: () { + setIsSettingsRoute(); + if (mounted) setState(() {}); + }, + ), + ); + + final children = [ + AnimatedSwitcher( + duration: ExpressiveCurves.expressiveSpatial.normalDuration, + switchInCurve: ExpressiveCurves.expressiveSpatial.normal, + switchOutCurve: ExpressiveCurves.expressiveSpatial.normal.flipped, + transitionBuilder: (child, animation) => SizeTransition( + sizeFactor: animation, + axis: Axis.horizontal, + alignment: const AlignmentDirectional(0.75, 0.5), + child: child, + ), + child: embeddedNavigation + ? navigationRail + : SizedBox(width: breakpoint.spacing), + ), + AnimatedContainer( + duration: ExpressiveCurves.standardSpatial.fastDuration, + curve: ExpressiveCurves.standardEffects.fast, + padding: breakpoint.panesRecommended >= 2 + ? EdgeInsetsDirectional.only(end: breakpoint.spacing) + : EdgeInsetsDirectional.zero, + child: AnimatedSwitcher( + duration: ExpressiveCurves.expressiveSpatial.normalDuration, + switchInCurve: ExpressiveCurves.expressiveSpatial.normal, + switchOutCurve: ExpressiveCurves.expressiveSpatial.normal.flipped, + transitionBuilder: (child, animation) => SizeTransition( + sizeFactor: animation, + axis: Axis.horizontal, + alignment: const AlignmentDirectional(0.25, 0.5), + child: child, ), - ListTile( - title: const Text("Add chat"), - onTap: () async { - if (ModelManager.instance.models.isEmpty) return; - var chat = ChatManager.instance.createChat( - context: context, - model: ModelManager.instance.models.first, - ); + child: breakpoint.panesRecommended >= 2 + ? Builder( + builder: (context) { + final children = [ + ClipRRect( + borderRadius: const BorderRadius.vertical( + top: Radius.circular(56 * (2 / 3)), + ), + child: chatsSearched.isEmpty + ? Padding( + padding: EdgeInsetsGeometry.only( + top: 64, + bottom: breakpoint.spacing, + ), + child: Center( + child: Padding( + padding: const EdgeInsets.all(24), + child: Text( + _searchBarController.text.isEmpty + ? appLocalizations.optionNoChatFound + : appLocalizations + .optionNoChatFoundSearch( + _searchBarController.text, + ), + style: textTheme.labelLarge!.copyWith( + color: colorScheme.outline, + ), + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ) + : ListView.builder( + padding: EdgeInsetsGeometry.only( + top: 64, + bottom: breakpoint.spacing, + ), + itemBuilder: (context, index) { + final chat = chatsSearched.elementAtOrNull( + index, + ); + if (chat == null) return null; + return ListTile( + title: Text(chat.title), + trailing: IconButton( + onPressed: () => + ChatManager.instance.deleteChat(chat), + icon: const Icon(Icons.delete_outline), + ), + ); + }, + ), + ), + DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + adaptedSurface, + adaptedSurface.withAlpha(0), + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + stops: const [0.25, 1.0], + ), + ), + child: const SizedBox( + width: double.infinity, + height: 56, + ), + ), + AnimatedBuilder( + animation: _searchBarFocusCurved, + builder: (context, child) => LayoutBuilder( + builder: (context, constraints) { + final padding = lerpDouble( + 12.0, + 0.0, + _searchBarFocusCurved.value, + )!; + return OverflowBox( + maxWidth: double.infinity, + alignment: AlignmentGeometry.topCenter, + child: SizedBox( + width: constraints.maxWidth - padding * 2, + child: child, + ), + ); + }, + ), + child: SearchBar( + hintText: appLocalizations.optionSearchChats, + leading: TwoStateWidget( + animation: _searchBarFocusCurved, + from: IconButton( + onPressed: null, + disabledColor: IconTheme.of(context).color, + icon: const Icon(Icons.search), + ), + to: IconButton( + onPressed: () { + _searchBarFocusNode.unfocus(); + onUpdate(); + }, + icon: const Icon(Icons.chevron_left), + ), + ), + elevation: WidgetStateProperty.all(0), + focusNode: _searchBarFocusNode, + controller: _searchBarController, + onChanged: (value) => onUpdate(), + ), + ), + ]; - await errorGuard( - context, - "M49WC9CW", - () async { - var msg = TextMessage( - "Write a long demo message for all GitHub Flavored Markdown features.", - sender: MessageSender.user, - ); - return chat.send(msg); - }, - errorMessage: errorGuardErrorMessageWithFallbackSingle( - OllamaClientException, - "Unable to send message", - ), - enableReporting: false, - ); + var pageViewChildren = [ + Stack(children: children), + const SettingsOptions(embeddedNavigation: true), + ]; + if (startedAtSettingsRoute) { + pageViewChildren = pageViewChildren.reversed.toList(); + } - if (!context.mounted || !chat.alive) return; - await errorGuard( - context, - "W97BM0DJ", - () async => chat.generateTitle(context: context), - errorMessage: errorGuardErrorMessageWithFallbackSingle( - OllamaClientException, - "Unable to generate chat title", - ), - ); + return SizedBox( + width: breakpoint.panesFixedWidth, + child: PageView( + controller: _sidebarController, + physics: const NeverScrollableScrollPhysics(), + scrollDirection: Axis.horizontal, + clipBehavior: Clip.antiAliasWithSaveLayer, + children: pageViewChildren, + ), + ); + }, + ) + : null, + ), + ), + Expanded( + child: Builder( + builder: (context) { + const radius = BorderRadius.vertical(top: Radius.circular(12)); + final border = BorderSide( + width: 2, + color: colorScheme.surfaceContainerHigh, + ); + + return AnimatedContainer( + duration: ExpressiveCurves.standardSpatial.fastDuration, + curve: ExpressiveCurves.standardEffects.fast, + decoration: breakpoint.panesRecommended >= 2 + ? BoxDecoration( + borderRadius: radius, + border: Border(top: border, left: border, right: border), + ) + : const BoxDecoration(), + child: const ClipRRect(borderRadius: radius, child: AutoRouter()), + ); + }, + ), + ), + AnimatedContainer( + duration: ExpressiveCurves.standardSpatial.fastDuration, + curve: ExpressiveCurves.standardEffects.fast, + padding: breakpoint.panes.contains(3) && _thirdPaneOpen + ? EdgeInsetsDirectional.only(start: breakpoint.spacing) + : EdgeInsetsDirectional.zero, + child: Card.filled( + margin: EdgeInsets.zero, + color: adaptedOnSurface, + child: AnimatedSwitcher( + duration: ExpressiveCurves.expressiveSpatial.normalDuration, + switchInCurve: ExpressiveCurves.expressiveSpatial.normal, + switchOutCurve: ExpressiveCurves.expressiveSpatial.normal.flipped, + transitionBuilder: (child, animation) => SizeTransition( + sizeFactor: animation, + axis: Axis.horizontal, + alignment: const AlignmentDirectional(0.25, 0.5), + child: child, + ), + child: breakpoint.panes.contains(3) && _thirdPaneOpen + ? SizedBox( + width: breakpoint.panesThirdFixedWidth, + child: ChatDetails( + onClose: () { + _thirdPaneOpen = false; + if (mounted) setState(() {}); + }, + ), + ) + : null, + ), + ), + ), + SizedBox(width: breakpoint.spacing), + ]; + + final modelSelectorAnimationDuration = + ExpressiveCurves.standardEffects.fastDuration; + final modelSelectorAnimationCurve = ExpressiveCurves.standardEffects.fast; + + final modelHostSelected = HostManager.instance.host != null; + final modelSelector = GestureDetector( + key: _modelSelectorKey, + onTap: !modelHostSelected + ? null + : () { + showModelSelector(context: context, anchorKey: _modelSelectorKey); + }, + child: Opacity( + opacity: !modelHostSelected ? kDisabledOpacity : 1.0, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text.rich( + TextSpan( + children: + Model.nameColoredStatic( + name: ModelManager.instance.currentModelName, + context: context, + ) ?? + [TextSpan(text: appLocalizations.noSelectedModel)], + ), + style: textTheme.titleMedium!.copyWith( + fontFamily: "GoogleSansCode", + ), + ), + SizedBox(width: breakpoint.spacing / 8), + const Icon(Icons.keyboard_arrow_down), + ], + ), + ), + ); + final modelSelectorShowSubtitle = breakpoint.panesRecommended >= 2; + final modelSelectorOffset = modelSelectorShowSubtitle + ? 80.0 + + (breakpoint.panesFixedWidth ?? 0) + + breakpoint.spacing - + NavigationToolbar.kMiddleSpacing - + kToolbarHeight + : 0.0; + + return Scaffold( + backgroundColor: adaptedSurface, + endDrawer: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 400), + child: DecoratedBox( + decoration: BoxDecoration( + color: colorScheme.surfaceContainerLow, + borderRadius: const BorderRadiusDirectional.only( + topStart: Radius.circular(16), + bottomStart: Radius.circular(16), + ), + ), + child: ChatDetails( + onClose: () { + if (Navigator.of(context).canPop()) { + Navigator.of(context).pop(); + } }, ), - ], + ), ), + appBar: AppBar( + clipBehavior: Clip.none, + leading: TwoStateWidgetManaged( + state: breakpoint.panesRecommended >= 2, + dimension: kToolbarHeight, + from: const DrawerBackButton(), + to: Transform.translate( + offset: const Offset(12, 2), + child: const Padding( + padding: EdgeInsetsGeometry.only(top: 8), + child: ImageIcon(kImageLogo), + ), + ), + ), + actions: [ + TwoStateWidgetManaged( + state: isSettingsRoute, + from: SizedBox.square( + dimension: kToolbarHeight, + child: Builder( + builder: (context) => IconButton( + icon: const Icon(Icons.info_outline), + tooltip: appLocalizations.optionChatDetails, + onPressed: () { + if (breakpoint.panes.contains(3)) { + _thirdPaneOpen = !_thirdPaneOpen; + if (mounted) setState(() {}); + } else { + Scaffold.of(context).openEndDrawer(); + } + }, + ), + ), + ), + ), + ], + title: SizedBox( + width: double.infinity, + height: theme.appBarTheme.toolbarHeight ?? kToolbarHeight, + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + AnimatedPositionedDirectional( + key: const ValueKey("modelSelectorSubtitle"), + duration: modelSelectorAnimationDuration, + curve: modelSelectorAnimationCurve, + start: modelSelectorShowSubtitle ? modelSelectorOffset : 64, + child: AnimatedSlide( + offset: Offset( + 0, + modelHostSelected || !modelSelectorShowSubtitle ? 0 : 0.7, + ), + duration: modelSelectorAnimationDuration, + curve: modelSelectorAnimationCurve, + child: IgnorePointer( + child: AnimatedOpacity( + opacity: modelHostSelected || !modelSelectorShowSubtitle + ? 0 + : 1, + duration: modelSelectorAnimationDuration, + curve: modelSelectorAnimationCurve, + child: Text( + appLocalizations.noHostSelected, + style: textTheme.labelSmall, + overflow: TextOverflow.ellipsis, + maxLines: 1, + softWrap: false, + ), + ), + ), + ), + ), + AnimatedPositionedDirectional( + key: const ValueKey("modelSelectorButton"), + duration: modelSelectorAnimationDuration, + curve: modelSelectorAnimationCurve, + start: modelSelectorShowSubtitle ? modelSelectorOffset : null, + child: AnimatedSlide( + offset: Offset( + 0, + modelHostSelected || !modelSelectorShowSubtitle ? 0 : -0.2, + ), + duration: modelSelectorAnimationDuration, + curve: modelSelectorAnimationCurve, + child: modelSelector, + ), + ), + ], + ), + ), + centerTitle: breakpoint.panesRecommended < 2, + backgroundColor: adaptedSurface, + scrolledUnderElevation: 0, + ), + body: Builder( + builder: (context) { + if (breakpoint == Breakpoint.extraLarge && + Scaffold.of(context).isEndDrawerOpen) { + _thirdPaneOpen = true; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; + setState(() {}); + Navigator.of(context).pop(); + }); + } + + return Row(mainAxisSize: MainAxisSize.max, children: children); + }, + ), + ); + + // return Scaffold( + // body: ListView( + // children: [ + // Padding( + // padding: const EdgeInsetsGeometry.only( + // top: 16, + // left: 16, + // right: 16, + // bottom: 8, + // ), + // child: Card.filled( + // margin: EdgeInsets.zero, + // clipBehavior: Clip.antiAlias, + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // ListTile( + // title: Text( + // HostManager.instance.host?.toString() ?? "", + // ), + // onTap: loadingModels + // ? null + // : () async { + // loadingModels = true; + // HostManager.instance.host = Uri.parse( + // HostManager.instance.host.toString() == + // "https://ollama.tunler.net" + // ? "https://raspimainollama.tunler.net" + // : "https://ollama.tunler.net", + // ); + // setState(() {}); + + // await loadModels(); + // }, + // dense: true, + // ), + // const Divider(height: 1), + // AnimatedSize( + // duration: Durations.medium1, + // curve: Curves.easeInOutCubic, + // child: ListTile( + // title: ModelManager.instance.models.isEmpty + // ? const Text("No models available") + // : Text.rich( + // TextSpan( + // children: [ + // const TextSpan( + // text: "Models: ", + // style: TextStyle( + // fontStyle: FontStyle.italic, + // ), + // ), + // for ( + // var i = 0; + // i < + // ModelManager.instance.models.length * + // 2 - + // 1; + // i++ + // ) + // if (i.isEven) + // TextSpan( + // text: ModelManager.instance.models + // .elementAt(i ~/ 2) + // .name, + // style: i ~/ 2 == modelIndex + // ? const TextStyle( + // fontWeight: FontWeight.bold, + // ) + // : null, + // ) + // else + // const TextSpan(text: ", "), + // ], + // ), + // ), + // onTap: + // loadingModels || ModelManager.instance.models.isEmpty + // ? null + // : () async { + // final currentIndex = modelIndex; + // if (currentIndex == null) return; + + // final nextIndex = + // (currentIndex + 1) % + // ModelManager.instance.models.length; + // modelIndex = nextIndex; + // ModelManager.instance.currentModel = ModelManager + // .instance + // .models + // .elementAt(nextIndex); + // setState(() {}); + // }, + // dense: true, + // ), + // ), + // ], + // ), + // ), + // ), + + // ...ChatManager.instance.chats.map( + // (chat) => ScreenMainChatTile(chat: chat, chatsLoaded: chatsLoaded), + // ), + // MenuAnchor( + // animated: true, + // menuChildren: + // <(String, String)>[ + // ( + // "GFM demo", + // "Write a long demo message for all GitHub Flavored Markdown features.", + // ), + // ( + // "Lorem Ipsum", + // "Write a middle long lorem ipsum stand in body text.", + // ), + // ( + // "Best emoji", + // "Think very hard about the objectively best emoji.", + // ), + // ( + // "Math test", + // "Calculate the normalized Shannon entropy for the following values: [0.1, 0.1, 0.2, 0.3, 0.3]", + // ), + // ].map((prompt) { + // return MenuItemButton( + // child: Text( + // prompt.$1, + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // ), + // onPressed: () async { + // final chat = ChatManager.instance.createChat( + // context: context, + // system: + // "Write using GitHub Flavored Markdown messages. Your messages support all GitHub Flavored Markdown features, including tables, task lists, strikethrough, alert boxes, emojis and autolinks. You must format LaTeX math using the dollar sign syntax (`\$...\$`); bracket style does not work! Speak german to the user, even if he doesn't write you in that language!", + // ); + + // await errorGuard( + // context, + // "M49WC9CW", + // () async { + // final msg = TextMessage( + // prompt.$2, + // sender: MessageSender.user, + // ); + // return chat.send(msg); + // }, + // errorMessage: errorGuardErrorMessageWithFallbackSingle( + // llama.OllamaException, + // "Unable to send message", + // ), + // enableReporting: false, + // ); + + // if (!context.mounted || !chat.alive) return; + // await errorGuard( + // context, + // "W97BM0DJ", + // () async => chat.generateTitle(context: context), + // errorMessage: errorGuardErrorMessageWithFallbackSingle( + // llama.OllamaException, + // "Unable to generate chat title", + // ), + // ); + // }, + // ); + // }).toList(), + // builder: (_, controller, _) => ListTile( + // leading: const Icon(Icons.add_rounded), + // title: const Text("Add chat"), + // onTap: loadingModels || ModelManager.instance.currentModel == null + // ? null + // : controller.open, + // ), + // ), + // ], + // ), + // ); + } +} + +class _ScreenMainNavigationBarWide extends StatelessWidget { + final Color adaptedSurface; + final bool isSettingsRoute; + final void Function()? onDestinationSelected; + const _ScreenMainNavigationBarWide({ + required this.adaptedSurface, + required this.isSettingsRoute, + this.onDestinationSelected, + }); + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + final isEmbeddedNavigation = breakpoint.panesRecommended >= 2; + + return NavigationRail( + leadingAtTop: true, + trailingAtBottom: true, + backgroundColor: adaptedSurface, + leading: FloatingActionButton( + onPressed: () async { + ChatManager.instance.currentChat = null; + if (isSettingsRoute) { + await context.router.navigate(const RouteNewChat()); + onDestinationSelected?.call(); + } + }, + elevation: 0, + heroTag: null, + child: const Icon(Icons.add), + ), + destinations: const [ + NavigationRailDestination( + icon: Icon(Icons.near_me), + label: Text("Chats"), + ), + NavigationRailDestination( + icon: Icon(Icons.settings), + label: Text("Settings"), + ), + ], + selectedIndex: isSettingsRoute ? 1 : 0, + onDestinationSelected: (value) async { + switch (value) { + case 0 when isSettingsRoute: + await context.router.navigate( + ChatManager.instance.currentChatId != null + ? RouteChat(chatId: ChatManager.instance.currentChatId) + : const RouteNewChat(), + ); + onDestinationSelected?.call(); + case 1 when !isSettingsRoute: + await context.router.navigate( + isEmbeddedNavigation + ? const RouteSettingsOverview() + : const RouteSettings(), + ); + onDestinationSelected?.call(); + default: + } + }, ); } } -class ScreenMainChatTile extends StatefulWidget { - final Chat chat; - - const ScreenMainChatTile({super.key, required this.chat}); +class DrawerBackButton extends StatefulWidget { + const DrawerBackButton({super.key}); @override - State createState() => _ScreenMainChatTileState(); + State createState() => _DrawerBackButtonState(); } -class _ScreenMainChatTileState extends State { +class _DrawerBackButtonState extends State { + StreamSubscription? _routerStream; + String? path; + @override void initState() { super.initState(); - widget.chat.addListener(onChange); + path = GlobalNavigationObserver.path; + _routerStream = GlobalNavigationObserver.routerStream.listen(onUpdate); } @override void dispose() { - widget.chat.removeListener(onChange); + _routerStream?.cancel(); super.dispose(); } - void onChange() { - if (mounted) setState(() {}); + void onUpdate(_) { + if (GlobalNavigationObserver.path != null) { + path = GlobalNavigationObserver.path; + if (mounted) setState(() {}); + } } @override Widget build(BuildContext context) { - return ListTile( - title: ChatText( - widget.chat.title.emptyOn(AppLocalizations.of(context).newChatTitle), - placeholder: Text(AppLocalizations.of(context).newChatTitle), + final isSettingsRoute = path?.contains("/settings") ?? false; + final state = isSettingsRoute && path != "/settings"; + return TwoStateWidgetManaged( + state: state, + from: const SizedBox.expand(child: DrawerButton()), + to: SizedBox.expand( + child: BackButton( + onPressed: () async { + if (!state) return; + if (context.router.canPop()) { + context.router.popTop(); + } else { + await context.router.navigate(const RouteSettings()); + } + if (mounted) setState(() {}); + }, + ), ), - subtitle: - (widget.chat.messages.isEmpty || - widget.chat.messages.last.runtimeType != TextMessage) - ? null - // : ChatText( - // (widget.chat.messages.last as TextMessage).content, - // placeholder: const Text(""), - // ), - : (widget.chat.messages.last as TextMessage).content.isEmpty - ? const LinearProgressIndicator() - : Text.rich( - Markdown( - (widget.chat.messages.last as TextMessage).content, - ).toTextSpan(context), - ), - onTap: () => ChatManager.instance.deleteChat(widget.chat), ); } } - -extension on String { - String emptyOn(String other) => (this == other) ? "" : this; -} diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 6fc1102..bab9089 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,312 +1,28 @@ import 'dart:async'; -import 'dart:convert'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; -import 'package:dartx/dartx.dart'; -import 'package:dynamic_color/dynamic_color.dart'; -import 'package:flutter/material.dart'; -import 'package:http/http.dart' as http; -import 'package:transparent_image/transparent_image.dart'; -import 'package:version/version.dart'; +import 'package:auto_route/auto_route.dart'; +import 'package:dynamic_system_colors/dynamic_system_colors.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart' hide RouteSettings; import '../l10n/gen/app_localizations.dart'; import '../main.dart'; -import '../worker/desktop.dart'; -import '../worker/haptic.dart'; -import '../worker/setter.dart'; -import '../worker/update.dart'; -import 'settings/about.dart'; -import 'settings/behavior.dart'; -import 'settings/export.dart'; -import 'settings/interface.dart'; -import 'settings/voice.dart'; +import '../main.gr.dart'; +import '../services/services.dart'; +import '../widgets/alpha_beta.dart'; +import '../widgets/child_size_notifier.dart'; +import '../widgets/sized_circular_progress_indicator.dart'; +import '../widgets/two_state_widget.dart'; -Widget toggle(BuildContext context, String text, bool value, - Function(bool value) onChanged, - {bool disabled = false, - void Function()? onDisabledTap, - void Function()? onLongTap, - void Function()? onDoubleTap, - Widget? icon, - bool? iconAfterwards}) { - return InkWell( - enableFeedback: false, - splashFactory: NoSplash.splashFactory, - highlightColor: Colors.transparent, - hoverColor: Colors.transparent, - onTap: () { - if (disabled) { - selectionHaptic(); - if (onDisabledTap != null) { - onDisabledTap(); - } - } else { - onChanged(!value); - } - }, - onLongPress: onLongTap, - onDoubleTap: onDoubleTap, - child: Padding( - padding: const EdgeInsets.only(top: 4, bottom: 4), - child: Row(children: [ - Expanded( - child: LayoutBuilder(builder: (context, constraints) { - return Row(mainAxisSize: MainAxisSize.max, children: [ - (icon != null && !(iconAfterwards ?? false)) - ? Padding( - padding: const EdgeInsets.only(right: 8), - child: icon, - ) - : const SizedBox.shrink(), - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: constraints.maxWidth - (icon != null ? 32 : 0)), - child: Text(text, - overflow: TextOverflow.ellipsis, - maxLines: 1, - style: TextStyle(color: disabled ? Colors.grey : null)), - ), - (icon != null && (iconAfterwards ?? false)) - ? Transform.translate( - offset: const Offset(0, 1), - child: Padding( - padding: const EdgeInsets.only(left: 8), - child: icon, - )) - : const SizedBox.shrink(), - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 16), - child: Divider(color: Theme.of(context).dividerColor)), - ), - ]); - }), - ), - Padding( - padding: const EdgeInsets.only(left: 16), - child: Switch( - value: value, - onChanged: disabled - ? (onDisabledTap != null) - ? (p0) { - selectionHaptic(); - onDisabledTap(); - } - : null - : onChanged, - activeTrackColor: disabled - ? Theme.of(context).colorScheme.primary.withAlpha(50) - : null, - trackOutlineColor: disabled - ? WidgetStatePropertyAll( - Theme.of(context).colorScheme.primary.withAlpha(150)) - : null, - thumbColor: disabled - ? WidgetStatePropertyAll( - Theme.of(context).colorScheme.primary.withAlpha(150)) - : !(prefs?.getBool("useDeviceTheme") ?? false) && value - ? WidgetStatePropertyAll( - Theme.of(context).colorScheme.secondary) - : null)) - ]), - ), - ); -} - -Widget title(String text, {double top = 16, double bottom = 16}) { - return Padding( - padding: EdgeInsets.only(left: 8, right: 8, top: top, bottom: bottom), - child: Row(children: [ - const Expanded(child: Divider()), - Padding( - padding: const EdgeInsets.only(left: 24, right: 24), - child: Text(text)), - const Expanded(child: Divider()) - ])); -} - -Widget titleDivider({double? top, double? bottom, BuildContext? context}) { - top ??= (context != null && desktopLayoutNotRequired(context)) ? 32 : 16; - bottom ??= (context != null && desktopLayoutNotRequired(context)) ? 32 : 16; - return AnimatedContainer( - duration: const Duration(milliseconds: 200), - padding: EdgeInsets.only(left: 8, right: 8, top: top, bottom: bottom), - child: const Row( - mainAxisSize: MainAxisSize.max, - children: [Expanded(child: Divider())])); -} - -Widget verticalTitleDivider( - {double? left, double? right, BuildContext? context}) { - left ??= (context != null && desktopLayoutNotRequired(context)) ? 32 : 16; - right ??= (context != null && desktopLayoutNotRequired(context)) ? 32 : 16; - return AnimatedContainer( - duration: const Duration(milliseconds: 200), - padding: EdgeInsets.only(left: left, right: right, top: 8, bottom: 8), - child: const Row( - mainAxisSize: MainAxisSize.max, - children: [VerticalDivider(width: 1)])); -} - -Widget button(String text, IconData? icon, void Function()? onPressed, - {BuildContext? context, - Color? color, - bool disabled = false, - bool replaceIconIfNull = false, - String? description, - bool onlyDesktopDescription = true, - bool alwaysMobileDescription = false, - String? badge, - String? iconBadge, - bool? iconAfterwards, - void Function()? onDisabledTap, - void Function()? onLongTap, - void Function()? onDoubleTap}) { - if (description != null && - ((context != null && desktopLayoutNotRequired(context)) || - !onlyDesktopDescription) && - !alwaysMobileDescription && - !description.startsWith("\n")) { - description = " • $description"; - } - return AnimatedContainer( - duration: const Duration(milliseconds: 200), - padding: (context != null && desktopLayoutNotRequired(context)) - ? const EdgeInsets.only(top: 8, bottom: 8) - : EdgeInsets.zero, - child: InkWell( - enableFeedback: false, - // disable hint that clickable, other tap functions still functional - splashFactory: (onPressed == null) ? NoSplash.splashFactory : null, - highlightColor: (onPressed == null) ? Colors.transparent : null, - hoverColor: (onPressed == null) ? Colors.transparent : null, - onTap: disabled - ? () { - selectionHaptic(); - if (onDisabledTap != null) { - onDisabledTap(); - } - } - : (onPressed == null && (onLongTap != null || onDoubleTap != null)) - ? selectionHaptic - : onPressed, - onLongPress: (description != null && context != null) - ? (desktopLayoutNotRequired(context) && !alwaysMobileDescription) || - !onlyDesktopDescription - ? null - : () { - selectionHaptic(); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(description!.trim()), - showCloseIcon: true)); - } - : onLongTap, - onDoubleTap: onDoubleTap, - borderRadius: BorderRadius.circular(8), - child: Padding( - padding: const EdgeInsets.all(8), - child: Builder(builder: (context) { - var iconContent = (icon != null || replaceIconIfNull) - ? replaceIconIfNull - ? ImageIcon(MemoryImage(kTransparentImage)) - : Icon(icon, - color: disabled || (iconAfterwards ?? false) - ? Colors.grey - : color) - : const SizedBox.shrink(); - return Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - !(iconAfterwards ?? false) - ? (iconBadge == null) - ? iconContent - : Badge( - label: (iconBadge != "") ? Text(iconBadge) : null, - child: iconContent) - : const SizedBox.shrink(), - (icon != null || replaceIconIfNull) - ? SizedBox( - width: !(iconAfterwards ?? false) ? 16 : null, - height: 42) - : const SizedBox.shrink(), - Expanded(child: Builder(builder: (context) { - Widget textWidget = Text(text, - style: - TextStyle(color: disabled ? Colors.grey : color)); - if (badge != null) { - textWidget = Badge( - label: Text(badge), - offset: const Offset(20, -4), - backgroundColor: - Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - child: textWidget); - } - if (iconAfterwards ?? false) { - return Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - textWidget, - // same info distance as [toggle] - const SizedBox(width: 8), - Transform.translate( - offset: const Offset(0, 1), - child: (iconBadge == null) - ? iconContent - : Badge( - label: (iconBadge != "") - ? Text(iconBadge) - : null, - child: iconContent)), - ]); - } else { - if (description == null || - description!.startsWith("\n")) { - description = description?.removePrefix("\n"); - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - textWidget, - (description != null && - !alwaysMobileDescription && - (desktopLayoutNotRequired(context) || - !onlyDesktopDescription)) - ? Text(description!, - style: const TextStyle( - color: Colors.grey, - overflow: TextOverflow.ellipsis)) - : const SizedBox.shrink() - ]); - } else { - return Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - textWidget, - (description != null && - !alwaysMobileDescription && - (desktopLayoutNotRequired(context) || - !onlyDesktopDescription)) - ? Expanded( - child: Text(description!, - style: const TextStyle( - color: Colors.grey, - overflow: TextOverflow.ellipsis)), - ) - : const SizedBox.shrink() - ]); - } - } - })) - ]); - }), - )), - ); +@RoutePage() +class ScreenSettingsShell extends StatelessWidget { + const ScreenSettingsShell({super.key}); + + @override + Widget build(_) => const AutoRouter(); } +@RoutePage() class ScreenSettings extends StatefulWidget { const ScreenSettings({super.key}); @@ -315,460 +31,890 @@ class ScreenSettings extends StatefulWidget { } class _ScreenSettingsState extends State { - final hostInputController = TextEditingController( - text: useHost - ? fixedHost - : (prefs?.getString("host") ?? "http://localhost:11434")); - bool hostLoading = false; - bool hostInvalidUrl = false; - bool hostInvalidHost = false; - Future checkHost() async { - setState(() { - hostLoading = true; - hostInvalidUrl = false; - hostInvalidHost = false; - }); - var tmpHost = hostInputController.text.trim().removeSuffix("/").trim(); - - if (tmpHost.isEmpty || !Uri.parse(tmpHost).isAbsolute) { - setState(() { - hostInvalidUrl = true; - hostLoading = false; + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + if (breakpoint.panesRecommended >= 2) { + context.router.navigate(const RouteSettingsOverview()).then((_) { + if (!context.mounted) return; + context.router.removeWhere((e) => e.name == RouteSettings.page.name); }); - return; } - http.Response? request; - try { - // don't use centralized client because of unexplainable inconsistency - // between the ways of calling a request - var requestBase = http.Request("get", Uri.parse(tmpHost)) - ..headers.addAll( - (jsonDecode(prefs!.getString("hostHeaders") ?? "{}") as Map) - .cast(), - ) - ..followRedirects = false; - request = await http.Response.fromStream(await requestBase.send().timeout( - Duration( - milliseconds: - (5000.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round()), onTimeout: () { - return http.StreamedResponse(const Stream.empty(), 408); - })); - } catch (e) { - setState(() { - hostInvalidHost = true; - hostLoading = false; - }); - return; - } - if ((request.statusCode == 200 && request.body == "Ollama is running") || - (Uri.parse(tmpHost).toString() == fixedHost)) { - setState(() { - hostLoading = false; - host = tmpHost; - if (hostInputController.text != host! && - (Uri.parse(tmpHost).toString() != fixedHost)) { - hostInputController.text = host!; - } - }); - prefs?.setString("host", host!); - } else { - setState(() { - hostInvalidHost = true; - hostLoading = false; - }); - } - selectionHaptic(); + return const SizedBox.expand(child: SettingsOptions()); } +} - double iconSize = 1; - bool animatedInitialized = false; - bool animatedDesktop = false; +class SettingsOptions extends StatefulWidget { + final bool embeddedNavigation; + const SettingsOptions({super.key, this.embeddedNavigation = false}); + + @override + State createState() => _SettingsOptionsState(); +} + +class _SettingsOptionsState extends State { + StreamSubscription? _routerStream; + String? path; @override void initState() { super.initState(); - WidgetsFlutterBinding.ensureInitialized(); - if (Uri.parse(hostInputController.text.trim().removeSuffix("/").trim()) - .toString() != - fixedHost) { - checkHost(); - } + path = GlobalNavigationObserver.path; + _routerStream = GlobalNavigationObserver.routerStream.listen(onUpdate); } @override void dispose() { + _routerStream?.cancel(); super.dispose(); - hostInputController.dispose(); + } + + void onUpdate(_) { + if (GlobalNavigationObserver.path != null) { + path = GlobalNavigationObserver.path; + if (mounted) setState(() {}); + } } @override Widget build(BuildContext context) { - if (!animatedInitialized) { - animatedInitialized = true; - animatedDesktop = desktopLayoutNotRequired(context); - } - return PopScope( - canPop: !hostLoading, - onPopInvokedWithResult: (didPop, result) { - settingsOpen = false; - FocusManager.instance.primaryFocus?.unfocus(); + final colorScheme = ColorScheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + Widget optionTile({ + required String title, + required String? subtitle, + required Widget leading, + required PageRouteInfo route, + required String path, + bool isBetaFeature = false, + }) => AnimatedContainer( + duration: ExpressiveCurves.expressiveEffects.fastDuration, + curve: ExpressiveCurves.expressiveEffects.fast, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: + (this.path?.contains("/settings/$path") ?? false) && + widget.embeddedNavigation + ? Border.all(color: colorScheme.outline, width: 2) + : Border.all( + color: Theme.of( + context, + ).colorScheme.primary.withValues(alpha: 0), + width: 2, + ), + ), + child: ListTile( + leading: leading, + title: Beta(showBadge: isBetaFeature, child: Text(title)), + subtitle: subtitle != null ? Text(subtitle) : null, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + onTap: () async { + await context.router.navigate(route); + if (context.mounted) setState(() {}); }, - child: WindowBorder( - color: Theme.of(context).colorScheme.surface, - child: Scaffold( - appBar: AppBar( - title: Row(children: [ - Text(AppLocalizations.of(context).optionSettings), - Expanded( - child: SizedBox(height: 200, child: MoveWindow())) - ]), - actions: desktopControlsActions(context)), - body: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 1200), - padding: const EdgeInsets.only(left: 16, right: 16), - child: LayoutBuilder(builder: (context, constraints) { - var column1 = - Column(mainAxisSize: MainAxisSize.min, children: [ - AnimatedContainer( - duration: const Duration(milliseconds: 200), - height: animatedDesktop ? 8 : 0, - child: const SizedBox.shrink()), - const SizedBox(height: 8), - TextField( - controller: hostInputController, - keyboardType: TextInputType.url, - autofillHints: const [AutofillHints.url], - readOnly: useHost, - onSubmitted: (value) { - selectionHaptic(); - checkHost(); - }, - decoration: InputDecoration( - labelText: - AppLocalizations.of(context).settingsHost, - hintText: "http://localhost:11434", - prefixIcon: IconButton( - enableFeedback: false, - tooltip: AppLocalizations.of(context) - .tooltipAddHostHeaders, - onPressed: () async { - selectionHaptic(); - var tmp = await prompt(context, - placeholder: - '{"Authorization": "Bearer ..."}', - title: AppLocalizations.of(context) - .settingsHostHeaderTitle, - value: prefs! - .getString("hostHeaders") ?? - "", - enableSuggestions: false, - valueIfCanceled: "{}", - validator: (content) async { - try { - var tmp = jsonDecode(content); - tmp as Map; - return true; - } catch (_) { - return false; - } - }, - validatorError: - AppLocalizations.of(context) - .settingsHostHeaderInvalid, - prefill: !((prefs!.getString( - "hostHeaders") ?? - {}) == - "{}")); - prefs!.setString("hostHeaders", tmp); - }, - icon: const Icon(Icons.add_rounded)), - suffixIcon: useHost - ? const SizedBox.shrink() - : (hostLoading - ? Transform.scale( - scale: 0.5, - child: - const CircularProgressIndicator()) - : IconButton( - enableFeedback: false, - tooltip: - AppLocalizations.of(context) - .tooltipSave, - onPressed: () { - selectionHaptic(); - checkHost(); - }, - icon: const Icon( - Icons.save_rounded), - )), - border: const OutlineInputBorder(), - error: (hostInvalidHost || hostInvalidUrl) - ? InkWell( - onTap: () { - selectionHaptic(); - ScaffoldMessenger.of(context) - .showSnackBar(SnackBar( - content: Text(AppLocalizations - .of(context) - .settingsHostInvalidDetailed( - hostInvalidHost - ? "host" - : "url")), - showCloseIcon: true)); - }, - splashFactory: NoSplash.splashFactory, - highlightColor: Colors.transparent, - hoverColor: Colors.transparent, - child: Row( - children: [ - Icon(Icons.error_rounded, - color: Theme.of(context) - .colorScheme - .error), - const SizedBox(width: 8), - Text( - AppLocalizations.of(context) - .settingsHostInvalid( - hostInvalidHost - ? "host" - : "url"), - style: TextStyle( - color: Theme.of(context) - .colorScheme - .error)) - ], - )) - : null, - helper: InkWell( - onTap: selectionHaptic, - splashFactory: NoSplash.splashFactory, - highlightColor: Colors.transparent, - hoverColor: Colors.transparent, - child: hostLoading - ? Row( - children: [ - const Icon(Icons.search_rounded, - color: Colors.grey), - const SizedBox(width: 8), - Text( - AppLocalizations.of(context) - .settingsHostChecking, - style: const TextStyle( - color: Colors.grey, - fontFamily: - "monospace")) - ], - ) - : Row( - children: [ - Icon(Icons.check_rounded, - color: Colors.green - .harmonizeWith( - Theme.of(context) - .colorScheme - .primary)), - const SizedBox(width: 8), - Text( - AppLocalizations.of(context) - .settingsHostValid, - style: TextStyle( - color: Colors.green - .harmonizeWith( - Theme.of( - context) - .colorScheme - .primary), - fontFamily: - "monospace")) - ], - )))) - ]); - var column2 = - Column(mainAxisSize: MainAxisSize.min, children: [ - button( - AppLocalizations.of(context) - .settingsTitleBehavior, - Icons.psychology_rounded, () { - selectionHaptic(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const ScreenSettingsBehavior())); - }, - context: context, - description: - "\n${AppLocalizations.of(context).settingsDescriptionBehavior}"), - button( - AppLocalizations.of(context) - .settingsTitleInterface, - Icons.web_asset_rounded, () { - selectionHaptic(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const ScreenSettingsInterface())); - }, - context: context, - description: - "\n${AppLocalizations.of(context).settingsDescriptionInterface}"), - (!desktopFeature(web: true)) - ? button( - AppLocalizations.of(context) - .settingsTitleVoice, - Icons.headphones_rounded, () { - selectionHaptic(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const ScreenSettingsVoice())); - }, - context: context, - description: - "\n${AppLocalizations.of(context).settingsDescriptionVoice}", - badge: AppLocalizations.of(context) - .settingsExperimentalBeta) - : const SizedBox.shrink(), - button( - AppLocalizations.of(context).settingsTitleExport, - Icons.share_rounded, () { - selectionHaptic(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const ScreenSettingsExport())); - }, - context: context, - description: - "\n${AppLocalizations.of(context).settingsDescriptionExport}"), - Builder(builder: (context) { - return button( - AppLocalizations.of(context).settingsTitleAbout, - Icons.help_rounded, () { - selectionHaptic(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const ScreenSettingsAbout())); - }, - context: context, - description: - "\n${AppLocalizations.of(context).settingsDescriptionAbout}", - iconBadge: (updateStatus == "ok" && - updateDetectedOnStart && - (Version.parse( - latestVersion ?? "1.0.0") > - Version.parse( - currentVersion ?? "2.0.0"))) - ? "" - : null); - }) - ]); - animatedDesktop = desktopLayoutNotRequired(context); - return Column(children: [ - Expanded( - child: desktopLayoutNotRequired(context) - ? Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: - MainAxisSize.max, - children: [ - column1, - Expanded( - child: Center( - child: InkWell( - splashFactory: - NoSplash.splashFactory, - highlightColor: - Colors.transparent, - enableFeedback: false, - hoverColor: - Colors.transparent, - onTap: () async { - if (iconSize != 1) return; - heavyHaptic(); - setState(() { - iconSize = 0.8; - }); - await Future.delayed( - const Duration( - milliseconds: 200)); - setState(() { - iconSize = 1.2; - }); - await Future.delayed( - const Duration( - milliseconds: 200)); - setState(() { - iconSize = 1; - }); - }, - child: AnimatedScale( - scale: iconSize, - duration: const Duration( - milliseconds: 400), - child: const ImageIcon( - AssetImage( - "assets/logo512.png"), - size: 44), - ), - ))), - Transform.translate( - offset: const Offset(0, 8), - child: button( - AppLocalizations.of( - context) - .settingsSavedAutomatically, - Icons.info_rounded, - null, - color: Colors.grey - .harmonizeWith( - Theme.of(context) - .colorScheme - .primary)), - ) - ])), - verticalTitleDivider( - context: context), - Expanded(child: column2) - ]) - : ListView(children: [ - column1, - AnimatedOpacity( - opacity: animatedDesktop ? 0 : 1, - duration: - const Duration(milliseconds: 200), - child: titleDivider(bottom: 4)), - AnimatedOpacity( - opacity: animatedDesktop ? 0 : 1, - duration: - const Duration(milliseconds: 200), - child: column2) - ])), - const SizedBox(height: 8), - desktopLayoutNotRequired(context) - ? const SizedBox.shrink() - : button( - AppLocalizations.of(context) - .settingsSavedAutomatically, - Icons.info_rounded, - null, - color: Colors.grey.harmonizeWith( - Theme.of(context).colorScheme.primary)) - ]); - })), - )))); + ), + ); + + return ListView( + children: [ + if (!widget.embeddedNavigation) ...[ + const SettingsOverviewHostInput( + embeddedNavigation: false, + padding: EdgeInsetsGeometry.directional(top: 8), + ), + const Padding( + padding: EdgeInsetsDirectional.only(top: 16, start: 128, end: 128), + child: Divider(), + ), + ], + if (widget.embeddedNavigation) + optionTile( + title: appLocalizations.settingsTitleOverview, + subtitle: appLocalizations.settingsDescriptionOverview, + leading: const Icon(Icons.dashboard_rounded), + route: const RouteSettingsOverview(), + path: "overview", + ), + optionTile( + title: appLocalizations.settingsTitleBehavior, + subtitle: appLocalizations.settingsDescriptionBehavior, + leading: const Icon(Icons.psychology), + route: const RouteSettingsBehavior(), + path: "behavior", + ), + optionTile( + title: appLocalizations.settingsTitleInterface, + subtitle: appLocalizations.settingsDescriptionInterface, + leading: const Icon(Icons.palette), + route: const RouteSettingsInterface(), + path: "interface", + ), + optionTile( + title: appLocalizations.settingsTitleVoice, + subtitle: appLocalizations.settingsDescriptionVoice, + leading: const Icon(Icons.record_voice_over), + route: const RouteSettingsVoice(), + path: "voice", + isBetaFeature: true, + ), + optionTile( + title: appLocalizations.settingsTitleExport, + subtitle: appLocalizations.settingsDescriptionExport, + leading: const Icon(Icons.file_upload), + route: const RouteSettingsExport(), + path: "export", + ), + optionTile( + title: appLocalizations.settingsTitleAbout, + subtitle: appLocalizations.settingsDescriptionAbout, + leading: const Icon(Icons.help_outline), + route: const RouteSettingsAbout(), + path: "about", + ), + ], + ); + } +} + +class SettingsOverviewHostInput extends StatefulWidget { + final bool embeddedNavigation; + final EdgeInsetsGeometry? padding; + const SettingsOverviewHostInput({ + super.key, + required this.embeddedNavigation, + this.padding, + }); + + @override + State createState() => + _SettingsOverviewHostInputState(); +} + +class _SettingsOverviewHostInputState extends State { + late final TextEditingController _controller; + String? _oldHostFromHostManager; + + bool _loading = false; + HostSettingError? _error; + + @override + void initState() { + super.initState(); + HostManager.instance.addListener(onUpdate); + + _oldHostFromHostManager = HostManager.instance.host?.toString(); + _controller = TextEditingController(text: _oldHostFromHostManager); + } + + @override + void dispose() { + HostManager.instance.removeListener(onUpdate); + _controller.dispose(); + super.dispose(); + } + + void onUpdate() { + final currentHostFromHostManager = HostManager.instance.host?.toString(); + if (currentHostFromHostManager != _oldHostFromHostManager && + _controller.text == _oldHostFromHostManager) { + _oldHostFromHostManager = currentHostFromHostManager; + _controller.text = currentHostFromHostManager ?? ""; + } + + if (mounted) setState(() {}); + } + + Future _submit() async { + if (_loading) return; + + final value = _controller.text.trim(); + if (value.isEmpty && HostManager.instance.host == null) return; + + _loading = true; + _error = null; + if (mounted) setState(() {}); + + if (value.isEmpty) { + await Future.delayed(Durations.medium1); + HostManager.instance.host = null; + _loading = false; + if (mounted) setState(() {}); + return; + } + + final error = (await Future.wait([ + HostManager.instance.smartSetHost(context, value), + Future.delayed(Durations.long1), + ])).first; + + _loading = false; + _error = error; + if (mounted) setState(() {}); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final colorScheme = ColorScheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final errorStyle = _error != null; + final errorTitle = _error?.title(context); + final errorDescription = _error?.description(context); + + Widget iconRow( + String text, + Widget Function(Color color) icon, { + String? subtitle, + bool errorStyle = false, + bool missingStyle = false, + bool validStyle = false, + }) { + final color = errorStyle + ? colorScheme.error + : (missingStyle + ? Colors.orange.harmonizeWith(colorScheme.primary) + : (validStyle + ? Colors.green.harmonizeWith(colorScheme.primary) + : colorScheme.onSurfaceVariant.withValues( + alpha: kDisabledOpacity, + ))); + return ListTile( + dense: true, + contentPadding: const EdgeInsetsDirectional.only(top: 4), + minTileHeight: 0, + minVerticalPadding: 0, + isThreeLine: subtitle != null, + leading: icon.call(color), + title: Builder( + builder: (context) => Text( + text, + style: DefaultTextStyle.of( + context, + ).style.copyWith(color: color, fontFamily: "GoogleSansCode"), + ), + ), + subtitle: subtitle != null + ? Builder( + builder: (context) => Text( + subtitle, + style: DefaultTextStyle.of( + context, + ).style.copyWith(color: color), + ), + ) + : null, + ); + } + + return AnimatedSize( + duration: ExpressiveCurves.expressiveSpatial.fastDuration, + curve: ExpressiveCurves.expressiveSpatial.fast, + alignment: Alignment.topCenter, + child: Padding( + padding: widget.padding ?? EdgeInsets.zero, + child: TextField( + controller: _controller, + onSubmitted: (_) => _submit(), + enabled: !_loading && !useHost, + keyboardType: TextInputType.url, + textInputAction: TextInputAction.done, + decoration: InputDecoration( + border: const OutlineInputBorder(), + labelText: appLocalizations.settingsHost, + hintText: "https://localhost:11434", + error: errorStyle + ? iconRow( + errorTitle ?? "", + (color) => Icon(Icons.error_outline, color: color), + subtitle: errorDescription, + errorStyle: true, + ) + : null, + helper: iconRow( + _loading + ? appLocalizations.settingsHostChecking + : (HostManager.instance.host == null + ? appLocalizations.settingsHostMissing + : appLocalizations.settingsHostValid), + (color) => TwoStateWidgetManaged( + state: _loading, + from: HostManager.instance.host == null + ? Icon(Icons.warning_amber, color: color) + : Icon(Icons.check_outlined, color: color), + to: Icon(Icons.search_outlined, color: color), + ), + missingStyle: HostManager.instance.host == null && !_loading, + validStyle: !_loading, + ), + prefixIcon: !widget.embeddedNavigation + ? Padding( + padding: const EdgeInsetsDirectional.only(start: 4), + child: IconButton( + onPressed: () { + showModalBottomSheet( + context: context, + useRootNavigator: true, + clipBehavior: Clip.antiAlias, + isScrollControlled: true, + builder: (_) => + const SettingsOverviewHostHeadersInputMobileSheet(), + ); + }, + tooltip: appLocalizations.tooltipAddHostHeaders, + icon: Icon( + Icons.data_object_outlined, + color: colorScheme.onSurfaceVariant, + ), + ), + ) + : null, + suffixIcon: Padding( + padding: const EdgeInsetsDirectional.only(end: 4), + child: _loading + ? SizedCircularProgressIndicator( + dimension: theme.iconTheme.size ?? 24, + padding: EdgeInsets.zero, + ) + : IconButton( + icon: const Icon(Icons.save), + tooltip: appLocalizations.tooltipSend, + onPressed: _submit, + ), + ), + ), + ), + ), + ); + } +} + +class SettingsOverviewHostHeadersInputMobileSheet extends StatefulWidget { + const SettingsOverviewHostHeadersInputMobileSheet({super.key}); + + @override + State createState() => + _SettingsOverviewHostHeadersInputMobileSheetState(); +} + +class _SettingsOverviewHostHeadersInputMobileSheetState + extends State { + double? _childHeight; + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + return LayoutBuilder( + builder: (context, constraints) { + final maxExtend = ((_childHeight ?? 0) / constraints.maxHeight).clamp( + 0.0, + 1.0, + ); + + final initialChildSize = maxExtend.clamp(0.05, 0.85); + final minChildSize = 0.05.clamp(0.05, initialChildSize); + final maxChildSize = 0.85.clamp(initialChildSize, 0.85); + + return DraggableScrollableSheet( + initialChildSize: initialChildSize, + minChildSize: minChildSize, + maxChildSize: maxChildSize, + expand: false, + builder: (context, scrollController) => SingleChildScrollView( + controller: scrollController, + child: MeasureSize( + onChange: (size) { + _childHeight = size.height; + if (mounted) setState(() {}); + }, + child: Padding( + padding: EdgeInsetsDirectional.all(breakpoint.spacing), + child: const SettingsOverviewHostHeadersInput(), + ), + ), + ), + ); + }, + ); + } +} + +class SettingsOverviewHostHeadersInput extends StatefulWidget { + final EdgeInsetsGeometry? padding; + const SettingsOverviewHostHeadersInput({super.key, this.padding}); + + @override + State createState() => + _SettingsOverviewHostHeadersInputState(); +} + +class _SettingsOverviewHostHeadersInputState + extends State { + final GlobalKey _listKey = GlobalKey(); + late final Map _headers; + + @override + void initState() { + super.initState(); + Preferences.instance.addListener(onUpdate); + _headers = Preferences.instance.hostHeaders; + } + + @override + void dispose() { + Preferences.instance.removeListener(onUpdate); + super.dispose(); + } + + void onUpdate() { + final newHeaders = Preferences.instance.hostHeaders; + final diff = {}; + + for (final key in newHeaders.keys) { + if (!_headers.containsKey(key) || _headers[key] != newHeaders[key]) { + diff[key] = newHeaders[key]!; + } + } + for (final key in _headers.keys) { + if (!newHeaders.containsKey(key)) { + diff[key] = null; + } + } + + final listState = _listKey.currentState; + if (listState != null) { + for (final key in diff.keys) { + final value = diff[key]; + if (value == null) { + final index = _headers.keys.toList().indexOf(key); + if (index != -1) { + final oldValue = _headers[key]; + _headers.remove(key); + listState.removeItem( + index, + (context, animation) => SizeTransition( + sizeFactor: animation, + child: SettingsOverviewHostHeadersInputTile( + index: index, + headerKey: key, + headerValue: oldValue ?? "", + onChanged: (_, _) {}, + ), + ), + ); + } + } else { + final index = _headers.keys.toList().indexOf(key); + if (index == -1) { + _headers[key] = value; + listState.insertItem(_headers.length - 1); + } else { + _headers[key] = value; + listState.setState(() {}); + } + } + } + } + + if (mounted) setState(() {}); + } + + @override + Widget build(BuildContext context) { + final tmp = AnimatedList( + key: _listKey, + initialItemCount: _headers.length + 1, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index, animation) { + final header = _headers.entries.toList().elementAtOrNull(index); + return SizeTransition( + sizeFactor: animation, + child: SettingsOverviewHostHeadersInputTile( + index: index, + headerKey: header?.key ?? "", + headerValue: header?.value ?? "", + onChanged: (key, value) { + final headers = _headers.entries.toList(); + final currentElement = headers.elementAtOrNull(index); + if (key == null || value == null) { + if (currentElement != null) { + headers.removeAt(index); + _headers + ..clear() + ..addEntries(headers); + _listKey.currentState?.removeItem( + index, + (context, animation) => SizeTransition( + sizeFactor: animation, + child: SettingsOverviewHostHeadersInputTile( + index: index, + headerKey: currentElement.key, + headerValue: currentElement.value, + onChanged: (_, _) {}, + ), + ), + ); + } + } else { + if (currentElement != null) { + headers[index] = MapEntry(key, value); + _headers + ..clear() + ..addEntries(headers); + } else { + headers.add(MapEntry(key, value)); + _headers + ..clear() + ..addEntries(headers); + _listKey.currentState?.insertItem(headers.length - 1); + } + } + Preferences.instance.hostHeaders = Map.fromEntries(headers); + }, + ), + ); + }, + ); + return Padding(padding: widget.padding ?? EdgeInsets.zero, child: tmp); + } +} + +class SettingsOverviewHostHeadersInputTile extends StatefulWidget { + final int index; + final String headerKey; + final String headerValue; + final void Function(String? key, String? value) onChanged; + + const SettingsOverviewHostHeadersInputTile({ + super.key, + required this.index, + required this.headerKey, + required this.headerValue, + required this.onChanged, + }); + + @override + State createState() => + _SettingsOverviewHostHeadersInputTileState(); +} + +class _SettingsOverviewHostHeadersInputTileState + extends State { + bool _noUpdateFlag = false; + late final TextEditingController _keyController; + late final TextEditingController _valueController; + + late final FocusNode _keyFocusNode; + late final FocusNode _valueFocusNode; + + String? Function() _keyErrorText = () => null; + final Set _defaultAllowedHeaders = { + "authorization", + "content-type", + "user-agent", + "accept", + "x-requested-with", + "openai-beta", + "x-stainless-arch", + "x-stainless-async", + "x-stainless-custom-poll-interval", + "x-stainless-helper-method", + "x-stainless-lang", + "x-stainless-os", + "x-stainless-package-version", + "x-stainless-poll-helper", + "x-stainless-retry-count", + "x-stainless-runtime", + "x-stainless-runtime-version", + "x-stainless-timeout", + }; + + @override + void initState() { + super.initState(); + + _keyController = TextEditingController(text: widget.headerKey) + ..addListener(onUpdate); + _valueController = TextEditingController(text: widget.headerValue) + ..addListener(onUpdate); + + _keyFocusNode = FocusNode()..addListener(onUpdateFocus); + _valueFocusNode = FocusNode()..addListener(onUpdateFocus); + + WidgetsBinding.instance.addPostFrameCallback((_) => onUpdateFocus(true)); + } + + @override + void dispose() { + _keyController.dispose(); + _valueController.dispose(); + _keyFocusNode.dispose(); + _valueFocusNode.dispose(); + super.dispose(); + } + + void onUpdate() { + if (_noUpdateFlag) { + _noUpdateFlag = false; + return; + } + + final newKey = _keyController.text.trim(); + final newValue = _valueController.text.trim(); + + if (newKey.isEmpty || newValue.isEmpty) { + if (newKey.isEmpty && newValue.isEmpty) widget.onChanged(null, null); + return; + } + + if (newKey.isNotEmpty && + Preferences.instance.hostHeaders.entries.toList().asMap().entries.any( + (e) => e.value.key == newKey && e.key != widget.index, + )) { + _keyErrorText = () { + if (newKey != _keyController.text) return null; + final appLocalizations = AppLocalizations.of(context); + return appLocalizations.settingsHostHeaderDuplicate(newKey); + }; + if (mounted) setState(() {}); + return; + } + + if (newKey != widget.headerKey || newValue != widget.headerValue) { + _keyErrorText = () => null; + widget.onChanged( + newKey.isEmpty ? null : newKey, + newValue.isEmpty ? null : newValue, + ); + } + if (mounted) setState(() {}); + } + + void onUpdateFocus([bool force = false]) { + if ((!_keyFocusNode.hasFocus || force) && + _keyController.text.isNotEmpty && + !_defaultAllowedHeaders.contains(_keyController.text.toLowerCase()) && + widget.index != Preferences.instance.hostHeaders.length && + kIsWeb) { + _keyErrorText = () { + if (_keyController.text.isEmpty) return null; + final appLocalizations = AppLocalizations.of(context); + return appLocalizations.settingsHostHeaderUnsupported( + _keyController.text, + ); + }; + } + if (mounted) setState(() {}); + } + + @override + void didUpdateWidget(SettingsOverviewHostHeadersInputTile oldWidget) { + if (_keyController.text != widget.headerKey) { + _noUpdateFlag = true; + _keyController.text = widget.headerKey; + onUpdateFocus(true); + } + if (_valueController.text != widget.headerValue) { + _noUpdateFlag = true; + _valueController.text = widget.headerValue; + } + super.didUpdateWidget(oldWidget); + } + + @override + Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); + final textTheme = TextTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final isLast = widget.index == Preferences.instance.hostHeaders.length; + final isDummy = widget.headerKey.isEmpty && widget.headerValue.isEmpty; + + return Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 2, + child: AnimatedSize( + duration: ExpressiveCurves.expressiveEffects.fastDuration, + curve: ExpressiveCurves.expressiveEffects.fast, + alignment: Alignment.topCenter, + child: TextField( + controller: _keyController, + focusNode: _keyFocusNode, + autofocus: false, + textInputAction: TextInputAction.next, + textCapitalization: TextCapitalization.words, + decoration: InputDecoration( + label: Text(appLocalizations.settingsHostHeaderHeaderName), + hintText: "Authorization", + helperText: _keyErrorText.call(), + helperStyle: textTheme.bodySmall?.copyWith( + color: Colors.orange.harmonizeWith(colorScheme.primary), + ), + helperMaxLines: 3, + ), + ), + ), + ), + Text(" " * 3), + Expanded( + flex: 3, + child: TextField( + controller: _valueController, + focusNode: _valueFocusNode, + autofocus: false, + textInputAction: isLast + ? TextInputAction.done + : TextInputAction.next, + textCapitalization: TextCapitalization.words, + decoration: InputDecoration( + label: Text(appLocalizations.settingsHostHeaderHeaderValue), + hintText: "Bearer XXX", + ), + ), + ), + isDummy + ? const Padding( + padding: EdgeInsets.all(8.0), + child: Icon(Icons.add), + ) + : IconButton( + onPressed: () => widget.onChanged(null, null), + icon: const Icon(Icons.close), + ), + ], + ); + } +} + +class SettingsPageContainmentBox extends StatefulWidget { + final List Function(BuildContext context, double halfSpacing) + itemBuilder; + + const SettingsPageContainmentBox({super.key, required this.itemBuilder}); + + @override + State createState() => + _SettingsPageContainmentBoxState(); +} + +class _SettingsPageContainmentBoxState + extends State { + final ScrollController _scrollController = ScrollController(); + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + final halfSpacing = breakpoint.spacing / 2; + + return ListView( + children: widget.itemBuilder + .call(context, halfSpacing) + .map( + (widget) => Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 560 - halfSpacing), + child: SizedBox(width: 560, child: widget), + ), + ], + ), + ) + .toList(), + ); + } +} + +@RoutePage() +class ScreenSettingsOverview extends StatelessWidget { + const ScreenSettingsOverview({super.key}); + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + if (breakpoint.panesRecommended < 2) { + context.router.navigate(const RouteSettings()).then((_) { + if (!context.mounted) return; + context.router.removeWhere( + (e) => e.name == RouteSettingsOverview.page.name, + ); + }); + } + + return SettingsPageContainmentBox( + itemBuilder: (context, halfSpacing) => [ + SettingsOverviewHostInput( + embeddedNavigation: true, + padding: EdgeInsetsGeometry.directional(top: 4 + halfSpacing), + ), + const SettingsOverviewHostHeadersInput( + padding: EdgeInsetsDirectional.only(top: 4), + ), + ], + ); + } +} + +// MARK: dummy pages + +@RoutePage() +class ScreenSettingsBehavior extends StatelessWidget { + const ScreenSettingsBehavior({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text("settings behavior")); + } +} + +@RoutePage() +class ScreenSettingsInterface extends StatelessWidget { + const ScreenSettingsInterface({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text("settings interface")); + } +} + +@RoutePage() +class ScreenSettingsVoice extends StatelessWidget { + const ScreenSettingsVoice({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text("settings voice")); + } +} + +@RoutePage() +class ScreenSettingsExport extends StatelessWidget { + const ScreenSettingsExport({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text("settings export")); + } +} + +@RoutePage() +class ScreenSettingsAbout extends StatelessWidget { + const ScreenSettingsAbout({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text("settings about")); } } diff --git a/lib/screens/settings/about.dart b/lib/screens/settings/about.dart index 1f5025d..67e5b89 100644 --- a/lib/screens/settings/about.dart +++ b/lib/screens/settings/about.dart @@ -42,141 +42,184 @@ class _ScreenSettingsAboutState extends State { return WindowBorder( color: Theme.of(context).colorScheme.surface, child: Scaffold( - appBar: AppBar( - title: Row(children: [ - Text(AppLocalizations.of(context).settingsTitleAbout), - Expanded(child: SizedBox(height: 200, child: MoveWindow())) - ]), - actions: desktopControlsActions(context)), - body: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 1000), - padding: const EdgeInsets.only(left: 16, right: 16), - child: Column(children: [ - Expanded( - child: ListView(children: [ + appBar: AppBar( + title: Row( + children: [ + Text(AppLocalizations.of(context).settingsTitleAbout), + Expanded(child: SizedBox(height: 200, child: MoveWindow())), + ], + ), + actions: desktopControlsActions(context), + ), + body: Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 1000), + padding: const EdgeInsets.only(left: 16, right: 16), + child: Column( + children: [ + Expanded( + child: ListView( + children: [ // const SizedBox(height: 8), button( - AppLocalizations.of(context) - .settingsVersion(currentVersion ?? ""), - Icons.verified_rounded, - null), + AppLocalizations.of( + context, + ).settingsVersion(currentVersion ?? ""), + Icons.verified_rounded, + null, + ), (updateStatus == "notAvailable") ? const SizedBox.shrink() : button( (!updateChecked - ? AppLocalizations.of(context) - .settingsUpdateCheck + ? AppLocalizations.of( + context, + ).settingsUpdateCheck : updateLoading - ? AppLocalizations.of(context) - .settingsUpdateChecking - : (updateStatus == "rateLimit") - ? AppLocalizations.of(context) - .settingsUpdateRateLimit - : (updateStatus != "ok") - ? AppLocalizations.of(context) - .settingsUpdateIssue - : (Version.parse(latestVersion ?? - "1.0.0") > - Version.parse( - currentVersion ?? - "2.0.0")) - ? AppLocalizations.of(context) - .settingsUpdateAvailable( - latestVersion!) - : AppLocalizations.of(context) - .settingsUpdateLatest), + ? AppLocalizations.of( + context, + ).settingsUpdateChecking + : (updateStatus == "rateLimit") + ? AppLocalizations.of( + context, + ).settingsUpdateRateLimit + : (updateStatus != "ok") + ? AppLocalizations.of( + context, + ).settingsUpdateIssue + : (Version.parse(latestVersion ?? "1.0.0") > + Version.parse( + currentVersion ?? "2.0.0", + )) + ? AppLocalizations.of( + context, + ).settingsUpdateAvailable(latestVersion!) + : AppLocalizations.of( + context, + ).settingsUpdateLatest), ((updateStatus != "ok") ? Icons.warning_rounded : (Version.parse(latestVersion ?? "1.0.0") > - Version.parse( - currentVersion ?? "2.0.0")) - ? Icons.info_outline_rounded - : Icons.update_rounded), () { - if (updateLoading) return; - selectionHaptic(); - if ((Version.parse(latestVersion ?? "1.0.0") > - Version.parse( - currentVersion ?? "2.0.0")) && - (updateStatus == "ok")) { - updateDialog(context, title); - } else { - checkUpdate(setState); - return; - } - }, - iconBadge: (updateStatus == "ok" && + Version.parse( + currentVersion ?? "2.0.0", + )) + ? Icons.info_outline_rounded + : Icons.update_rounded), + () { + if (updateLoading) return; + selectionHaptic(); + if ((Version.parse(latestVersion ?? "1.0.0") > + Version.parse( + currentVersion ?? "2.0.0", + )) && + (updateStatus == "ok")) { + updateDialog(context, title); + } else { + checkUpdate(setState); + return; + } + }, + iconBadge: + (updateStatus == "ok" && updateDetectedOnStart && (Version.parse(latestVersion ?? "1.0.0") > Version.parse( - currentVersion ?? "2.0.0"))) + currentVersion ?? "2.0.0", + ))) ? "" - : null), + : null, + ), (updateStatus == "notAvailable") ? const SizedBox.shrink() : toggle( context, - AppLocalizations.of(context) - .settingsCheckForUpdates, + AppLocalizations.of( + context, + ).settingsCheckForUpdates, prefs!.getBool("checkUpdateOnSettingsOpen") ?? - true, (value) { - selectionHaptic(); - prefs! - .setBool("checkUpdateOnSettingsOpen", value); - setState(() {}); - }), + true, + (value) { + selectionHaptic(); + prefs!.setBool( + "checkUpdateOnSettingsOpen", + value, + ); + setState(() {}); + }, + ), titleDivider(context: context), - button(AppLocalizations.of(context).settingsGithub, - SimpleIcons.github, () { - selectionHaptic(); - launchUrl( + button( + AppLocalizations.of(context).settingsGithub, + SimpleIcons.github, + () { + selectionHaptic(); + launchUrl( mode: LaunchMode.inAppBrowserView, - Uri.parse(repoUrl)); - }), - button(AppLocalizations.of(context).settingsReportIssue, - Icons.report_rounded, () { - selectionHaptic(); - launchUrl( + Uri.parse(repoUrl), + ); + }, + ), + button( + AppLocalizations.of(context).settingsReportIssue, + Icons.report_rounded, + () { + selectionHaptic(); + launchUrl( mode: LaunchMode.inAppBrowserView, - Uri.parse("$repoUrl/issues")); - }), - button(AppLocalizations.of(context).settingsLicenses, - Icons.gavel_rounded, () { - selectionHaptic(); - var legal = "Copyright 2024 JHubi1"; - Widget icon = const Padding( - padding: EdgeInsets.all(16), - child: ImageIcon(AssetImage("assets/logo512.png"), - size: 48), - ); - if (desktopFeature()) { - showDialog( + Uri.parse("$repoUrl/issues"), + ); + }, + ), + button( + AppLocalizations.of(context).settingsLicenses, + Icons.gavel_rounded, + () { + selectionHaptic(); + const legal = "Copyright 2024 JHubi1"; + const Widget icon = Padding( + padding: EdgeInsets.all(16), + child: ImageIcon( + AssetImage("assets/logo512.png"), + size: 48, + ), + ); + if (desktopFeature()) { + showDialog( context: context, builder: (context) { return Dialog( - child: ClipRRect( - borderRadius: BorderRadius.circular(28), - child: LicensePage( + child: ClipRRect( + borderRadius: BorderRadius.circular(28), + child: LicensePage( applicationName: "Ollama App", applicationVersion: currentVersion, applicationIcon: icon, - applicationLegalese: legal), - )); - }); - } else { - showLicensePage( + applicationLegalese: legal, + ), + ), + ); + }, + ); + } else { + showLicensePage( context: context, applicationName: "Ollama App", applicationVersion: currentVersion, applicationIcon: icon, - applicationLegalese: legal); - } - }), - const SizedBox(height: 16) - ]), - ) - ])), - )), + applicationLegalese: legal, + ); + } + }, + ), + const SizedBox(height: 16), + ], + ), + ), + ], + ), + ), + ), + ), ); } } diff --git a/lib/screens/settings/behavior.dart b/lib/screens/settings/behavior.dart index 3341048..2a685a4 100644 --- a/lib/screens/settings/behavior.dart +++ b/lib/screens/settings/behavior.dart @@ -17,7 +17,8 @@ class ScreenSettingsBehavior extends StatefulWidget { class _ScreenSettingsBehaviorState extends State { final systemInputController = TextEditingController( - text: prefs?.getString("system") ?? "You are a helpful assistant"); + text: prefs?.getString("system") ?? "You are a helpful assistant", + ); @override void dispose() { @@ -30,84 +31,110 @@ class _ScreenSettingsBehaviorState extends State { return WindowBorder( color: Theme.of(context).colorScheme.surface, child: Scaffold( - appBar: AppBar( - title: Row(children: [ - Text(AppLocalizations.of(context).settingsTitleBehavior), - Expanded(child: SizedBox(height: 200, child: MoveWindow())) - ]), - actions: desktopControlsActions(context)), - body: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 1000), - padding: const EdgeInsets.only(left: 16, right: 16), - child: Column(children: [ - Expanded( - child: ListView(children: [ + appBar: AppBar( + title: Row( + children: [ + Text(AppLocalizations.of(context).settingsTitleBehavior), + Expanded(child: SizedBox(height: 200, child: MoveWindow())), + ], + ), + actions: desktopControlsActions(context), + ), + body: Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 1000), + padding: const EdgeInsets.only(left: 16, right: 16), + child: Column( + children: [ + Expanded( + child: ListView( + children: [ const SizedBox(height: 8), TextField( - controller: systemInputController, - keyboardType: TextInputType.multiline, - maxLines: desktopLayoutNotRequired(context) ? 5 : 2, - decoration: InputDecoration( - labelText: AppLocalizations.of(context) - .settingsSystemMessage, - alignLabelWithHint: true, - hintText: "You are a helpful assistant", - suffixIcon: IconButton( - enableFeedback: false, - tooltip: - AppLocalizations.of(context).tooltipSave, - onPressed: () { - selectionHaptic(); - prefs?.setString( - "system", - (systemInputController.text.isNotEmpty) - ? systemInputController.text - : "You are a helpful assistant"); - }, - icon: const Icon(Icons.save_rounded), - ), - border: const OutlineInputBorder())), + controller: systemInputController, + keyboardType: TextInputType.multiline, + maxLines: desktopLayoutNotRequired(context) ? 5 : 2, + decoration: InputDecoration( + labelText: AppLocalizations.of( + context, + ).settingsSystemMessage, + alignLabelWithHint: true, + hintText: "You are a helpful assistant", + suffixIcon: IconButton( + enableFeedback: false, + tooltip: AppLocalizations.of(context).tooltipSave, + onPressed: () { + selectionHaptic(); + prefs?.setString( + "system", + (systemInputController.text.isNotEmpty) + ? systemInputController.text + : "You are a helpful assistant", + ); + }, + icon: const Icon(Icons.save_rounded), + ), + border: const OutlineInputBorder(), + ), + ), const SizedBox(height: 16), toggle( - context, - AppLocalizations.of(context).settingsUseSystem, - prefs!.getBool("useSystem") ?? true, - (value) { - selectionHaptic(); - prefs!.setBool("useSystem", value); - setState(() {}); - }, - icon: const Icon(Icons.info_rounded, - color: Colors.grey), - iconAfterwards: true, - onLongTap: () { - selectionHaptic(); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(AppLocalizations.of(context) - .settingsUseSystemDescription), - showCloseIcon: true)); - }), + context, + AppLocalizations.of(context).settingsUseSystem, + prefs!.getBool("useSystem") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("useSystem", value); + setState(() {}); + }, + icon: const Icon( + Icons.info_rounded, + color: Colors.grey, + ), + iconAfterwards: true, + onLongTap: () { + selectionHaptic(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of( + context, + ).settingsUseSystemDescription, + ), + showCloseIcon: true, + ), + ); + }, + ), toggle( - context, - AppLocalizations.of(context).settingsDisableMarkdown, - prefs!.getBool("noMarkdown") ?? false, (value) { - selectionHaptic(); - prefs!.setBool("noMarkdown", value); - setState(() {}); - }) - ]), + context, + AppLocalizations.of(context).settingsDisableMarkdown, + prefs!.getBool("noMarkdown") ?? false, + (value) { + selectionHaptic(); + prefs!.setBool("noMarkdown", value); + setState(() {}); + }, + ), + ], ), - const SizedBox(height: 8), - button( - AppLocalizations.of(context) - .settingsBehaviorNotUpdatedForOlderChats, - Icons.info_rounded, - null, - color: Colors.grey - .harmonizeWith(Theme.of(context).colorScheme.primary)) - ])), - )), + ), + const SizedBox(height: 8), + button( + AppLocalizations.of( + context, + ).settingsBehaviorNotUpdatedForOlderChats, + Icons.info_rounded, + null, + color: Colors.grey.harmonizeWith( + Theme.of(context).colorScheme.primary, + ), + ), + ], + ), + ), + ), + ), ); } } diff --git a/lib/screens/settings/export.dart b/lib/screens/settings/export.dart index 3cb99b8..081136e 100644 --- a/lib/screens/settings/export.dart +++ b/lib/screens/settings/export.dart @@ -29,203 +29,262 @@ class _ScreenSettingsExportState extends State { return WindowBorder( color: Theme.of(context).colorScheme.surface, child: Scaffold( - appBar: AppBar( - title: Row(children: [ - Text(AppLocalizations.of(context).settingsTitleExport), - Expanded(child: SizedBox(height: 200, child: MoveWindow())) - ]), - actions: desktopControlsActions(context)), - body: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 1000), - padding: const EdgeInsets.only(left: 16, right: 16), - child: Column(children: [ - Expanded( - child: ListView(children: [ + appBar: AppBar( + title: Row( + children: [ + Text(AppLocalizations.of(context).settingsTitleExport), + Expanded(child: SizedBox(height: 200, child: MoveWindow())), + ], + ), + actions: desktopControlsActions(context), + ), + body: Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 1000), + padding: const EdgeInsets.only(left: 16, right: 16), + child: Column( + children: [ + Expanded( + child: ListView( + children: [ // const SizedBox(height: 8), - button(AppLocalizations.of(context).settingsExportChats, - Icons.upload_rounded, () async { - selectionHaptic(); - var name = - "ollama-export-${DateFormat('yyyy-MM-dd-H-m-s').format(DateTime.now())}.json"; - var content = - jsonEncode(prefs!.getStringList("chats") ?? []); - if (kIsWeb) { - // web fallback - var bytes = utf8.encode(content); - var blob = html.Blob([bytes]); - var url = html.Url.createObjectUrlFromBlob(blob); - var anchor = html.document.createElement("a") - as html.AnchorElement - ..href = url - ..style.display = "none" - ..download = name; - html.document.body!.children.add(anchor); + button( + AppLocalizations.of(context).settingsExportChats, + Icons.upload_rounded, + () async { + selectionHaptic(); + final name = + "ollama-export-${DateFormat('yyyy-MM-dd-H-m-s').format(DateTime.now())}.json"; + final content = jsonEncode( + prefs!.getStringList("chats") ?? [], + ); + if (kIsWeb) { + // web fallback + final bytes = utf8.encode(content); + final blob = html.Blob([bytes]); + final url = html.Url.createObjectUrlFromBlob(blob); + final anchor = + html.document.createElement("a") + as html.AnchorElement + ..href = url + ..style.display = "none" + ..download = name; + html.document.body!.children.add(anchor); - anchor.click(); + anchor.click(); - html.document.body!.children.remove(anchor); - html.Url.revokeObjectUrl(url); - } else { - String? path = ""; - try { - path = (await file_selector - .getSaveLocation(acceptedTypeGroups: [ - const file_selector.XTypeGroup( - label: "Ollama App File", - extensions: ["json"]) - ], suggestedName: name)) - ?.path; - } catch (_) { - path = await FilePicker.platform.saveFile( + html.document.body!.children.remove(anchor); + html.Url.revokeObjectUrl(url); + } else { + String? path = ""; + try { + path = (await file_selector.getSaveLocation( + acceptedTypeGroups: [ + const file_selector.XTypeGroup( + label: "Ollama App File", + extensions: ["json"], + ), + ], + suggestedName: name, + ))?.path; + } catch (_) { + path = await FilePicker.platform.saveFile( type: FileType.custom, allowedExtensions: ["json"], fileName: name, - bytes: utf8.encode(jsonEncode( - prefs!.getStringList("chats") ?? []))); + bytes: utf8.encode( + jsonEncode( + prefs!.getStringList("chats") ?? [], + ), + ), + ); + } + selectionHaptic(); + if (path == null) return; + if (desktopFeature()) { + File(path).writeAsString(content); + } } - selectionHaptic(); - if (path == null) return; - if (desktopFeature()) { - File(path).writeAsString(content); - } - } - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - // ignore: use_build_context_synchronously - content: Text(AppLocalizations.of(context) - .settingsExportChatsSuccess), - showCloseIcon: true)); - }), + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + // ignore: use_build_context_synchronously + content: Text( + AppLocalizations.of( + context, + ).settingsExportChatsSuccess, + ), + showCloseIcon: true, + ), + ); + }, + ), allowMultipleChats ? button( AppLocalizations.of(context).settingsImportChats, - Icons.download_rounded, () async { - selectionHaptic(); - await showDialog( + Icons.download_rounded, + () async { + selectionHaptic(); + await showDialog( context: context, builder: (context) { return AlertDialog( - title: Text(AppLocalizations.of(context) - .settingsImportChatsTitle), - content: Text(AppLocalizations.of( - context) - .settingsImportChatsDescription), - actions: [ - TextButton( - onPressed: () { - selectionHaptic(); - Navigator.of(context).pop(); - }, - child: Text(AppLocalizations.of( - context) - .settingsImportChatsCancel)), - TextButton( - onPressed: () async { - selectionHaptic(); - String content; - try { - if (kIsWeb) { - throw Exception( - "web must use file picker"); - } - var result = await file_selector - .openFile( - acceptedTypeGroups: [ - const file_selector - .XTypeGroup( - label: - "Ollama App File", - extensions: [ - "json" - ]) - ]); - if (result == null) { - // ignore: use_build_context_synchronously - Navigator.of(context).pop(); - return; - } - content = await result - .readAsString(); - } catch (_) { - var result = await FilePicker - .platform - .pickFiles( - type: FileType.custom, - allowedExtensions: [ - "json" - ]); - if (result == null) { - // ignore: use_build_context_synchronously - Navigator.of(context).pop(); - return; - } - try { - var file = File(result - .files.single.path!); - content = await file - .readAsString(); - } catch (_) { - // web fallback - content = utf8.decode(result - .files - .single - .bytes! as List); - } - } - List tmpHistory = - jsonDecode(content); - var history = []; - - for (var i = 0; - i < tmpHistory.length; - i++) { - history.add(tmpHistory[i]); - } - - prefs!.setStringList( - "chats", history); - - messages = []; - chatUuid = null; - - setState(() {}); - + title: Text( + AppLocalizations.of( + context, + ).settingsImportChatsTitle, + ), + content: Text( + AppLocalizations.of( + context, + ).settingsImportChatsDescription, + ), + actions: [ + TextButton( + onPressed: () { + selectionHaptic(); + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of( + context, + ).settingsImportChatsCancel, + ), + ), + TextButton( + onPressed: () async { + selectionHaptic(); + String content; + try { + if (kIsWeb) { + throw Exception( + "web must use file picker", + ); + } + final result = await file_selector + .openFile( + acceptedTypeGroups: [ + const file_selector.XTypeGroup( + label: + "Ollama App File", + extensions: ["json"], + ), + ], + ); + if (result == null) { // ignore: use_build_context_synchronously Navigator.of(context).pop(); + return; + } + content = await result + .readAsString(); + } catch (_) { + final result = await FilePicker + .platform + .pickFiles( + type: FileType.custom, + allowedExtensions: ["json"], + ); + if (result == null) { // ignore: use_build_context_synchronously Navigator.of(context).pop(); - // ignore: use_build_context_synchronously - Navigator.of(context).pop(); - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context) - .showSnackBar(SnackBar( - content: Text(AppLocalizations - // ignore: use_build_context_synchronously - .of(context) - .settingsImportChatsSuccess), - showCloseIcon: true)); - }, - child: Text(AppLocalizations.of( - context) - .settingsImportChatsImport)) - ]); - }); - }) - : const SizedBox.shrink() - ]), + return; + } + try { + final file = File( + result.files.single.path!, + ); + content = await file + .readAsString(); + } catch (_) { + // web fallback + content = utf8.decode( + result.files.single.bytes! + as List, + ); + } + } + final List tmpHistory = + jsonDecode(content); + final history = []; + + for ( + var i = 0; + i < tmpHistory.length; + i++ + ) { + history.add(tmpHistory[i]); + } + + prefs!.setStringList( + "chats", + history, + ); + + messages = []; + chatUuid = null; + + setState(() {}); + + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + // ignore: use_build_context_synchronously + ScaffoldMessenger.of( + context, + ).showSnackBar( + SnackBar( + content: Text( + AppLocalizations + // ignore: use_build_context_synchronously + .of(context) + .settingsImportChatsSuccess, + ), + showCloseIcon: true, + ), + ); + }, + child: Text( + AppLocalizations.of( + context, + ).settingsImportChatsImport, + ), + ), + ], + ); + }, + ); + }, + ) + : const SizedBox.shrink(), + ], ), - const SizedBox(height: 8), - button(AppLocalizations.of(context).settingsExportInfo, - Icons.info_rounded, null, - color: Colors.grey.harmonizeWith( - Theme.of(context).colorScheme.primary)), - button(AppLocalizations.of(context).settingsExportWarning, - Icons.warning_rounded, null, - color: Colors.orange - .harmonizeWith(Theme.of(context).colorScheme.primary)) - ])), - )), + ), + const SizedBox(height: 8), + button( + AppLocalizations.of(context).settingsExportInfo, + Icons.info_rounded, + null, + color: Colors.grey.harmonizeWith( + Theme.of(context).colorScheme.primary, + ), + ), + button( + AppLocalizations.of(context).settingsExportWarning, + Icons.warning_rounded, + null, + color: Colors.orange.harmonizeWith( + Theme.of(context).colorScheme.primary, + ), + ), + ], + ), + ), + ), + ), ); } } diff --git a/lib/screens/settings/interface.dart b/lib/screens/settings/interface.dart index 4019ebc..9e9ca6e 100644 --- a/lib/screens/settings/interface.dart +++ b/lib/screens/settings/interface.dart @@ -45,403 +45,499 @@ class _ScreenSettingsInterfaceState extends State { return WindowBorder( color: Theme.of(context).colorScheme.surface, child: Scaffold( - appBar: AppBar( - title: Row(children: [ - Text(AppLocalizations.of(context).settingsTitleInterface), - Expanded(child: SizedBox(height: 200, child: MoveWindow())) - ]), - actions: desktopControlsActions(context)), - body: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 1000), - padding: const EdgeInsets.only(left: 16, right: 16), - child: Column(children: [ - Expanded( - child: ListView(children: [ + appBar: AppBar( + title: Row( + children: [ + Text(AppLocalizations.of(context).settingsTitleInterface), + Expanded(child: SizedBox(height: 200, child: MoveWindow())), + ], + ), + actions: desktopControlsActions(context), + ), + body: Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 1000), + padding: const EdgeInsets.only(left: 16, right: 16), + child: Column( + children: [ + Expanded( + child: ListView( + children: [ // const SizedBox(height: 8), toggle( - context, - AppLocalizations.of(context).settingsShowModelTags, - prefs!.getBool("modelTags") ?? false, (value) { - selectionHaptic(); - prefs!.setBool("modelTags", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsShowModelTags, + prefs!.getBool("modelTags") ?? false, + (value) { + selectionHaptic(); + prefs!.setBool("modelTags", value); + setState(() {}); + }, + ), toggle( - context, - AppLocalizations.of(context).settingsPreloadModels, - prefs!.getBool("preloadModel") ?? true, (value) { - selectionHaptic(); - prefs!.setBool("preloadModel", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsPreloadModels, + prefs!.getBool("preloadModel") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("preloadModel", value); + setState(() {}); + }, + ), toggle( - context, - AppLocalizations.of(context) - .settingsResetOnModelChange, - prefs!.getBool("resetOnModelSelect") ?? true, - (value) { - selectionHaptic(); - prefs!.setBool("resetOnModelSelect", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsResetOnModelChange, + prefs!.getBool("resetOnModelSelect") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("resetOnModelSelect", value); + setState(() {}); + }, + ), titleDivider( - bottom: desktopLayoutNotRequired(context) ? 38 : 20, - context: context), + bottom: desktopLayoutNotRequired(context) ? 38 : 20, + context: context, + ), SegmentedButton( - segments: [ - ButtonSegment( - value: "stream", - label: Text(AppLocalizations.of(context) - .settingsRequestTypeStream), - icon: const Icon(Icons.stream_rounded)), - ButtonSegment( - value: "request", - label: Text(AppLocalizations.of(context) - .settingsRequestTypeRequest), - icon: const Icon(Icons.send_rounded)) - ], - selected: { - prefs!.getString("requestType") ?? "stream" - }, - onSelectionChanged: (p0) { - selectionHaptic(); - setState(() { - prefs!.setString("requestType", p0.elementAt(0)); - }); - }), + segments: [ + ButtonSegment( + value: "stream", + label: Text( + AppLocalizations.of( + context, + ).settingsRequestTypeStream, + ), + icon: const Icon(Icons.stream_rounded), + ), + ButtonSegment( + value: "request", + label: Text( + AppLocalizations.of( + context, + ).settingsRequestTypeRequest, + ), + icon: const Icon(Icons.send_rounded), + ), + ], + selected: {prefs!.getString("requestType") ?? "stream"}, + onSelectionChanged: (p0) { + selectionHaptic(); + setState(() { + prefs!.setString("requestType", p0.elementAt(0)); + }); + }, + ), const SizedBox(height: 16), toggle( - context, - AppLocalizations.of(context).settingsGenerateTitles, - prefs!.getBool("generateTitles") ?? true, (value) { - selectionHaptic(); - prefs!.setBool("generateTitles", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsGenerateTitles, + prefs!.getBool("generateTitles") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("generateTitles", value); + setState(() {}); + }, + ), toggle( - context, - AppLocalizations.of(context).settingsEnableEditing, - prefs!.getBool("enableEditing") ?? true, (value) { - selectionHaptic(); - prefs!.setBool("enableEditing", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsEnableEditing, + prefs!.getBool("enableEditing") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("enableEditing", value); + setState(() {}); + }, + ), toggle( - context, - AppLocalizations.of(context).settingsAskBeforeDelete, - prefs!.getBool("askBeforeDeletion") ?? false, - (value) { - selectionHaptic(); - prefs!.setBool("askBeforeDeletion", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsAskBeforeDelete, + prefs!.getBool("askBeforeDeletion") ?? false, + (value) { + selectionHaptic(); + prefs!.setBool("askBeforeDeletion", value); + setState(() {}); + }, + ), toggle( - context, - AppLocalizations.of(context).settingsShowTips, - prefs!.getBool("tips") ?? true, (value) { - selectionHaptic(); - prefs!.setBool("tips", value); - setState(() {}); - }), + context, + AppLocalizations.of(context).settingsShowTips, + prefs!.getBool("tips") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("tips", value); + setState(() {}); + }, + ), titleDivider(context: context), toggle( + context, + AppLocalizations.of( context, - AppLocalizations.of(context) - .settingsKeepModelLoadedAlways, - int.parse(prefs!.getString("keepAlive") ?? "300") == - -1, (value) { - selectionHaptic(); - setState(() { - if (value) { - prefs!.setString("keepAlive", "-1"); - } else { - prefs!.setString("keepAlive", "300"); - } - }); - }), + ).settingsKeepModelLoadedAlways, + int.parse(prefs!.getString("keepAlive") ?? "300") == -1, + (value) { + selectionHaptic(); + setState(() { + if (value) { + prefs!.setString("keepAlive", "-1"); + } else { + prefs!.setString("keepAlive", "300"); + } + }); + }, + ), toggle( + context, + AppLocalizations.of( context, - AppLocalizations.of(context) - .settingsKeepModelLoadedNever, - int.parse(prefs!.getString("keepAlive") ?? "300") == - 0, (value) { - selectionHaptic(); - setState(() { - if (value) { - prefs!.setString("keepAlive", "0"); - } else { - prefs!.setString("keepAlive", "300"); - } - }); - }), + ).settingsKeepModelLoadedNever, + int.parse(prefs!.getString("keepAlive") ?? "300") == 0, + (value) { + selectionHaptic(); + setState(() { + if (value) { + prefs!.setString("keepAlive", "0"); + } else { + prefs!.setString("keepAlive", "300"); + } + }); + }, + ), button( - (int.parse(prefs!.getString("keepAlive") ?? "300") > - 0) - ? AppLocalizations.of(context) - .settingsKeepModelLoadedSet((int.parse( - prefs!.getString("keepAlive") ?? - "300") ~/ - 60) - .toString()) - : AppLocalizations.of(context) - .settingsKeepModelLoadedFor, - Icons.snooze_rounded, () async { - selectionHaptic(); - var loaded = false; - await showDialog( + (int.parse(prefs!.getString("keepAlive") ?? "300") > 0) + ? AppLocalizations.of( + context, + ).settingsKeepModelLoadedSet( + (int.parse( + prefs!.getString("keepAlive") ?? + "300", + ) ~/ + 60) + .toString(), + ) + : AppLocalizations.of( + context, + ).settingsKeepModelLoadedFor, + Icons.snooze_rounded, + () async { + selectionHaptic(); + var loaded = false; + await showDialog( context: context, builder: (context) { return Dialog( - alignment: desktopLayout(context) - ? null - : Alignment.bottomRight, - child: StatefulBuilder( - builder: (context, setLocalState) { + alignment: desktopLayout(context) + ? null + : Alignment.bottomRight, + child: StatefulBuilder( + builder: (context, setLocalState) { if (int.parse( - prefs!.getString("keepAlive") ?? - "0") <= + prefs!.getString("keepAlive") ?? + "0", + ) <= 0 && loaded == false) { prefs!.setString("keepAlive", "0"); WidgetsBinding.instance .addPostFrameCallback((timeStamp) { - setLocalState(() {}); - Future load() async { - try { - while (int.parse(prefs! - .getString("keepAlive")!) < - 300) { - await Future.delayed( - const Duration( - milliseconds: 5)); - prefs!.setString( + setLocalState(() {}); + Future load() async { + try { + while (int.parse( + prefs!.getString( + "keepAlive", + )!, + ) < + 300) { + await Future.delayed( + const Duration( + milliseconds: 5, + ), + ); + prefs!.setString( + "keepAlive", + (int.parse( + prefs!.getString( + "keepAlive", + )!, + ) + + 30) + .toString(), + ); + setLocalState(() {}); + setState(() {}); + } + prefs!.setString( "keepAlive", - (int.parse(prefs!.getString( - "keepAlive")!) + - 30) - .toString()); - setLocalState(() {}); - setState(() {}); + "300", + ); + loaded = true; + } catch (_) { + prefs!.setString( + "keepAlive", + "300", + ); + loaded = true; + } } - prefs! - .setString("keepAlive", "300"); - loaded = true; - } catch (_) { - prefs! - .setString("keepAlive", "300"); - loaded = true; - } - } - load(); - }); + load(); + }); } else { loaded = true; } return Padding( padding: const EdgeInsets.all(16), child: Theme( - data: (prefs?.getBool( - "useDeviceTheme") ?? + data: + (prefs?.getBool("useDeviceTheme") ?? false) ? Theme.of(context) : ThemeData.from( colorScheme: ColorScheme.fromSeed( - seedColor: Colors.black, - brightness: - Theme.of(context) - .colorScheme - .brightness)), + seedColor: Colors.black, + brightness: Theme.of( + context, + ).colorScheme.brightness, + ), + ), child: DurationPicker( - duration: Duration( - seconds: int.parse(prefs! - .getString( - "keepAlive") ?? - "300")), - baseUnit: BaseUnit.minute, - lowerBound: - const Duration(minutes: 1), - upperBound: - const Duration(minutes: 60), - onChange: (value) { - if (!loaded) return; - if (value.inSeconds == 0) return; - prefs!.setString("keepAlive", - value.inSeconds.toString()); - setLocalState(() {}); - setState(() {}); - }), + duration: Duration( + seconds: int.parse( + prefs!.getString("keepAlive") ?? + "300", + ), + ), + baseUnit: BaseUnit.minute, + lowerBound: const Duration( + minutes: 1, + ), + upperBound: const Duration( + minutes: 60, + ), + onChange: (value) { + if (!loaded) return; + if (value.inSeconds == 0) return; + prefs!.setString( + "keepAlive", + value.inSeconds.toString(), + ); + setLocalState(() {}); + setState(() {}); + }, + ), ), ); - })); - }); - }), + }, + ), + ); + }, + ); + }, + ), titleDivider(context: context), button( - AppLocalizations.of(context) - .settingsTimeoutMultiplier, - Icons.info_rounded, - null, - iconAfterwards: true, - context: context, - alwaysMobileDescription: true, - description: - "\n${AppLocalizations.of(context).settingsTimeoutMultiplierDescription}"), + AppLocalizations.of(context).settingsTimeoutMultiplier, + Icons.info_rounded, + null, + iconAfterwards: true, + context: context, + alwaysMobileDescription: true, + description: + "\n${AppLocalizations.of(context).settingsTimeoutMultiplierDescription}", + ), Slider( - value: prefs!.getDouble("timeoutMultiplier") ?? 1, - min: 0.5, - divisions: 19, - max: 10, - label: (prefs!.getDouble("timeoutMultiplier") ?? 1) - .toString() - .removeSuffix(".0"), - onChanged: (value) { - selectionHaptic(); - prefs!.setDouble("timeoutMultiplier", value); - setState(() {}); - }), + value: prefs!.getDouble("timeoutMultiplier") ?? 1, + min: 0.5, + divisions: 19, + max: 10, + label: (prefs!.getDouble("timeoutMultiplier") ?? 1) + .toString() + .removeSuffix(".0"), + onChanged: (value) { + selectionHaptic(); + prefs!.setDouble("timeoutMultiplier", value); + setState(() {}); + }, + ), button( - AppLocalizations.of(context) - .settingsTimeoutMultiplierExample, - Icons.calculate_rounded, - null, - onlyDesktopDescription: false, - // making it complicated because web is weird and doesn't like to round numbers - description: "\n${() { - var value = - prefs!.getDouble("timeoutMultiplier") ?? 1; - if (value == 10) { - return "${value.round()}."; - } else { - if (!value.toString().contains(".")) { - return "${value.toString()}.0"; + AppLocalizations.of( + context, + ).settingsTimeoutMultiplierExample, + Icons.calculate_rounded, + null, + onlyDesktopDescription: false, + // making it complicated because web is weird and doesn't like to round numbers + description: + "\n${() { + final value = prefs!.getDouble("timeoutMultiplier") ?? 1; + if (value == 10) { + return "${value.round()}."; + } else { + if (!value.toString().contains(".")) { + return "${value.toString()}.0"; + } + return value; } - return value; - } - }.call()} x 30s = ${((prefs!.getDouble("timeoutMultiplier") ?? 1) * 30).round()}s ${secondsBeautify((prefs!.getDouble("timeoutMultiplier") ?? 1) * 30)}"), + }.call()} x 30s = ${((prefs!.getDouble("timeoutMultiplier") ?? 1) * 30).round()}s ${secondsBeautify((prefs!.getDouble("timeoutMultiplier") ?? 1) * 30)}", + ), titleDivider(context: context), toggle( + context, + AppLocalizations.of( context, - AppLocalizations.of(context) - .settingsEnableHapticFeedback, - prefs!.getBool("enableHaptic") ?? true, (value) { - prefs!.setBool("enableHaptic", value); - selectionHaptic(); - setState(() {}); - }), + ).settingsEnableHapticFeedback, + prefs!.getBool("enableHaptic") ?? true, + (value) { + prefs!.setBool("enableHaptic", value); + selectionHaptic(); + setState(() {}); + }, + ), desktopFeature() ? toggle( context, - AppLocalizations.of(context) - .settingsMaximizeOnStart, + AppLocalizations.of( + context, + ).settingsMaximizeOnStart, prefs!.getBool("maximizeOnStart") ?? false, (value) { - selectionHaptic(); - prefs!.setBool("maximizeOnStart", value); - setState(() {}); - }) + selectionHaptic(); + prefs!.setBool("maximizeOnStart", value); + setState(() {}); + }, + ) : const SizedBox.shrink(), const SizedBox(height: 8), SegmentedButton( - segments: [ - ButtonSegment( - value: "dark", - label: Text(AppLocalizations.of(context) - .settingsBrightnessDark), - icon: const Icon(Icons.brightness_4_rounded)), - ButtonSegment( - value: "system", - label: Text(AppLocalizations.of(context) - .settingsBrightnessSystem), - icon: - const Icon(Icons.brightness_auto_rounded)), - ButtonSegment( - value: "light", - label: Text(AppLocalizations.of(context) - .settingsBrightnessLight), - icon: const Icon(Icons.brightness_high_rounded)) - ], - selected: { - prefs!.getString("brightness") ?? "system" - }, - onSelectionChanged: (p0) async { - selectionHaptic(); - await prefs! - .setString("brightness", p0.elementAt(0)); - setMainAppState!(() {}); - setState(() {}); - }), + segments: [ + ButtonSegment( + value: "dark", + label: Text( + AppLocalizations.of( + context, + ).settingsBrightnessDark, + ), + icon: const Icon(Icons.brightness_4_rounded), + ), + ButtonSegment( + value: "system", + label: Text( + AppLocalizations.of( + context, + ).settingsBrightnessSystem, + ), + icon: const Icon(Icons.brightness_auto_rounded), + ), + ButtonSegment( + value: "light", + label: Text( + AppLocalizations.of( + context, + ).settingsBrightnessLight, + ), + icon: const Icon(Icons.brightness_high_rounded), + ), + ], + selected: {prefs!.getString("brightness") ?? "system"}, + onSelectionChanged: (p0) async { + selectionHaptic(); + await prefs!.setString("brightness", p0.elementAt(0)); + setMainAppState!(() {}); + setState(() {}); + }, + ), AnimatedContainer( - duration: const Duration(milliseconds: 200), - height: desktopLayoutNotRequired(context) ? 16 : 8), + duration: const Duration(milliseconds: 200), + height: desktopLayoutNotRequired(context) ? 16 : 8, + ), (colorSchemeLight != null && colorSchemeDark != null) ? SegmentedButton( segments: [ - ButtonSegment( - value: "device", - label: Text(AppLocalizations.of(context) - .settingsThemeDevice), - icon: const Icon(Icons.devices_rounded)), - ButtonSegment( - value: "ollama", - label: Text(AppLocalizations.of(context) - .settingsThemeOllama), - icon: const ImageIcon( - AssetImage("assets/logo512.png"))) - ], + ButtonSegment( + value: "device", + label: Text( + AppLocalizations.of( + context, + ).settingsThemeDevice, + ), + icon: const Icon(Icons.devices_rounded), + ), + ButtonSegment( + value: "ollama", + label: Text( + AppLocalizations.of( + context, + ).settingsThemeOllama, + ), + icon: const ImageIcon( + AssetImage("assets/logo512.png"), + ), + ), + ], selected: { - (prefs?.getBool("useDeviceTheme") ?? false) - ? "device" - : "ollama" - }, + (prefs?.getBool("useDeviceTheme") ?? false) + ? "device" + : "ollama", + }, onSelectionChanged: (p0) async { selectionHaptic(); - await prefs!.setBool("useDeviceTheme", - p0.elementAt(0) == "device"); + await prefs!.setBool( + "useDeviceTheme", + p0.elementAt(0) == "device", + ); setMainAppState!(() {}); setState(() {}); - }) + }, + ) : const SizedBox.shrink(), titleDivider(), button( - AppLocalizations.of(context).settingsTemporaryFixes, - Icons.fast_forward_rounded, () { - selectionHaptic(); - showModalBottomSheet( + AppLocalizations.of(context).settingsTemporaryFixes, + Icons.fast_forward_rounded, + () { + selectionHaptic(); + showModalBottomSheet( context: context, builder: (context) { return StatefulBuilder( - builder: (context, setState) { - return Container( - width: double.infinity, - padding: EdgeInsets.only( + builder: (context, setState) { + return Container( + width: double.infinity, + padding: EdgeInsets.only( left: 16, right: 16, top: 16, - bottom: desktopLayout(context) ? 16 : 0), - child: Column( + bottom: desktopLayout(context) ? 16 : 0, + ), + child: Column( mainAxisSize: MainAxisSize.min, children: [ button( - AppLocalizations.of(context) - .settingsTemporaryFixesDescription, - Icons.info_rounded, - null, - color: Colors.grey.harmonizeWith( - Theme.of(context) - .colorScheme - .primary)), + AppLocalizations.of( + context, + ).settingsTemporaryFixesDescription, + Icons.info_rounded, + null, + color: Colors.grey.harmonizeWith( + Theme.of( + context, + ).colorScheme.primary, + ), + ), button( - AppLocalizations.of(context) - .settingsTemporaryFixesInstructions, - Icons.warning_rounded, - null, - color: Colors.orange.harmonizeWith( - Theme.of(context) - .colorScheme - .primary)), + AppLocalizations.of( + context, + ).settingsTemporaryFixesInstructions, + Icons.warning_rounded, + null, + color: Colors.orange.harmonizeWith( + Theme.of( + context, + ).colorScheme.primary, + ), + ), titleDivider(), // Text( // AppLocalizations.of(context)! @@ -449,37 +545,57 @@ class _ScreenSettingsInterfaceState extends State { // style: const TextStyle( // color: Colors.grey)), toggle( - context, - "Fixing code block not scrollable", - prefs!.getBool( - "fixCodeblockScroll") ?? - false, (value) { - selectionHaptic(); - prefs!.setBool( - "fixCodeblockScroll", value); - if ((prefs!.getBool( - "fixCodeblockScroll") ?? - false) == - false) { - prefs!.remove("fixCodeblockScroll"); - } - setState(() {}); - }, onLongTap: () { - selectionHaptic(); - launchUrl(Uri.parse( - "https://github.com/JHubi1/ollama-app/issues/26")); - }), - const SizedBox(height: 16) - ]), - ); - }); - }); - }), - const SizedBox(height: 16) - ]), - ) - ])), - )), + context, + "Fixing code block not scrollable", + prefs!.getBool( + "fixCodeblockScroll", + ) ?? + false, + (value) { + selectionHaptic(); + prefs!.setBool( + "fixCodeblockScroll", + value, + ); + if ((prefs!.getBool( + "fixCodeblockScroll", + ) ?? + false) == + false) { + prefs!.remove( + "fixCodeblockScroll", + ); + } + setState(() {}); + }, + onLongTap: () { + selectionHaptic(); + launchUrl( + Uri.parse( + "https://github.com/JHubi1/ollama-app/issues/26", + ), + ); + }, + ), + const SizedBox(height: 16), + ], + ), + ); + }, + ); + }, + ); + }, + ), + const SizedBox(height: 16), + ], + ), + ), + ], + ), + ), + ), + ), ); } } diff --git a/lib/screens/settings/voice.dart b/lib/screens/settings/voice.dart index 21e26f7..1de99ff 100644 --- a/lib/screens/settings/voice.dart +++ b/lib/screens/settings/voice.dart @@ -32,7 +32,7 @@ class _ScreenSettingsVoiceState extends State { bool dialogMustLoad = true; Future load() async { - var tmp = await speech.locales(); + final tmp = await speech.locales(); languageOptionIds = tmp.map((e) => e.localeId); languageOptions = tmp.map((e) => e.name); @@ -43,8 +43,9 @@ class _ScreenSettingsVoiceState extends State { voiceLanguageOptions = await voice.getLanguages as List; for (var i = 0; i < languageOptionIds.length; i++) { - if (voiceLanguageOptions - .contains(languageOptionIds.elementAt(i).replaceAll("_", "-"))) { + if (voiceLanguageOptions.contains( + languageOptionIds.elementAt(i).replaceAll("_", "-"), + )) { voiceLanguageOptionsAvailable.add(languageOptionIds.elementAt(i)); } } @@ -63,298 +64,381 @@ class _ScreenSettingsVoiceState extends State { return WindowBorder( color: Theme.of(context).colorScheme.surface, child: Scaffold( - appBar: AppBar( - title: Badge( - label: Text( - AppLocalizations.of(context).settingsExperimentalBeta), - offset: const Offset(20, -4), - backgroundColor: Theme.of(context).colorScheme.primary, - textColor: Theme.of(context).colorScheme.onPrimary, - child: - Text(AppLocalizations.of(context).settingsTitleVoice))), - body: Padding( - padding: const EdgeInsets.only(left: 16, right: 16), - child: Column(children: [ - Expanded( - child: ListView(children: [ + appBar: AppBar( + title: Badge( + label: Text(AppLocalizations.of(context).settingsExperimentalBeta), + offset: const Offset(20, -4), + backgroundColor: Theme.of(context).colorScheme.primary, + textColor: Theme.of(context).colorScheme.onPrimary, + child: Text(AppLocalizations.of(context).settingsTitleVoice), + ), + ), + body: Padding( + padding: const EdgeInsets.only(left: 16, right: 16), + child: Column( + children: [ + Expanded( + child: ListView( + children: [ (permissionLoading || (permissionBluetooth && permissionRecord && voiceSupported && voiceLanguageOptionsAvailable.contains( - prefs!.getString("voiceLanguage") ?? - "en_US"))) + prefs!.getString("voiceLanguage") ?? "en_US", + ))) ? const SizedBox.shrink() : button( permissionLoading - ? AppLocalizations.of(context) - .settingsVoicePermissionLoading + ? AppLocalizations.of( + context, + ).settingsVoicePermissionLoading : (!voiceLanguageOptionsAvailable.contains( - prefs!.getString("voiceLanguage") ?? - "en_US") && - (prefs!.getBool("voiceModeEnabled") ?? - false)) - ? AppLocalizations.of(context) - .settingsVoiceTtsNotSupported - : !(permissionBluetooth && permissionRecord) - ? AppLocalizations.of(context) - .settingsVoicePermissionNot - : AppLocalizations.of(context) - .settingsVoiceNotSupported, - Icons.info_rounded, () { - selectionHaptic(); - if (permissionLoading) return; - if (!(permissionBluetooth && permissionRecord)) { - Future load() async { - try { - if (await Permission - .bluetooth.isPermanentlyDenied || - await Permission - .microphone.isPermanentlyDenied) { - await openAppSettings(); - } - permissionRecord = await Permission.microphone - .request() - .isGranted; - permissionBluetooth = await Permission - .bluetoothConnect - .request() - .isGranted; - permissionLoading = false; - - if (permissionBluetooth && permissionRecord) { - voiceSupported = await speech.initialize(); - } - - setState(() {}); - } catch (_) { - permissionLoading = false; + prefs!.getString("voiceLanguage") ?? + "en_US", + ) && + (prefs!.getBool("voiceModeEnabled") ?? + false)) + ? AppLocalizations.of( + context, + ).settingsVoiceTtsNotSupported + : !(permissionBluetooth && permissionRecord) + ? AppLocalizations.of( + context, + ).settingsVoicePermissionNot + : AppLocalizations.of( + context, + ).settingsVoiceNotSupported, + Icons.info_rounded, + () { + selectionHaptic(); + if (permissionLoading) return; + if (!(permissionBluetooth && permissionRecord)) { + Future load() async { try { + if (await Permission + .bluetooth + .isPermanentlyDenied || + await Permission + .microphone + .isPermanentlyDenied) { + await openAppSettings(); + } + permissionRecord = await Permission + .microphone + .request() + .isGranted; + permissionBluetooth = await Permission + .bluetoothConnect + .request() + .isGranted; + permissionLoading = false; + + if (permissionBluetooth && + permissionRecord) { + voiceSupported = await speech + .initialize(); + } + setState(() {}); - } catch (_) {} + } catch (_) { + permissionLoading = false; + try { + setState(() {}); + } catch (_) {} + } + } + + load(); + } else if (!voiceLanguageOptions.contains( + prefs!.getString("voiceLanguage") ?? "en_US", + )) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of( + context, + ).settingsVoiceTtsNotSupportedDescription, + ), + showCloseIcon: true, + ), + ); + } + }, + ), + toggle( + context, + AppLocalizations.of(context).settingsVoiceEnable, + prefs!.getBool("voiceModeEnabled") ?? false, + (value) { + selectionHaptic(); + prefs!.setBool("voiceModeEnabled", value); + setState(() {}); + }, + disabled: !voiceSupported, + ), + button( + ((prefs!.getString("voiceLanguage") ?? "") == "" || + languageOptions.isEmpty) + ? AppLocalizations.of(context).settingsVoiceNoLanguage + : () { + for ( + var i = 0; + i < languageOptionIds.length; + i++ + ) { + if (languageOptionIds.elementAt(i) == + prefs!.getString("voiceLanguage")) { + return languageOptions.elementAt(i); + } + } + return ""; + }(), + Icons.language_rounded, + () { + var usedIndex = -1; + Function? setModalState; + + selectionHaptic(); + + showModalBottomSheet( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, setLocalState) { + setModalState = setLocalState; + + Future loadSelected() async { + await load(); + if ((prefs!.getString("voiceLanguage") ?? "") != + "") { + for ( + var i = 0; + i < languageOptionIds.length; + i++ + ) { + if (languageOptionIds.elementAt(i) == + (prefs!.getString("voiceLanguage") ?? + "")) { + setModalState!(() { + usedIndex = i; + }); + break; + } + } } } - load(); - } else if (!voiceLanguageOptions.contains( - prefs!.getString("voiceLanguage") ?? "en_US")) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(AppLocalizations.of(context) - .settingsVoiceTtsNotSupportedDescription), - showCloseIcon: true)); - } - }), - toggle( - context, - AppLocalizations.of(context).settingsVoiceEnable, - prefs!.getBool("voiceModeEnabled") ?? false, (value) { - selectionHaptic(); - prefs!.setBool("voiceModeEnabled", value); - setState(() {}); - }, disabled: !voiceSupported), - button( - ((prefs!.getString("voiceLanguage") ?? "") == "" || - languageOptions.isEmpty) - ? AppLocalizations.of(context) - .settingsVoiceNoLanguage - : () { - for (var i = 0; - i < languageOptionIds.length; - i++) { - if (languageOptionIds.elementAt(i) == - prefs!.getString("voiceLanguage")) { - return languageOptions.elementAt(i); - } - } - return ""; - }(), - Icons.language_rounded, () { - var usedIndex = -1; - Function? setModalState; + if (dialogMustLoad) { + loadSelected(); + dialogMustLoad = false; + } - selectionHaptic(); - - showModalBottomSheet( - context: context, - builder: - (context) => StatefulBuilder( - builder: (context, setLocalState) { - setModalState = setLocalState; - - Future loadSelected() async { - await load(); - if ((prefs!.getString("voiceLanguage") ?? - "") != - "") { - for (var i = 0; - i < languageOptionIds.length; - i++) { - if (languageOptionIds.elementAt(i) == - (prefs!.getString( - "voiceLanguage") ?? - "")) { - setModalState!(() { - usedIndex = i; - }); - break; - } - } - } - } - - if (dialogMustLoad) { - loadSelected(); - dialogMustLoad = false; - } - - return PopScope( - onPopInvokedWithResult: - (didPop, result) { - if (usedIndex == -1) return; - prefs!.setString( - "voiceLanguage", - languageOptionIds - .elementAt(usedIndex)); - setState(() { - dialogMustLoad = true; - }); - }, - child: Container( - width: double.infinity, - padding: const EdgeInsets.only( - left: 16, - right: 16, - top: 16, - bottom: 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - width: ((Platform - .isWindows || - Platform - .isLinux || - Platform - .isMacOS) && - MediaQuery.of( - context) - .size - .width >= - 1000) - ? 300 - : double.infinity, - constraints: BoxConstraints( - maxHeight: - MediaQuery.of( - context) - .size - .height * - 0.4), - child: - SingleChildScrollView( - scrollDirection: - Axis.vertical, - child: Wrap( - spacing: 5.0, - alignment: - WrapAlignment - .center, - children: List< - Widget>.generate( - languageOptionIds - .length, - (int index) { - return ChoiceChip( - label: Text( - languageOptions - .elementAt(index)), - selected: - usedIndex == - index, - avatar: (usedIndex == - index) - ? null - : (voiceLanguageOptionsAvailable.contains(languageOptionIds.elementAt(index))) - ? const Icon(Icons.spatial_tracking_rounded) - : null, - checkmarkColor: (usedIndex == index && - !(prefs?.getBool("useDeviceTheme") ?? - false)) - ? ((MediaQuery.of(context).platformBrightness == Brightness.light) - ? themeLight().colorScheme.secondary - : themeDark().colorScheme.secondary) - : null, - labelStyle: (usedIndex == index && - !(prefs?.getBool("useDeviceTheme") ?? - false)) - ? TextStyle( - color: (MediaQuery.of(context).platformBrightness == Brightness.light) ? themeLight().colorScheme.secondary : themeDark().colorScheme.secondary) - : null, - selectedColor: (prefs?.getBool("useDeviceTheme") ?? - false) - ? null - : (MediaQuery.of(context).platformBrightness == Brightness.light) - ? themeLight().colorScheme.primary - : themeDark().colorScheme.primary, - onSelected: - (bool - selected) { - selectionHaptic(); - setLocalState( - () { - usedIndex = selected - ? index - : -1; - }); - }, - ); - }, - ).toList(), - ))) - ]))); - })); - }, - disabled: !voiceSupported || - !(prefs!.getBool("voiceModeEnabled") ?? false)), + return PopScope( + onPopInvokedWithResult: (didPop, result) { + if (usedIndex == -1) return; + prefs!.setString( + "voiceLanguage", + languageOptionIds.elementAt(usedIndex), + ); + setState(() { + dialogMustLoad = true; + }); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.only( + left: 16, + right: 16, + top: 16, + bottom: 0, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: + ((Platform.isWindows || + Platform.isLinux || + Platform.isMacOS) && + MediaQuery.of( + context, + ).size.width >= + 1000) + ? 300 + : double.infinity, + constraints: BoxConstraints( + maxHeight: + MediaQuery.of( + context, + ).size.height * + 0.4, + ), + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Wrap( + spacing: 5.0, + alignment: WrapAlignment.center, + children: List.generate( + languageOptionIds.length, + (int index) { + return ChoiceChip( + label: Text( + languageOptions.elementAt( + index, + ), + ), + selected: usedIndex == index, + avatar: (usedIndex == index) + ? null + : (voiceLanguageOptionsAvailable + .contains( + languageOptionIds + .elementAt( + index, + ), + )) + ? const Icon( + Icons + .spatial_tracking_rounded, + ) + : null, + checkmarkColor: + (usedIndex == index && + !(prefs?.getBool( + "useDeviceTheme", + ) ?? + false)) + ? ((MediaQuery.of( + context, + ).platformBrightness == + Brightness + .light) + ? themeLight() + .colorScheme + .secondary + : themeDark() + .colorScheme + .secondary) + : null, + labelStyle: + (usedIndex == index && + !(prefs?.getBool( + "useDeviceTheme", + ) ?? + false)) + ? TextStyle( + color: + (MediaQuery.of( + context, + ).platformBrightness == + Brightness + .light) + ? themeLight() + .colorScheme + .secondary + : themeDark() + .colorScheme + .secondary, + ) + : null, + selectedColor: + (prefs?.getBool( + "useDeviceTheme", + ) ?? + false) + ? null + : (MediaQuery.of( + context, + ).platformBrightness == + Brightness.light) + ? themeLight() + .colorScheme + .primary + : themeDark() + .colorScheme + .primary, + onSelected: (bool selected) { + selectionHaptic(); + setLocalState(() { + usedIndex = selected + ? index + : -1; + }); + }, + ); + }, + ).toList(), + ), + ), + ), + ], + ), + ), + ); + }, + ), + ); + }, + disabled: + !voiceSupported || + !(prefs!.getBool("voiceModeEnabled") ?? false), + ), titleDivider(), toggle( - context, - AppLocalizations.of(context).settingsVoiceLimitLanguage, - prefs!.getBool("voiceLimitLanguage") ?? true, (value) { - selectionHaptic(); - prefs!.setBool("voiceLimitLanguage", value); - setState(() {}); - }, - disabled: !voiceSupported || - !(prefs!.getBool("voiceModeEnabled") ?? false)), + context, + AppLocalizations.of(context).settingsVoiceLimitLanguage, + prefs!.getBool("voiceLimitLanguage") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("voiceLimitLanguage", value); + setState(() {}); + }, + disabled: + !voiceSupported || + !(prefs!.getBool("voiceModeEnabled") ?? false), + ), toggle( - context, - AppLocalizations.of(context).settingsVoicePunctuation, - prefs!.getBool("aiPunctuation") ?? true, (value) { - selectionHaptic(); - prefs!.setBool("aiPunctuation", value); - setState(() {}); - }, - disabled: !voiceSupported || - !(prefs!.getBool("voiceModeEnabled") ?? false)) - ]), + context, + AppLocalizations.of(context).settingsVoicePunctuation, + prefs!.getBool("aiPunctuation") ?? true, + (value) { + selectionHaptic(); + prefs!.setBool("aiPunctuation", value); + setState(() {}); + }, + disabled: + !voiceSupported || + !(prefs!.getBool("voiceModeEnabled") ?? false), + ), + ], ), - const SizedBox(height: 8), - button( - AppLocalizations.of(context) - .settingsExperimentalBetaFeature, - Icons.warning_rounded, - null, - color: Colors.orange - .harmonizeWith(Theme.of(context).colorScheme.primary), - onLongTap: () { + ), + const SizedBox(height: 8), + button( + AppLocalizations.of(context).settingsExperimentalBetaFeature, + Icons.warning_rounded, + null, + color: Colors.orange.harmonizeWith( + Theme.of(context).colorScheme.primary, + ), + onLongTap: () { selectionHaptic(); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(AppLocalizations.of(context) - .settingsExperimentalBetaDescription), - showCloseIcon: true)); - }) - ]))), + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of( + context, + ).settingsExperimentalBetaDescription, + ), + showCloseIcon: true, + ), + ); + }, + ), + ], + ), + ), + ), ); } } diff --git a/lib/screens/voice.dart b/lib/screens/voice.dart index 913e8fa..39e22de 100644 --- a/lib/screens/voice.dart +++ b/lib/screens/voice.dart @@ -37,36 +37,39 @@ class _ScreenVoiceState extends State { speaking = true; sttDone = false; }); - var textOldOld = text; + final textOldOld = text; var textOld = ""; text = ""; speech.listen( - localeId: prefs!.getString("voiceLanguage") ?? "en-US", - listenOptions: - stt.SpeechListenOptions(listenMode: stt.ListenMode.dictation), - onResult: (result) { - lightHaptic(); - if (!speaking) return; - setState(() { - sttDone = result.finalResult; - text = result.recognizedWords; - }); - }, - pauseFor: const Duration(seconds: 3)); + localeId: prefs!.getString("voiceLanguage") ?? "en-US", + listenOptions: stt.SpeechListenOptions( + listenMode: stt.ListenMode.dictation, + ), + onResult: (result) { + lightHaptic(); + if (!speaking) return; + setState(() { + sttDone = result.finalResult; + text = result.recognizedWords; + }); + }, + pauseFor: const Duration(seconds: 3), + ); var start = DateTime.now(); var timeout = false; - await Future.doWhile(() => - Future.delayed(const Duration(milliseconds: 1)).then((_) { - if (textOld != text) { - start = DateTime.now(); - } - timeout = - DateTime.now().difference(start) >= const Duration(seconds: 3); - textOld = text; - return !sttDone && speaking && !timeout; - })); + await Future.doWhile( + () => Future.delayed(const Duration(milliseconds: 1)).then((_) { + if (textOld != text) { + start = DateTime.now(); + } + timeout = + DateTime.now().difference(start) >= const Duration(seconds: 3); + textOld = text; + return !sttDone && speaking && !timeout; + }), + ); if (!sttDone || timeout) { sttDone = true; speech.stop(); @@ -103,17 +106,21 @@ class _ScreenVoiceState extends State { aiThinking = true; try { if (prefs!.getBool("aiPunctuation") ?? true) { - var generated = await ollamaClient + final generated = await ollamaClient .generateCompletion( request: llama.GenerateCompletionRequest( - model: model!, - prompt: - "Add punctuation and syntax to the following sentence. You must not change order of words or a word in itself! You must not add any word or phrase or remove one! Do not change between formal and personal form, keep the original one!\n\n$text", - keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")), + model: model!, + prompt: + "Add punctuation and syntax to the following sentence. You must not change order of words or a word in itself! You must not add any word or phrase or remove one! Do not change between formal and personal form, keep the original one!\n\n$text", + keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300"), + ), ) - .timeout(Duration( + .timeout( + Duration( seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); setState(() { text = generated.response!; }); @@ -121,50 +128,59 @@ class _ScreenVoiceState extends State { } catch (_) {} // ignore: use_build_context_synchronously - send(text, context, setState, onStream: (currentText, done) async { - setState(() { - aiText = currentText; - lightHaptic(); - updateScrollState(); - }); - if (done) { - aiThinking = false; - heavyHaptic(); + send( + text, + context, + setState, + onStream: (currentText, done) async { + setState(() { + aiText = currentText; + lightHaptic(); + updateScrollState(); + }); + if (done) { + aiThinking = false; + heavyHaptic(); - if (currentText.isEmpty) { - text = ""; - speaking = false; - try { - setState(() {}); - } catch (_) {} - return; + if (currentText.isEmpty) { + text = ""; + speaking = false; + try { + setState(() {}); + } catch (_) {} + return; + } + + if ((await voice.getLanguages as List).contains( + (prefs!.getString("voiceLanguage") ?? "en_US").replaceAll("_", "-"), + )) { + voice + ..setLanguage( + (prefs!.getString("voiceLanguage") ?? "en_US").replaceAll( + "_", + "-", + ), + ) + ..setSpeechRate(0.6) + ..setCompletionHandler(() async { + speaking = false; + try { + setState(() {}); + } catch (_) {} + process(); + }); + final tmp = aiText + ..replaceAll("-", ".") + ..replaceAll("*", "."); + + voice.speak(tmp); + } } - - if ((await voice.getLanguages as List).contains( - (prefs!.getString("voiceLanguage") ?? "en_US") - .replaceAll("_", "-"))) { - voice - ..setLanguage((prefs!.getString("voiceLanguage") ?? "en_US") - .replaceAll("_", "-")) - ..setSpeechRate(0.6) - ..setCompletionHandler(() async { - speaking = false; - try { - setState(() {}); - } catch (_) {} - process(); - }); - var tmp = aiText - ..replaceAll("-", ".") - ..replaceAll("*", "."); - - voice.speak(tmp); - } - } - }, - addToSystem: (prefs!.getBool("voiceLimitLanguage") ?? true) - ? "You must write in the following language: ${prefs!.getString("voiceLanguage") ?? "en_US"}!" - : null); + }, + addToSystem: (prefs!.getBool("voiceLimitLanguage") ?? true) + ? "You must write in the following language: ${prefs!.getString("voiceLanguage") ?? "en_US"}!" + : null, + ); } final ScrollController scrollController = ScrollController(); @@ -183,7 +199,7 @@ class _ScreenVoiceState extends State { scrollController.addListener(updateScrollState); Future load() async { - var tmp = await speech.locales(); + final tmp = await speech.locales(); languageOptionIds = tmp.map((e) => e.localeId); languageOptions = tmp.map((e) => e.name); setState(() {}); @@ -202,198 +218,235 @@ class _ScreenVoiceState extends State { @override Widget build(BuildContext context) { return Theme( - data: themeDark(), - child: PopScope( - canPop: !aiThinking, - onPopInvokedWithResult: (didPop, result) { - if (!didPop) return; - speaking = false; - voice.stop(); - if (chatUuid != null) { - loadChat(chatUuid!, setGlobalState!); - } - settingsOpen = false; - logoVisible = true; - }, - child: Scaffold( - appBar: AppBar( - scrolledUnderElevation: 0.0, - leading: IconButton( - enableFeedback: false, - onPressed: () { - Navigator.of(context).pop(); - }, - icon: const Icon(Icons.close_rounded, - color: Colors.grey)), - title: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - child: Text( - (model ?? - AppLocalizations.of(context) - .noSelectedModel) - .split(":")[0], - textAlign: TextAlign.center, - overflow: TextOverflow.fade, - style: const TextStyle( - fontFamily: "monospace", fontSize: 16))), - ], + data: themeDark(), + child: PopScope( + canPop: !aiThinking, + onPopInvokedWithResult: (didPop, result) { + if (!didPop) return; + speaking = false; + voice.stop(); + if (chatUuid != null) { + loadChat(chatUuid!, setGlobalState!); + } + settingsOpen = false; + logoVisible = true; + }, + child: Scaffold( + appBar: AppBar( + scrolledUnderElevation: 0.0, + leading: IconButton( + enableFeedback: false, + onPressed: () { + Navigator.of(context).pop(); + }, + icon: const Icon(Icons.close_rounded, color: Colors.grey), + ), + title: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Text( + (model ?? AppLocalizations.of(context).noSelectedModel) + .split(":")[0], + textAlign: TextAlign.center, + overflow: TextOverflow.fade, + style: const TextStyle( + fontFamily: "monospace", + fontSize: 16, ), - actions: [ - IconButton( - enableFeedback: false, - onPressed: () { - speaking = false; - settingsOpen = false; - logoVisible = true; - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => - const ScreenSettingsVoice())); - }, - icon: const Icon( - Icons.settings_rounded, - color: Colors.grey, - )) - ]), - body: SafeArea( - child: Column(mainAxisSize: MainAxisSize.max, children: [ - Expanded( - child: Column(mainAxisSize: MainAxisSize.max, children: [ - Expanded( - child: Padding( + ), + ), + ], + ), + actions: [ + IconButton( + enableFeedback: false, + onPressed: () { + speaking = false; + settingsOpen = false; + logoVisible = true; + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (context) => const ScreenSettingsVoice(), + ), + ); + }, + icon: const Icon(Icons.settings_rounded, color: Colors.grey), + ), + ], + ), + body: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Padding( padding: const EdgeInsets.only(left: 16, right: 16), child: Center( - child: Text(text, - textAlign: TextAlign.center, - overflow: TextOverflow.fade, - style: const TextStyle( - color: Colors.grey, - fontFamily: "monospace"))), - )) - ]), - ), - Expanded( - child: Center( - child: DateTimeLoopBuilder( - timeUnit: TimeUnit.seconds, - builder: (context, dateTime, child) { - return SizedBox( - height: 96, - width: 96, - child: AnimatedScale( - scale: speaking - ? aiThinking - ? dateTime.second.isEven - ? 2.4 - : 2 - : 2 - : dateTime.second - .toString() - .endsWith("1") - ? 1.6 - : 1.4, - duration: aiThinking - ? const Duration(seconds: 1) - : const Duration(milliseconds: 200), - curve: Curves.easeInOut, - child: InkWell( - borderRadius: - BorderRadius.circular(48), - onTap: () { - if (speaking && !aiThinking) { - intendedStop = true; - speaking = false; - voice.stop(); - return; - } - process(); - }, - child: CircleAvatar( - backgroundColor: themeDark() + child: Text( + text, + textAlign: TextAlign.center, + overflow: TextOverflow.fade, + style: const TextStyle( + color: Colors.grey, + fontFamily: "monospace", + ), + ), + ), + ), + ), + ], + ), + ), + Expanded( + child: Center( + child: DateTimeLoopBuilder( + timeUnit: TimeUnit.seconds, + builder: (context, dateTime, child) { + return SizedBox( + height: 96, + width: 96, + child: AnimatedScale( + scale: speaking + ? aiThinking + ? dateTime.second.isEven + ? 2.4 + : 2 + : 2 + : dateTime.second.toString().endsWith("1") + ? 1.6 + : 1.4, + duration: aiThinking + ? const Duration(seconds: 1) + : const Duration(milliseconds: 200), + curve: Curves.easeInOut, + child: InkWell( + borderRadius: BorderRadius.circular(48), + onTap: () { + if (speaking && !aiThinking) { + intendedStop = true; + speaking = false; + voice.stop(); + return; + } + process(); + }, + child: CircleAvatar( + backgroundColor: themeDark().colorScheme.primary + .withAlpha(!speaking ? 200 : 255), + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 200), + child: speaking + ? aiThinking + ? Icon( + Icons.auto_awesome_rounded, + color: themeDark() .colorScheme - .primary - .withAlpha( - !speaking ? 200 : 255), - child: AnimatedSwitcher( - duration: const Duration( - milliseconds: 200), - child: speaking - ? aiThinking - ? Icon(Icons.auto_awesome_rounded, - color: themeDark() - .colorScheme - .secondary, - key: const ValueKey( - "aiThinking")) - : sttDone - ? Icon(Icons.volume_up_rounded, - color: themeDark() - .colorScheme - .secondary, - key: const ValueKey( - "tts")) - : Icon(Icons.mic_rounded, - color: themeDark() - .colorScheme - .secondary, - key: const ValueKey("stt")) - : null)))), - ); - }))), - Expanded( - child: Column(mainAxisSize: MainAxisSize.max, children: [ - Expanded( - child: Stack( + .secondary, + key: const ValueKey( + "aiThinking", + ), + ) + : sttDone + ? Icon( + Icons.volume_up_rounded, + color: themeDark() + .colorScheme + .secondary, + key: const ValueKey("tts"), + ) + : Icon( + Icons.mic_rounded, + color: themeDark() + .colorScheme + .secondary, + key: const ValueKey("stt"), + ) + : null, + ), + ), + ), + ), + ); + }, + ), + ), + ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Stack( children: [ ShaderMask( - shaderCallback: (Rect bounds) { - return LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: const [ - Colors.transparent, - Colors.black - ], - stops: [0.0, atScrollEnd ? 0.0 : 0.1], - ).createShader(bounds); - }, - blendMode: BlendMode.dstIn, - child: SingleChildScrollView( - controller: scrollController, - child: Padding( - padding: const EdgeInsets.only( - left: 16, right: 16), - child: Center( - child: Text(aiText, - textAlign: TextAlign.center, - overflow: TextOverflow.fade, - style: const TextStyle( - fontFamily: - "monospace")))))), + shaderCallback: (Rect bounds) { + return LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: const [ + Colors.transparent, + Colors.black, + ], + stops: [0.0, atScrollEnd ? 0.0 : 0.1], + ).createShader(bounds); + }, + blendMode: BlendMode.dstIn, + child: SingleChildScrollView( + controller: scrollController, + child: Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + ), + child: Center( + child: Text( + aiText, + textAlign: TextAlign.center, + overflow: TextOverflow.fade, + style: const TextStyle( + fontFamily: "monospace", + ), + ), + ), + ), + ), + ), if (!atScrollEnd) Positioned( right: 0, bottom: 0, child: IconButton( - icon: const Icon( - Icons.arrow_downward_rounded, - color: Colors.grey), - onPressed: () { - scrollController.animateTo( - scrollController - .position.maxScrollExtent, - duration: - const Duration(milliseconds: 500), - curve: Curves.easeInOut); - }), - ) + icon: const Icon( + Icons.arrow_downward_rounded, + color: Colors.grey, + ), + onPressed: () { + scrollController.animateTo( + scrollController.position.maxScrollExtent, + duration: const Duration( + milliseconds: 500, + ), + curve: Curves.easeInOut, + ); + }, + ), + ), ], - )) - ]), - ) - ]), - )))); + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); } } diff --git a/lib/screens/welcome.dart b/lib/screens/welcome.dart index f2ef95c..e79c61d 100644 --- a/lib/screens/welcome.dart +++ b/lib/screens/welcome.dart @@ -27,84 +27,105 @@ class _ScreenWelcomeState extends State { precacheImage(const AssetImage("assets/welcome/3dark.png"), context); return Scaffold( - bottomNavigationBar: BottomSheet( - enableDrag: false, - backgroundColor: (Theme.of(context).brightness == Brightness.light) - ? Colors.grey[100] - : Colors.grey[900], - onClosing: () {}, - builder: (context) { - return Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - child: Column(mainAxisSize: MainAxisSize.min, children: [ - SmoothPageIndicator( - controller: _pageController, - count: 3, - effect: ExpandingDotsEffect( - activeDotColor: (Theme.of(context).brightness == - Brightness.light) - ? themeLight().colorScheme.primary - : themeDark().colorScheme.primary)), - ])); - }), - floatingActionButtonLocation: FloatingActionButtonLocation.endDocked, - floatingActionButton: FloatingActionButton( - onPressed: () { - if (page < 2) { - _pageController.nextPage( - duration: const Duration(milliseconds: 250), - curve: Curves.easeInOut); - } else { - prefs!.setBool("welcomeFinished", true); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => const ScreenMain())); - } - }, - child: (page < 2) - ? const Icon(Icons.arrow_forward) - : const Icon(Icons.check_rounded)), - body: SafeArea( - child: Column(children: [ - Expanded( - child: PageView( + bottomNavigationBar: BottomSheet( + enableDrag: false, + backgroundColor: (Theme.of(context).brightness == Brightness.light) + ? Colors.grey[100] + : Colors.grey[900], + onClosing: () {}, + builder: (context) { + return Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SmoothPageIndicator( controller: _pageController, - onPageChanged: (value) { - setState(() { - page = value; - }); - }, - children: [ - Center( + count: 3, + effect: ExpandingDotsEffect( + activeDotColor: + (Theme.of(context).brightness == Brightness.light) + ? themeLight().colorScheme.primary + : themeDark().colorScheme.primary, + ), + ), + ], + ), + ); + }, + ), + floatingActionButtonLocation: FloatingActionButtonLocation.endDocked, + floatingActionButton: FloatingActionButton( + onPressed: () { + if (page < 2) { + _pageController.nextPage( + duration: const Duration(milliseconds: 250), + curve: Curves.easeInOut, + ); + } else { + prefs!.setBool("welcomeFinished", true); + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const ScreenMain()), + ); + } + }, + child: (page < 2) + ? const Icon(Icons.arrow_forward) + : const Icon(Icons.check_rounded), + ), + body: SafeArea( + child: Column( + children: [ + Expanded( + child: PageView( + controller: _pageController, + onPageChanged: (value) { + setState(() { + page = value; + }); + }, + children: [ + Center( child: (Theme.of(context).brightness == Brightness.light) ? FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: const AssetImage("assets/welcome/1.png")) + image: const AssetImage("assets/welcome/1.png"), + ) : FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: - const AssetImage("assets/welcome/1dark.png"))), - Center( + image: const AssetImage("assets/welcome/1dark.png"), + ), + ), + Center( child: (Theme.of(context).brightness == Brightness.light) ? FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: const AssetImage("assets/welcome/2.png")) + image: const AssetImage("assets/welcome/2.png"), + ) : FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: - const AssetImage("assets/welcome/2dark.png"))), - Center( + image: const AssetImage("assets/welcome/2dark.png"), + ), + ), + Center( child: (Theme.of(context).brightness == Brightness.light) ? FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: const AssetImage("assets/welcome/3.png")) + image: const AssetImage("assets/welcome/3.png"), + ) : FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: - const AssetImage("assets/welcome/3dark.png"))) - ])), - ]))); + image: const AssetImage("assets/welcome/3dark.png"), + ), + ), + ], + ), + ), + ], + ), + ), + ); } } diff --git a/lib/services/chat.dart b/lib/services/chat.dart index a0ca1f5..0089133 100644 --- a/lib/services/chat.dart +++ b/lib/services/chat.dart @@ -3,11 +3,15 @@ import 'dart:convert'; import 'package:dartx/dartx.dart'; import 'package:flutter/material.dart'; -import 'package:ollama_dart/ollama_dart.dart' as ollama; +import 'package:image/image.dart' as img; +import 'package:mime/mime.dart'; +import 'package:ollama_dart/ollama_dart.dart' as llama; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:uuid/uuid.dart'; import '../l10n/gen/app_localizations.dart'; import '../main.dart'; +import 'chat_database/chat_database.dart'; import 'clients.dart' as clients; import 'haptic.dart'; import 'model.dart'; @@ -36,6 +40,14 @@ abstract class Message extends ChangeNotifier { operator ==(Object other) => other is Message && other.id == id; @override int get hashCode => id.hashCode; + + static Message Function(Map json)? constructorForType( + String type, + ) => switch (type) { + "text" => TextMessage.fromJson, + "image" => ImageMessage.fromJson, + _ => null, + }; } class TextMessage extends Message { @@ -44,6 +56,12 @@ class TextMessage extends Message { String _content; String get content => _content; + String? _thinking; + String? get thinking => _thinking; + + ChatUsageStats? _stats; + ChatUsageStats? get stats => _stats; + bool _includesError = false; bool get includesError => _includesError; @@ -62,24 +80,49 @@ class TextMessage extends Message { "type": "text", "role": sender.name, "content": content, + "thinking": thinking, + "stats": stats?.toJson(), "includesError": includesError, "createdAt": createdAt.toUtc().millisecondsSinceEpoch, }; + TextMessage.fromJson(Map json) + : _content = json["content"], + _thinking = json["thinking"], + _stats = json["stats"] != null + ? ChatUsageStats.fromJson(json["stats"]) + : null, + _includesError = json["includesError"] ?? false, + super( + sender: MessageSender.values.byName(json["role"]), + createdAt: DateTime.fromMillisecondsSinceEpoch( + json["createdAt"], + isUtc: true, + ), + ); + factory TextMessage.fromStream( - Stream stream, { + Stream stream, { required MessageSender sender, Completer? completer, void Function(String content)? onContent, + Future Function()? saveChat, }) => TextMessage("", sender: sender, createdAt: DateTime.now()) - .._contentFromStream(stream, completer: completer, onContent: onContent); + .._contentFromStream( + stream, + completer: completer, + onContent: onContent, + saveChat: saveChat, + ); Future _contentFromStream( - Stream stream, { + Stream stream, { Completer? completer, void Function(String content)? onContent, + Future Function()? saveChat, }) async { assert(!_locked, "Cannot modify a locked message."); + if (_locked) return; _locked = true; try { @@ -89,11 +132,20 @@ class TextMessage extends Message { sub?.cancel(); return; } - _content += event.message.content; + + if (event.message?.thinking != null) { + _thinking = "${_thinking ?? ""}${event.message?.thinking}"; + } + if (event.done ?? false) { + _stats = ChatUsageStats.fromChatResponse(event); + } + + _content += event.message!.content!; chatHaptic(); notifyListeners(); onContent?.call(_content); + saveChat?.call(); }); await sub.asFuture(); } catch (e, s) { @@ -110,12 +162,22 @@ class TextMessage extends Message { } class ImageMessage extends Message { - final Uri image; + Uri _image; + Uri get image => _image; + final String? name; + double? _aspectRatio; + double? get aspectRatio => _aspectRatio; + + int? _width; + int? get width => _width; + ImageMessage({ - required this.image, + required this._image, this.name, + this._aspectRatio, + this._width, required super.sender, super.createdAt, }); @@ -126,8 +188,128 @@ class ImageMessage extends Message { "role": sender.name, "image": image.toString(), "name": name, + "aspectRatio": aspectRatio, + "width": width, "createdAt": createdAt.toUtc().millisecondsSinceEpoch, }; + + ImageMessage.fromJson(Map json) + : _image = json["image"] != null + ? Uri.parse(json["image"]) + : Uri.parse( + "data:${lookupMimeType(json["name"])};base64,${json["content"]}", + ), + name = json["name"], + _aspectRatio = (json["aspectRatio"] as num?)?.toDouble(), + _width = json["width"], + super( + sender: MessageSender.values.byName(json["role"]), + createdAt: DateTime.fromMillisecondsSinceEpoch( + json["createdAt"], + isUtc: true, + ), + ); + + Future computeImageMeta() async { + try { + final data = image.scheme == "ref" + ? await (chatDb.select(chatDb.assets) + ..where((a) => a.id.equals(image.authority))) + .getSingleOrNull() + .then((r) => r?.data) + : base64Decode(image.toString().split(",").last); + if (data == null) return; + + final decodedImage = img.decodeImage(data); + if (decodedImage == null) return; + + _aspectRatio = decodedImage.width / decodedImage.height; + _width = decodedImage.width; + } catch (_) {} + } + + Future get imageProvider async { + assert( + image.scheme == "ref", + "Only images with a 'ref' scheme should be used; please await for migration before using images.", + ); + + if (image.scheme == "ref") { + final img = await (chatDb.select( + chatDb.assets, + )..where((img) => img.id.equals(image.authority))).getSingleOrNull(); + if (img != null) return MemoryImage(img.data); + } else if (image.scheme == "data") { + return MemoryImage(base64Decode(image.toString().split(",").last)); + } + return NetworkImage(image.toString()); + } +} + +class ChatUsageStats { + final Duration totalDuration; + final Duration? loadDuration; + final int promptEvalCount; + final Duration? promptEvalDuration; + final int evalCount; + final Duration? evalDuration; + + ChatUsageStats._({ + required this.totalDuration, + required this.loadDuration, + required this.promptEvalCount, + required this.promptEvalDuration, + required this.evalCount, + required this.evalDuration, + }); + + static ChatUsageStats? fromChatResponse(llama.ChatStreamEvent response) { + if (response.totalDuration == null || + response.promptEvalCount == null || + response.evalCount == null) { + return null; + } + + return ChatUsageStats._( + totalDuration: Duration(microseconds: response.totalDuration! ~/ 1000), + loadDuration: response.loadDuration != null + ? Duration(microseconds: response.loadDuration! ~/ 1000) + : null, + promptEvalCount: response.promptEvalCount!, + promptEvalDuration: response.promptEvalDuration != null + ? Duration(microseconds: response.promptEvalDuration! ~/ 1000) + : null, + evalCount: response.evalCount!, + evalDuration: response.evalDuration != null + ? Duration(microseconds: response.evalDuration! ~/ 1000) + : null, + ); + } + + Map toJson() => { + "totalDuration": totalDuration.inMicroseconds, + "loadDuration": loadDuration?.inMicroseconds, + "promptEvalCount": promptEvalCount, + "promptEvalDuration": promptEvalDuration?.inMicroseconds, + "evalCount": evalCount, + "evalDuration": evalDuration?.inMicroseconds, + }; + + factory ChatUsageStats.fromJson(Map json) => + ChatUsageStats._( + totalDuration: Duration(microseconds: json["totalDuration"]), + loadDuration: json["loadDuration"] != null + ? Duration(microseconds: json["loadDuration"]) + : null, + promptEvalCount: json["promptEvalCount"], + promptEvalDuration: json["loadDuration"] != null + ? Duration(microseconds: json["promptEvalDuration"]) + : null, + evalCount: json["evalCount"], + evalDuration: json["loadDuration"] != null + ? Duration(microseconds: json["evalDuration"]) + : null, + ); } class Chat extends ChangeNotifier { @@ -143,12 +325,14 @@ class Chat extends ChangeNotifier { String? get modelName => _modelName; set modelName(String? name) { assert(alive, "Chat must be alive to be modified."); + if (!alive) return; _modelName = name; if (ChatManager.instance.currentChatId == id) { ModelManager.instance.currentModelName = name; } notifyListeners(); + saveChat(); } Model? get model => ModelManager.instance.models.firstOrNullWhere( @@ -160,26 +344,28 @@ class Chat extends ChangeNotifier { String get title => _title; set title(String title) { assert(alive, "Chat must be alive to be modified."); + if (!alive) return; _title = title; notifyListeners(); + saveChat(); } - final Set _messages; - Set get messages => Set.unmodifiable(_messages); + final List _messages; + List get messages => List.unmodifiable(_messages); final String? system; Chat._({ + String? id, required String? modelName, - required String title, + required this._title, required this.createdAt, - Set? messages, + List? messages, String? system, - }) : id = const Uuid().v4(), - _modelName = modelName, - _title = title, - _messages = messages ?? {}, + }) : id = id ?? const Uuid().v4(), + _modelName = modelName ?? ModelManager.instance.currentModelName, + _messages = messages ?? [], system = system ?? Preferences.instance.system { addListener(ChatManager.instance.notifyListeners); for (var m in _messages) { @@ -199,31 +385,35 @@ class Chat extends ChangeNotifier { super.dispose(); } - List toApi() { - var messages = []; - var images = []; + List toApi() { + final messages = []; + final images = []; - var systemMessage = system; + final systemMessage = system; if (systemMessage != null) { messages.add( - ollama.Message(role: ollama.MessageRole.system, content: systemMessage), + llama.ChatMessage( + role: llama.MessageRole.system, + content: systemMessage, + ), ); } for (var message in _messages) { switch (message) { - case TextMessage message: + case final TextMessage message: messages.add( - ollama.Message( + llama.ChatMessage( role: message.sender == MessageSender.user - ? ollama.MessageRole.user - : ollama.MessageRole.assistant, + ? llama.MessageRole.user + : llama.MessageRole.assistant, content: message.content, images: images.map((e) => e.image.toString()).toList(), ), ); images.clear(); - case ImageMessage message: + case final ImageMessage message + when message.sender == MessageSender.user: images.add(message); } } @@ -246,19 +436,20 @@ class Chat extends ChangeNotifier { }) async { assert(alive, "Chat must be alive to be modified."); assert(model != null, "Chat model must be set to generate a title."); + if (!alive || model == null) return; if (_messages.isEmpty || model == null || !Preferences.instance.generateTitles) { - _title = AppLocalizations.of(mainContext!).newChatTitle; + _title = AppLocalizations.of(context).newChatTitle; return; } - var effectiveThink = + final effectiveThink = (think ?? false) && model!.capabilities.contains(ModelCapability.thinking); - var content = jsonEncode( + final content = jsonEncode( (toJson()["messages"] as List>) .map( (e) => e @@ -268,32 +459,32 @@ class Chat extends ChangeNotifier { ) .toList(), ); - var request = ollama.GenerateChatCompletionRequest( + final request = llama.ChatRequest( model: modelName!, messages: [ - const ollama.Message( - role: ollama.MessageRole.system, + const llama.ChatMessage( + role: llama.MessageRole.system, content: "Generate a two to five word title for the conversation provided by the user. " - "If an object or person is very important in the conversation, put it in the title as well; keep the focus on the main subject. Also make an assumption about things happening in the conversation following the messages provided. " - "You must not put the assistant in the focus and you must not put the word 'assistant' in the title! " - "Use a factual, formal tone; don't make the title dramatic using dramatic words. Preferably use nouns and adjectives, not verbs. Also avoid using words like 'simple' or 'easy' to not belittle the user or their problem. " - "Do preferably use title case. You must not use markdown or any other formatting language! You must not use emojis or any other symbols! You must not use general clauses like 'assistance', 'help' or 'session' in your title!\n\n" - "Example bad titles compared to good titles:\n\n~~User Introduces Themselves~~ -> User Introduction\n~~User Asks for Help with a Problem~~ -> Problem Help\n~~User has a _**big**_ Problem~~ -> Big Problem", + "Focus on the main subject or topic. If a specific object, person, or concept is central to the discussion, include it in the title. " + "Do not focus on the assistant; never use the word 'assistant' or imply it is the subject. " + "Use a factual, neutral tone. Prefer nouns and adjectives over verbs. Do not use dramatic, vague, or belittling words such as 'simple', 'easy', 'big', or 'interesting'. " + "Use title case. Do not use markdown, emojis, symbols, or generic terms like 'assistance', 'help', 'session', or 'conversation'.\n\n" + "---\n\nExamples (bad -> good):\n\n~~User Introduces Themselves~~ -> User Introduction\n~~User Asks for Help with a Problem~~ -> Problem Troubleshooting\n~~User has a _**big**_ Problem~~ -> Issue Diagnosis\n~~Simple Python Question~~ -> Python Syntax Help", ), - ollama.Message( - role: ollama.MessageRole.user, + llama.ChatMessage( + role: llama.MessageRole.user, content: "```json\n$content\n```", ), ], - keepAlive: Preferences.instance.keepAlive, - think: effectiveThink, + keepAlive: llama.KeepAlive.number(Preferences.instance.keepAlive), + think: llama.ThinkValue.enabled(effectiveThink), ); - ollama.GenerateChatCompletionResponse generated; + llama.ChatResponse generated; try { - generated = await clients.ollamaClient - .generateChatCompletion(request: request) + generated = await clients.ollamaClient.chat + .create(request: request) .timeout(TimeoutMultiplier.long); } catch (e, s) { if (alive) Error.throwWithStackTrace(e, s); @@ -301,7 +492,7 @@ class Chat extends ChangeNotifier { } if (!alive) return; - var newTitle = generated.message.content; + var newTitle = generated.message!.content!; newTitle = newTitle.replaceAll("\n", " "); for (var term in [ @@ -336,9 +527,11 @@ class Chat extends ChangeNotifier { void append(Message message) { assert(alive, "Chat must be alive to be modified."); + if (!alive) return; _messages.add(message..addListener(notifyListeners)); notifyListeners(); + saveChat(); } Future send( @@ -348,6 +541,7 @@ class Chat extends ChangeNotifier { void Function(String content)? onContent, }) async { assert(alive, "Chat must be alive to be modified."); + if (!alive) return; assert(model != null, "Chat model must be set to send messages."); if (model == null) return; @@ -356,32 +550,36 @@ class Chat extends ChangeNotifier { completer.isCompleted, "Cannot send a message while another message is being sent.", ); + if (!completer.isCompleted) return; _messages.add(message..addListener(notifyListeners)); - var finalThink = + final finalThink = (think ?? Preferences.instance.thinking) && model!.capabilities.contains(ModelCapability.thinking); if (message is TextMessage && message.sender == MessageSender.user) { completer = Completer(); - var message = TextMessage.fromStream( - clients.ollamaClient.generateChatCompletionStream( - request: ollama.GenerateChatCompletionRequest( + final message = TextMessage.fromStream( + clients.ollamaClient.chat.createStream( + request: llama.ChatRequest( model: model!.name, messages: toApi(), stream: true, - keepAlive: Preferences.instance.keepAlive, - think: finalThink, + keepAlive: llama.KeepAlive.number(Preferences.instance.keepAlive), + think: llama.ThinkValue.enabled(finalThink), ), ), sender: MessageSender.assistant, completer: completer, onContent: onContent, + saveChat: () async { + if (alive) await saveChat(); + }, )..addListener(notifyListeners); _messages.add(message); - var future = completer.future.catchError((e, s) { + final future = completer.future.catchError((e, s) { message .._locked = false .._includesError = true @@ -389,18 +587,74 @@ class Chat extends ChangeNotifier { Error.throwWithStackTrace(e, s); }); if (awaitCompletion) await future; + } else if (message is ImageMessage) { + await message.computeImageMeta(); } notifyListeners(); - await ChatManager.instance.saveChats(); + if (alive) await saveChat(); } - void deleteMessage(Message message) { + void delete(Message message) { assert(alive, "Chat must be alive to be modified."); + if (!alive) return; _messages.remove(message); message.removeListener(notifyListeners); notifyListeners(); + saveChat(); + } + + Future saveChat() async { + assert(alive, "Chat must be alive to be modified."); + if (!alive) return; + + await chatDb + .into(chatDb.chats) + .insertOnConflictUpdate( + ChatsCompanion(id: Value(id), json: Value(jsonEncode(toJson()))), + ); + } + + Future _migrateImageStorageFormat() async { + var didMigrate = false; + for (var message in _messages.whereType()) { + if (message.image.scheme != "ref") { + final id = const Uuid().v4(); + final data = base64Decode(message.image.toString().split(",").last); + await chatDb + .into(chatDb.assets) + .insert( + AssetsCompanion( + id: Value(id), + chatId: Value(this.id), + data: Value(data), + ), + ); + + double? aspectRatio; + int? width; + if (message.aspectRatio == null || message.width == null) { + try { + final decodedImage = img.decodeImage(data); + if (decodedImage != null) { + aspectRatio = decodedImage.width / decodedImage.height; + width = decodedImage.width; + } + } catch (_) {} + } else { + aspectRatio = message.aspectRatio; + width = message.width; + } + + message + .._image = Uri.parse("ref://$id") + .._aspectRatio = aspectRatio + .._width = width; + didMigrate = true; + } + } + return didMigrate; } @override @@ -416,12 +670,16 @@ class ChatManager extends ChangeNotifier { String? _currentChatId; String? get currentChatId => _currentChatId; set currentChatId(String? id) { + final chat = _chats.where((e) => e.id == id).firstOrNull; + if (chat == null && id != null) { + throw ArgumentError.value(id, "id", "Chat with this ID does not exist."); + } + _currentChatId = id; if (id != null) { - ModelManager.instance.currentModelName = _chats - .singleWhere((e) => e.id == id) - .model! - .name; + if (chat!.model != null) { + ModelManager.instance.currentModelName = chat.model!.name; + } } notifyListeners(); } @@ -436,90 +694,94 @@ class ChatManager extends ChangeNotifier { ChatManager._(); - void clearChats() { - for (var chat in _chats) { - chat.dispose(); - } - _chats.clear(); - _currentChatId = null; - notifyListeners(); - } - Future loadChats() async { DateTime getDateTimeFromMilliseconds(int? milliseconds) { if (milliseconds == null) return DateTime.now(); return DateTime.fromMillisecondsSinceEpoch(milliseconds, isUtc: true); } - var stored = prefs!.getStringList("chats") ?? []; + var stored = []; + + final oldPrefs = await SharedPreferences.getInstance(); + final oldStored = oldPrefs.getStringList("chats") ?? []; + if (oldStored.isNotEmpty) { + stored = oldStored; + await oldPrefs.remove("chats"); + await prefs!.remove("chats"); + } + + if (stored.isEmpty) { + stored = await chatDb + .select(chatDb.chats) + .get() + .then((rows) => rows.map((r) => r.json).toList()); + } + _chats.clear(); for (var chatJson in stored) { try { - var chatData = jsonDecode(chatJson); + final chatData = jsonDecode(chatJson); - var messages = {}; + final messages = []; String? system; - for (var message in chatData["messages"]) { + + final data = chatData["messages"] is String + ? (jsonDecode(chatData["messages"]) as List) + : chatData["messages"]; + + for (var message in data) { if (message["role"] == "system") { system = message["content"]; + continue; } - switch (message["type"]) { - case "text": - messages.add( - TextMessage( - message["content"], - sender: MessageSender.values.byName(message["role"]), - createdAt: getDateTimeFromMilliseconds(message["createdAt"]), - ), - ); - case "image": - messages.add( - ImageMessage( - image: Uri.parse(message["image"]), - name: message["name"], - sender: MessageSender.values.byName(message["role"]), - createdAt: getDateTimeFromMilliseconds(message["createdAt"]), - ), - ); - } + final constructor = Message.constructorForType( + message["type"] ?? "text", + ); + if (constructor == null) continue; + messages.add(constructor.call(message)); } _chats.add( Chat._( + id: chatData["uuid"] ?? chatData["id"], modelName: chatData["model"], createdAt: getDateTimeFromMilliseconds(chatData["createdAt"]), title: chatData["title"], messages: messages, system: system, - ), + )..addListener(notifyListeners), ); } catch (_) { rethrow; } } + + if (oldStored.isNotEmpty) await saveChats(); notifyListeners(); } Future saveChats() async { - prefs!.setStringList( - "chats", - _chats.map((c) => jsonEncode(c.toJson())).toList(), - ); + for (var chat in _chats) { + await chatDb + .into(chatDb.chats) + .insertOnConflictUpdate( + ChatsCompanion( + id: Value(chat.id), + json: Value(jsonEncode(chat.toJson())), + ), + ); + if (await chat._migrateImageStorageFormat()) await chat.saveChat(); + } } Chat createChat({ required BuildContext? context, - required Model? model, + Model? model, String? title, String? system, }) { - assert( - allowMultipleChats || chats.isEmpty, - "Cannot create a new chat when multiple chats are not allowed and there is already a chat.", - ); - - var chat = Chat._( + final chat = Chat._( modelName: model?.name, createdAt: DateTime.now(), title: @@ -533,7 +795,7 @@ class ChatManager extends ChangeNotifier { _currentChatId = chat.id; notifyListeners(); - saveChats(); + chat.saveChat(); return chat; } @@ -549,7 +811,7 @@ class ChatManager extends ChangeNotifier { if (_currentChatId == chat.id) _currentChatId = null; notifyListeners(); - saveChats(); + (chatDb.delete(chatDb.chats)..where((c) => c.id.equals(chat.id))).go(); } } @@ -561,7 +823,7 @@ Future showDeleteChatDialog( FutureOr Function()? onDelete, }) { chat ??= ChatManager.instance.currentChat; - var completer = Completer(); + final completer = Completer(); if (Preferences.instance.askBeforeDeletion) { showDialog( context: context, @@ -575,6 +837,8 @@ Future showDeleteChatDialog( ); } else { ChatManager.instance.deleteChat(chat!); + onDelete?.call(); + completer.complete(true); } return completer.future; } @@ -622,15 +886,32 @@ class DeleteChatDialog extends StatelessWidget { // MARK: Chat Text Widget +class _AnimatedWord { + final String text; + final WidgetSpan? widgetSpan; + TextStyle? style; + AnimationController? controller; + + bool get isWidget => widgetSpan != null; + + _AnimatedWord(this.text, this.style, [this.controller]) : widgetSpan = null; + _AnimatedWord.forWidget(this.widgetSpan) + : text = '', + style = null, + controller = null; +} + class ChatText extends StatefulWidget { - final String content; + final InlineSpan content; final Duration? flyInDuration; + final Duration? wordDelay; final Widget? placeholder; const ChatText( this.content, { super.key, this.flyInDuration, + this.wordDelay, this.placeholder, }); @@ -639,84 +920,221 @@ class ChatText extends StatefulWidget { } class _ChatTextState extends State with TickerProviderStateMixin { - late List _words; - late final List _controllers; + final List<_AnimatedWord> _words = []; + final List<_AnimatedWord> _queue = []; + Timer? _delayTimer; + DateTime? _lastWordShownAt; + + List _splitWords(String text) { + if (text.isEmpty) return const []; + return text.split(RegExp(r'(?=\s)')).where((s) => s.isNotEmpty).toList(); + } + + List<_AnimatedWord> _flattenAll(InlineSpan span, [TextStyle? parent]) { + final result = <_AnimatedWord>[]; + if (span is TextSpan) { + final eff = (parent != null && span.style != null) + ? parent.merge(span.style!) + : (span.style ?? parent); + if (span.text?.isNotEmpty ?? false) { + result.add(_AnimatedWord(span.text!, eff)); + } + for (var child in span.children ?? const []) { + result.addAll(_flattenAll(child, eff)); + } + } else if (span is WidgetSpan) { + result.add(_AnimatedWord.forWidget(span)); + } + return result; + } @override void initState() { super.initState(); - _words = _splitWords(widget.content); - _controllers = List.generate(_words.length, (_) => null); + for (var entry in _flattenAll(widget.content)) { + if (entry.isWidget) { + _words.add(entry); + } else { + for (var w in _splitWords(entry.text)) { + _words.add(_AnimatedWord(w, entry.style)); + } + } + } + } + + @override + void didUpdateWidget(ChatText old) { + super.didUpdateWidget(old); + if (widget.content != old.content) _processUpdate(); + } + + void _enqueue(_AnimatedWord word) { + if (widget.wordDelay == null) { + word.controller?.forward(); + return; + } + _queue.add(word); + _drainQueue(); + } + + void _drainQueue() { + if ((_delayTimer?.isActive ?? false) || _queue.isEmpty) return; + final remaining = + widget.wordDelay! - + (_lastWordShownAt != null + ? DateTime.now().difference(_lastWordShownAt!) + : widget.wordDelay!); + if (remaining <= Duration.zero) { + _lastWordShownAt = DateTime.now(); + _queue.removeAt(0).controller?.forward(); + if (_queue.isNotEmpty) _drainQueue(); + } else { + _delayTimer = Timer(remaining, _drainQueue); + } + } + + void _cancelQueue() { + _delayTimer?.cancel(); + _delayTimer = null; + _lastWordShownAt = null; + _queue.clear(); } @override void dispose() { - for (var c in _controllers) { - c?.dispose(); + _cancelQueue(); + for (var w in _words) { + w.controller?.dispose(); } super.dispose(); } - List _splitWords(String s) { - if (s.trim().isEmpty) return []; - return s.split(RegExp(r"(?=\s+)")); + void _processUpdate() { + final newEntries = _flattenAll(widget.content); + final newFullText = newEntries + .where((e) => !e.isWidget) + .map((e) => e.text) + .join(); + final oldFullText = _words + .where((w) => !w.isWidget) + .map((w) => w.text) + .join(); + + if (newFullText == oldFullText) { + _syncStyles(newEntries); + setState(() {}); + return; + } + + if (newFullText.startsWith(oldFullText)) { + _animateAppended(newEntries, oldFullText.length); + } else { + _reset(newEntries); + } + } + + void _syncStyles(List<_AnimatedWord> entries) { + final flat = <_AnimatedWord>[]; + for (var entry in entries) { + if (entry.isWidget) continue; + for (var w in _splitWords(entry.text)) { + flat.add(_AnimatedWord(w, entry.style)); + } + } + final textWords = _words.where((w) => !w.isWidget).toList(); + for (var i = 0; i < textWords.length && i < flat.length; i++) { + textWords[i].style = flat[i].style; + } + } + + void _animateAppended(List<_AnimatedWord> newEntries, int oldLength) { + var seen = 0; + for (var leaf in newEntries) { + if (leaf.isWidget) { + if (seen >= oldLength) _words.add(leaf); + continue; + } + final leafEnd = seen + leaf.text.length; + if (leafEnd <= oldLength) { + seen = leafEnd; + continue; + } + final start = (oldLength - seen).clamp(0, leaf.text.length); + final newText = leaf.text.substring(start); + for (var word in _splitWords(newText)) { + final ctrl = AnimationController( + value: 0.0, + vsync: this, + duration: widget.flyInDuration ?? Durations.medium1, + ); + final entry = _AnimatedWord(word, leaf.style, ctrl); + ctrl + ..addListener(() { + if (mounted) setState(() {}); + }) + ..addStatusListener((status) { + if (status == AnimationStatus.completed) { + entry.controller?.dispose(); + entry.controller = null; + } + }); + _words.add(entry); + _enqueue(entry); + } + seen = leafEnd; + } + } + + void _reset(List<_AnimatedWord> entries) { + _cancelQueue(); + for (var w in _words) { + w.controller?.dispose(); + } + _words.clear(); + for (var entry in entries) { + if (entry.isWidget) { + _words.add(entry); + } else { + for (var w in _splitWords(entry.text)) { + _words.add(_AnimatedWord(w, entry.style)); + } + } + } + setState(() {}); } @override Widget build(BuildContext context) { - var newWords = _splitWords( - widget.content.replaceFirst( - RegExp("^${RegExp.escape(_words.join())}"), - "", + final isEmpty = _words.isEmpty; + if (isEmpty && widget.placeholder != null) return widget.placeholder!; + + final defaultColor = + Theme.of(context).textTheme.bodyMedium?.color ?? Colors.black; + + return AnimatedSize( + alignment: Alignment.topLeft, + duration: Durations.short2, + child: Text.rich( + TextSpan( + children: _words + .where((w) => w.controller?.status != AnimationStatus.dismissed) + .map((word) { + final alpha = word.controller?.value; + if (alpha == null) { + return TextSpan(text: word.text, style: word.style); + } + + final baseColor = word.style?.color ?? defaultColor; + return TextSpan( + text: word.text, + style: (word.style ?? const TextStyle()).copyWith( + color: baseColor.withValues(alpha: alpha), + ), + ); + }) + .toList(), + ), ), ); - - for (var word in newWords.asMap().entries) { - _words.add(word.value); - _controllers.add( - AnimationController( - value: 0, - vsync: this, - duration: widget.flyInDuration ?? Durations.medium1, - ) - ..addListener(() { - var index = word.key + _words.length - newWords.length; - if (_controllers[index]?.value == 1) { - _controllers[index]!.dispose(); - _controllers[index] = null; - } - - setState(() {}); - }) - ..forward(), - ); - } - - var finalColor = - Theme.of(context).textTheme.bodyMedium?.color ?? Colors.black; - return (_words.isEmpty && widget.placeholder != null) - ? widget.placeholder! - : AnimatedSize( - alignment: Alignment.topLeft, - duration: Durations.short2, - child: Text.rich( - TextSpan( - children: _words - .asMap() - .entries - .map( - (e) => TextSpan( - text: e.value, - style: TextStyle( - color: finalColor.withValues( - alpha: _controllers[e.key]?.value, - ), - ), - ), - ) - .toList(), - ), - ), - ); } } diff --git a/lib/services/chat_database/chat_database.dart b/lib/services/chat_database/chat_database.dart new file mode 100644 index 0000000..e5771d3 --- /dev/null +++ b/lib/services/chat_database/chat_database.dart @@ -0,0 +1,58 @@ +import 'package:drift/drift.dart'; +import 'package:drift_flutter/drift_flutter.dart'; + +export 'package:drift/drift.dart'; + +part 'chat_database.g.dart'; + +late final ChatDatabase chatDb; + +class Chats extends Table { + TextColumn get id => text().unique()(); + TextColumn get json => text()(); + + @override + Set>? get primaryKey => {id}; +} + +class Assets extends Table { + TextColumn get id => text().unique()(); + TextColumn get chatId => + text().references(Chats, #id, onDelete: KeyAction.cascade)(); + BlobColumn get data => blob()(); + + @override + Set>? get primaryKey => {id}; +} + +@DriftDatabase(tables: [Chats, Assets]) +class ChatDatabase extends _$ChatDatabase { + ChatDatabase([QueryExecutor? executor]) + : super(executor ?? _openConnection()); + + @override + int get schemaVersion => 1; + + static QueryExecutor _openConnection() { + return driftDatabase( + name: "chatDatabase", + native: const DriftNativeOptions(), + web: DriftWebOptions( + sqlite3Wasm: Uri.parse("sqlite3.wasm"), + driftWorker: Uri.parse("drift_worker.js"), + ), + ); + } + + @override + MigrationStrategy get migration { + return MigrationStrategy( + beforeOpen: (details) async { + await customStatement("PRAGMA foreign_keys = ON"); + }, + onUpgrade: (Migrator m, int from, int to) async { + // if (from < 2) {} + }, + ); + } +} diff --git a/lib/services/chat_database/chat_database.g.dart b/lib/services/chat_database/chat_database.g.dart new file mode 100644 index 0000000..a5398b8 --- /dev/null +++ b/lib/services/chat_database/chat_database.g.dart @@ -0,0 +1,998 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'chat_database.dart'; + +// ignore_for_file: type=lint +class $ChatsTable extends Chats with TableInfo<$ChatsTable, Chat> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $ChatsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways('UNIQUE'), + ); + static const VerificationMeta _jsonMeta = const VerificationMeta('json'); + @override + late final GeneratedColumn json = GeneratedColumn( + 'json', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [id, json]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'chats'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('json')) { + context.handle( + _jsonMeta, + json.isAcceptableOrUnknown(data['json']!, _jsonMeta), + ); + } else if (isInserting) { + context.missing(_jsonMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + Chat map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return Chat( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + json: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}json'], + )!, + ); + } + + @override + $ChatsTable createAlias(String alias) { + return $ChatsTable(attachedDatabase, alias); + } +} + +class Chat extends DataClass implements Insertable { + final String id; + final String json; + const Chat({required this.id, required this.json}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['json'] = Variable(json); + return map; + } + + ChatsCompanion toCompanion(bool nullToAbsent) { + return ChatsCompanion(id: Value(id), json: Value(json)); + } + + factory Chat.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return Chat( + id: serializer.fromJson(json['id']), + json: serializer.fromJson(json['json']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'json': serializer.toJson(json), + }; + } + + Chat copyWith({String? id, String? json}) => + Chat(id: id ?? this.id, json: json ?? this.json); + Chat copyWithCompanion(ChatsCompanion data) { + return Chat( + id: data.id.present ? data.id.value : this.id, + json: data.json.present ? data.json.value : this.json, + ); + } + + @override + String toString() { + return (StringBuffer('Chat(') + ..write('id: $id, ') + ..write('json: $json') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, json); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is Chat && other.id == this.id && other.json == this.json); +} + +class ChatsCompanion extends UpdateCompanion { + final Value id; + final Value json; + final Value rowid; + const ChatsCompanion({ + this.id = const Value.absent(), + this.json = const Value.absent(), + this.rowid = const Value.absent(), + }); + ChatsCompanion.insert({ + required String id, + required String json, + this.rowid = const Value.absent(), + }) : id = Value(id), + json = Value(json); + static Insertable custom({ + Expression? id, + Expression? json, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (json != null) 'json': json, + if (rowid != null) 'rowid': rowid, + }); + } + + ChatsCompanion copyWith({ + Value? id, + Value? json, + Value? rowid, + }) { + return ChatsCompanion( + id: id ?? this.id, + json: json ?? this.json, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (json.present) { + map['json'] = Variable(json.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ChatsCompanion(') + ..write('id: $id, ') + ..write('json: $json, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $AssetsTable extends Assets with TableInfo<$AssetsTable, Asset> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $AssetsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways('UNIQUE'), + ); + static const VerificationMeta _chatIdMeta = const VerificationMeta('chatId'); + @override + late final GeneratedColumn chatId = GeneratedColumn( + 'chat_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES chats (id) ON DELETE CASCADE', + ), + ); + static const VerificationMeta _dataMeta = const VerificationMeta('data'); + @override + late final GeneratedColumn data = GeneratedColumn( + 'data', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + ); + @override + List get $columns => [id, chatId, data]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'assets'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('chat_id')) { + context.handle( + _chatIdMeta, + chatId.isAcceptableOrUnknown(data['chat_id']!, _chatIdMeta), + ); + } else if (isInserting) { + context.missing(_chatIdMeta); + } + if (data.containsKey('data')) { + context.handle( + _dataMeta, + this.data.isAcceptableOrUnknown(data['data']!, _dataMeta), + ); + } else if (isInserting) { + context.missing(_dataMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + Asset map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return Asset( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + chatId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}chat_id'], + )!, + data: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}data'], + )!, + ); + } + + @override + $AssetsTable createAlias(String alias) { + return $AssetsTable(attachedDatabase, alias); + } +} + +class Asset extends DataClass implements Insertable { + final String id; + final String chatId; + final Uint8List data; + const Asset({required this.id, required this.chatId, required this.data}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['chat_id'] = Variable(chatId); + map['data'] = Variable(data); + return map; + } + + AssetsCompanion toCompanion(bool nullToAbsent) { + return AssetsCompanion( + id: Value(id), + chatId: Value(chatId), + data: Value(data), + ); + } + + factory Asset.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return Asset( + id: serializer.fromJson(json['id']), + chatId: serializer.fromJson(json['chatId']), + data: serializer.fromJson(json['data']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'chatId': serializer.toJson(chatId), + 'data': serializer.toJson(data), + }; + } + + Asset copyWith({String? id, String? chatId, Uint8List? data}) => Asset( + id: id ?? this.id, + chatId: chatId ?? this.chatId, + data: data ?? this.data, + ); + Asset copyWithCompanion(AssetsCompanion data) { + return Asset( + id: data.id.present ? data.id.value : this.id, + chatId: data.chatId.present ? data.chatId.value : this.chatId, + data: data.data.present ? data.data.value : this.data, + ); + } + + @override + String toString() { + return (StringBuffer('Asset(') + ..write('id: $id, ') + ..write('chatId: $chatId, ') + ..write('data: $data') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, chatId, $driftBlobEquality.hash(data)); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is Asset && + other.id == this.id && + other.chatId == this.chatId && + $driftBlobEquality.equals(other.data, this.data)); +} + +class AssetsCompanion extends UpdateCompanion { + final Value id; + final Value chatId; + final Value data; + final Value rowid; + const AssetsCompanion({ + this.id = const Value.absent(), + this.chatId = const Value.absent(), + this.data = const Value.absent(), + this.rowid = const Value.absent(), + }); + AssetsCompanion.insert({ + required String id, + required String chatId, + required Uint8List data, + this.rowid = const Value.absent(), + }) : id = Value(id), + chatId = Value(chatId), + data = Value(data); + static Insertable custom({ + Expression? id, + Expression? chatId, + Expression? data, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (chatId != null) 'chat_id': chatId, + if (data != null) 'data': data, + if (rowid != null) 'rowid': rowid, + }); + } + + AssetsCompanion copyWith({ + Value? id, + Value? chatId, + Value? data, + Value? rowid, + }) { + return AssetsCompanion( + id: id ?? this.id, + chatId: chatId ?? this.chatId, + data: data ?? this.data, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (chatId.present) { + map['chat_id'] = Variable(chatId.value); + } + if (data.present) { + map['data'] = Variable(data.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('AssetsCompanion(') + ..write('id: $id, ') + ..write('chatId: $chatId, ') + ..write('data: $data, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +abstract class _$ChatDatabase extends GeneratedDatabase { + _$ChatDatabase(QueryExecutor e) : super(e); + $ChatDatabaseManager get managers => $ChatDatabaseManager(this); + late final $ChatsTable chats = $ChatsTable(this); + late final $AssetsTable assets = $AssetsTable(this); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [chats, assets]; + @override + StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules([ + WritePropagation( + on: TableUpdateQuery.onTableName( + 'chats', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('assets', kind: UpdateKind.delete)], + ), + ]); +} + +typedef $$ChatsTableCreateCompanionBuilder = + ChatsCompanion Function({ + required String id, + required String json, + Value rowid, + }); +typedef $$ChatsTableUpdateCompanionBuilder = + ChatsCompanion Function({ + Value id, + Value json, + Value rowid, + }); + +final class $$ChatsTableReferences + extends BaseReferences<_$ChatDatabase, $ChatsTable, Chat> { + $$ChatsTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$AssetsTable, List> _assetsRefsTable( + _$ChatDatabase db, + ) => MultiTypedResultKey.fromTable( + db.assets, + aliasName: 'chats__id__assets__chat_id', + ); + + $$AssetsTableProcessedTableManager get assetsRefs { + final manager = $$AssetsTableTableManager( + $_db, + $_db.assets, + ).filter((f) => f.chatId.id.sqlEquals($_itemColumn('id')!)); + + final cache = $_typedResult.readTableOrNull(_assetsRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache), + ); + } +} + +class $$ChatsTableFilterComposer extends Composer<_$ChatDatabase, $ChatsTable> { + $$ChatsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get json => $composableBuilder( + column: $table.json, + builder: (column) => ColumnFilters(column), + ); + + Expression assetsRefs( + Expression Function($$AssetsTableFilterComposer f) f, + ) { + final $$AssetsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.assets, + getReferencedColumn: (t) => t.chatId, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$AssetsTableFilterComposer( + $db: $db, + $table: $db.assets, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return f(composer); + } +} + +class $$ChatsTableOrderingComposer + extends Composer<_$ChatDatabase, $ChatsTable> { + $$ChatsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get json => $composableBuilder( + column: $table.json, + builder: (column) => ColumnOrderings(column), + ); +} + +class $$ChatsTableAnnotationComposer + extends Composer<_$ChatDatabase, $ChatsTable> { + $$ChatsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get json => + $composableBuilder(column: $table.json, builder: (column) => column); + + Expression assetsRefs( + Expression Function($$AssetsTableAnnotationComposer a) f, + ) { + final $$AssetsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.assets, + getReferencedColumn: (t) => t.chatId, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$AssetsTableAnnotationComposer( + $db: $db, + $table: $db.assets, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return f(composer); + } +} + +class $$ChatsTableTableManager + extends + RootTableManager< + _$ChatDatabase, + $ChatsTable, + Chat, + $$ChatsTableFilterComposer, + $$ChatsTableOrderingComposer, + $$ChatsTableAnnotationComposer, + $$ChatsTableCreateCompanionBuilder, + $$ChatsTableUpdateCompanionBuilder, + (Chat, $$ChatsTableReferences), + Chat, + PrefetchHooks Function({bool assetsRefs}) + > { + $$ChatsTableTableManager(_$ChatDatabase db, $ChatsTable table) + : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$ChatsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$ChatsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$ChatsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: + ({ + Value id = const Value.absent(), + Value json = const Value.absent(), + Value rowid = const Value.absent(), + }) => ChatsCompanion(id: id, json: json, rowid: rowid), + createCompanionCallback: + ({ + required String id, + required String json, + Value rowid = const Value.absent(), + }) => ChatsCompanion.insert(id: id, json: json, rowid: rowid), + withReferenceMapper: (p0) => p0 + .map( + (e) => + (e.readTable(table), $$ChatsTableReferences(db, table, e)), + ) + .toList(), + prefetchHooksCallback: ({assetsRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [if (assetsRefs) db.assets], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (assetsRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: $$ChatsTableReferences._assetsRefsTable( + db, + ), + managerFromTypedResult: (p0) => + $$ChatsTableReferences(db, table, p0).assetsRefs, + referencedItemsForCurrentItem: (item, referencedItems) => + referencedItems.where((e) => e.chatId == item.id), + typedResults: items, + ), + ]; + }, + ); + }, + ), + ); +} + +typedef $$ChatsTableProcessedTableManager = + ProcessedTableManager< + _$ChatDatabase, + $ChatsTable, + Chat, + $$ChatsTableFilterComposer, + $$ChatsTableOrderingComposer, + $$ChatsTableAnnotationComposer, + $$ChatsTableCreateCompanionBuilder, + $$ChatsTableUpdateCompanionBuilder, + (Chat, $$ChatsTableReferences), + Chat, + PrefetchHooks Function({bool assetsRefs}) + >; +typedef $$AssetsTableCreateCompanionBuilder = + AssetsCompanion Function({ + required String id, + required String chatId, + required Uint8List data, + Value rowid, + }); +typedef $$AssetsTableUpdateCompanionBuilder = + AssetsCompanion Function({ + Value id, + Value chatId, + Value data, + Value rowid, + }); + +final class $$AssetsTableReferences + extends BaseReferences<_$ChatDatabase, $AssetsTable, Asset> { + $$AssetsTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static $ChatsTable _chatIdTable(_$ChatDatabase db) => + db.chats.createAlias('assets__chat_id__chats__id'); + + $$ChatsTableProcessedTableManager get chatId { + final $_column = $_itemColumn('chat_id')!; + + final manager = $$ChatsTableTableManager( + $_db, + $_db.chats, + ).filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_chatIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item]), + ); + } +} + +class $$AssetsTableFilterComposer + extends Composer<_$ChatDatabase, $AssetsTable> { + $$AssetsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get data => $composableBuilder( + column: $table.data, + builder: (column) => ColumnFilters(column), + ); + + $$ChatsTableFilterComposer get chatId { + final $$ChatsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.chatId, + referencedTable: $db.chats, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$ChatsTableFilterComposer( + $db: $db, + $table: $db.chats, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } +} + +class $$AssetsTableOrderingComposer + extends Composer<_$ChatDatabase, $AssetsTable> { + $$AssetsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get data => $composableBuilder( + column: $table.data, + builder: (column) => ColumnOrderings(column), + ); + + $$ChatsTableOrderingComposer get chatId { + final $$ChatsTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.chatId, + referencedTable: $db.chats, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$ChatsTableOrderingComposer( + $db: $db, + $table: $db.chats, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } +} + +class $$AssetsTableAnnotationComposer + extends Composer<_$ChatDatabase, $AssetsTable> { + $$AssetsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get data => + $composableBuilder(column: $table.data, builder: (column) => column); + + $$ChatsTableAnnotationComposer get chatId { + final $$ChatsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.chatId, + referencedTable: $db.chats, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$ChatsTableAnnotationComposer( + $db: $db, + $table: $db.chats, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } +} + +class $$AssetsTableTableManager + extends + RootTableManager< + _$ChatDatabase, + $AssetsTable, + Asset, + $$AssetsTableFilterComposer, + $$AssetsTableOrderingComposer, + $$AssetsTableAnnotationComposer, + $$AssetsTableCreateCompanionBuilder, + $$AssetsTableUpdateCompanionBuilder, + (Asset, $$AssetsTableReferences), + Asset, + PrefetchHooks Function({bool chatId}) + > { + $$AssetsTableTableManager(_$ChatDatabase db, $AssetsTable table) + : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$AssetsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$AssetsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$AssetsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: + ({ + Value id = const Value.absent(), + Value chatId = const Value.absent(), + Value data = const Value.absent(), + Value rowid = const Value.absent(), + }) => AssetsCompanion( + id: id, + chatId: chatId, + data: data, + rowid: rowid, + ), + createCompanionCallback: + ({ + required String id, + required String chatId, + required Uint8List data, + Value rowid = const Value.absent(), + }) => AssetsCompanion.insert( + id: id, + chatId: chatId, + data: data, + rowid: rowid, + ), + withReferenceMapper: (p0) => p0 + .map( + (e) => + (e.readTable(table), $$AssetsTableReferences(db, table, e)), + ) + .toList(), + prefetchHooksCallback: ({chatId = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: + < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic + > + >(state) { + if (chatId) { + state = + state.withJoin( + currentTable: table, + currentColumn: table.chatId, + referencedTable: $$AssetsTableReferences + ._chatIdTable(db), + referencedColumn: $$AssetsTableReferences + ._chatIdTable(db) + .id, + ) + as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, + ), + ); +} + +typedef $$AssetsTableProcessedTableManager = + ProcessedTableManager< + _$ChatDatabase, + $AssetsTable, + Asset, + $$AssetsTableFilterComposer, + $$AssetsTableOrderingComposer, + $$AssetsTableAnnotationComposer, + $$AssetsTableCreateCompanionBuilder, + $$AssetsTableUpdateCompanionBuilder, + (Asset, $$AssetsTableReferences), + Asset, + PrefetchHooks Function({bool chatId}) + >; + +class $ChatDatabaseManager { + final _$ChatDatabase _db; + $ChatDatabaseManager(this._db); + $$ChatsTableTableManager get chats => + $$ChatsTableTableManager(_db, _db.chats); + $$AssetsTableTableManager get assets => + $$AssetsTableTableManager(_db, _db.assets); +} diff --git a/lib/services/clients.dart b/lib/services/clients.dart index ad3ee06..4942379 100644 --- a/lib/services/clients.dart +++ b/lib/services/clients.dart @@ -5,6 +5,7 @@ import 'package:http/http.dart' as http; import 'package:ollama_dart/ollama_dart.dart' as llama; import '../main.dart'; +import 'host.dart'; const String userAgent = "Ollama App"; @@ -13,14 +14,16 @@ class OllamaHttpOverrides extends HttpOverrides { HttpClient createHttpClient(SecurityContext? context) { return super.createHttpClient(context) ..userAgent = userAgent - ..badCertificateCallback = (_, __, ___) => true; + ..badCertificateCallback = (_, _, _) => true; } } final httpClient = http.Client(); llama.OllamaClient get ollamaClient => llama.OllamaClient( - headers: (jsonDecode(prefs!.getString("hostHeaders") ?? "{}") as Map) - .cast(), - baseUrl: "$host/api", - client: httpClient, + config: llama.OllamaConfig( + baseUrl: HostManager.instance.host!.toString(), + defaultHeaders: (jsonDecode(prefs!.getString("hostHeaders") ?? "{}") as Map) + .cast(), + ), + httpClient: httpClient, ); diff --git a/lib/services/curves.dart b/lib/services/curves.dart new file mode 100644 index 0000000..308f89f --- /dev/null +++ b/lib/services/curves.dart @@ -0,0 +1,50 @@ +import 'package:flutter/animation.dart'; + +typedef CurveGroup = ({ + Curve fast, + Duration fastDuration, + Curve normal, + Duration normalDuration, + Curve slow, + Duration slowDuration, +}); + +final class ExpressiveCurves { + ExpressiveCurves._(); + + static const CurveGroup expressiveSpatial = ( + fast: Cubic(0.42, 1.67, 0.21, 0.90), + fastDuration: Duration(milliseconds: 350), + normal: Cubic(0.38, 1.21, 0.22, 1.00), + normalDuration: Duration(milliseconds: 500), + slow: Cubic(0.39, 1.29, 0.35, 0.98), + slowDuration: Duration(milliseconds: 650), + ); + + static const CurveGroup expressiveEffects = ( + fast: Cubic(0.31, 0.94, 0.34, 1.00), + fastDuration: Duration(milliseconds: 150), + normal: Cubic(0.34, 0.80, 0.34, 1.00), + normalDuration: Duration(milliseconds: 200), + slow: Cubic(0.34, 0.88, 0.34, 1.00), + slowDuration: Duration(milliseconds: 300), + ); + + static const CurveGroup standardSpatial = ( + fast: Cubic(0.27, 1.06, 0.18, 1.00), + fastDuration: Duration(milliseconds: 350), + normal: Cubic(0.27, 1.06, 0.18, 1.00), + normalDuration: Duration(milliseconds: 500), + slow: Cubic(0.27, 1.06, 0.18, 1.00), + slowDuration: Duration(milliseconds: 750), + ); + + static const CurveGroup standardEffects = ( + fast: Cubic(0.31, 0.94, 0.34, 1.00), + fastDuration: Duration(milliseconds: 150), + normal: Cubic(0.34, 0.80, 0.34, 1.00), + normalDuration: Duration(milliseconds: 200), + slow: Cubic(0.34, 0.88, 0.34, 1.00), + slowDuration: Duration(milliseconds: 300), + ); +} diff --git a/lib/services/error.dart b/lib/services/error.dart index 72162e9..a934080 100644 --- a/lib/services/error.dart +++ b/lib/services/error.dart @@ -6,11 +6,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:http/http.dart'; -import 'package:ollama_dart/ollama_dart.dart'; +import 'package:ollama_dart/ollama_dart.dart' as llama; import 'package:url_launcher/url_launcher.dart'; import '../l10n/gen/app_localizations.dart'; import 'markdown.dart'; +import 'services.dart'; final _logIdRegex = RegExp(r"^[A-Z0-9]{2,16}$"); @@ -23,7 +24,7 @@ typedef ErrorGuardDetailsMessageGenerator = typedef ErrorGuardIgnoreIfGenerator = bool Function(Object exception); String _defaultErrorMessage(Object exception) => switch (exception) { - OllamaClientException _ => "Unknown client error", + llama.OllamaException _ => "Unknown client error", AssertionError _ => exception.toString().split(": ").elementAtOrNull(4) ?? "An assertion failed", @@ -39,15 +40,15 @@ String? _defaultDetailsMessage( Object exception, StackTrace stackTrace, ) => switch (exception) { - OllamaClientException e => + final llama.OllamaException e => [ - "SocketException", - "HttpException", - "ClientException", - ].contains(e.body.toString().split(":").first) + SocketException, + HttpException, + ClientException, + ].contains(e.cause.runtimeType) ? "A network error occurred while trying to connect to the server." "\n\nYou may check your network connection and server reachability and try again." - : "The Ollama API client received a faulty response with code `${e.code}`." + : "The Ollama API client received a faulty response with code `${e.message.split(":").last.trim()}`." "\n\nPlease check your Ollama server or proxy configuration and try again.", AssertionError _ => "An assertion failed, meaning that the app is misconfigured or a bug occurred." @@ -123,7 +124,7 @@ ErrorGuardDetailsMessageGenerator errorGuardDetailsMessageWithFallbackSingle( /// alphanumeric characters, starting with a letter. Other values will be /// ignored. The recommended length is 8 characters. /// -/// To generate a random log ID, run: `dart run tools/logid.dart` +/// To generate a random log ID, run: `dart run tool/logid.dart` /// /// The [errorMessage] function is used to generate the error message. This /// should be a short message that describes the error in a user-friendly way. @@ -156,6 +157,11 @@ ErrorGuardDetailsMessageGenerator errorGuardDetailsMessageWithFallbackSingle( /// useful if it's certain that the error is not caused by a bug in the app, /// but rather by a user error or a misconfiguration. [forceReporting] can be /// used to force the reporting of the error. +/// +/// The [onError] callback can be used to perform additional actions when an +/// error occurs, such as logging the error to a remote server or performing +/// additional cleanup. This callback is called before the error dialog or +/// snackbar is shown. Future errorGuard( BuildContext context, String? logId, @@ -167,6 +173,7 @@ Future errorGuard( bool enableDetails = true, bool enableReporting = true, bool forceReporting = false, + void Function(Object exception, StackTrace stackTrace)? onError, }) async { assert( logId == null || _logIdRegex.hasMatch(logId), @@ -193,9 +200,10 @@ Future errorGuard( action.call(), ).catchError(Error.throwWithStackTrace); } catch (exception, stackTrace) { + onError?.call(exception, stackTrace); if (context.mounted && !ignoreIf.call(exception)) { - var dateTime = DateTime.now(); - var colorScheme = Theme.of(context).colorScheme; + final dateTime = DateTime.now(); + final colorScheme = Theme.of(context).colorScheme; logId = logId?.toUpperCase(); if (logId != null && !_logIdRegex.hasMatch(logId)) { @@ -261,24 +269,26 @@ Future errorGuard( if (instantDialog) { showErrorDialog(); } else { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - _removeNewlines( - Markdown(errorMessageText).toTextSpan(context).toPlainText(), + ScaffoldMessenger.of(context) + ..clearSnackBars() + ..showSnackBar( + SnackBar( + content: Text( + _removeNewlines( + Markdown(errorMessageText).toTextSpan(context).toPlainText(), + ), + style: TextStyle(color: colorScheme.onErrorContainer), ), - style: TextStyle(color: colorScheme.onErrorContainer), + backgroundColor: colorScheme.errorContainer, + action: !enableDetails + ? null + : SnackBarAction( + label: AppLocalizations.of(context).errorGuardDetails, + textColor: colorScheme.onErrorContainer, + onPressed: showErrorDialog, + ), ), - backgroundColor: colorScheme.errorContainer, - action: !enableDetails - ? null - : SnackBarAction( - label: AppLocalizations.of(context).errorGuardDetails, - textColor: colorScheme.onErrorContainer, - onPressed: showErrorDialog, - ), - ), - ); + ); } } return null; @@ -317,6 +327,7 @@ class _ErrorGuardDetailsDialogState extends State<_ErrorGuardDetailsDialog> { return PopScope( canPop: !widget.forceReporting, child: AlertDialog( + constraints: const BoxConstraints(minWidth: 280, maxWidth: 560), title: Stack( children: [ Align( @@ -334,7 +345,14 @@ class _ErrorGuardDetailsDialogState extends State<_ErrorGuardDetailsDialog> { ), ), ), - Text(AppLocalizations.of(context).errorGuardTitle), + Builder( + builder: (context) => Text( + AppLocalizations.of(context).errorGuardTitle, + style: DefaultTextStyle.of( + context, + ).style.copyWith(fontFamily: "GoogleSansCode"), + ), + ), ], ), content: Column( @@ -344,7 +362,14 @@ class _ErrorGuardDetailsDialogState extends State<_ErrorGuardDetailsDialog> { if (widget.logId != null) Transform.translate( offset: const Offset(0, -20), - child: Text("@${widget.logId}"), + child: Builder( + builder: (context) => Text( + "@${widget.logId}", + style: DefaultTextStyle.of( + context, + ).style.copyWith(fontFamily: "GoogleSansCode"), + ), + ), ), Text.rich(Markdown(widget.errorMessage).toTextSpan(context)), @@ -414,7 +439,7 @@ ${(widget.exception != null) ? "```\n${widget.exception}\n```" : "> Not availabl Stack Trace ``` -${widget.stackTrace.toString().trim()} +${widget.stackTrace.toString().trim().split("\n").take(20).join("\n")} ``` @@ -424,7 +449,7 @@ ${widget.stackTrace.toString().trim()} The app suggested the following cause of the issue: - ***Error Message:*** ${_removeNewlines(widget.errorMessage)} -- ***Details Message:*** ${_removeNewlines((widget.detailsMessage ?? "None provided").trim())}""" +- ***Details Message:*** ${_removeNewlines((widget.detailsMessage ?? "*None provided*").trim())}""" .trim(); void _report() { @@ -434,7 +459,7 @@ The app suggested the following cause of the issue: url += "&description=${Uri.encodeComponent('Received error: "${widget.errorMessage.replaceFirst(RegExp(r".$"), "")}"${(widget.logId != null) ? " (@${widget.logId})" : ""}')}"; - var contextText = _reportText(); + final contextText = _reportText(); url += "&context=${Uri.encodeComponent(contextText)}"; Clipboard.setData(ClipboardData(text: url)); @@ -475,17 +500,24 @@ class _ErrorGuardDetailsPanelState extends State<_ErrorGuardDetailsPanel> super.initState(); _animationController = AnimationController( value: widget.isExpanded ? 1.0 : 0.0, - duration: kThemeAnimationDuration, + duration: ExpressiveCurves.expressiveEffects.fastDuration, vsync: this, ); _expanded = widget.isExpanded; _animation = CurvedAnimation( parent: _animationController, - curve: Curves.fastEaseInToSlowEaseOut, + curve: ExpressiveCurves.expressiveEffects.fast, + reverseCurve: ExpressiveCurves.expressiveEffects.fast.flipped, ); } + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + void _toggleAnimation() { setState(() { _expanded = !_expanded; @@ -514,7 +546,7 @@ class _ErrorGuardDetailsPanelState extends State<_ErrorGuardDetailsPanel> @override Widget build(BuildContext context) { - var theme = Theme.of(context); + final theme = Theme.of(context); return DecoratedBox( decoration: BoxDecoration( @@ -541,7 +573,7 @@ class _ErrorGuardDetailsPanelState extends State<_ErrorGuardDetailsPanel> ), SizeTransition( sizeFactor: _animation, - axisAlignment: -1, + alignment: Alignment.topCenter, child: _monospacedContent( child: Padding( padding: const EdgeInsets.only(left: 16, right: 16, bottom: 12), @@ -549,7 +581,7 @@ class _ErrorGuardDetailsPanelState extends State<_ErrorGuardDetailsPanel> ? Text( widget.content.trim(), style: const TextStyle( - fontFamily: "monospace", + fontFamily: "GoogleSansCode", height: kTextHeightNone, ), ) diff --git a/lib/services/haptic.dart b/lib/services/haptic.dart index 675752a..112ec59 100644 --- a/lib/services/haptic.dart +++ b/lib/services/haptic.dart @@ -30,9 +30,22 @@ DateTime _lastHapticChat = DateTime.fromMillisecondsSinceEpoch(0); void chatHaptic() { if (!Preferences.instance.enableHaptic) return; - var now = DateTime.now(); + final now = DateTime.now(); if (now.difference(_lastHapticChat) < _hapticChatDelay) return; _lastHapticChat = now; HapticFeedback.selectionClick(); } + +const Duration _hapticThinkingDelay = Duration(milliseconds: 150); +DateTime _lastHapticThinking = DateTime.fromMillisecondsSinceEpoch(0); + +void chatHapticThinking() { + if (!Preferences.instance.enableHaptic) return; + + final now = DateTime.now(); + if (now.difference(_lastHapticThinking) < _hapticThinkingDelay) return; + _lastHapticThinking = now; + + HapticFeedback.successNotification(); +} diff --git a/lib/services/host.dart b/lib/services/host.dart new file mode 100644 index 0000000..3cedaf0 --- /dev/null +++ b/lib/services/host.dart @@ -0,0 +1,142 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:ollama_dart/ollama_dart.dart' as ollama; + +import '../l10n/gen/app_localizations.dart'; +import '../main.dart'; +import 'clients.dart' as clients; +import 'services.dart'; + +enum HostSettingError { + invalidUrl, + unreachable, + undetectable, + timeout, + outdated, + other; + + String title(BuildContext context) { + final appLocalizations = AppLocalizations.of(context); + return appLocalizations.settingsHostInvalid(name); + } + + String description(BuildContext context) { + final appLocalizations = AppLocalizations.of(context); + return appLocalizations.settingsHostInvalidDetailed(name); + } +} + +typedef HostSettingErrorCallbackStore = ({ + Object exception, + StackTrace stackTrace, +}); + +class HostManager extends ChangeNotifier { + static final HostManager _instance = HostManager._(); + static HostManager get instance => _instance; + + bool _silentFlag = false; + + Uri? _host; + Uri? get host => _host; + set host(Uri? value) { + assert(!useHost, "Host is fixed to $fixedHost and cannot be changed."); + if (useHost) return; + + var uri = value; + if (uri != null && uri.path.endsWith("/")) { + uri = uri.replace(path: uri.path.substring(0, uri.path.length - 1)); + } + + if (uri == _host) return; + _host = uri; + Preferences.instance.host = uri; + if (!_silentFlag) notifyListeners(); + } + + HostManager._() + : _host = useHost ? Uri.parse(fixedHost) : Preferences.instance.host; + + Future smartSetHost( + BuildContext context, + String value, + ) async { + assert(!useHost, "Host is fixed to $fixedHost and cannot be changed."); + + final uri = Uri.tryParse(value)?.normalizePath(); + if (uri == null || (uri.scheme != "http" && uri.scheme != "https")) { + return HostSettingError.invalidUrl; + } + + final oldHost = this.host; + final host = uri.resolve("api/version"); + + try { + HostSettingErrorCallbackStore? error; + final response = await errorGuard( + context, + "S4XS48Z9", + () async => clients.httpClient + .get(host, headers: Preferences.instance.hostHeaders) + .timeout( + TimeoutMultiplier.medium, + onTimeout: () => throw HostSettingError.timeout, + ), + errorMessage: errorGuardErrorMessageWithFallback( + (_) => "Failed to connect to host.", + ), + enableReporting: false, + onError: (e, s) => error = (exception: e, stackTrace: s), + ); + if (response == null) { + Error.throwWithStackTrace(error!.exception, error!.stackTrace); + } + + if (response.statusCode == 200) { + final version = jsonDecode(response.body)["version"] as String?; + if (!RegExp(r"(?:.*?\.){2}.*").hasMatch(version ?? "")) { + return HostSettingError.undetectable; + } + + _silentFlag = true; + this.host = host.resolve(".."); + ollama.ListResponse? data; + + try { + if (context.mounted) { + data = await errorGuard( + context, + "U7K91OW8", + () async => clients.ollamaClient.models.list().timeout( + TimeoutMultiplier.medium, + onTimeout: () => throw HostSettingError.timeout, + ), + enableReporting: false, + onError: (e, s) => error = (exception: e, stackTrace: s), + ); + } + if (data == null) { + Error.throwWithStackTrace(error!.exception, error!.stackTrace); + } + } on HostSettingError catch (_) { + rethrow; + } catch (_) { + this.host = oldHost; + return HostSettingError.undetectable; + } + + // TODO: maybe implement version checking + + ModelManager.instance.loadModelsRaw(data: data); + _silentFlag = false; + notifyListeners(); + return null; + } + } on HostSettingError catch (e) { + return e; + } catch (_) {} + + return HostSettingError.unreachable; + } +} diff --git a/lib/services/markdown.dart b/lib/services/markdown.dart index 2a22a68..b29ae31 100644 --- a/lib/services/markdown.dart +++ b/lib/services/markdown.dart @@ -365,6 +365,7 @@ final class Markdown { final document = md.Document( blockSyntaxes: [ LatexBlockSyntax(), + LatexBracketBlockSyntax(), DetailsBlockSyntax(), const md.AlertBlockSyntax(), ], @@ -373,6 +374,7 @@ final class Markdown { SubscriptSyntax(), MarkSyntax(), LatexInlineSyntax(), + LatexBracketInlineSyntax(), md.EmojiSyntax(), md.ColorSwatchSyntax(), ], @@ -381,7 +383,7 @@ final class Markdown { ); final String content; - Tree get tree => document.parse( + late final Tree tree = document.parse( content.trim().replaceAll(RegExp(r"", dotAll: true), ""), ); @@ -389,16 +391,9 @@ final class Markdown { final TextStyle? _textStyle; final TapLongPressGestureRecognizer? _recognizer; - Markdown( - this.content, { - Uri? rootUrl, - TextStyle? textStyle, - TapLongPressGestureRecognizer? recognizer, - }) : _rootUrl = rootUrl, - _textStyle = textStyle, - _recognizer = recognizer; + Markdown(this.content, {this._rootUrl, this._textStyle, this._recognizer}); - double get _paragraphHeight => (TextPainter( + late final double _paragraphHeight = (TextPainter( text: TextSpan(text: "A", style: _textStyle), textDirection: TextDirection.ltr, )..layout()).preferredLineHeight; @@ -438,33 +433,33 @@ final class Markdown { _MarkdownPayload payload, { bool block = false, }) { - var context = payload.context; - var theme = Theme.of(context); - var colorScheme = theme.colorScheme; + final context = payload.context; + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; - var codeBox = BoxDecoration( + final codeBox = BoxDecoration( color: colorScheme.surfaceContainerHigh, border: Border.all(color: colorScheme.outline), borderRadius: BorderRadius.circular(6), ); - var spans = []; + final spans = []; for (var nodePair in payload.tree.asMap().entries) { var skipParagraphBreak = false; - var node = nodePair.value; + final node = nodePair.value; if (node is md.Text) { var text = node.text.replaceAll("\n", " "); while (text.contains(" ")) { text = text.replaceAll(" ", " "); } - var nodeStyle = const TextStyle( + const nodeStyle = TextStyle( // height: kTextHeightNone, fontFeatures: [FontFeature.tabularFigures()], ); spans.addAll( text - .split(r"(?=\s|\/|\\)") + .split(RegExp(r"(?=\s|\/|\\)")) .map( (t) => TextSpan( text: t, @@ -476,7 +471,7 @@ final class Markdown { } else if (node is md.Element) { switch (node.tag) { case "p": // MARK: Paragraph - var block = + final block = node.children!.length == 1 && node.children![0] is md.Element && (node.children![0] as md.Element).tag == "img"; @@ -486,13 +481,16 @@ final class Markdown { spans.addAll( _toInlineSpans(payload.copy(tree: node.children), block: block), ); + case "br": // MARK: Line Break + skipParagraphBreak = true; + spans.add(const TextSpan(text: "\n")); case "hr": // MARK: Horizontal Rule spans.add(const WidgetSpan(child: Divider())); case "h1" || "h2" || "h3" || "h4" || "h5" || "h6": // MARK: Headings - var multiplier = + final multiplier = (payload.textStyle?.fontSize ?? kDefaultFontSize) / kDefaultFontSize; - var size = + final size = switch (node.tag) { // stolen from HTML "h1" => 32, @@ -504,7 +502,7 @@ final class Markdown { _ => kDefaultFontSize, } - 2; - var nodeStyle = TextStyle( + final nodeStyle = TextStyle( fontSize: multiplier * size, fontWeight: FontWeight.bold, ); @@ -517,7 +515,7 @@ final class Markdown { ), ); case "em": // MARK: Italic - var nodeStyle = const TextStyle(fontStyle: FontStyle.italic); + const nodeStyle = TextStyle(fontStyle: FontStyle.italic); spans.addAll( _toInlineSpans( payload.copy( @@ -527,7 +525,7 @@ final class Markdown { ), ); case "strong": // MARK: Bold - var nodeStyle = const TextStyle(fontWeight: FontWeight.bold); + const nodeStyle = TextStyle(fontWeight: FontWeight.bold); spans.addAll( _toInlineSpans( payload.copy( @@ -537,9 +535,7 @@ final class Markdown { ), ); case "del": // MARK: Strikethrough - var nodeStyle = const TextStyle( - decoration: TextDecoration.lineThrough, - ); + const nodeStyle = TextStyle(decoration: TextDecoration.lineThrough); spans.addAll( _toInlineSpans( payload.copy( @@ -549,10 +545,10 @@ final class Markdown { ), ); case "mark": // MARK: Highlight - var color = Colors.amberAccent + final color = Colors.amberAccent .harmonizeWith(colorScheme.primary) .withValues(alpha: 0.6); - var nodeStyle = TextStyle( + final nodeStyle = TextStyle( color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white, @@ -567,13 +563,13 @@ final class Markdown { ), ); case "a": // MARK: Link - var href = node.attributes["href"]; - var parsed = href == null ? null : Uri.tryParse(href); - var valid = + final href = node.attributes["href"]; + final parsed = href == null ? null : Uri.tryParse(href); + final valid = href != null && parsed != null && ["http", "https"].contains(parsed.scheme); - var recognizer = valid + final recognizer = valid ? TapLongPressGestureRecognizer( onTap: () => launchUrl(payload.resolveUri(href)), onLongPress: () { @@ -583,8 +579,10 @@ final class Markdown { ) : null; - var linkColor = Colors.lightBlue.harmonizeWith(colorScheme.primary); - var nodeStyle = TextStyle( + final linkColor = Colors.lightBlue.harmonizeWith( + colorScheme.primary, + ); + final nodeStyle = TextStyle( color: valid ? linkColor : theme.disabledColor, decoration: TextDecoration.underline, decorationThickness: 1.2, @@ -603,9 +601,9 @@ final class Markdown { ); case "sub": // MARK: Subscript/Superscript case "sup": - var isSup = node.tag == "sup"; + final isSup = node.tag == "sup"; - var referenceTo = + final referenceTo = isSup && node.attributes["class"] == "footnote-ref" ? (node.children!.first as md.Element).attributes["href"] ?.substring(1) @@ -633,7 +631,9 @@ final class Markdown { } catch (_) {} if (referenced == null) break; - var referencedTree = List.from(referenced.children!); + final referencedTree = List.from( + referenced.children!, + ); if (referencedTree.isEmpty) break; referencedTree.last = md.Element( @@ -649,7 +649,7 @@ final class Markdown { alignment: PlaceholderAlignment.middle, child: Builder( builder: (context) { - var nodeStyle = TextStyle( + final nodeStyle = TextStyle( color: colorScheme.onSurface, fontSize: math.max( 8.0, @@ -705,7 +705,7 @@ final class Markdown { alignment: PlaceholderAlignment.middle, child: Builder( builder: (context) { - var nodeStyle = TextStyle( + final nodeStyle = TextStyle( fontSize: math.max( 8.0, (DefaultTextStyle.of(context).style.fontSize ?? @@ -728,9 +728,9 @@ final class Markdown { ), ); case "code": // MARK: Inline code - var text = (node.children!.first as md.Text).text; + final text = (node.children!.first as md.Text).text; - var backgroundColor = + final backgroundColor = node.attributes.containsKey("class") && node.attributes["class"] == "gfm-color_chip" ? (node.children!.firstWhere( @@ -739,7 +739,7 @@ final class Markdown { as md.Element) .attributes["style"] : null; - var colorCode = + final colorCode = backgroundColor != null && backgroundColor.startsWith("background-color:") ? backgroundColor @@ -747,32 +747,32 @@ final class Markdown { .trim() .replaceAll(RegExp(r"^#|;$"), "") : null; - var color = colorCode != null + final color = colorCode != null ? switch (colorCode.length) { 3 || 4 => () { - var r = int.tryParse(colorCode[0] * 2, radix: 16); - var g = int.tryParse(colorCode[1] * 2, radix: 16); - var b = int.tryParse(colorCode[2] * 2, radix: 16); - var a = int.tryParse( + final r = int.tryParse(colorCode[0] * 2, radix: 16); + final g = int.tryParse(colorCode[1] * 2, radix: 16); + final b = int.tryParse(colorCode[2] * 2, radix: 16); + final a = int.tryParse( (colorCode.length == 4 ? colorCode[3] : "F") * 2, radix: 16, ); return Color.fromARGB(a ?? 255, r ?? 0, g ?? 0, b ?? 0); }(), 6 || 8 => () { - var r = int.tryParse( + final r = int.tryParse( colorCode.substring(0, 2), radix: 16, ); - var g = int.tryParse( + final g = int.tryParse( colorCode.substring(2, 4), radix: 16, ); - var b = int.tryParse( + final b = int.tryParse( colorCode.substring(4, 6), radix: 16, ); - var a = int.tryParse( + final a = int.tryParse( (colorCode.length == 8 ? colorCode.substring(6, 8) : "FF"), @@ -784,10 +784,10 @@ final class Markdown { } : null; - var textStyle = _mergeOrOther( + final textStyle = _mergeOrOther( payload.textStyle, TextStyle( - fontFamily: "monospace", + fontFamily: "GoogleSansCode", fontSize: 14, backgroundColor: Colors.transparent, color: @@ -795,7 +795,7 @@ final class Markdown { theme.colorScheme.onSurface, ), ); - var parts = [ + final parts = [ ...text .split(RegExp(r"(?<=\s|\/|\\)")) .map((t) => Text(t, style: textStyle)), @@ -818,10 +818,10 @@ final class Markdown { } for (var w in parts.asMap().entries) { - var isStart = w.key == 0; - var isEnd = w.key == parts.length - 1; + final isStart = w.key == 0; + final isEnd = w.key == parts.length - 1; - var decoration = BoxDecoration( + final decoration = BoxDecoration( color: codeBox.color, // border: Border( // top: codeBox.border!.top, @@ -856,7 +856,7 @@ final class Markdown { ), ), ); - var padding = EdgeInsets.only( + final padding = EdgeInsets.only( left: isStart ? 2 : 0, right: isEnd ? 2 : 0, ); @@ -869,6 +869,7 @@ final class Markdown { height: kTextHeightNone, backgroundColor: decoration.color, ), + spellOut: color != null, ), WidgetSpan( alignment: PlaceholderAlignment.middle, @@ -881,9 +882,9 @@ final class Markdown { ]); } case "pre": // MARK: Fenced code block - var codeElement = node.children!.first as md.Element; - var text = (codeElement.children!.first as md.Text).text.trim(); - var lang = + final codeElement = node.children!.first as md.Element; + final text = (codeElement.children!.first as md.Text).text.trim(); + final lang = codeElement.attributes.containsKey("class") && codeElement.attributes["class"]!.startsWith("language-") ? codeElement.attributes["class"]!.substring(9) @@ -953,8 +954,8 @@ final class Markdown { ), ); case "img": // MARK: Image - var alt = (node.attributes["alt"] ?? "").trim(); - var title = node.attributes["title"]?.trim(); + final alt = (node.attributes["alt"] ?? "").trim(); + final title = node.attributes["title"]?.trim(); var src = node.attributes["src"]; void imageScreen(String src) => Navigator.of(context).push( @@ -1073,7 +1074,7 @@ final class Markdown { ].contains(alertType)) { alertType = null; } - var alertTitle = alertType != null + final alertTitle = alertType != null ? node.children!.removeAt( node.children!.indexWhere( (e) => @@ -1083,16 +1084,17 @@ final class Markdown { ) as md.Element : null; - var alertIcon = alertType != null + final alertIcon = alertType != null ? switch (alertType) { "note" => Icons.info_outline, "tip" => Icons.lightbulb_outline, - "important" || "warning" => Icons.feedback_outlined, + "important" => Icons.feedback_outlined, + "warning" => Icons.warning_amber_rounded, "caution" => Icons.report_outlined, _ => null, } : null; - var alertColor = alertType != null + final alertColor = alertType != null ? (switch (alertType) { "note" => Colors.blue[600], "tip" => Colors.green[600], @@ -1103,12 +1105,12 @@ final class Markdown { })?.harmonizeWith(colorScheme.primary) : null; - var contentSpans = _toInlineSpans( + final contentSpans = _toInlineSpans( payload.copy(tree: node.children), block: true, ); if (alertType != null && alertTitle != null) { - var titleSpans = _toInlineSpans( + final titleSpans = _toInlineSpans( payload.copy(tree: alertTitle.children), ); contentSpans.insertAll(0, [ @@ -1154,12 +1156,12 @@ final class Markdown { ), ); case "table": // MARK: Table - var head = + final head = node.children!.firstWhere( (e) => e is md.Element && e.tag == "thead", ) as md.Element; - var body = + final body = node.children!.firstWhere( (e) => e is md.Element && e.tag == "tbody", orElse: () => md.Element("tbody", []), @@ -1180,35 +1182,37 @@ final class Markdown { headingRowColor: WidgetStatePropertyAll( colorScheme.surfaceContainerLow, ), - columns: (head.children!.first as md.Element).children!.map(( - e, - ) { - e as md.Element; - var align = switch (e.attributes["align"]) { - "left" => MainAxisAlignment.start, - "right" => MainAxisAlignment.end, - _ => MainAxisAlignment.center, - }; - return DataColumn( - label: Padding( - padding: const EdgeInsets.only(top: 4, bottom: 4), - child: Text( - // TODO: Reimplement table to better fit rendered content. Then use [Text.rich] here. - TextSpan( - children: _toInlineSpans( - payload.copy(tree: e.children), + columns: (head.children!.first as md.Element).children!.map( + (e) { + e as md.Element; + final align = switch (e.attributes["align"]) { + "left" => MainAxisAlignment.start, + "right" => MainAxisAlignment.end, + _ => MainAxisAlignment.center, + }; + return DataColumn( + label: Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Text.rich( + TextSpan( + children: _toInlineSpans( + payload.copy(tree: e.children), + ), + ), + overflow: TextOverflow.visible, ), - ).toPlainText(), + ), ), - ), - headingRowAlignment: align, - ); - }).toList(), + headingRowAlignment: align, + ); + }, + ).toList(), rows: body.children!.map((e) { return DataRow( cells: (e as md.Element).children!.map((c) { c as md.Element; - var align = switch (c.attributes["align"]) { + final align = switch (c.attributes["align"]) { "right" => Alignment.centerRight, "center" => Alignment.center, _ => Alignment.centerLeft, @@ -1216,13 +1220,13 @@ final class Markdown { return DataCell( Align( alignment: align, - child: Text( - // TODO: Reimplement table to better fit rendered content. Then use [Text.rich] here. + child: Text.rich( TextSpan( children: _toInlineSpans( payload.copy(tree: c.children), ), - ).toPlainText(), + ), + overflow: TextOverflow.visible, ), ), ); @@ -1236,20 +1240,20 @@ final class Markdown { ); case "ol": // MARK: Ordered/Unordered List case "ul": - var ordered = node.tag == "ol"; + final ordered = node.tag == "ol"; - var checkboxes = {}; - var elements = []; + final checkboxes = {}; + final elements = []; for (var child in (node.children ?? []).asMap().entries) { if (child.value is md.Element && (child.value as md.Element).tag == "li") { - var childElement = child.value as md.Element; - var children = childElement.children ?? []; + final childElement = child.value as md.Element; + final children = childElement.children ?? []; if (!ordered && childElement.attributes.containsKey("class") && childElement.attributes["class"] == "task-list-item") { - var checkbox = + final checkbox = childElement.children!.firstWhere( (e) => e is md.Element && @@ -1257,7 +1261,7 @@ final class Markdown { e.attributes["type"] == "checkbox", ) as md.Element; - var isChecked = checkbox.attributes.containsKey("checked"); + final isChecked = checkbox.attributes.containsKey("checked"); checkboxes[child.key] = isChecked; children.removeAt(0); } @@ -1302,13 +1306,16 @@ final class Markdown { ), ), ) - : ExcludeSemantics( - child: Text( - ordered ? "${e.key + 1}." : "•", - style: TextStyle( - height: - payload.textStyle?.height ?? - kTextHeightNone, + : Transform.translate( + offset: const Offset(0, 2), + child: ExcludeSemantics( + child: Text( + ordered ? "${e.key + 1}." : "•", + style: TextStyle( + height: + payload.textStyle?.height ?? + kTextHeightNone, + ), ), ), ), @@ -1323,12 +1330,12 @@ final class Markdown { ), ); case "details": // MARK: Details - var opened = + final opened = node.attributes.containsKey("class") && node.attributes["class"]! .split(" ") .contains("markdown-details-open"); - var summary = + final summary = (node.children!.removeAt( node.children!.indexWhere( (e) => @@ -1360,8 +1367,8 @@ final class Markdown { ), ); case "latex": // MARK: LaTeX Block - var text = (node.children!.first as md.Text).text; - var errorStyle = TextStyle( + final text = (node.children!.first as md.Text).text; + final errorStyle = TextStyle( color: colorScheme.error, fontStyle: FontStyle.italic, ); @@ -1394,8 +1401,8 @@ final class Markdown { ), ); case "latexInline": // MARK: LaTeX Inline - var text = (node.children!.first as md.Text).text; - var errorStyle = TextStyle( + final text = (node.children!.first as md.Text).text; + final errorStyle = TextStyle( color: colorScheme.error, fontStyle: FontStyle.italic, ); @@ -1433,7 +1440,7 @@ final class Markdown { } class SuperscriptSyntax extends md.InlineSyntax { - SuperscriptSyntax() : super(r"\^.+\^"); + SuperscriptSyntax() : super(r"\^.+?\^"); @override bool onMatch(md.InlineParser parser, Match match) { @@ -1465,11 +1472,11 @@ class SubscriptSyntax extends md.InlineSyntax { } class MarkSyntax extends md.InlineSyntax { - MarkSyntax() : super(r"<\s*mark\s*>(.*)<\/\s*mark\s*>"); + MarkSyntax() : super(r"<\s*mark\s*>(.*?)<\/\s*mark\s*>"); @override bool onMatch(md.InlineParser parser, Match match) { - var text = match[1]!.trim(); + final text = match[1]!.trim(); if (text.isEmpty) { parser.addNode(md.Text(match[0]!)); } else { @@ -1482,14 +1489,14 @@ class MarkSyntax extends md.InlineSyntax { class LatexBlockSyntax extends md.BlockSyntax { @override md.Node? parse(md.BlockParser parser) { - var opening = parser.current.content; - var m = pattern.firstMatch(opening)!; - var after = opening.substring(m.end); + final opening = parser.current.content; + final m = pattern.firstMatch(opening)!; + final after = opening.substring(m.end); parser.advance(); - var buf = StringBuffer(); + final buf = StringBuffer(); - var closeSame = after.indexOf(_pattern); + final closeSame = after.indexOf(_pattern); if (closeSame != -1) { buf.write(after.substring(0, closeSame)); return _toElement(buf); @@ -1497,8 +1504,8 @@ class LatexBlockSyntax extends md.BlockSyntax { if (after.isNotEmpty) buf.write(after); while (!parser.isDone) { - var line = parser.current.content; - var ci = line.indexOf(_pattern); + final line = parser.current.content; + final ci = line.indexOf(_pattern); if (ci != -1) { buf.write(line.substring(0, ci)); parser.advance(); @@ -1520,7 +1527,7 @@ class LatexBlockSyntax extends md.BlockSyntax { } class LatexInlineSyntax extends md.InlineSyntax { - LatexInlineSyntax() : super(r"\$.+\$"); + LatexInlineSyntax() : super(r"\$.+?\$"); @override bool onMatch(md.InlineParser parser, Match match) { @@ -1535,17 +1542,73 @@ class LatexInlineSyntax extends md.InlineSyntax { } } +class LatexBracketBlockSyntax extends md.BlockSyntax { + @override + md.Node? parse(md.BlockParser parser) { + final opening = parser.current.content; + final m = pattern.firstMatch(opening)!; + final after = opening.substring(m.end); + parser.advance(); + + final buf = StringBuffer(); + + final closeSame = after.indexOf(_closePattern); + if (closeSame != -1) { + buf.write(after.substring(0, closeSame)); + return _toElement(buf); + } + + if (after.isNotEmpty) buf.write(after); + while (!parser.isDone) { + final line = parser.current.content; + final ci = line.indexOf(_closePattern); + if (ci != -1) { + buf.write(line.substring(0, ci)); + parser.advance(); + return _toElement(buf); + } + buf.writeln(line); + parser.advance(); + } + + return _toElement(buf); + } + + md.Element _toElement(StringBuffer buf) => + md.Element("latex", [md.Text(buf.toString())]); + + @override + RegExp get pattern => RegExp(r"^\\\["); + final _closePattern = r"\]"; +} + +class LatexBracketInlineSyntax extends md.InlineSyntax { + LatexBracketInlineSyntax() : super(r"\\\(.+?\\\)"); + + @override + bool onMatch(md.InlineParser parser, Match match) { + var text = match[0]!.substring(2); + text = text.substring(0, text.length - 2).trim(); + if (text.isEmpty) { + parser.addNode(md.Text(match[0]!)); + } else { + parser.addNode(md.Element("latexInline", [md.Text(text)])); + } + return true; + } +} + class DetailsBlockSyntax extends md.BlockSyntax { @override md.Node? parse(md.BlockParser parser) { - var opening = parser.current.content; - var m = pattern.firstMatch(opening)!; - var after = opening.substring(m.end); + final opening = parser.current.content; + final m = pattern.firstMatch(opening)!; + final after = opening.substring(m.end); parser.advance(); - var buf = StringBuffer(); + final buf = StringBuffer(); - var closeSame = after.indexOf(_closePattern); + final closeSame = after.indexOf(_closePattern); if (closeSame != -1) { buf.write(after.substring(0, closeSame)); return _toElement(parser.document, buf); @@ -1553,8 +1616,8 @@ class DetailsBlockSyntax extends md.BlockSyntax { if (after.isNotEmpty) buf.write(after); while (!parser.isDone) { - var line = parser.current.content; - var ci = line.indexOf(_closePattern); + final line = parser.current.content; + final ci = line.indexOf(_closePattern); if (ci != -1) { buf.write(line.substring(0, ci)); parser.advance(); @@ -1568,12 +1631,12 @@ class DetailsBlockSyntax extends md.BlockSyntax { } md.Element? _toElement(md.Document doc, StringBuffer buf) { - var m = _realPattern.firstMatch(""); + final m = _realPattern.firstMatch(""); if (m == null) return null; var className = "markdown-details"; if (m.namedGroup("argument") != null) { - var argument = m.namedGroup("argument")!.trim(); + final argument = m.namedGroup("argument")!.trim(); if (argument.isNotEmpty && ["open"].contains(argument)) { className += " markdown-details-$argument"; } @@ -1587,9 +1650,9 @@ class DetailsBlockSyntax extends md.BlockSyntax { summary = summary.replaceAll(" " * 2, " " * 1); } - var content = m.namedGroup("content")!.trimRight().split("\n\n"); - var contentFirstLine = content.removeAt(0); - var contentNodes = [ + final content = m.namedGroup("content")!.trimRight().split("\n\n"); + final contentFirstLine = content.removeAt(0); + final contentNodes = [ md.Element("p", [md.Text(summary)]) ..attributes["class"] = "markdown-details-summary", if (contentFirstLine.trim().isNotEmpty) @@ -1730,9 +1793,10 @@ class _MarkdownFootnoteModal extends StatefulWidget { class _MarkdownFootnoteModalState extends State<_MarkdownFootnoteModal> { var urlMode = false; + bool _loadedData = false; + bool urlModeError = false; late final Uri? urlModeUrl; OgpData? urlModeData; - bool _loadedData = false; Uri? urlModeFavicon; @override @@ -1744,32 +1808,35 @@ class _MarkdownFootnoteModalState extends State<_MarkdownFootnoteModal> { urlMode = urlModeUrl != null && ["http", "https"].contains(urlModeUrl!.scheme); if (urlMode) { - OgpDataExtract.execute(urlModeUrl!.toString(), userAgent: userAgent).then( - (v) { - _loadedData = true; - if (mounted) setState(() {}); - urlModeData = v; - if (mounted) setState(() {}); - }, - ); - OgpDataExtract.fetchFavicon( - urlModeUrl!.toString(), - userAgent: userAgent, - ).then((v) async { - for (var i in v) { - if (i == null) continue; - var req = await httpClient.head(Uri.parse(i)); - if (req.statusCode == 200 && - [ - "image/jpeg", - "image/png", - ].contains(req.headers["content-type"])) { - urlModeFavicon = Uri.parse(i); - if (mounted && _loadedData) setState(() {}); - break; - } - } - }); + OgpDataExtract.execute(urlModeUrl!.toString(), userAgent: userAgent) + .then((v) { + _loadedData = true; + if (mounted) setState(() {}); + urlModeData = v; + if (mounted) setState(() {}); + }) + .catchError((_) { + _loadedData = true; + urlModeError = true; + if (mounted) setState(() {}); + }); + OgpDataExtract.fetchFavicon(urlModeUrl!.toString(), userAgent: userAgent) + .then((v) async { + for (var i in v) { + if (i == null) continue; + final req = await httpClient.head(Uri.parse(i)); + if (req.statusCode == 200 && + [ + "image/jpeg", + "image/png", + ].contains(req.headers["content-type"])) { + urlModeFavicon = Uri.parse(i); + if (mounted && _loadedData) setState(() {}); + break; + } + } + }) + .catchError((_) {}); } } @@ -1777,21 +1844,21 @@ class _MarkdownFootnoteModalState extends State<_MarkdownFootnoteModal> { Widget build(BuildContext context) { Widget child; if (urlMode) { - var image = urlModeData?.image; - var title = urlModeData?.title ?? urlModeUrl.toString(); - var description = urlModeData?.description; + final image = urlModeData?.image; + final title = urlModeData?.title ?? urlModeUrl.toString(); + final description = urlModeData?.description; - var duration = kThemeAnimationDuration; - var curve = Curves.fastEaseInToSlowEaseOut; + const duration = kThemeAnimationDuration; + const curve = Curves.fastEaseInToSlowEaseOut; - child = InkWell( - onTap: () async { - await launchUrl(urlModeUrl!, mode: LaunchMode.inAppBrowserView); - if (context.mounted) Navigator.of(context).pop(); - }, - borderRadius: BorderRadius.circular(12), - child: Card.filled( - margin: EdgeInsets.zero, + child = Card.filled( + margin: EdgeInsets.zero, + clipBehavior: Clip.antiAlias, + child: InkWell( + onTap: () async { + await launchUrl(urlModeUrl!, mode: LaunchMode.inAppBrowserView); + if (context.mounted) Navigator.of(context).pop(); + }, child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -1799,40 +1866,34 @@ class _MarkdownFootnoteModalState extends State<_MarkdownFootnoteModal> { Column( mainAxisSize: MainAxisSize.min, children: [ - ClipRRect( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(12), - topRight: Radius.circular(12), - ), - child: AnimatedSize( - duration: duration, - curve: curve, - alignment: Alignment.topCenter, - child: image != null - ? Image.network( - image, - loadingBuilder: (_, child, loadingProgress) { - if (loadingProgress == null) return child; - return SizedBox( - width: double.infinity, - child: LinearProgressIndicator( - value: - loadingProgress.expectedTotalBytes != - null - ? loadingProgress - .cumulativeBytesLoaded / - loadingProgress - .expectedTotalBytes! - : null, - ), - ); - }, - ) - : const SizedBox( - width: double.infinity, - child: LinearProgressIndicator(), - ), - ), + AnimatedSize( + duration: duration, + curve: curve, + alignment: Alignment.topCenter, + child: image != null + ? Image.network( + image, + loadingBuilder: (_, child, loadingProgress) { + if (loadingProgress == null) return child; + return SizedBox( + width: double.infinity, + child: LinearProgressIndicator( + value: + loadingProgress.expectedTotalBytes != + null + ? loadingProgress + .cumulativeBytesLoaded / + loadingProgress + .expectedTotalBytes! + : null, + ), + ); + }, + ) + : const SizedBox( + width: double.infinity, + child: LinearProgressIndicator(), + ), ), if (_loadedData) const Divider(height: 1), ], @@ -1841,6 +1902,8 @@ class _MarkdownFootnoteModalState extends State<_MarkdownFootnoteModal> { duration: duration, curve: curve, child: ListTile( + isThreeLine: + !(!_loadedData || (_loadedData && description == null)), leading: SizedBox( height: 24, width: 24, @@ -1957,6 +2020,12 @@ class _MarkdownDetailsState extends State<_MarkdownDetails> ); } + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + void _toggleAnimation() { if (!kIsWeb) selectionHaptic(); setState(() { @@ -2001,7 +2070,7 @@ class _MarkdownDetailsState extends State<_MarkdownDetails> ), SizeTransition( sizeFactor: _animation, - axisAlignment: -1, + alignment: Alignment.topCenter, child: Text.rich( TextSpan(children: widget.contentSpans), style: widget.textStyle, @@ -2083,7 +2152,7 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> @override void dispose() { - _controller.removeListener(onUpdate); + _controller.dispose(); super.dispose(); } @@ -2093,8 +2162,8 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> @override Widget build(BuildContext context) { - var finalTitle = widget.title ?? "Untitled Image"; - var titleWidget = Text( + final finalTitle = widget.title ?? "Untitled Image"; + final titleWidget = Text( finalTitle, maxLines: 1, overflow: TextOverflow.ellipsis, @@ -2103,8 +2172,8 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> data: ThemeBuilderData.current!.themeDark(), child: LayoutBuilder( builder: (context, constraints) { - var ratio = _ratioFromDouble(_imageSize?.aspectRatio ?? 1); - var realScale = _imageSize != null + final ratio = _ratioFromDouble(_imageSize?.aspectRatio ?? 1); + final realScale = _imageSize != null ? (_toRealScale( _controller.value.getMaxScaleOnAxis(), _imageSize!, @@ -2224,14 +2293,14 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> Size imageSize, BoxConstraints constraints, ) { - var iw = imageSize.width; - var ih = imageSize.height; - var cw = constraints.maxWidth; - var ch = constraints.maxHeight; + final iw = imageSize.width; + final ih = imageSize.height; + final cw = constraints.maxWidth; + final ch = constraints.maxHeight; if (iw <= 0 || ih <= 0 || cw <= 0 || ch <= 0) return scale; - var fitScale = (iw / ih > cw / ch) ? cw / iw : ch / ih; + final fitScale = (iw / ih > cw / ch) ? cw / iw : ch / ih; return scale * fitScale; } @@ -2240,17 +2309,17 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> Size imageSize, BoxConstraints constraints, ) { - var iw = imageSize.width * (constraints.maxWidth / imageSize.width); - var ih = imageSize.height * (constraints.maxHeight / imageSize.height); - var cw = constraints.maxWidth; - var ch = constraints.maxHeight; + final iw = imageSize.width * (constraints.maxWidth / imageSize.width); + final ih = imageSize.height * (constraints.maxHeight / imageSize.height); + final cw = constraints.maxWidth; + final ch = constraints.maxHeight; if (iw <= 0 || ih <= 0) return realScale; if (!cw.isFinite || !ch.isFinite) return realScale; if (cw <= 0 || ch <= 0) return realScale; // if (iw <= cw && ih <= ch) return realScale; - var fitScale = (iw / ih > cw / ch) ? cw / iw : ch / ih; + final fitScale = (iw / ih > cw / ch) ? cw / iw : ch / ih; return (realScale / fitScale) * (imageSize.width / constraints.maxWidth); } @@ -2262,10 +2331,10 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> if (!v.isFinite || v <= 0) { throw ArgumentError.value(v, 'v', 'must be > 0 and finite'); } - var inverted = preferWidth && v < 1.0; + final inverted = preferWidth && v < 1.0; if (inverted) v = 1.0 / v; - var a0 = v.floor(); + final a0 = v.floor(); if ((v - a0).abs() < 1e-12) { return inverted ? (denominator: 1, numerator: a0) @@ -2280,12 +2349,12 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> while (true) { if (frac.abs() < 1e-12) break; - var x = 1.0 / frac; - var a = x.floor(); + final x = 1.0 / frac; + final a = x.floor(); var p2 = a * p1 + p0; var q2 = a * q1 + q0; if (q2 > maxDen) { - var k = (maxDen - q0) ~/ q1; + final k = (maxDen - q0) ~/ q1; if (k <= 0) { p2 = p1; q2 = q1; @@ -2308,7 +2377,7 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> a = a.abs(); b = b.abs(); while (b != 0) { - var t = a % b; + final t = a % b; a = b; b = t; } @@ -2318,11 +2387,11 @@ class _MarkdownImageScreenState extends State<_MarkdownImageScreen> var num = p1; var den = q1; if (inverted) { - var t = num; + final t = num; num = den; den = t; } - var gg = g(num, den); + final gg = g(num, den); return (numerator: num ~/ gg, denominator: den ~/ gg); } } @@ -2371,9 +2440,9 @@ class TapLongPressGestureRecognizer extends GestureRecognizer { extension on md.Node { String toInfoString() { switch (this) { - case md.Text e: + case final md.Text e: return 'Text("${e.text}")'; - case md.Element e: + case final md.Element e: return 'Element(tag: ${e.tag}, attributes: ${e.attributes}, children: [${e.children?.map((e) => e.toInfoString()).join(", ")}])'; default: return 'Node()'; diff --git a/lib/services/model.dart b/lib/services/model.dart index ff4ea0f..8429968 100644 --- a/lib/services/model.dart +++ b/lib/services/model.dart @@ -2,54 +2,136 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:ollama_dart/ollama_dart.dart' as ollama; +import '../main.dart'; import 'clients.dart' as clients; import 'preferences.dart'; -typedef ModelCapability = ollama.Capability; +/// Container class for model capabilities. +/// +/// See more: +/// - https://github.com/ollama/ollama/blob/main/types/model/capability.go +class ModelCapability { + final String name; + + ModelCapability(this.name); + + static ModelCapability completion = ModelCapability("completion"); + static ModelCapability tools = ModelCapability("tools"); + static ModelCapability insertion = ModelCapability("insert"); + static ModelCapability vision = ModelCapability("vision"); + static ModelCapability embedding = ModelCapability("embedding"); + static ModelCapability thinking = ModelCapability("thinking"); + static ModelCapability image = ModelCapability("image"); + static ModelCapability audio = ModelCapability("audio"); + + @override + operator ==(Object other) => other is ModelCapability && other.name == name; + @override + int get hashCode => name.hashCode; + + IconData? get icon => switch (name) { + "completion" => Icons.text_fields, + "tools" => Icons.build, + "insert" => Icons.read_more, + "vision" => Icons.visibility_outlined, + "embedding" => Icons.link, + "thinking" => Icons.emoji_objects_outlined, + "image" => Icons.image_outlined, + "audio" => Icons.audiotrack_outlined, + _ => Icons.inventory_2_outlined, + }; +} class Model extends ChangeNotifier { final String name; + List nameColored(BuildContext context) => + nameColoredStatic(name: name, context: context)!; + static List? nameColoredStatic({ + required String? name, + required BuildContext context, + }) { + if (name == null) return null; + final colorScheme = ColorScheme.of(context); + + final parts = name.split(":"); + assert( + parts.isNotEmpty && parts.length <= 2, + "Model name should be in format family:version, but got $name", + ); + + return [ + TextSpan(text: parts.first), + if (parts.length == 2) + TextSpan( + text: ":${parts.last}", + style: TextStyle(color: colorScheme.outline), + ), + ]; + } + + DateTime _modifiedAt; + DateTime get modifiedAt => _modifiedAt; + + int _size; + int get size => _size; + String _family; String get family => _family; Set _families; Set get families => Set.unmodifiable(_families); + String _parameterSize; + String get parameterSize => _parameterSize; + Set _capabilities; Set get capabilities => Set.unmodifiable(_capabilities); Model._( this.name, { - required String family, - Set families = const {}, - Set capabilities = const {}, - }) : _family = family, - _families = families, - _capabilities = capabilities; + required this._modifiedAt, + required this._size, + required this._family, + this._families = const {}, + required this._parameterSize, + }) : _capabilities = const {}; - factory Model.fromApi({required ollama.Model model, ollama.ModelInfo? info}) { + factory Model.fromApi({required ollama.ModelSummary model}) { return Model._( model.model!, + modifiedAt: + DateTime.tryParse(model.modifiedAt!)?.toLocal() ?? + DateTime.fromMillisecondsSinceEpoch(0), + size: model.size ?? 0, family: model.details!.family!, families: model.details!.families?.toSet() ?? {}, - capabilities: info?.capabilities?.toSet() ?? {}, + parameterSize: model.details!.parameterSize!.replaceAll(".0", ""), ); } + bool _didCallUpdateData = false; + bool get didCallUpdateData => _didCallUpdateData; + Future updateData() async { - var data = await clients.ollamaClient.showModelInfo( - request: ollama.ModelInfoRequest(model: name), + final data = await clients.ollamaClient.models.show( + request: ollama.ShowRequest(model: name), ); // just in case, but should always be present if (data.details != null) { - _family = data.details!.family!; - _families = data.details!.families?.toSet() ?? {}; + _family = data.details?["family"] ?? _family; + _families = data.details?["families"] != null + ? (data.details!["families"] as List).map((e) => e.toString()).toSet() + : _families; + _parameterSize = data.details?["parameterSize"] ?? _parameterSize; } - _capabilities = data.capabilities!.toSet(); + _capabilities = data.capabilities!.map(ModelCapability.new).toSet(); + + _didCallUpdateData = true; notifyListeners(); } @@ -58,15 +140,15 @@ class Model extends ChangeNotifier { // sending a [GenerateChatCompletionRequest] without [messages], which is // required for loading, otherwise a message will be generated - var headers = { + final headers = { "Content-Type": "application/json", ...Preferences.instance.hostHeaders, }; - var body = {"model": name, "keep_alive": Preferences.instance.keepAlive}; + final body = {"model": name, "keep_alive": Preferences.instance.keepAlive}; await clients.httpClient .post( - Uri.parse("${clients.ollamaClient.baseUrl}/api/generate"), + Uri.parse("${clients.ollamaClient.config.baseUrl}/api/generate"), headers: headers, body: jsonEncode(body), ) @@ -89,12 +171,16 @@ class ModelManager extends ChangeNotifier { String? _currentModelName; String? get currentModelName => _currentModelName; set currentModelName(String? name) { + assert(!useModel, "Model if fixed to $fixedModel and cannot be changed."); + if (useModel) return; + + if (name == _currentModelName) return; _currentModelName = name; Preferences.instance.model = name; notifyListeners(); } - Model? get currentModel => _currentModelName == null + Model? get currentModel => _currentModelName == null || _models.isEmpty ? null : _models.singleWhere((e) => e.name == _currentModelName); set currentModel(Model? model) => currentModelName = model?.name; @@ -102,11 +188,23 @@ class ModelManager extends ChangeNotifier { final Set _models = {}; Set get models => Set.unmodifiable(_models); - ModelManager._() : _currentModelName = Preferences.instance.model; + ModelManager._() + : _currentModelName = useModel ? fixedModel : Preferences.instance.model; Future loadModels({bool fetchCapabilitiesInBackground = true}) async { - var data = await clients.ollamaClient.listModels(); + final data = await clients.ollamaClient.models.list().timeout( + TimeoutMultiplier.medium, + ); + loadModelsRaw( + data: data, + fetchCapabilitiesInBackground: fetchCapabilitiesInBackground, + ); + } + void loadModelsRaw({ + required ollama.ListResponse data, + bool fetchCapabilitiesInBackground = true, + }) { for (var model in _models) { model.dispose(); } @@ -115,6 +213,10 @@ class ModelManager extends ChangeNotifier { for (var model in data.models!) { _models.add(Model.fromApi(model: model)..addListener(notifyListeners)); } + if (_currentModelName != null && + !_models.any((e) => e.name == _currentModelName)) { + _currentModelName = null; + } _initialized = true; notifyListeners(); @@ -123,60 +225,49 @@ class ModelManager extends ChangeNotifier { compute((_) async { for (var model in _instance.models) { await model.updateData().catchError((_) {}); + notifyListeners(); } }, null); } } } -// MARK: Model Set Dialog +String bytesToHumanReadable(int bytes, {String? locale}) { + const units = ["B", "KB", "MB", "GB", "TB"]; + var value = bytes.toDouble(); + var unitIndex = 0; -// class ModelSetDialog extends StatefulWidget { -// final bool contentOnly; + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex++; + } + final nf = NumberFormat.decimalPattern(locale) + ..maximumFractionDigits = 2 + ..minimumFractionDigits = 0; -// const ModelSetDialog({super.key, this.contentOnly = false}); + final separator = + RegExp(r"(\s)") + .firstMatch( + NumberFormat.simpleCurrency(locale: locale, name: "USD").format(0), + ) + ?.group(1) ?? + ""; -// @override -// State createState() => _ModelSetDialogState(); -// } + return "${nf.format(value)}$separator${units[unitIndex]}"; +} -// class _ModelSetDialogState extends State { -// @override -// void initState() { -// super.initState(); -// ModelManager.instance.addListener(onChange); -// ModelManager.instance.loadModels(); -// } - -// @override -// void dispose() { -// ModelManager.instance.removeListener(onChange); -// super.dispose(); -// } - -// void onChange() { -// setState(() {}); -// } - -// @override -// Widget build(BuildContext context) { -// Widget main = Placeholder(); - -// if (widget.contentOnly) { -// return main; -// } else { -// return AlertDialog(); -// } -// } -// } - -// void showModelSetDialog(BuildContext context) { -// if (Display.of(context).isDesktop) { -// showModalBottomSheet( -// context: context, -// builder: (_) => const ModelSetDialog(contentOnly: true), -// ); -// } else { -// showDialog(context: context, builder: (_) => const ModelSetDialog()); -// } -// } +extension FilterSupportedCapabilities on Iterable { + Iterable filterSupportedCapabilities() => where( + (capability) => switch (capability.name) { + "completion" => false, + "tools" => false, + "insert" => false, + "vision" => true, + "embedding" => false, + "thinking" => true, + "image" => false, + "audio" => false, + _ => false, + }, + ); +} diff --git a/lib/services/preferences.dart b/lib/services/preferences.dart index 1039f55..8e01b86 100644 --- a/lib/services/preferences.dart +++ b/lib/services/preferences.dart @@ -14,12 +14,14 @@ class Preferences extends ChangeNotifier { } } - String? get host => prefs?.getString("host") ?? (useHost ? fixedHost : null); - set host(String? value) { - if (value == null || value.isEmpty) { + Uri? get host => Uri.tryParse( + prefs?.getString("host") ?? (useHost ? fixedHost : null) ?? "::", + ); + set host(Uri? value) { + if (value == null) { prefs?.remove("host"); } else { - prefs?.setString("host", value); + prefs?.setString("host", value.toString()); } notifyListeners(); } @@ -41,6 +43,16 @@ class Preferences extends ChangeNotifier { notifyListeners(); } + String? get user => prefs?.getString("user"); + set user(String? value) { + if (value == null || value.isEmpty) { + prefs?.remove("user"); + } else { + prefs?.setString("user", value); + } + notifyListeners(); + } + bool get useSystem => prefs?.getBool("useSystem") ?? true; set useSystem(bool value) { prefs?.setBool("useSystem", value); @@ -48,7 +60,9 @@ class Preferences extends ChangeNotifier { } String? get system => useSystem - ? prefs?.getString("system") ?? "You are a helpful assistant." + ? prefs?.getString("system") ?? + "You are a helpful assistant. Answer the user's questions to the best of your ability. If you do not know the answer, say that you do not know and do not fabricate information.\n\n" + "You may use Markdown to format your response. For math, you may use LaTeX with standard Markdown LaTeX syntax." : null; set system(String? value) { if (value == null || value.isEmpty) { diff --git a/lib/services/responsive.dart b/lib/services/responsive.dart index fa155fd..c87b2d1 100644 --- a/lib/services/responsive.dart +++ b/lib/services/responsive.dart @@ -3,20 +3,164 @@ import 'dart:io' as io; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -class Display { - late final Size size; +enum BreakpointNavigationType { + navigationBar, + navigationRail, + navigationRailExtended, + navigationRailModal, +} - Display.from(BuildContext context) { - size = MediaQuery.sizeOf(context); +enum Breakpoint { + compact( + null, + 599, + panes: [1], + panesRecommended: 1, + navigation: [.navigationBar, .navigationRailModal], + fullScreenDialogRecommended: true, + spacing: 16, + ), + medium( + 600, + 839, + panes: [1, 2], + panesRecommended: 1, + navigation: [.navigationBar, .navigationRail], + spacing: 24, + ), + expanded( + 840, + 1199, + panes: [1, 2], + panesRecommended: 2, + panesFixedWidth: 360, + navigation: [.navigationRail, .navigationRailExtended], + spacing: 24, + ), + large( + 1200, + 1599, + panes: [1, 2], + panesRecommended: 2, + panesFixedWidth: 412, + navigation: [.navigationRail, .navigationRailExtended], + spacing: 24, + ), + extraLarge( + 1600, + null, + panes: [1, 2, 3], + panesRecommended: 2, + panesFixedWidth: 412, + panesThirdFixedWidth: 400, + navigation: [.navigationRail, .navigationRailExtended], + spacing: 24, + ); + + final int? from; + final int? to; + + /// List of possible pane numbers according to specification. + /// + /// [panesRecommended] is always included in this list. It is the recommended + /// number of panes for this breakpoint. If not using the recommended number + /// of panes, good reasoning should be documented. + /// + /// The first two panes can use either of the following layout types: + /// - Split-pane layout: + /// - The two panes are displayed side by side, with the same width. If the + /// navigation rail is used, it is counted into the 50 percent split of the + /// pane next to it, typically the first one. + /// - Fixed-and-flexible layout: + /// - One pane, typically the first one, has the fixed width of + /// [panesFixedWidth]. The other pane takes up the remaining space. + /// - This layout option is only supported if [panesFixedWidth] is not null. + /// + /// All panes are separated by [spacing] and have that much space to the + /// screen edge as well. + /// + /// The third pane of the [extraLarge] breakpoint is largely independent of + /// the rules for the first two panes. It must always have the width of + /// [panesThirdFixedWidth]. It is separated from the other panes by [spacing]. + /// Stylistically, according to the specification, it should be a *standard + /// side sheet*. + final List panes; + + /// The number of panes that are recommended for this breakpoint. + final int panesRecommended; + + /// The fixed width for the fixed pane in a fixed-and-flexible layout. + /// + /// See the documentation for [panes] for more details on usage of this + /// property. + /// + /// If this is null, a fixed-and-flexible layout is not supported for this + /// breakpoint. + final double? panesFixedWidth; + + /// The fixed width for the third pane in the [extraLarge] breakpoint. + /// + /// This is only used for the third pane in the [extraLarge] breakpoint. If a + /// third pane is used, the width of ot must always be set to this value. + /// + /// The third pane is separated from the other panes by [spacing]. + /// Stylistically, according to the specification, it should be a *standard + /// side sheet*. + final double? panesThirdFixedWidth; + + /// The navigation types that are recommended for this breakpoint. + final List navigation; + + /// Whether a full screen dialog is recommended for this breakpoint. + /// + /// If this is false, using a normal dialog is recommended instead. Normal + /// dialogs can still be used for this breakpoint if this is true. + final bool fullScreenDialogRecommended; + + /// The spacing between panes, and between panes and the screen edge. + /// + /// This is the spacing that is recommended for this breakpoint. + /// + /// Please note that the Material specification also includes a complicated + /// set of guidelines for spacing using rulers. Usually these can be sidelined + /// in favor of a single spacing value that is used everywhere. Read more + /// here: https://m3.material.io/foundations/layout/grids-spacing/grids + final double spacing; + + const Breakpoint( + this.from, + this.to, { + required this.panes, + required this.panesRecommended, + this.panesFixedWidth, + this.panesThirdFixedWidth, + required this.navigation, + this.fullScreenDialogRecommended = false, + required this.spacing, + }); + + /// Returns the [Breakpoint] for the given [BuildContext]. + static Breakpoint of(BuildContext context) { + final width = MediaQuery.sizeOf(context).width.ceil(); + return Breakpoint.values.firstWhere( + (breakpoint) => + width >= (breakpoint.from ?? double.negativeInfinity) && + width <= (breakpoint.to ?? double.infinity), + ); } - bool get isMobile => size.width < 600; + bool operator >(Breakpoint b) => + (to ?? double.infinity) > (b.from ?? double.negativeInfinity); + bool operator <(Breakpoint b) => + (from ?? double.negativeInfinity) < (b.to ?? double.infinity); + bool operator >=(Breakpoint b) => this > b || this == b; + bool operator <=(Breakpoint b) => this < b || this == b; - bool get isTabletOrLess => size.width < 1200; - bool get isTablet => size.width >= 600 && size.width < 1200; - bool get isTabletOrMore => size.width >= 600; - - bool get isDesktop => size.width >= 1200; + @override + String toString() => + "Breakpoint.$name(from: $from, to: $to, panes: $panes, panesRecommended: $panesRecommended, navigation: $navigation, fullScreenDialogRecommended: $fullScreenDialogRecommended, spacing: $spacing)"; + String toPrettyString() => + "Breakpoint.$name(\n\tfrom: $from,\n\tto: $to,\n\tpanes: $panes,\n\tpanesRecommended: $panesRecommended,\n\tnavigation: [${navigation.map((n) => n.name).join(", ")}],\n\tfullScreenDialogRecommended: $fullScreenDialogRecommended,\n\tspacing: $spacing\n)"; } class LayoutFeature { diff --git a/lib/services/services.dart b/lib/services/services.dart new file mode 100644 index 0000000..2cce01e --- /dev/null +++ b/lib/services/services.dart @@ -0,0 +1,12 @@ +export 'chat.dart'; +export 'chat_database/chat_database.dart' show ChatDatabase, chatDb; +export 'clients.dart'; +export 'curves.dart'; +export 'error.dart'; +export 'haptic.dart'; +export 'host.dart'; +export 'markdown.dart'; +export 'model.dart'; +export 'preferences.dart'; +export 'responsive.dart'; +export 'theme.dart'; diff --git a/lib/services/theme.dart b/lib/services/theme.dart index a458667..94db221 100644 --- a/lib/services/theme.dart +++ b/lib/services/theme.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../l10n/gen/app_localizations.dart'; @@ -23,24 +24,32 @@ class ThemeBuilderData { } ThemeData themeModifier(BuildContext context, ThemeData theme) { - var isMobile = Display.from(context).isMobile; + final floatingSnackbar = Breakpoint.of(context) <= Breakpoint.medium; return theme.copyWith( pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: PredictiveBackPageTransitionsBuilder(), + builders: { + TargetPlatform.android: FadeForwardsPageTransitionsBuilder(), + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + TargetPlatform.macOS: CupertinoPageTransitionsBuilder(), + TargetPlatform.windows: FadeForwardsPageTransitionsBuilder(), + TargetPlatform.linux: FadeForwardsPageTransitionsBuilder(), }, ), sliderTheme: theme.sliderTheme.copyWith(year2023: false), progressIndicatorTheme: theme.progressIndicatorTheme.copyWith( year2023: false, ), + dividerTheme: theme.dividerTheme.copyWith( + color: theme.colorScheme.outline, + ), snackBarTheme: theme.snackBarTheme.copyWith( - behavior: isMobile ? null : SnackBarBehavior.floating, - width: isMobile ? null : 288, + behavior: SnackBarBehavior.floating, + width: floatingSnackbar ? null : 288, ), listTileTheme: theme.listTileTheme.copyWith( contentPadding: const EdgeInsets.symmetric(horizontal: 16), ), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); } @@ -48,10 +57,16 @@ class ThemeBuilderData { if (Preferences.instance.themeSystem && dynamicLight != null) { return ThemeData.from(colorScheme: dynamicLight!); } else { + final colorScheme = ColorScheme.fromSeed( + seedColor: Colors.black, + dynamicSchemeVariant: DynamicSchemeVariant.content, + ); return ThemeData.from( - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.black, - dynamicSchemeVariant: DynamicSchemeVariant.content, + colorScheme: colorScheme.copyWith( + surface: Colors.white, + onPrimaryContainer: colorScheme.onPrimary, + onSecondaryContainer: colorScheme.onSurface, + onTertiaryContainer: colorScheme.onTertiary, ), ); } @@ -61,12 +76,18 @@ class ThemeBuilderData { if (Preferences.instance.themeSystem && dynamicDark != null) { return ThemeData.from(colorScheme: dynamicDark!); } else { + final colorScheme = ColorScheme.fromSeed( + seedColor: Colors.white, + dynamicSchemeVariant: DynamicSchemeVariant.content, + brightness: Brightness.dark, + ); return ThemeData.from( - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.white, - dynamicSchemeVariant: DynamicSchemeVariant.content, - brightness: Brightness.dark, - ).copyWith(surface: Colors.black), + colorScheme: colorScheme.copyWith( + surface: Colors.black, + onPrimaryContainer: colorScheme.onPrimary, + onSecondaryContainer: colorScheme.onSurface, + onTertiaryContainer: colorScheme.onTertiary, + ), ).copyWith(dividerColor: Colors.white30); } } @@ -86,7 +107,9 @@ class _ThemeBuilderState extends State { @override void initState() { super.initState(); - Preferences.instance.addListener(onChange); + WidgetsBinding.instance.addPostFrameCallback( + (_) => Preferences.instance.addListener(onChange), + ); } @override diff --git a/lib/util/extensions.dart b/lib/util/extensions.dart new file mode 100644 index 0000000..be4d43a --- /dev/null +++ b/lib/util/extensions.dart @@ -0,0 +1,26 @@ +extension StringExtension on String { + String toTitleCase() { + if (isEmpty) return this; + return split(" ") + .map( + (word) => word.isEmpty + ? word + : "${word[0].toUpperCase()}${word.substring(1)}", + ) + .join(" "); + } + + String emptyOn(String other) => (this == other) ? "" : this; +} + +extension IterableExtension on Iterable { + Iterable joinElements(T separator) { + if (length <= 1) return this; + final result = []; + for (var i = 0; i < length; i++) { + result.add(elementAt(i)); + if (i < length - 1) result.add(separator); + } + return result; + } +} diff --git a/lib/widgets/alert_dialog_child.dart b/lib/widgets/alert_dialog_child.dart new file mode 100644 index 0000000..61ca40d --- /dev/null +++ b/lib/widgets/alert_dialog_child.dart @@ -0,0 +1,344 @@ +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +/// A widget that implements the Material Design alert dialog layout structure. +/// +/// The handling is identical to [AlertDialog], but instead of returning a +/// [Dialog], it returns a [Widget] that can be used as a child of a [Dialog]: +/// +/// ```dart +/// Dialog( +/// semanticsRole: SemanticsRole.alertDialog, +/// child: AlertDialogChild(...), +/// ); +/// ``` +/// +/// The code above would be equivalent to using [AlertDialog] directly. +/// Dialog-level properties ([backgroundColor], [elevation], [shadowColor], +/// [surfaceTintColor], [insetPadding], [clipBehavior], [shape], [alignment], +/// [constraints]) are not accepted by this widget and must be passed directly +/// to the [Dialog] wrapper instead. +class AlertDialogChild extends StatelessWidget { + const AlertDialogChild({ + super.key, + this.icon, + this.iconPadding, + this.iconColor, + this.title, + this.titlePadding, + this.titleTextStyle, + this.content, + this.contentPadding, + this.contentTextStyle, + this.actions, + this.actionsPadding, + this.actionsAlignment, + this.actionsOverflowAlignment, + this.actionsOverflowDirection, + this.actionsOverflowButtonSpacing, + this.buttonPadding, + this.semanticLabel, + this.scrollable = false, + }); + + final Widget? icon; + final Color? iconColor; + final EdgeInsetsGeometry? iconPadding; + final Widget? title; + final EdgeInsetsGeometry? titlePadding; + final TextStyle? titleTextStyle; + final Widget? content; + final EdgeInsetsGeometry? contentPadding; + final TextStyle? contentTextStyle; + final List? actions; + final EdgeInsetsGeometry? actionsPadding; + final MainAxisAlignment? actionsAlignment; + final OverflowBarAlignment? actionsOverflowAlignment; + final VerticalDirection? actionsOverflowDirection; + final double? actionsOverflowButtonSpacing; + final EdgeInsetsGeometry? buttonPadding; + final String? semanticLabel; + final bool scrollable; + + @override + Widget build(BuildContext context) { + assert( + debugCheckHasMaterialLocalizations(context), + "No MaterialLocalizations found.", + ); + final theme = Theme.of(context); + + final dialogTheme = DialogTheme.of(context); + final defaults = theme.useMaterial3 + ? _DialogDefaultsM3(context) + : _DialogDefaultsM2(context); + + final label = switch (defaultTargetPlatform) { + TargetPlatform.iOS || TargetPlatform.macOS => semanticLabel, + TargetPlatform.android || + TargetPlatform.fuchsia || + TargetPlatform.linux || + TargetPlatform.windows => + semanticLabel ?? MaterialLocalizations.of(context).alertDialogLabel, + }; + + // The paddingScaleFactor is used to adjust the padding of Dialog's + // children. + const fontSizeToScale = 14.0; + final effectiveTextScale = + MediaQuery.textScalerOf(context).scale(fontSizeToScale) / + fontSizeToScale; + final paddingScaleFactor = _scalePadding(effectiveTextScale); + final textDirection = Directionality.maybeOf(context); + + Widget? iconWidget; + Widget? titleWidget; + Widget? contentWidget; + Widget? actionsWidget; + + if (icon != null) { + final belowIsTitle = title != null; + final belowIsContent = !belowIsTitle && content != null; + final defaultIconPadding = EdgeInsets.only( + left: 24.0, + top: 24.0, + right: 24.0, + bottom: belowIsTitle + ? 16.0 + : belowIsContent + ? 0.0 + : 24.0, + ); + final effectiveIconPadding = + iconPadding?.resolve(textDirection) ?? defaultIconPadding; + iconWidget = Padding( + padding: EdgeInsets.only( + left: effectiveIconPadding.left * paddingScaleFactor, + right: effectiveIconPadding.right * paddingScaleFactor, + top: effectiveIconPadding.top * paddingScaleFactor, + bottom: effectiveIconPadding.bottom, + ), + child: IconTheme( + data: IconThemeData( + color: iconColor ?? dialogTheme.iconColor ?? defaults.iconColor, + ), + child: icon!, + ), + ); + } + + if (title != null) { + final defaultTitlePadding = EdgeInsets.only( + left: 24.0, + top: icon == null ? 24.0 : 0.0, + right: 24.0, + bottom: content == null ? 20.0 : 0.0, + ); + final effectiveTitlePadding = + titlePadding?.resolve(textDirection) ?? defaultTitlePadding; + titleWidget = Padding( + padding: EdgeInsets.only( + left: effectiveTitlePadding.left * paddingScaleFactor, + right: effectiveTitlePadding.right * paddingScaleFactor, + top: icon == null + ? effectiveTitlePadding.top * paddingScaleFactor + : effectiveTitlePadding.top, + bottom: effectiveTitlePadding.bottom, + ), + child: DefaultTextStyle( + style: + titleTextStyle ?? + dialogTheme.titleTextStyle ?? + defaults.titleTextStyle!, + textAlign: icon == null ? TextAlign.start : TextAlign.center, + child: Semantics( + // For iOS platform, the focus always lands on the title. + // Set nameRoute to false to avoid title being announce twice. + namesRoute: + label == null && defaultTargetPlatform != TargetPlatform.iOS, + container: true, + child: title, + ), + ), + ); + } + + if (content != null) { + final defaultContentPadding = EdgeInsets.only( + left: 24.0, + top: theme.useMaterial3 ? 16.0 : 20.0, + right: 24.0, + bottom: 24.0, + ); + final effectiveContentPadding = + contentPadding?.resolve(textDirection) ?? defaultContentPadding; + contentWidget = Padding( + padding: EdgeInsets.only( + left: effectiveContentPadding.left * paddingScaleFactor, + right: effectiveContentPadding.right * paddingScaleFactor, + top: title == null && icon == null + ? effectiveContentPadding.top * paddingScaleFactor + : effectiveContentPadding.top, + bottom: effectiveContentPadding.bottom, + ), + child: DefaultTextStyle( + style: + contentTextStyle ?? + dialogTheme.contentTextStyle ?? + defaults.contentTextStyle!, + child: Semantics( + container: true, + explicitChildNodes: true, + child: content, + ), + ), + ); + } + + if (actions != null) { + final spacing = (buttonPadding?.horizontal ?? 16) / 2; + actionsWidget = Padding( + padding: + actionsPadding ?? + dialogTheme.actionsPadding ?? + (theme.useMaterial3 + ? defaults.actionsPadding! + : defaults.actionsPadding!.add(EdgeInsets.all(spacing))), + child: OverflowBar( + alignment: actionsAlignment ?? MainAxisAlignment.end, + spacing: spacing, + overflowAlignment: + actionsOverflowAlignment ?? OverflowBarAlignment.end, + overflowDirection: actionsOverflowDirection ?? VerticalDirection.down, + overflowSpacing: actionsOverflowButtonSpacing ?? 0, + children: actions!, + ), + ); + } + + List columnChildren; + if (scrollable) { + columnChildren = [ + if (title != null || content != null) + Flexible( + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [?iconWidget, ?titleWidget, ?contentWidget], + ), + ), + ), + ?actionsWidget, + ]; + } else { + columnChildren = [ + ?iconWidget, + ?titleWidget, + if (contentWidget != null) Flexible(child: contentWidget), + ?actionsWidget, + ]; + } + + Widget dialogChild = IntrinsicWidth( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: columnChildren, + ), + ); + + if (label != null) { + dialogChild = Semantics( + scopesRoute: true, + explicitChildNodes: true, + namesRoute: true, + label: label, + child: dialogChild, + ); + } + + return dialogChild; + } +} + +class _DialogDefaultsM2 extends DialogThemeData { + _DialogDefaultsM2(this.context) + : super( + alignment: Alignment.center, + elevation: 24.0, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(4.0)), + ), + clipBehavior: Clip.none, + ); + + final BuildContext context; + late final ThemeData theme = Theme.of(context); + late final TextTheme textTheme = theme.textTheme; + late final IconThemeData iconTheme = theme.iconTheme; + + @override + Color? get iconColor => iconTheme.color; + + @override + Color? get backgroundColor => + theme.brightness == Brightness.dark ? Colors.grey[800]! : Colors.white; + + @override + Color? get shadowColor => theme.shadowColor; + + @override + TextStyle? get titleTextStyle => textTheme.titleLarge; + + @override + TextStyle? get contentTextStyle => textTheme.titleMedium; + + @override + EdgeInsetsGeometry? get actionsPadding => EdgeInsets.zero; +} + +class _DialogDefaultsM3 extends DialogThemeData { + _DialogDefaultsM3(this.context) + : super( + alignment: Alignment.center, + elevation: 6.0, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(28.0)), + ), + clipBehavior: Clip.none, + ); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + late final TextTheme _textTheme = Theme.of(context).textTheme; + + @override + Color? get iconColor => _colors.secondary; + + @override + Color? get backgroundColor => _colors.surfaceContainerHigh; + + @override + Color? get shadowColor => Colors.transparent; + + @override + Color? get surfaceTintColor => Colors.transparent; + + @override + TextStyle? get titleTextStyle => _textTheme.headlineSmall; + + @override + TextStyle? get contentTextStyle => _textTheme.bodyMedium; + + @override + EdgeInsetsGeometry? get actionsPadding => + const EdgeInsets.only(left: 24.0, right: 24.0, bottom: 24.0); +} + +double _scalePadding(double textScaleFactor) { + final clampedTextScaleFactor = clampDouble(textScaleFactor, 1.0, 2.0); + return lerpDouble(1.0, 1.0 / 3.0, clampedTextScaleFactor - 1.0)!; +} diff --git a/lib/widgets/alpha_beta.dart b/lib/widgets/alpha_beta.dart new file mode 100644 index 0000000..884415a --- /dev/null +++ b/lib/widgets/alpha_beta.dart @@ -0,0 +1,107 @@ +import 'package:flutter/material.dart'; + +import '../l10n/gen/app_localizations.dart'; + +class AlphaBadge extends StatelessWidget { + const AlphaBadge({super.key}); + + @override + Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); + final textTheme = TextTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + return Container( + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: colorScheme.errorContainer, + shape: const StadiumBorder(), + ), + padding: const EdgeInsets.symmetric(horizontal: 4), + alignment: Alignment.center, + child: Text( + appLocalizations.settingsExperimentalAlpha, + style: textTheme.labelSmall!.copyWith( + color: colorScheme.onErrorContainer, + ), + textAlign: TextAlign.center, + softWrap: false, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ); + } +} + +class Alpha extends StatelessWidget { + final Widget child; + final bool showBadge; + const Alpha({super.key, required this.child, this.showBadge = true}); + + @override + Widget build(BuildContext context) => Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible(child: child), + if (showBadge) ...[ + const SizedBox(width: 2), + Transform.translate( + offset: const Offset(0, -4), + child: const AlphaBadge(), + ), + ], + ], + ); +} + +class BetaBadge extends StatelessWidget { + const BetaBadge({super.key}); + + @override + Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); + final textTheme = TextTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + return Container( + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: colorScheme.primaryContainer, + shape: const StadiumBorder(), + ), + padding: const EdgeInsets.symmetric(horizontal: 4), + alignment: Alignment.center, + child: Text( + appLocalizations.settingsExperimentalBeta, + style: textTheme.labelSmall!.copyWith( + color: colorScheme.onPrimaryContainer, + ), + textAlign: TextAlign.center, + softWrap: false, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ); + } +} + +class Beta extends StatelessWidget { + final Widget child; + final bool showBadge; + const Beta({super.key, required this.child, this.showBadge = true}); + + @override + Widget build(BuildContext context) => Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible(child: child), + if (showBadge) ...[ + const SizedBox(width: 2), + Transform.translate( + offset: const Offset(0, -4), + child: const BetaBadge(), + ), + ], + ], + ); +} diff --git a/lib/widgets/child_size_notifier.dart b/lib/widgets/child_size_notifier.dart new file mode 100644 index 0000000..56f904d --- /dev/null +++ b/lib/widgets/child_size_notifier.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +class MeasureSize extends SingleChildRenderObjectWidget { + final void Function(Size size) onChange; + const MeasureSize({super.key, required this.onChange, required super.child}); + + @override + RenderObject createRenderObject(BuildContext context) => + MeasureSizeRenderObject(onChange); + + @override + void updateRenderObject( + BuildContext context, + MeasureSizeRenderObject renderObject, + ) => renderObject.onChange = onChange; +} + +class MeasureSizeRenderObject extends RenderProxyBox { + ValueChanged onChange; + Size? _oldSize; + + MeasureSizeRenderObject(this.onChange); + + @override + void performLayout() { + super.performLayout(); + final newSize = child?.size ?? Size.zero; + + if (_oldSize != newSize) { + _oldSize = newSize; + WidgetsBinding.instance.addPostFrameCallback((_) => onChange(newSize)); + } + } +} diff --git a/lib/widgets/hero_text_flight_shuttle_builder.dart b/lib/widgets/hero_text_flight_shuttle_builder.dart index 2277a7f..5d1c376 100644 --- a/lib/widgets/hero_text_flight_shuttle_builder.dart +++ b/lib/widgets/hero_text_flight_shuttle_builder.dart @@ -22,13 +22,13 @@ Widget heroTextFlightShuttleBuilder( (begin, end) = (end, begin); } - var styleTween = TextStyleTween(begin: begin, end: end); - var textString = fromText.data ?? toText.data ?? ""; + final styleTween = TextStyleTween(begin: begin, end: end); + final textString = fromText.data ?? toText.data ?? ""; return AnimatedBuilder( animation: animation, builder: (context, child) { - var currentStyle = styleTween.lerp(animation.value); + final currentStyle = styleTween.lerp(animation.value); return Material( type: MaterialType.transparency, child: Center( diff --git a/lib/widgets/list_tile_slide.dart b/lib/widgets/list_tile_slide.dart index 54e9bbf..f254db3 100644 --- a/lib/widgets/list_tile_slide.dart +++ b/lib/widgets/list_tile_slide.dart @@ -62,7 +62,7 @@ class ListTileSlide extends StatelessWidget { @override Widget build(BuildContext context) { - var content = Column( + final content = Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -87,9 +87,9 @@ class ListTileSlide extends StatelessWidget { ], ); - var theme = Theme.of(context); - var switchTheme = SliderTheme.of(context); - var effectiveActiveColor = + final theme = Theme.of(context); + final switchTheme = SliderTheme.of(context); + final effectiveActiveColor = thumbColor ?? switchTheme.thumbColor ?? theme.colorScheme.secondary; return MergeSemantics( diff --git a/lib/widgets/list_tile_switch.dart b/lib/widgets/list_tile_switch.dart index 457e8cb..c0b0e8c 100644 --- a/lib/widgets/list_tile_switch.dart +++ b/lib/widgets/list_tile_switch.dart @@ -85,13 +85,13 @@ class ListTileSwitchInteractive extends StatelessWidget { @override Widget build(BuildContext context) { - var listTileTheme = ListTileTheme.of(context); - var effectiveControlAffinity = + final listTileTheme = ListTileTheme.of(context); + final effectiveControlAffinity = controlAffinity ?? listTileTheme.controlAffinity ?? ListTileControlAffinity.platform; - var controlChildren = [ + final controlChildren = [ const SizedBox(height: 32, child: VerticalDivider()), const SizedBox(width: 8), Switch( @@ -126,7 +126,7 @@ class ListTileSwitchInteractive extends StatelessWidget { overlayColor: overlayColor, ), ]; - var control = ExcludeFocus( + final control = ExcludeFocus( child: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, @@ -144,15 +144,15 @@ class ListTileSwitchInteractive extends StatelessWidget { ListTileControlAffinity.platform => (secondary, control), }; - var theme = Theme.of(context); - var switchTheme = SwitchTheme.of(context); - var states = {if (selected) WidgetState.selected}; - var effectiveActiveColor = + final theme = Theme.of(context); + final switchTheme = SwitchTheme.of(context); + final states = {if (selected) WidgetState.selected}; + final effectiveActiveColor = activeThumbColor ?? switchTheme.thumbColor?.resolve(states) ?? theme.colorScheme.secondary; - var effectiveContentPadding = + final effectiveContentPadding = contentPadding ?? EdgeInsets.only( left: effectiveControlAffinity == ListTileControlAffinity.leading @@ -273,13 +273,13 @@ class ListTileSwitch extends StatelessWidget { @override Widget build(BuildContext context) { - var listTileTheme = ListTileTheme.of(context); - var effectiveControlAffinity = + final listTileTheme = ListTileTheme.of(context); + final effectiveControlAffinity = controlAffinity ?? listTileTheme.controlAffinity ?? ListTileControlAffinity.platform; - var control = ExcludeFocus( + final control = ExcludeFocus( child: IgnorePointer( child: Switch( value: value, @@ -316,15 +316,15 @@ class ListTileSwitch extends StatelessWidget { ListTileControlAffinity.platform => (secondary, control), }; - var theme = Theme.of(context); - var switchTheme = SwitchTheme.of(context); - var states = {if (selected) WidgetState.selected}; - var effectiveActiveColor = + final theme = Theme.of(context); + final switchTheme = SwitchTheme.of(context); + final states = {if (selected) WidgetState.selected}; + final effectiveActiveColor = activeThumbColor ?? switchTheme.thumbColor?.resolve(states) ?? theme.colorScheme.secondary; - var effectiveContentPadding = + final effectiveContentPadding = contentPadding ?? EdgeInsets.only( left: effectiveControlAffinity == ListTileControlAffinity.leading diff --git a/lib/widgets/model_adder.dart b/lib/widgets/model_adder.dart new file mode 100644 index 0000000..5f3fbdf --- /dev/null +++ b/lib/widgets/model_adder.dart @@ -0,0 +1,551 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:ollama_dart/ollama_dart.dart' as ollama; +import 'package:url_launcher/url_launcher.dart'; + +import '../l10n/gen/app_localizations.dart'; +import '../services/services.dart'; +import 'alert_dialog_child.dart'; + +final modelTagRegex = RegExp( + r"^((?:(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*|\[(?:[a-fA-F0-9:]+)\])(?::[0-9]+)?/)?[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*)*)(?::([\w][\w.-]{0,127}))?$", +); + +Map> _downloadingModels = {}; +Map _downloadingModelsState = {}; + +class _DownloadingModelsState with ChangeNotifier { + double? progress; + int? total; + bool completedType; + + bool? pageState; + + bool cancelFlag; + bool cancelledType; + + bool errorNotFoundType; + bool errorNetworkType; + bool errorCorruptionType; + + void _notify() => notifyListeners(); + + _DownloadingModelsState() + : progress = null, + total = null, + completedType = false, + pageState = null, + cancelFlag = false, + cancelledType = false, + errorNotFoundType = false, + errorNetworkType = false, + errorCorruptionType = false; +} + +class ModelAdder extends StatefulWidget { + const ModelAdder({super.key}); + + @override + State createState() => _ModelAdderState(); +} + +class _ModelAdderState extends State { + bool? get _pageState => + modelName != null ? _downloadingModelsState[modelName]?.pageState : false; + set _pageState(bool? value) => modelName != null + ? _downloadingModelsState[modelName]!.pageState = value + : null; + bool _wantPop = false; + + final _controller = TextEditingController(); + final _focusNode = FocusNode(); + + String? Function() _errorText = () => null; + bool _errorIsCorruption = false; + + String? modelName; + + @override + void dispose() { + _controller.dispose(); + _focusNode.dispose(); + _downloadingModelsState.forEach( + (_, state) => state.removeListener(onUpdate), + ); + super.dispose(); + } + + Future _downloadModel([String? model]) async { + var modelName = model ?? _controller.text.trim(); + if (modelName.isEmpty) { + _focusNode.requestFocus(); + return; + } + if (!modelName.contains(":")) { + modelName = "$modelName:latest"; + } + + _errorText = () => null; + _errorIsCorruption = false; + if (mounted) setState(() {}); + + if (ModelManager.instance.models.any((model) => model.name == modelName)) { + _errorText = () => + AppLocalizations.of(context).modelDialogAddPromptAlreadyExists; + if (mounted) setState(() {}); + _focusNode.requestFocus(); + return; + } + + if (!modelTagRegex.hasMatch(modelName)) { + _errorText = () => + AppLocalizations.of(context).modelDialogAddPromptInvalid; + if (mounted) setState(() {}); + _focusNode.requestFocus(); + return; + } + + _pageState = null; + if (mounted) setState(() {}); + + try { + _downloadingModelsState + .putIfAbsent(modelName, _DownloadingModelsState.new) + .addListener(onUpdate); + this.modelName = modelName; + + var sub = _downloadingModels[modelName]; + sub ??= ollamaClient.models + .pullStream( + request: ollama.PullRequest(model: modelName, stream: true), + ) + .listen( + (event) { + final state = _downloadingModelsState[modelName]!; + if (state.cancelFlag) { + state + ..cancelledType = true + .._notify(); + this.modelName = null; + _downloadingModels.remove(modelName); + _downloadingModelsState.remove(modelName); + sub?.cancel(); + return; + } else if (event.status == "success") { + state + ..completedType = true + .._notify(); + this.modelName = null; + _downloadingModels.remove(modelName); + _downloadingModelsState.remove(modelName); + return; + } + if ((event.total ?? 0) == 0 && (event.progress ?? 0) == 0) return; + + _pageState = true; + if ((event.progress ?? -1) > (state.progress ?? -1)) { + state.progress = event.progress; + } + if ((event.total ?? -1) > (state.total ?? -1)) { + state.total = event.total; + } + + if (!_downloadingModels.containsKey(modelName)) { + _downloadingModels[modelName] = sub!; + } + state._notify(); + }, + onError: (Object error) { + final state = _downloadingModelsState[modelName]; + if (error is ollama.StreamException) { + if (error.message.contains("EOF")) { + state?.errorCorruptionType = true; + } else { + state?.errorNotFoundType = true; + } + } else { + state?.errorNetworkType = true; + } + state?._notify(); + this.modelName = null; + _downloadingModels.remove(modelName); + _downloadingModelsState.remove(modelName); + sub?.cancel(); + }, + ); + } catch (_) { + if (!mounted) return; + _downloadingModelsState[modelName] + ?..errorNetworkType = true + .._notify(); + _downloadingModels.remove(modelName); + _downloadingModelsState.remove(modelName); + if (mounted) { + setState(() {}); + _focusNode.requestFocus(); + } + } + } + + void onUpdate() { + final state = modelName != null ? _downloadingModelsState[modelName] : null; + if (state == null || !mounted) return; + if (state.completedType || state.cancelledType) { + final modelName = state.completedType ? this.modelName : null; + ModelManager.instance.loadModels().then((_) { + if (mounted) Navigator.of(context).pop(modelName); + }); + return; + } else if (state.errorNotFoundType || + state.errorNetworkType || + state.errorCorruptionType) { + _errorText = () { + if (state.errorNotFoundType) { + return AppLocalizations.of(context).modelDialogAddPromptNotFound; + } else if (state.errorNetworkType) { + return AppLocalizations.of(context).modelDialogAddPromptNetworkError; + } else if (state.errorCorruptionType) { + _errorIsCorruption = true; + return AppLocalizations.of( + context, + ).modelDialogAddPromptCorruptionError; + } + return null; + }; + if (mounted) setState(() {}); + _focusNode.requestFocus(); + } + setState(() {}); + } + + @override + Widget build(BuildContext context) { + final state = modelName != null ? _downloadingModelsState[modelName] : null; + + final colorScheme = ColorScheme.of(context); + final textTheme = TextTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final breakpoint = Breakpoint.of(context); + final embeddedNavigation = breakpoint.panesRecommended >= 2; + + final alignment = !embeddedNavigation + ? AlignmentDirectional.bottomCenter + : AlignmentDirectional.topStart; + const constraints = BoxConstraints(minWidth: 280, maxWidth: 360); + + final childInput = AlertDialogChild( + key: const ValueKey("input"), + title: Text(appLocalizations.modelDialogAddPromptTitle), + content: SizedBox( + width: 560, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(appLocalizations.modelDialogAddPromptDescription), + const SizedBox(height: 12), + TextField( + controller: _controller, + focusNode: _focusNode, + autofocus: true, + autocorrect: false, + enableSuggestions: false, + keyboardType: TextInputType.text, + textInputAction: TextInputAction.done, + maxLines: 1, + onSubmitted: (_) => _downloadModel(), + decoration: InputDecoration( + hintText: "gemma4:latest", + errorText: _errorText.call(), + errorMaxLines: 4, + ), + ), + + if (_errorIsCorruption) ...[ + ListTile( + contentPadding: EdgeInsets.zero, + minTileHeight: 0, + title: Text.rich( + TextSpan( + style: TextStyle(color: colorScheme.error), + children: [ + TextSpan(text: appLocalizations.learnMore), + const TextSpan(text: " "), + WidgetSpan( + child: Builder( + builder: (context) => Transform.translate( + offset: const Offset(0, -1), + child: Icon( + Icons.open_in_new, + size: DefaultTextStyle.of(context).style.fontSize, + color: colorScheme.error, + ), + ), + ), + ), + ], + ), + ), + onTap: () => launchUrl( + webOnlyWindowName: "_blank", + Uri.parse( + "https://github.com/ollama/ollama/issues/8088#issuecomment-2541889671", + ), + ), + ), + Text.rich( + TextSpan( + children: [ + TextSpan( + text: appLocalizations + .modelDialogAddPromptCorruptionErrorSolution + .split("\n") + .first, + ), + const TextSpan(text: "\n"), + TextSpan( + text: r"$ rm -f $OLLAMA_MODELS/blobs/sha256-*partial*", + style: textTheme.labelMedium?.copyWith( + fontFamily: "GoogleSansCode", + color: colorScheme.error, + ), + ), + const TextSpan(text: "\n"), + TextSpan( + text: appLocalizations + .modelDialogAddPromptCorruptionErrorSolution + .split("\n") + .last, + ), + ], + style: textTheme.labelMedium?.copyWith( + color: colorScheme.error, + ), + ), + ), + ], + + if (_downloadingModels.isNotEmpty) ...[ + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + child: Card.outlined( + margin: EdgeInsets.zero, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsetsDirectional.only( + top: 6, + start: 8, + ), + child: Text(appLocalizations.modelDialogAddCurrently), + ), + Padding( + padding: const EdgeInsetsDirectional.only( + top: 4, + bottom: 8, + start: 8, + end: 8, + ), + child: Wrap( + spacing: 4, + runSpacing: 4, + children: _downloadingModels.keys + .map( + (modelName) => ActionChip( + label: Text(modelName), + onPressed: () => _downloadModel(modelName), + ), + ) + .toList(), + ), + ), + ], + ), + ), + ), + ], + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(appLocalizations.modelDialogAddCancelConfirm), + ), + TextButton( + onPressed: _downloadModel, + child: Text(appLocalizations.modelDialogAdd), + ), + ], + ); + const childLoading = SizedBox( + key: ValueKey("loading"), + width: 560, + child: Padding( + padding: EdgeInsets.all(24), + child: LinearProgressIndicator(), + ), + ); + final childDownload = Builder( + builder: (context) { + final closeInput = [ + if (embeddedNavigation) const Divider(height: 1), + Padding( + padding: const EdgeInsetsDirectional.only( + top: 24, + bottom: 4, + start: 24, + end: 24, + ), + child: Text(appLocalizations.modelDialogAddCancelTitle), + ), + Padding( + padding: const EdgeInsetsDirectional.only( + bottom: 24, + start: 24, + end: 24, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FilledButton( + onPressed: () async => state!.cancelFlag = true, + style: FilledButton.styleFrom( + backgroundColor: colorScheme.error, + ), + child: Text(appLocalizations.modelDialogAddCancelConfirm), + ), + const SizedBox(width: 4), + OutlinedButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(appLocalizations.modelDialogAddCancelHide), + ), + ], + ), + ), + if (!embeddedNavigation) const Divider(height: 1), + ]; + return SizedBox( + key: const ValueKey("download"), + width: 560, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_wantPop && !embeddedNavigation) ...closeInput, + Padding( + padding: const EdgeInsets.all(24), + child: ListTile( + minTileHeight: 0, + minVerticalPadding: 0, + contentPadding: EdgeInsets.zero, + title: Builder( + builder: (context) => Text( + modelName ?? appLocalizations.noSelectedModel, + style: DefaultTextStyle.of( + context, + ).style.copyWith(fontFamily: "GoogleSansCode"), + ), + ), + subtitle: Builder( + builder: (context) => Wrap( + children: [ + Text( + NumberFormat.decimalPercentPattern( + locale: appLocalizations.localeName, + decimalDigits: 2, + ).format(state?.progress ?? 0), + style: DefaultTextStyle.of(context).style.copyWith( + fontFeatures: const [FontFeature.tabularFigures()], + ), + ), + Text(" " * 3), + const Text("/"), + Text(" " * 3), + Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Transform.translate( + offset: const Offset(0, -1), + child: Icon( + Icons.sd_storage_outlined, + size: DefaultTextStyle.of( + context, + ).style.fontSize, + ), + ), + ), + const TextSpan(text: " "), + TextSpan( + text: bytesToHumanReadable( + state?.total ?? 0, + locale: appLocalizations.localeName, + ), + ), + ], + ), + ), + ], + ), + ), + trailing: CircularProgressIndicator( + value: state?.progress ?? 0, + ), + ), + ), + if (_wantPop && embeddedNavigation) ...closeInput, + ], + ), + ); + }, + ); + + return PopScope( + canPop: _pageState == false, + onPopInvokedWithResult: (didPop, result) { + if (_pageState != true || _wantPop) return; + _wantPop = true; + if (mounted) setState(() {}); + }, + child: Dialog( + alignment: alignment, + constraints: constraints, + insetPadding: const EdgeInsets.all(12), // 24 + child: AnimatedSize( + duration: ExpressiveCurves.expressiveSpatial.normalDuration, + curve: ExpressiveCurves.expressiveSpatial.normal, + alignment: embeddedNavigation + ? AlignmentGeometry.topCenter + : AlignmentGeometry.bottomCenter, + child: AnimatedSwitcher( + duration: ExpressiveCurves.expressiveSpatial.normalDuration, + switchInCurve: ExpressiveCurves.expressiveSpatial.normal, + switchOutCurve: ExpressiveCurves.expressiveEffects.slow.flipped, + transitionBuilder: (child, animation) => SizeTransition( + sizeFactor: animation, + alignment: embeddedNavigation + ? AlignmentDirectional.bottomCenter + : AlignmentDirectional.topCenter, + child: FadeTransition(opacity: animation, child: child), + ), + child: _pageState == null + ? childLoading + : (_pageState! ? childDownload : childInput), + ), + ), + ), + ); + } +} + +Future showModelAdderDialog(BuildContext context) async => + showDialog( + context: context, + builder: (context) => const ModelAdder(), + ); diff --git a/lib/widgets/model_selector.dart b/lib/widgets/model_selector.dart new file mode 100644 index 0000000..bca490e --- /dev/null +++ b/lib/widgets/model_selector.dart @@ -0,0 +1,454 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:get_time_ago/get_time_ago.dart'; +import 'package:intl/intl.dart' as intl; + +import '../l10n/gen/app_localizations.dart'; +import '../services/services.dart'; +import '../util/extensions.dart'; +import 'model_adder.dart'; +import 'sized_circular_progress_indicator.dart'; +import 'two_state_widget.dart'; + +// MARK: Model Selector Dialog + +class _ModelSelectorDialog extends StatelessWidget { + final GlobalKey? anchorKey; + + const _ModelSelectorDialog({this.anchorKey}); + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + final embeddedNavigation = breakpoint.panesRecommended >= 2; + if (!embeddedNavigation) { + return const Dialog.fullscreen( + child: ModelSelector(embeddedNavigation: false), + ); + } + + var anchorRect = Rect.zero; + final renderBox = anchorKey?.currentContext?.findRenderObject(); + if (renderBox is RenderBox) { + anchorRect = renderBox.localToGlobal(Offset.zero) & renderBox.size; + } + + final screenSize = MediaQuery.sizeOf(context); + final isRtl = Directionality.of(context) == TextDirection.rtl; + const minWidth = 280.0; + const maxWidth = 560.0; + const edgeGap = 24.0; + + final anchorEdge = isRtl + ? screenSize.width - anchorRect.right + : anchorRect.left; + final position = anchorEdge + .clamp(0.0, max(0.0, screenSize.width - maxWidth)) + .toDouble(); + final effectiveMaxWidth = (screenSize.width - position - edgeGap).clamp( + minWidth, + maxWidth, + ); + final top = anchorRect.bottom - 24; + + final popup = ConstrainedBox( + constraints: BoxConstraints( + minWidth: minWidth, + maxWidth: effectiveMaxWidth, + maxHeight: screenSize.height - top - edgeGap, + ), + child: Material( + type: MaterialType.card, + elevation: 6, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + clipBehavior: Clip.antiAlias, + child: const ModelSelector(embeddedNavigation: true), + ), + ); + + return Stack( + children: [ + if (isRtl) + Positioned(right: position, top: top, child: popup) + else + Positioned(left: position, top: top, child: popup), + ], + ); + } +} + +Future showModelSelector({ + required BuildContext context, + required GlobalKey? anchorKey, +}) => showDialog( + context: context, + barrierDismissible: true, + barrierColor: Colors.transparent, + builder: (context) => _ModelSelectorDialog(anchorKey: anchorKey), +); + +// MARK: Model Selector + +class ModelSelector extends StatefulWidget { + final bool embeddedNavigation; + const ModelSelector({super.key, required this.embeddedNavigation}); + + @override + State createState() => _ModelSelectorState(); +} + +class _ModelSelectorState extends State { + @override + void initState() { + super.initState(); + ModelManager.instance.addListener(onUpdate); + } + + @override + void dispose() { + ModelManager.instance.removeListener(onUpdate); + super.dispose(); + } + + void onUpdate() { + if (mounted) setState(() {}); + } + + @override + Widget build(BuildContext context) { + final breakpoint = Breakpoint.of(context); + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ModelSelectorHeader(embeddedNavigation: widget.embeddedNavigation), + ...ModelManager.instance.models.map((model) { + final tmp = ModelSelectorTile( + model: model, + onTap: () { + ModelManager.instance.currentModel = model; + Navigator.of(context).pop(); + }, + ); + if (widget.embeddedNavigation) { + return tmp; + } else { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: breakpoint.spacing / 2, + ), + child: tmp, + ); + } + }), + ], + ), + ); + } +} + +class ModelSelectorHeader extends StatefulWidget { + final bool embeddedNavigation; + const ModelSelectorHeader({super.key, required this.embeddedNavigation}); + + @override + State createState() => _ModelSelectorHeaderState(); +} + +class _ModelSelectorHeaderState extends State { + bool _isLoading = false; + bool _loadingFromAdd = false; + + Future refreshModels() async { + if (_isLoading) return; + if (HostManager.instance.host == null) { + Navigator.of(context).pop(); + } + + _isLoading = true; + if (mounted) setState(() {}); + + if (mounted) { + await errorGuard(context, "N3AI17J1", () async { + try { + await Future.wait([ + ModelManager.instance.loadModels(), + Future.delayed(Durations.long1), + ]).catchError(Error.throwWithStackTrace); + } finally { + _isLoading = false; + _loadingFromAdd = false; + if (mounted) setState(() {}); + } + }); + } + } + + @override + Widget build(BuildContext context) { + final iconTheme = IconTheme.of(context); + final textTheme = TextTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final title = Text( + appLocalizations.modelDialogTitle, + style: widget.embeddedNavigation ? textTheme.titleMedium : null, + ); + final actions = [ + TwoStateWidgetManaged( + state: _isLoading && _loadingFromAdd, + dimension: (iconTheme.size ?? 24) + (8 * 2), + from: IconButton( + icon: const Icon(Icons.add), + tooltip: appLocalizations.modelDialogAdd, + onPressed: !_isLoading + ? () async { + final addedModel = await showModelAdderDialog(context); + if (addedModel != null) { + ModelManager.instance.currentModelName = addedModel; + if (!context.mounted) return; + Navigator.of(context).pop(); + + ScaffoldMessenger.of(context).clearSnackBars(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + appLocalizations.modelDialogAddDownloadSuccess, + ), + ), + ); + } + } + : null, + ), + to: const AspectRatio( + aspectRatio: 1 / 1, + child: SizedBox.expand( + child: Center( + child: SizedCircularProgressIndicator( + dimension: 24, + padding: EdgeInsets.zero, + ), + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.only( + end: widget.embeddedNavigation ? 0 : 8, + ), + child: TwoStateWidgetManaged( + state: _isLoading && !_loadingFromAdd, + dimension: (iconTheme.size ?? 24) + (8 * 2), + from: IconButton( + icon: const Icon(Icons.refresh), + tooltip: appLocalizations.modelDialogRefresh, + onPressed: !_isLoading ? refreshModels : null, + ), + to: const AspectRatio( + aspectRatio: 1 / 1, + child: SizedBox.expand( + child: Center( + child: SizedCircularProgressIndicator( + dimension: 24, + padding: EdgeInsets.zero, + ), + ), + ), + ), + ), + ), + ]; + + return widget.embeddedNavigation + ? Row(mainAxisAlignment: MainAxisAlignment.end, children: actions) + : AppBar( + leading: const AspectRatio( + aspectRatio: 1 / 1, + child: SizedBox.expand(child: BackButton()), + ), + title: title, + actions: actions, + ); + } +} + +class ModelSelectorTile extends StatelessWidget { + final Model model; + final VoidCallback? onTap; + + const ModelSelectorTile({ + super.key, + required this.model, + required this.onTap, + }); + + @override + Widget build(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + final iconTheme = IconTheme.of(context); + final appLocalizations = AppLocalizations.of(context); + + final Widget subtitle = Builder( + builder: (context) => Wrap( + children: [ + Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Transform.translate( + offset: const Offset(0, -1), + child: Icon( + Icons.functions, + size: DefaultTextStyle.of(context).style.fontSize, + ), + ), + ), + const TextSpan(text: " "), + TextSpan( + text: model.parameterSize.replaceAll( + ".", + intl.NumberFormat.decimalPattern( + appLocalizations.localeName, + ).symbols.DECIMAL_SEP, + ), + ), + ], + ), + ), + Text(" " * 3), + if ((model.families.isEmpty ? [model.family] : model.families) + .length != + 1 || + (model.families.isEmpty ? [model.family] : model.families) + .first != + model.name.split(":").first) ...[ + Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Transform.translate( + offset: const Offset(0, -1), + child: Icon( + Icons.group, + size: DefaultTextStyle.of(context).style.fontSize, + ), + ), + ), + const TextSpan(text: " "), + TextSpan( + children: + (model.families.isEmpty + ? [model.family] + : model.families) + .map((family) => TextSpan(text: family)) + .joinElements(const TextSpan(text: ", ")) + .toList(), + ), + ], + ), + ), + Text(" " * 3), + ], + Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Transform.translate( + offset: const Offset(0, -1), + child: Icon( + Icons.sd_storage_outlined, + size: DefaultTextStyle.of(context).style.fontSize, + ), + ), + ), + const TextSpan(text: " "), + TextSpan( + text: bytesToHumanReadable( + model.size, + locale: appLocalizations.localeName, + ), + ), + ], + ), + ), + Text(" " * 3), + Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Transform.translate( + offset: const Offset(0, -1), + child: Icon( + Icons.calendar_today, + size: DefaultTextStyle.of(context).style.fontSize, + ), + ), + ), + const TextSpan(text: " "), + TextSpan( + text: GetTimeAgo.parse( + model.modifiedAt, + locale: appLocalizations.localeName, + pattern: intl.DateFormat.yMd( + appLocalizations.localeName, + ).pattern, + ), + ), + ], + ), + ), + ], + ), + ); + + final tmp = ListTile( + title: Builder( + builder: (context) => Text.rich( + TextSpan(children: model.nameColored(context)), + style: DefaultTextStyle.of( + context, + ).style.copyWith(fontFamily: "GoogleSansCode"), + ), + ), + subtitle: subtitle, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: model.capabilities + .map( + (capability) => Padding( + padding: const EdgeInsetsDirectional.only(start: 2), + child: Tooltip( + message: capability.name.toTitleCase(), + child: Icon( + capability.icon, + size: (iconTheme.size ?? 24) - ((iconTheme.size ?? 24) / 3), + ), + ), + ), + ) + .toList(), + ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + onTap: onTap, + ); + + return AnimatedContainer( + duration: ExpressiveCurves.expressiveEffects.fastDuration, + curve: ExpressiveCurves.expressiveEffects.fast, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: ModelManager.instance.currentModel == model + ? Border.all(color: colorScheme.outline, width: 2) + : Border.all( + color: Theme.of( + context, + ).colorScheme.primary.withValues(alpha: 0), + width: 2, + ), + ), + child: tmp, + ); + } +} diff --git a/lib/widgets/sized_circular_progress_indicator.dart b/lib/widgets/sized_circular_progress_indicator.dart new file mode 100644 index 0000000..fb7fd2f --- /dev/null +++ b/lib/widgets/sized_circular_progress_indicator.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; + +class SizedCircularProgressIndicator extends StatelessWidget { + final double? dimension; + final double? value; + final Color? backgroundColor; + final Color? color; + final Animation? valueColor; + final String? semanticsLabel; + final String? semanticsValue; + final double? strokeWidth; + final double? strokeAlign; + final StrokeCap? strokeCap; + final BoxConstraints? constraints; + final double? trackGap; + + @Deprecated( + 'Set this flag to false to opt into the 2024 progress indicator appearance. Defaults to true. ' + 'In the future, this flag will default to false. Use ProgressIndicatorThemeData to customize individual properties. ' + 'This feature was deprecated after v3.27.0-0.2.pre.', + ) + final bool? year2023; + final EdgeInsetsGeometry? padding; + final AnimationController? controller; + + const SizedCircularProgressIndicator({ + super.key, + this.value, + this.dimension, + this.backgroundColor, + this.color, + this.valueColor, + this.strokeWidth, + this.strokeAlign, + this.semanticsLabel, + this.semanticsValue, + this.strokeCap, + this.constraints, + this.trackGap, + @Deprecated( + 'Set this flag to false to opt into the 2024 progress indicator appearance. Defaults to true. ' + 'In the future, this flag will default to false. Use ProgressIndicatorThemeData to customize individual properties. ' + 'This feature was deprecated after v3.27.0-0.1.pre.', + ) + this.year2023, + this.padding, + this.controller, + }); + + @override + Widget build(BuildContext context) { + final scale = (dimension ?? 40) / 40; + + final indicator = CircularProgressIndicator( + value: value, + backgroundColor: backgroundColor, + color: color, + valueColor: valueColor, + strokeWidth: (strokeWidth ?? 4) / scale, + strokeAlign: strokeAlign, + semanticsLabel: semanticsLabel, + semanticsValue: semanticsValue, + strokeCap: strokeCap, + constraints: constraints, + trackGap: trackGap, + // pipe through + // ignore: deprecated_member_use + year2023: year2023, + padding: padding, + controller: controller, + ); + if (scale == 1) return indicator; + + return Transform.scale(scale: scale, child: indicator); + } +} diff --git a/lib/widgets/two_state_widget.dart b/lib/widgets/two_state_widget.dart new file mode 100644 index 0000000..1479eca --- /dev/null +++ b/lib/widgets/two_state_widget.dart @@ -0,0 +1,128 @@ +import 'package:flutter/material.dart'; +import '../services/services.dart'; + +/// Widget used to blend between two widget states, like icons. +class TwoStateWidget extends StatelessWidget { + final Animation animation; + + final double? dimension; + + final Widget? from; + final Widget? to; + + const TwoStateWidget({ + super.key, + required this.animation, + this.dimension, + this.from, + this.to, + }); + + @override + Widget build(BuildContext context) { + final animationFrom = ReverseAnimation(animation); + final animationTo = animation; + + final children = [ + if (from != null) ScaleTransition(scale: animationFrom, child: from), + if (to != null) ScaleTransition(scale: animationTo, child: to), + ]; + final child = Stack( + children: children.map((child) { + if (dimension != null) return Positioned.fill(child: child); + return child; + }).toList(), + ); + + if (dimension != null) { + return ConstrainedBox( + constraints: BoxConstraints.tight(Size.square(dimension!)), + child: child, + ); + } + return child; + } +} + +class TwoStateWidgetManaged extends StatefulWidget { + final bool state; + + final double? dimension; + + final Widget? from; + final Widget? to; + + final Duration duration; + final Curve curve; + + TwoStateWidgetManaged({ + super.key, + required this.state, + this.dimension, + this.from, + this.to, + Duration? duration, + Curve? curve, + }) : duration = duration ?? ExpressiveCurves.expressiveSpatial.fastDuration, + curve = curve ?? ExpressiveCurves.expressiveSpatial.fast; + + @override + State createState() => _TwoStateWidgetManagedState(); +} + +class _TwoStateWidgetManagedState extends State + with SingleTickerProviderStateMixin { + late final AnimationController _animationController; + Animation? _animation; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, + value: widget.state ? 1.0 : 0.0, + duration: widget.duration, + ); + _animation = CurvedAnimation( + parent: _animationController, + curve: widget.curve, + ); + } + + @override + void didUpdateWidget(covariant TwoStateWidgetManaged oldWidget) { + super.didUpdateWidget(oldWidget); + + if (widget.duration != oldWidget.duration) { + _animationController.duration = widget.duration; + } + if (widget.curve != oldWidget.curve) { + _animation = CurvedAnimation( + parent: _animationController, + curve: widget.curve, + ); + } + + if (widget.state != oldWidget.state) { + if (widget.state) { + _animationController.forward(); + } else { + _animationController.reverse(); + } + } + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => TwoStateWidget( + animation: _animation!, + dimension: widget.dimension, + from: widget.from, + to: widget.to, + ); +} diff --git a/lib/worker/desktop.dart b/lib/worker/desktop.dart index 1148f7a..925a967 100644 --- a/lib/worker/desktop.dart +++ b/lib/worker/desktop.dart @@ -15,56 +15,81 @@ bool desktopFeature({bool web = false}) { } } -bool desktopLayout(BuildContext context, - {bool web = true, double? value, double valueCap = 1000}) { +bool desktopLayout( + BuildContext context, { + bool web = true, + double? value, + double valueCap = 1000, +}) { value ??= MediaQuery.of(context).size.width; return desktopFeature(web: web) || value >= valueCap; } -bool desktopLayoutRequired(BuildContext context, - {bool web = true, double? value, double valueCap = 1000}) { +bool desktopLayoutRequired( + BuildContext context, { + bool web = true, + double? value, + double valueCap = 1000, +}) { value ??= MediaQuery.of(context).size.width; return desktopFeature(web: web) && value >= valueCap; } -bool desktopLayoutNotRequired(BuildContext context, - {bool web = true, double? value, double valueCap = 1000}) { +bool desktopLayoutNotRequired( + BuildContext context, { + bool web = true, + double? value, + double valueCap = 1000, +}) { value ??= MediaQuery.of(context).size.width; return value >= valueCap; } Widget desktopControls(BuildContext context) { return SizedBox( - height: 200, - child: WindowTitleBarBox( - child: Row( + height: 200, + child: WindowTitleBarBox( + child: Row( children: [ SizedBox( - width: 46, - height: 200, - child: MinimizeWindowButton( - animate: true, - colors: WindowButtonColors( - iconNormal: Theme.of(context).colorScheme.primary))), + width: 46, + height: 200, + child: MinimizeWindowButton( + animate: true, + colors: WindowButtonColors( + iconNormal: Theme.of(context).colorScheme.primary, + ), + ), + ), SizedBox( - width: 46, - height: 72, - child: MaximizeWindowButton( - animate: true, - colors: WindowButtonColors( - iconNormal: Theme.of(context).colorScheme.primary))), + width: 46, + height: 72, + child: MaximizeWindowButton( + animate: true, + colors: WindowButtonColors( + iconNormal: Theme.of(context).colorScheme.primary, + ), + ), + ), SizedBox( - width: 46, - height: 72, - child: CloseWindowButton( - animate: true, - colors: WindowButtonColors( - iconNormal: Theme.of(context).colorScheme.primary))), + width: 46, + height: 72, + child: CloseWindowButton( + animate: true, + colors: WindowButtonColors( + iconNormal: Theme.of(context).colorScheme.primary, + ), + ), + ), ], - ))); + ), + ), + ); } -List? desktopControlsActions(BuildContext context, - [List? ifNotAvailable]) { +List? desktopControlsActions( + BuildContext context, [ + List? ifNotAvailable, +]) { return desktopFeature() ? [desktopControls(context)] : ifNotAvailable; } diff --git a/lib/worker/sender.dart b/lib/worker/sender.dart index c8cded5..e4c8df5 100644 --- a/lib/worker/sender.dart +++ b/lib/worker/sender.dart @@ -27,23 +27,26 @@ Future> getHistory([String? addToSystem]) async { system += "\n$addToSystem"; } - var history = (prefs!.getBool("useSystem") ?? true) + final history = (prefs!.getBool("useSystem") ?? true) ? [llama.Message(role: llama.MessageRole.system, content: system)] : []; - var history2 = []; + final history2 = []; images = []; for (var i = 0; i < messages.length; i++) { if (jsonDecode(jsonEncode(messages[i]))["text"] != null) { - history2.add(llama.Message( + history2.add( + llama.Message( role: (messages[i].author.id == user.id) ? llama.MessageRole.user : llama.MessageRole.system, content: jsonDecode(jsonEncode(messages[i]))["text"], - images: (images.isNotEmpty) ? images : null)); + images: (images.isNotEmpty) ? images : null, + ), + ); images = []; } else { var uri = jsonDecode(jsonEncode(messages[i]))["uri"] as String; - var content = (uri.startsWith("data:image/png;base64,")) + final content = (uri.startsWith("data:image/png;base64,")) ? uri.removePrefix("data:image/png;base64,") : base64.encode(await File(uri).readAsBytes()); uri = uri.removePrefix("data:image/png;base64,"); @@ -61,7 +64,8 @@ List getHistoryString([String? uuid]) { for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) { if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == uuid) { messages = jsonDecode( - jsonDecode((prefs!.getStringList("chats") ?? [])[i])["messages"]); + jsonDecode((prefs!.getStringList("chats") ?? [])[i])["messages"], + ); break; } } @@ -73,7 +77,7 @@ List getHistoryString([String? uuid]) { if (messages[i]["type"] == "image") { messages[i] = { "role": messages[i]["role"]!, - "content": "<${messages[i]["role"]} inserted an image>" + "content": "<${messages[i]["role"]} inserted an image>", }; } } @@ -82,28 +86,34 @@ List getHistoryString([String? uuid]) { } Future getTitleAi(List history) async { - var generated = await ollamaClient + final generated = await ollamaClient .generateChatCompletion( request: llama.GenerateChatCompletionRequest( - model: model!, - messages: [ - const llama.Message( - role: llama.MessageRole.system, - content: - "Generate a three to six word title for the conversation provided by the user. If an object or person is very important in the conversation, put it in the title as well; keep the focus on the main subject. You must not put the assistant in the focus and you must not put the word 'assistant' in the title! Do preferably use title case. Use a formal tone, don't use dramatic words, like 'mystery' Use spaces between words, do not use camel case! You must not use markdown or any other formatting language! You must not use emojis or any other symbols! You must not use general clauses like 'assistance', 'help' or 'session' in your title! \n\n~~User Introduces Themselves~~ -> User Introduction\n~~User Asks for Help with a Problem~~ -> Problem Help\n~~User has a _**big**_ Problem~~ -> Big Problem"), - llama.Message( - role: llama.MessageRole.user, - content: "```\n${jsonEncode(history)}\n```") - ], - keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")), + model: model!, + messages: [ + const llama.Message( + role: llama.MessageRole.system, + content: + "Generate a three to six word title for the conversation provided by the user. If an object or person is very important in the conversation, put it in the title as well; keep the focus on the main subject. You must not put the assistant in the focus and you must not put the word 'assistant' in the title! Do preferably use title case. Use a formal tone, don't use dramatic words, like 'mystery' Use spaces between words, do not use camel case! You must not use markdown or any other formatting language! You must not use emojis or any other symbols! You must not use general clauses like 'assistance', 'help' or 'session' in your title! \n\n~~User Introduces Themselves~~ -> User Introduction\n~~User Asks for Help with a Problem~~ -> Problem Help\n~~User has a _**big**_ Problem~~ -> Big Problem", + ), + llama.Message( + role: llama.MessageRole.user, + content: "```\n${jsonEncode(history)}\n```", + ), + ], + keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300"), + ), ) - .timeout(Duration( - seconds: - (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)).round())); + .timeout( + Duration( + seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) + .round(), + ), + ); var title = generated.message.content; title = title.replaceAll("\n", " "); - var terms = [ + final terms = [ '"', "'", "*", @@ -119,7 +129,7 @@ Future getTitleAi(List history) async { "[", "]", "{", - "}" + "}", ]; for (var i = 0; i < terms.length; i++) { title = title.replaceAll(terms[i], ""); @@ -138,12 +148,12 @@ Future getTitleAi(List history) async { Future setTitleAi(List history) async { try { - var title = await getTitleAi(history); - var tmp = prefs!.getStringList("chats") ?? []; + final title = await getTitleAi(history); + final tmp = prefs!.getStringList("chats") ?? []; for (var i = 0; i < tmp.length; i++) { if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == chatUuid) { - var tmp2 = jsonDecode(tmp[i]); + final tmp2 = jsonDecode(tmp[i]); tmp2["title"] = title; tmp[i] = jsonEncode(tmp2); break; @@ -153,18 +163,25 @@ Future setTitleAi(List history) async { } catch (_) {} } -Future send(String value, BuildContext context, Function setState, - {void Function(String currentText, bool done)? onStream, - String? addToSystem}) async { +Future send( + String value, + BuildContext context, + Function setState, { + void Function(String currentText, bool done)? onStream, + String? addToSystem, +}) async { selectionHaptic(); setState(() { sendable = false; }); if (host == null) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( content: Text(AppLocalizations.of(context).noHostSelected), - showCloseIcon: true)); + showCloseIcon: true, + ), + ); if (onStream != null) { onStream("", true); } @@ -173,9 +190,12 @@ Future send(String value, BuildContext context, Function setState, if (!chatAllowed || model == null) { if (model == null) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( content: Text(AppLocalizations.of(context).noModelSelected), - showCloseIcon: true)); + showCloseIcon: true, + ), + ); } if (onStream != null) { onStream("", true); @@ -188,26 +208,30 @@ Future send(String value, BuildContext context, Function setState, newChat = true; chatUuid = const Uuid().v4(); prefs!.setStringList( - "chats", - (prefs!.getStringList("chats") ?? []).append([ - jsonEncode({ - "title": AppLocalizations.of(context).newChatTitle, - "uuid": chatUuid, - "messages": [] - }) - ]).toList()); + "chats", + (prefs!.getStringList("chats") ?? []).append([ + jsonEncode({ + "title": AppLocalizations.of(context).newChatTitle, + "uuid": chatUuid, + "messages": [], + }), + ]).toList(), + ); } - var history = await getHistory(addToSystem); + final history = await getHistory(addToSystem); - history.add(llama.Message( + history.add( + llama.Message( role: llama.MessageRole.user, content: value.trim(), - images: (images.isNotEmpty) ? images : null)); + images: (images.isNotEmpty) ? images : null, + ), + ); messages.insert( - 0, - types.TextMessage( - author: user, id: const Uuid().v4(), text: value.trim())); + 0, + types.TextMessage(author: user, id: const Uuid().v4(), text: value.trim()), + ); saveChat(chatUuid!, setState); @@ -215,20 +239,24 @@ Future send(String value, BuildContext context, Function setState, chatAllowed = false; var text = ""; - var newId = const Uuid().v4(); + final newId = const Uuid().v4(); try { if ((prefs!.getString("requestType") ?? "stream") == "stream") { - var stream = ollamaClient + final stream = ollamaClient .generateChatCompletionStream( request: llama.GenerateChatCompletionRequest( - model: model!, - messages: history, - keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")), + model: model!, + messages: history, + keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300"), + ), ) - .timeout(Duration( + .timeout( + Duration( seconds: (30.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); await for (var res in stream) { text += res.message.content; @@ -240,7 +268,9 @@ Future send(String value, BuildContext context, Function setState, } if (chatAllowed) return ""; messages.insert( - 0, types.TextMessage(author: assistant, id: newId, text: text)); + 0, + types.TextMessage(author: assistant, id: newId, text: text), + ); //TODO: add functionality // // chatKey!.currentState!.scrollToMessage(messages[1].id, @@ -256,18 +286,26 @@ Future send(String value, BuildContext context, Function setState, request = await ollamaClient .generateChatCompletion( request: llama.GenerateChatCompletionRequest( - model: model!, - messages: history, - keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")), + model: model!, + messages: history, + keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300"), + ), ) - .timeout(Duration( + .timeout( + Duration( seconds: (30.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); if (chatAllowed) return ""; messages.insert( - 0, - types.TextMessage( - author: assistant, id: newId, text: request.message.content)); + 0, + types.TextMessage( + author: assistant, + id: newId, + text: request.message.content, + ), + ); text = request.message.content; setState(() {}); heavyHaptic(); @@ -283,7 +321,7 @@ Future send(String value, BuildContext context, Function setState, chatAllowed = true; messages.removeAt(0); if (messages.isEmpty) { - var tmp = prefs!.getStringList("chats") ?? []; + final tmp = prefs!.getStringList("chats") ?? []; for (var i = 0; i < tmp.length; i++) { if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == chatUuid) { @@ -296,11 +334,14 @@ Future send(String value, BuildContext context, Function setState, } }); // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar(SnackBar( + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( content: // ignore: use_build_context_synchronously Text(AppLocalizations.of(context).settingsHostInvalid("timeout")), - showCloseIcon: true)); + showCloseIcon: true, + ), + ); return ""; } //TODO: add functionality diff --git a/lib/worker/setter.dart b/lib/worker/setter.dart index b0b1fa4..2cf0472 100644 --- a/lib/worker/setter.dart +++ b/lib/worker/setter.dart @@ -18,9 +18,9 @@ import 'sender.dart'; import 'theme.dart'; void setModel(BuildContext context, Function setState) { - var models = []; - var modelsReal = []; - var modal = []; + final models = []; + final modelsReal = []; + final modal = []; var usedIndex = -1; var oldIndex = -1; var addIndex = -1; @@ -30,16 +30,22 @@ void setModel(BuildContext context, Function setState) { setState(() {}); Future load() async { try { - var list = await ollamaClient.listModels().timeout(Duration( - seconds: - (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)).round())); + final list = await ollamaClient.listModels().timeout( + Duration( + seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) + .round(), + ), + ); for (var i = 0; i < list.models!.length; i++) { - var details = await ollamaClient.showModelInfo( - request: llama.ModelInfoRequest(model: list.models![i].model!)); + final details = await ollamaClient.showModelInfo( + request: llama.ModelInfoRequest(model: list.models![i].model!), + ); models.add(list.models![i].model!.split(":")[0]); modelsReal.add(list.models![i].model!); - modal.add((list.models![i].details!.families ?? []).contains("clip") || - (details.capabilities ?? []).contains(llama.Capability.vision)); + modal.add( + (list.models![i].details!.families ?? []).contains("clip") || + (details.capabilities ?? []).contains(llama.Capability.vision), + ); } addIndex = models.length; @@ -54,7 +60,7 @@ void setModel(BuildContext context, Function setState) { } } if (prefs!.getBool("modelTags") == null) { - var duplicateFinder = []; + final duplicateFinder = []; for (var model in models) { if (duplicateFinder.contains(model)) { prefs!.setBool("modelTags", true); @@ -73,11 +79,15 @@ void setModel(BuildContext context, Function setState) { // ignore: use_build_context_synchronously Navigator.of(context).pop(); // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar(SnackBar( + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( content: Text( - // ignore: use_build_context_synchronously - AppLocalizations.of(context).settingsHostInvalid("timeout")), - showCloseIcon: true)); + // ignore: use_build_context_synchronously + AppLocalizations.of(context).settingsHostInvalid("timeout"), + ), + showCloseIcon: true, + ), + ); } } @@ -86,9 +96,10 @@ void setModel(BuildContext context, Function setState) { load(); - var content = StatefulBuilder(builder: (context, setLocalState) { - setModalState = setLocalState; - return PopScope( + final content = StatefulBuilder( + builder: (context, setLocalState) { + setModalState = setLocalState; + return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) async { if (!loaded) return; @@ -125,25 +136,35 @@ void setModel(BuildContext context, Function setState) { headers: { "Content-Type": "application/json", ...(jsonDecode(prefs!.getString("hostHeaders") ?? "{}") - as Map) + as Map), }.cast(), body: jsonEncode({ "model": model!, - "keep_alive": - int.parse(prefs!.getString("keepAlive") ?? "300") + "keep_alive": int.parse( + prefs!.getString("keepAlive") ?? "300", + ), }), ) - .timeout(Duration( - seconds: (10.0 * - (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .timeout( + Duration( + seconds: + (10.0 * + (prefs!.getDouble("timeoutMultiplier") ?? + 1.0)) + .round(), + ), + ); } catch (_) { // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar(SnackBar( + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( // ignore: use_build_context_synchronously - content: Text(AppLocalizations.of(context) - .settingsHostInvalid("timeout")), - showCloseIcon: true)); + content: Text( + AppLocalizations.of(context).settingsHostInvalid("timeout"), + ), + showCloseIcon: true, + ), + ); setState(() { model = null; chatAllowed = false; @@ -164,138 +185,149 @@ void setModel(BuildContext context, Function setState) { } }, child: Container( - width: desktopLayout(context) ? null : double.infinity, - padding: EdgeInsets.only( - left: 16, - right: 16, - top: 16, - bottom: desktopLayout(context) ? 16 : 0), - child: (!loaded) - ? SizedBox( - width: desktopLayout(context) ? 300 : double.infinity, - child: const LinearProgressIndicator()) - : Column(mainAxisSize: MainAxisSize.min, children: [ + width: desktopLayout(context) ? null : double.infinity, + padding: EdgeInsets.only( + left: 16, + right: 16, + top: 16, + bottom: desktopLayout(context) ? 16 : 0, + ), + child: (!loaded) + ? SizedBox( + width: desktopLayout(context) ? 300 : double.infinity, + child: const LinearProgressIndicator(), + ) + : Column( + mainAxisSize: MainAxisSize.min, + children: [ Container( - width: desktopLayout(context) ? 300 : double.infinity, - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context).size.height * 0.4), - child: SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Wrap( - spacing: desktopLayout(context) ? 10.0 : 5.0, - runSpacing: - desktopFeature(web: true) ? 10.0 : 0.0, - alignment: WrapAlignment.center, - children: List.generate( - models.length, - (int index) { - return ChoiceChip( - label: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(models[index]), - ((prefs!.getBool("modelTags") ?? - false) && - modelsReal[index] - .split(":") - .length > - 1) - ? Text( - ":${modelsReal[index].split(":")[1]}", - style: const TextStyle( - color: Colors.grey)) - : const SizedBox.shrink() - ]), - selected: usedIndex == index, - avatar: (usedIndex == index) - ? null - : (addIndex == index) - ? const Icon(Icons.add_rounded) - : ((recommendedModels - .contains(models[index])) - ? const Icon(Icons.star_rounded) - : ((modal[index]) - ? const Icon(Icons - .collections_rounded) - : null)), - checkmarkColor: (usedIndex == index && - !(prefs?.getBool( - "useDeviceTheme") ?? - false)) - ? ((MediaQuery.of(context) - .platformBrightness == - Brightness.light) - ? themeLight().colorScheme.secondary - : themeDark().colorScheme.secondary) - : null, - labelStyle: (usedIndex == index && - !(prefs?.getBool( - "useDeviceTheme") ?? - false)) - ? TextStyle( - color: (MediaQuery.of(context) - .platformBrightness == - Brightness.light) - ? themeLight() - .colorScheme - .secondary - : themeDark() - .colorScheme - .secondary) - : null, - selectedColor: (prefs - ?.getBool("useDeviceTheme") ?? - false) - ? null - : (MediaQuery.of(context) - .platformBrightness == - Brightness.light) - ? themeLight().colorScheme.primary - : themeDark().colorScheme.primary, - onSelected: (bool selected) { - selectionHaptic(); - if (addIndex == index) { - usedIndex = oldIndex; - Navigator.of(context).pop(); - addModel(context, setState); - } - if (!chatAllowed && model != null) { - return; - } - setLocalState(() { - usedIndex = selected ? index : -1; - }); - }, - ); - }, - ).toList(), - ))) - ]))); - }); + width: desktopLayout(context) ? 300 : double.infinity, + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.4, + ), + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Wrap( + spacing: desktopLayout(context) ? 10.0 : 5.0, + runSpacing: desktopFeature(web: true) ? 10.0 : 0.0, + alignment: WrapAlignment.center, + children: List.generate(models.length, ( + int index, + ) { + return ChoiceChip( + label: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(models[index]), + ((prefs!.getBool("modelTags") ?? false) && + modelsReal[index].split(":").length > + 1) + ? Text( + ":${modelsReal[index].split(":")[1]}", + style: const TextStyle( + color: Colors.grey, + ), + ) + : const SizedBox.shrink(), + ], + ), + selected: usedIndex == index, + avatar: (usedIndex == index) + ? null + : (addIndex == index) + ? const Icon(Icons.add_rounded) + : ((recommendedModels.contains(models[index])) + ? const Icon(Icons.star_rounded) + : ((modal[index]) + ? const Icon( + Icons.collections_rounded, + ) + : null)), + checkmarkColor: + (usedIndex == index && + !(prefs?.getBool("useDeviceTheme") ?? + false)) + ? ((MediaQuery.of( + context, + ).platformBrightness == + Brightness.light) + ? themeLight().colorScheme.secondary + : themeDark().colorScheme.secondary) + : null, + labelStyle: + (usedIndex == index && + !(prefs?.getBool("useDeviceTheme") ?? + false)) + ? TextStyle( + color: + (MediaQuery.of( + context, + ).platformBrightness == + Brightness.light) + ? themeLight().colorScheme.secondary + : themeDark().colorScheme.secondary, + ) + : null, + selectedColor: + (prefs?.getBool("useDeviceTheme") ?? false) + ? null + : (MediaQuery.of( + context, + ).platformBrightness == + Brightness.light) + ? themeLight().colorScheme.primary + : themeDark().colorScheme.primary, + onSelected: (bool selected) { + selectionHaptic(); + if (addIndex == index) { + usedIndex = oldIndex; + Navigator.of(context).pop(); + addModel(context, setState); + } + if (!chatAllowed && model != null) { + return; + } + setLocalState(() { + usedIndex = selected ? index : -1; + }); + }, + ); + }).toList(), + ), + ), + ), + ], + ), + ), + ); + }, + ); if (desktopLayoutNotRequired(context)) { showDialog( - context: context, - builder: (context) { - return Transform.translate( - offset: desktopLayoutRequired(context) - ? const Offset(289, 0) - : Offset.zero, - child: Dialog( - surfaceTintColor: - (Theme.of(context).brightness == Brightness.dark) - ? Colors.grey[800] - : null, - alignment: desktopLayoutRequired(context) - ? Alignment.topLeft - : Alignment.topCenter, - child: content), - ); - }); + context: context, + builder: (context) { + return Transform.translate( + offset: desktopLayoutRequired(context) + ? const Offset(289, 0) + : Offset.zero, + child: Dialog( + surfaceTintColor: (Theme.of(context).brightness == Brightness.dark) + ? Colors.grey[800] + : null, + alignment: desktopLayoutRequired(context) + ? Alignment.topLeft + : Alignment.topCenter, + child: content, + ), + ); + }, + ); } else { showModalBottomSheet( - context: context, builder: (context) => Container(child: content)); + context: context, + builder: (context) => Container(child: content), + ); } } @@ -304,19 +336,25 @@ Future addModel(BuildContext context, Function setState) async { var networkError = false; var ratelimitError = false; var alreadyExists = false; - var invalidText = AppLocalizations.of(context).modelDialogAddPromptInvalid; - var networkErrorText = - AppLocalizations.of(context).settingsHostInvalid("other"); - var timeoutErrorText = - AppLocalizations.of(context).settingsHostInvalid("timeout"); - var ratelimitErrorText = - AppLocalizations.of(context).settingsHostInvalid("ratelimit"); - var alreadyExistsText = - AppLocalizations.of(context).modelDialogAddPromptAlreadyExists; - var downloadSuccessText = - AppLocalizations.of(context).modelDialogAddDownloadSuccess; - var downloadFailedText = - AppLocalizations.of(context).modelDialogAddDownloadFailed; + final invalidText = AppLocalizations.of(context).modelDialogAddPromptInvalid; + final networkErrorText = AppLocalizations.of( + context, + ).settingsHostInvalid("other"); + final timeoutErrorText = AppLocalizations.of( + context, + ).settingsHostInvalid("timeout"); + final ratelimitErrorText = AppLocalizations.of( + context, + ).settingsHostInvalid("ratelimit"); + final alreadyExistsText = AppLocalizations.of( + context, + ).modelDialogAddPromptAlreadyExists; + final downloadSuccessText = AppLocalizations.of( + context, + ).modelDialogAddDownloadSuccess; + final downloadFailedText = AppLocalizations.of( + context, + ).modelDialogAddDownloadFailed; var requestedModel = await prompt( context, title: AppLocalizations.of(context).modelDialogAddPromptTitle, @@ -332,11 +370,14 @@ Future addModel(BuildContext context, Function setState) async { ratelimitError = false; alreadyExists = false; try { - var request = await ollamaClient.listModels().timeout(Duration( + final request = await ollamaClient.listModels().timeout( + Duration( seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); for (var element in request.models!) { - var localModel = element.model!.removeSuffix(":latest"); + final localModel = element.model!.removeSuffix(":latest"); if (localModel == model) { alreadyExists = true; } @@ -351,34 +392,44 @@ Future addModel(BuildContext context, Function setState) async { if (!(prefs!.getBool("allowWebProxy") ?? false)) { var returnValue = false; await showDialog( - context: mainContext!, - barrierDismissible: false, - builder: (context) { - return AlertDialog( - title: Text(AppLocalizations.of(context) - .modelDialogAddAllowanceTitle), - content: SizedBox( - width: 640, - child: Text(AppLocalizations.of(context) - .modelDialogAddAllowanceDescription), + context: mainContext!, + barrierDismissible: false, + builder: (context) { + return AlertDialog( + title: Text( + AppLocalizations.of(context).modelDialogAddAllowanceTitle, + ), + content: SizedBox( + width: 640, + child: Text( + AppLocalizations.of( + context, + ).modelDialogAddAllowanceDescription, + ), + ), + actions: [ + TextButton( + onPressed: () { + canceled = true; + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context).modelDialogAddAllowanceDeny, ), - actions: [ - TextButton( - onPressed: () { - canceled = true; - Navigator.of(context).pop(); - }, - child: Text(AppLocalizations.of(context) - .modelDialogAddAllowanceDeny)), - TextButton( - onPressed: () { - returnValue = true; - Navigator.of(context).pop(); - }, - child: Text(AppLocalizations.of(context) - .modelDialogAddAllowanceAllow)) - ]); - }); + ), + TextButton( + onPressed: () { + returnValue = true; + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context).modelDialogAddAllowanceAllow, + ), + ), + ], + ); + }, + ); if (!returnValue) return false; prefs!.setBool("allowWebProxy", true); } @@ -388,9 +439,12 @@ Future addModel(BuildContext context, Function setState) async { try { response = await httpClient .get(Uri.parse("$endpoint${Uri.encodeComponent(model)}")) - .timeout(Duration( + .timeout( + Duration( seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); } catch (_) { networkError = true; return false; @@ -398,34 +452,46 @@ Future addModel(BuildContext context, Function setState) async { if (response.statusCode == 200) { var returnValue = false; await showDialog( - context: mainContext!, - barrierDismissible: false, - builder: (context) { - return AlertDialog( - title: Text(AppLocalizations.of(context) - .modelDialogAddAssuranceTitle(model)), - content: SizedBox( - width: 640, - child: Text(AppLocalizations.of(context) - .modelDialogAddAssuranceDescription(model)), + context: mainContext!, + barrierDismissible: false, + builder: (context) { + return AlertDialog( + title: Text( + AppLocalizations.of( + context, + ).modelDialogAddAssuranceTitle(model), + ), + content: SizedBox( + width: 640, + child: Text( + AppLocalizations.of( + context, + ).modelDialogAddAssuranceDescription(model), + ), + ), + actions: [ + TextButton( + onPressed: () { + canceled = true; + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context).modelDialogAddAssuranceCancel, ), - actions: [ - TextButton( - onPressed: () { - canceled = true; - Navigator.of(context).pop(); - }, - child: Text(AppLocalizations.of(context) - .modelDialogAddAssuranceCancel)), - TextButton( - onPressed: () { - returnValue = true; - Navigator.of(context).pop(); - }, - child: Text(AppLocalizations.of(context) - .modelDialogAddAssuranceAdd)) - ]); - }); + ), + TextButton( + onPressed: () { + returnValue = true; + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context).modelDialogAddAssuranceAdd, + ), + ), + ], + ); + }, + ); return returnValue; } if (response.statusCode == 429) { @@ -446,45 +512,57 @@ Future addModel(BuildContext context, Function setState) async { double? percent; Function? setDialogState; showModalBottomSheet( - context: mainContext!, - builder: (context) { - return StatefulBuilder(builder: (context, setLocalState) { + context: mainContext!, + builder: (context) { + return StatefulBuilder( + builder: (context, setLocalState) { setDialogState = setLocalState; return PopScope( - canPop: false, - child: Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 16, - right: 16, - top: 16, - bottom: desktopLayout(context) ? 16 : 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - percent == null - ? AppLocalizations.of(context) - .modelDialogAddDownloadPercentLoading - : AppLocalizations.of(context) - .modelDialogAddDownloadPercent( - (percent * 100).round().toString()), - ), - const Padding(padding: EdgeInsets.only(top: 8)), - LinearProgressIndicator(value: percent), - ], - ))); - }); - }); + canPop: false, + child: Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 16, + right: 16, + top: 16, + bottom: desktopLayout(context) ? 16 : 0, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + percent == null + ? AppLocalizations.of( + context, + ).modelDialogAddDownloadPercentLoading + : AppLocalizations.of( + context, + ).modelDialogAddDownloadPercent( + (percent * 100).round().toString(), + ), + ), + const Padding(padding: EdgeInsets.only(top: 8)), + LinearProgressIndicator(value: percent), + ], + ), + ), + ); + }, + ); + }, + ); try { - var stream = ollamaClient + final stream = ollamaClient .pullModelStream(request: llama.PullModelRequest(model: requestedModel)) - .timeout(Duration( + .timeout( + Duration( seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); var alreadyProgressed = false; await for (var res in stream) { - var tmpPercent = + final tmpPercent = (res.completed ?? 0).toInt() / (res.total ?? 100).toInt(); if ((tmpPercent * 100).round() == 0) { if (!alreadyProgressed) { @@ -507,9 +585,12 @@ Future addModel(BuildContext context, Function setState) async { } var exists = false; try { - var request = await ollamaClient.listModels().timeout(Duration( - seconds: - (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)).round())); + final request = await ollamaClient.listModels().timeout( + Duration( + seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) + .round(), + ), + ); for (var element in request.models!) { if (element.model == model) { exists = true; @@ -530,10 +611,12 @@ Future addModel(BuildContext context, Function setState) async { Navigator.of(mainContext!).pop(); if (!exists) { ScaffoldMessenger.of(mainContext!).showSnackBar( - SnackBar(content: Text(downloadFailedText), showCloseIcon: true)); + SnackBar(content: Text(downloadFailedText), showCloseIcon: true), + ); } else { ScaffoldMessenger.of(mainContext!).showSnackBar( - SnackBar(content: Text(timeoutErrorText), showCloseIcon: true)); + SnackBar(content: Text(timeoutErrorText), showCloseIcon: true), + ); } return; } @@ -544,11 +627,13 @@ Future addModel(BuildContext context, Function setState) async { }); Navigator.of(mainContext!).pop(); ScaffoldMessenger.of(mainContext!).showSnackBar( - SnackBar(content: Text(downloadSuccessText), showCloseIcon: true)); + SnackBar(content: Text(downloadSuccessText), showCloseIcon: true), + ); } catch (_) { Navigator.of(mainContext!).pop(); ScaffoldMessenger.of(mainContext!).showSnackBar( - SnackBar(content: Text(downloadFailedText), showCloseIcon: true)); + SnackBar(content: Text(downloadFailedText), showCloseIcon: true), + ); } } @@ -565,11 +650,11 @@ Future saveChat(String uuid, Function setState) async { if ((jsonDecode(jsonEncode(messages[i])) as Map).containsKey("text")) { history.add({ "role": (messages[i].author == user) ? "user" : "assistant", - "content": jsonDecode(jsonEncode(messages[i]))["text"] + "content": jsonDecode(jsonEncode(messages[i]))["text"], }); } else { - var uri = jsonDecode(jsonEncode(messages[i]))["uri"] as String; - var content = (uri.startsWith("data:image/png;base64,")) + final uri = jsonDecode(jsonEncode(messages[i]))["uri"] as String; + final content = (uri.startsWith("data:image/png;base64,")) ? uri.removePrefix("data:image/png;base64,") : base64.encode(await File(uri).readAsBytes()); history.add({ @@ -577,7 +662,7 @@ Future saveChat(String uuid, Function setState) async { "type": "image", "name": (messages[i] as types.ImageMessage).name, "size": (messages[i] as types.ImageMessage).size.toString(), - "content": content + "content": content, }); } } @@ -585,24 +670,26 @@ Future saveChat(String uuid, Function setState) async { for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) { if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == chatUuid) { - var tmp = prefs!.getStringList("chats")!..removeAt(i); + final tmp = prefs!.getStringList("chats")!..removeAt(i); prefs!.setStringList("chats", tmp); chatUuid = null; return; } } } - if (jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"] - .length >= + if (jsonDecode( + (prefs!.getStringList("chats") ?? [])[index], + )["messages"].length >= 1) { - if (jsonDecode(jsonDecode((prefs!.getStringList("chats") ?? [])[index])[ - "messages"])[0]["role"] == + if (jsonDecode( + jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"], + )[0]["role"] == "system") { history.add({ "role": "system", - "content": jsonDecode(jsonDecode( - (prefs!.getStringList("chats") ?? [])[index])["messages"])[0] - ["content"] + "content": jsonDecode( + jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"], + )[0]["content"], }); } } else { @@ -614,17 +701,19 @@ Future saveChat(String uuid, Function setState) async { history.add({"role": "system", "content": system}); } history = history.reversed.toList(); - var tmp = prefs!.getStringList("chats") ?? [] + final tmp = prefs!.getStringList("chats") ?? [] ..removeAt(index) ..insert( - 0, - jsonEncode({ - "title": - jsonDecode((prefs!.getStringList("chats") ?? [])[index])["title"], - "uuid": uuid, - "model": model, - "messages": jsonEncode(history) - })); + 0, + jsonEncode({ + "title": jsonDecode( + (prefs!.getStringList("chats") ?? [])[index], + )["title"], + "uuid": uuid, + "model": model, + "messages": jsonEncode(history), + }), + ); prefs!.setStringList("chats", tmp); setState(() {}); } @@ -640,27 +729,32 @@ void loadChat(String uuid, Function setState) { messages = []; model = null; setState(() {}); - var history = jsonDecode( - jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"]); + final history = jsonDecode( + jsonDecode((prefs!.getStringList("chats") ?? [])[index])["messages"], + ); for (var i = 0; i < history.length; i++) { if (history[i]["role"] != "system") { if ((history[i] as Map).containsKey("type") && history[i]["type"] == "image") { messages.insert( - 0, - types.ImageMessage( - author: (history[i]["role"] == "user") ? user : assistant, - id: const Uuid().v4(), - name: history[i]["name"], - size: int.parse(history[i]["size"]), - uri: "data:image/png;base64,${history[i]["content"]}")); + 0, + types.ImageMessage( + author: (history[i]["role"] == "user") ? user : assistant, + id: const Uuid().v4(), + name: history[i]["name"], + size: int.parse(history[i]["size"]), + uri: "data:image/png;base64,${history[i]["content"]}", + ), + ); } else { messages.insert( - 0, - types.TextMessage( - author: (history[i]["role"] == "user") ? user : assistant, - id: const Uuid().v4(), - text: history[i]["content"])); + 0, + types.TextMessage( + author: (history[i]["role"] == "user") ? user : assistant, + id: const Uuid().v4(), + text: history[i]["content"], + ), + ); } } } @@ -668,32 +762,35 @@ void loadChat(String uuid, Function setState) { setState(() {}); } -Future prompt(BuildContext context, - {String description = "", - String value = "", - String title = "", - String? valueIfCanceled, - TextInputType keyboard = TextInputType.text, - bool autocorrect = true, - Iterable autofillHints = const [], - bool enableSuggestions = true, - Icon? prefixIcon, - int maxLines = 1, - String? uuid, - Future Function(String content)? validator, - String? validatorError, - String? Function(String content)? validatorErrorCallback, - String? placeholder, - bool prefill = true}) async { +Future prompt( + BuildContext context, { + String description = "", + String value = "", + String title = "", + String? valueIfCanceled, + TextInputType keyboard = TextInputType.text, + bool autocorrect = true, + Iterable autofillHints = const [], + bool enableSuggestions = true, + Icon? prefixIcon, + int maxLines = 1, + String? uuid, + Future Function(String content)? validator, + String? validatorError, + String? Function(String content)? validatorErrorCallback, + String? placeholder, + bool prefill = true, +}) async { var returnText = (valueIfCanceled != null) ? valueIfCanceled : value; - var controller = TextEditingController(text: prefill ? value : ""); + final controller = TextEditingController(text: prefill ? value : ""); var loading = false; String? error; await showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (context) { - return StatefulBuilder(builder: (context, setLocalState) { + context: context, + isScrollControlled: true, + builder: (context) { + return StatefulBuilder( + builder: (context, setLocalState) { Future submit() async { selectionHaptic(); if (validator != null) { @@ -701,7 +798,7 @@ Future prompt(BuildContext context, error = null; loading = true; }); - var valid = await validator(controller.text); + final valid = await validator(controller.text); setLocalState(() { loading = false; }); @@ -724,102 +821,116 @@ Future prompt(BuildContext context, } return PopScope( - child: Container( - padding: EdgeInsets.only( - left: 16, - right: 16, - top: 16, - bottom: desktopFeature(web: true) - ? 12 - : MediaQuery.of(context).viewInsets.bottom), - width: double.infinity, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - (title != "") - ? Text(title, - style: const TextStyle( - fontWeight: FontWeight.bold)) - : const SizedBox.shrink(), - (title != "") - ? const Divider() - : const SizedBox.shrink(), - (description != "") - ? Text(description) - : const SizedBox.shrink(), - const SizedBox(height: 8), - TextField( - controller: controller, - autofocus: true, - keyboardType: keyboard, - autocorrect: autocorrect, - autofillHints: autofillHints, - enableSuggestions: enableSuggestions, - maxLines: maxLines, - onSubmitted: (_) => submit(), - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintText: placeholder, - errorText: error, - suffixIcon: IconButton( - enableFeedback: false, - tooltip: AppLocalizations.of(context) - .tooltipSave, - onPressed: submit, - icon: const Icon(Icons.save_rounded)), - prefixIcon: (title == - AppLocalizations.of(context) - .dialogEnterNewTitle && - uuid != null) - ? IconButton( - enableFeedback: false, - tooltip: AppLocalizations.of(context) - .tooltipLetAIThink, - onPressed: () async { - selectionHaptic(); - setLocalState(() { - loading = true; - }); + child: Container( + padding: EdgeInsets.only( + left: 16, + right: 16, + top: 16, + bottom: desktopFeature(web: true) + ? 12 + : MediaQuery.of(context).viewInsets.bottom, + ), + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (title != "") + ? Text( + title, + style: const TextStyle(fontWeight: FontWeight.bold), + ) + : const SizedBox.shrink(), + (title != "") ? const Divider() : const SizedBox.shrink(), + (description != "") + ? Text(description) + : const SizedBox.shrink(), + const SizedBox(height: 8), + TextField( + controller: controller, + autofocus: true, + keyboardType: keyboard, + autocorrect: autocorrect, + autofillHints: autofillHints, + enableSuggestions: enableSuggestions, + maxLines: maxLines, + onSubmitted: (_) => submit(), + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintText: placeholder, + errorText: error, + suffixIcon: IconButton( + enableFeedback: false, + tooltip: AppLocalizations.of(context).tooltipSave, + onPressed: submit, + icon: const Icon(Icons.save_rounded), + ), + prefixIcon: + (title == + AppLocalizations.of( + context, + ).dialogEnterNewTitle && + uuid != null) + ? IconButton( + enableFeedback: false, + tooltip: AppLocalizations.of( + context, + ).tooltipLetAIThink, + onPressed: () async { + selectionHaptic(); + setLocalState(() { + loading = true; + }); - try { - var title = await getTitleAi( - getHistoryString(uuid)); - controller.text = title; - setLocalState(() { - loading = false; - }); - } catch (_) { - try { - setLocalState(() { - loading = false; - }); - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context) - .showSnackBar(SnackBar( - content: Text( - AppLocalizations.of( - // ignore: use_build_context_synchronously - context) - .settingsHostInvalid( - "timeout")), - showCloseIcon: true)); - } catch (_) {} - } - }, - icon: const Icon( - Icons.auto_awesome_rounded)) - : prefixIcon)), - SizedBox( - height: 3, - child: loading - ? const LinearProgressIndicator() - : const SizedBox.shrink()), - (MediaQuery.of(context).viewInsets.bottom != 0) - ? const SizedBox(height: 16) - : const SizedBox.shrink() - ]))); - }); - }); + try { + final title = await getTitleAi( + getHistoryString(uuid), + ); + controller.text = title; + setLocalState(() { + loading = false; + }); + } catch (_) { + try { + setLocalState(() { + loading = false; + }); + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of( + // ignore: use_build_context_synchronously + context, + ).settingsHostInvalid("timeout"), + ), + showCloseIcon: true, + ), + ); + } catch (_) {} + } + }, + icon: const Icon(Icons.auto_awesome_rounded), + ) + : prefixIcon, + ), + ), + SizedBox( + height: 3, + child: loading + ? const LinearProgressIndicator() + : const SizedBox.shrink(), + ), + (MediaQuery.of(context).viewInsets.bottom != 0) + ? const SizedBox(height: 16) + : const SizedBox.shrink(), + ], + ), + ), + ); + }, + ); + }, + ); return returnText; } diff --git a/lib/worker/update.dart b/lib/worker/update.dart index 21b7540..242fa57 100644 --- a/lib/worker/update.dart +++ b/lib/worker/update.dart @@ -23,23 +23,26 @@ String? updateUrl; String? latestVersion; String? currentVersion; String? updateChangeLog; -Future updatesSupported(Function setState, - [bool takeAction = false]) async { +Future updatesSupported( + Function setState, [ + bool takeAction = false, +]) async { var returnValue = true; - var installerApps = [ + final installerApps = [ "org.fdroid.fdroid", "org.gdroid.gdroid", "eu.bubu1.fdroidclassic", "in.sunilpaulmathew.izzyondroid", "com.looker.droidify", "com.machiav3lli.fdroid", - "nya.kitsunyan.foxydroid" + "nya.kitsunyan.foxydroid", ]; if (!desktopFeature(web: true)) { if ((await InstallReferrer.referrer != InstallationAppReferrer.androidManually) || - (installerApps - .contains((await InstallReferrer.app).packageName ?? ""))) { + (installerApps.contains( + (await InstallReferrer.app).packageName ?? "", + ))) { returnValue = false; if (await InstallReferrer.referrer == InstallationAppReferrer.androidDebug) { @@ -75,20 +78,26 @@ Future checkUpdate(Function setState) async { return false; } - var repo = repoUrl.split("/"); + final repo = repoUrl.split("/"); currentVersion = (await PackageInfo.fromPlatform()).version; // currentVersion = "1.0.0"; String? version; try { - var request = await httpClient - .get(Uri.parse( - "https://api.github.com/repos/${repo[3]}/${repo[4]}/releases")) - .timeout(Duration( + final request = await httpClient + .get( + Uri.parse( + "https://api.github.com/repos/${repo[3]}/${repo[4]}/releases", + ), + ) + .timeout( + Duration( milliseconds: (5000.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)) - .round())); + .round(), + ), + ); if (request.statusCode == 403) { setState(() { updateStatus = "rateLimit"; @@ -126,41 +135,53 @@ Future checkUpdate(Function setState) async { Future updateDialog(BuildContext context, Function title) async { await showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(AppLocalizations.of(context).settingsUpdateDialogTitle), - content: Column(mainAxisSize: MainAxisSize.min, children: [ - Text( - AppLocalizations.of(context).settingsUpdateDialogDescription), - title(AppLocalizations.of(context).settingsUpdateChangeLog), - Flexible( - child: SingleChildScrollView( - child: Container( - constraints: const BoxConstraints(maxWidth: 1000), - child: MarkdownBody( + context: context, + builder: (context) { + return AlertDialog( + title: Text(AppLocalizations.of(context).settingsUpdateDialogTitle), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(AppLocalizations.of(context).settingsUpdateDialogDescription), + title(AppLocalizations.of(context).settingsUpdateChangeLog), + Flexible( + child: SingleChildScrollView( + child: Container( + constraints: const BoxConstraints(maxWidth: 1000), + child: MarkdownBody( data: updateChangeLog ?? "No changelog given.", - shrinkWrap: true), - ))) - ]), - actions: [ - TextButton( - onPressed: () { - selectionHaptic(); - Navigator.of(context).pop(); - }, - child: Text( - AppLocalizations.of(context).settingsUpdateDialogCancel)), - TextButton( - onPressed: () { - selectionHaptic(); - Navigator.of(context).pop(); - launchUrl( - mode: LaunchMode.inAppBrowserView, - Uri.parse(updateUrl!)); - }, - child: Text( - AppLocalizations.of(context).settingsUpdateDialogUpdate)) - ]); - }); + shrinkWrap: true, + ), + ), + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + selectionHaptic(); + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context).settingsUpdateDialogCancel, + ), + ), + TextButton( + onPressed: () { + selectionHaptic(); + Navigator.of(context).pop(); + launchUrl( + mode: LaunchMode.inAppBrowserView, + Uri.parse(updateUrl!), + ); + }, + child: Text( + AppLocalizations.of(context).settingsUpdateDialogUpdate, + ), + ), + ], + ); + }, + ); } diff --git a/pubspec.lock b/pubspec.lock index 0fc5911..cc8fe7c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,38 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: cd6add6f846f35fb79f3c315296703c1a24f3cfd7f4739d91a74961c1c7e9f1b + url: "https://pub.dev" + source: hosted + version: "100.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "6ba98576948803398b69e3a444df24eacdbe12ed699c7014e120ea38552debbf" + url: "https://pub.dev" + source: hosted + version: "13.0.0" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" + url: "https://pub.dev" + source: hosted + version: "2.0.3" + archive: + dependency: transitive + description: + name: archive + sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff + url: "https://pub.dev" + source: hosted + version: "4.0.9" args: dependency: transitive description: @@ -17,6 +49,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + auto_route: + dependency: "direct main" + description: + name: auto_route + sha256: e9acfeb3df33d188fce4ad0239ef4238f333b7aa4d95ec52af3c2b9360dcd969 + url: "https://pub.dev" + source: hosted + version: "11.1.0" + auto_route_generator: + dependency: "direct dev" + description: + name: auto_route_generator + sha256: f58fdb20c51b36afe7bf8a162aea3b22dff580a8a0b5c35e8e3a91367121c8f1 + url: "https://pub.dev" + source: hosted + version: "10.6.0" bitsdojo_window: dependency: "direct main" description: @@ -65,14 +113,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: a156715e7cd728130c592f30552575908aae5b100005fbc1f0fb16b3c03a3d10 + url: "https://pub.dev" + source: hosted + version: "4.0.6" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 + url: "https://pub.dev" + source: hosted + version: "4.1.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "1523ce62448ebac2c15a8ba5fbad8acac169788658a7dd2a1c2d9c2a9318b9a6" + url: "https://pub.dev" + source: hosted + version: "2.15.0" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" + url: "https://pub.dev" + source: hosted + version: "8.12.6" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" charcode: dependency: transitive description: @@ -81,6 +177,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" clock: dependency: transitive description: @@ -89,6 +201,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d" + url: "https://pub.dev" + source: hosted + version: "4.11.1" collection: dependency: transitive description: @@ -97,6 +225,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" cross_file: dependency: transitive description: @@ -121,6 +257,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "59d53ef8eaed9d288ed9767618e2b31c4fa0383a127db59d5eb2e737a7638a60" + url: "https://pub.dev" + source: hosted + version: "3.1.9" dartx: dependency: "direct main" description: @@ -145,6 +289,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.1" + drift: + dependency: "direct main" + description: + name: drift + sha256: "8033500116b24398fba0cca0369cc31678cd627c01e41753a61186911cea743e" + url: "https://pub.dev" + source: hosted + version: "2.33.0" + drift_dev: + dependency: "direct dev" + description: + name: drift_dev + sha256: "042a5fb507ab5697f67eb55b75cfff2f665701f6606926136d6d4e85f81ff837" + url: "https://pub.dev" + source: hosted + version: "2.34.1+1" + drift_flutter: + dependency: "direct main" + description: + name: drift_flutter + sha256: "887fdec622174dc7eaefd0048403e34ee07cc18626ac8a7544cc3b8a4a172166" + url: "https://pub.dev" + source: hosted + version: "0.3.0" duration_picker: dependency: "direct main" description: @@ -157,10 +325,10 @@ packages: dependency: "direct main" description: name: dynamic_system_colors - sha256: "43794e658fa88cbdec9f397dd1afd2eb69b6c9717e99b93b16ba37c3aa3b3a8c" + sha256: "6cda994363fe362e3c433e068af83feffc2c9a26ba0be7ecdb2b96f676d2dfd8" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.0" equatable: dependency: transitive description: @@ -315,10 +483,10 @@ packages: dependency: "direct main" description: name: flutter_install_referrer - sha256: "8f994ff0653be0483303af0a6f4ecbe2fc643a61456e5bd3bf5e28e38b035c77" + sha256: "4a82a6b09e9a3e38b41522e1d44413fe20f7dd48faa636412d0af2c8821d4de4" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.1" flutter_link_previewer: dependency: transitive description: @@ -348,6 +516,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27" + url: "https://pub.dev" + source: hosted + version: "0.7.7+1" flutter_math_fork: dependency: "direct main" description: @@ -389,23 +565,47 @@ packages: dependency: "direct main" description: name: flutter_tts - sha256: bdf2fc4483e74450dc9fc6fe6a9b6a5663e108d4d0dad3324a22c8e26bf48af4 + sha256: ce5eb209b40e95f2f4a1397116c87ab2fcdff32257d04ed7a764e75894c03775 url: "https://pub.dev" source: hosted - version: "4.2.3" + version: "4.2.5" flutter_web_plugins: - dependency: transitive + dependency: "direct main" description: flutter source: sdk version: "0.0.0" - freezed_annotation: + frontend_server_client: dependency: transitive description: - name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "4.0.0" + get_time_ago: + dependency: "direct main" + description: + name: get_time_ago + sha256: "010abc128f885c223ccf4f86a88d4789bb4dd5cecdddd87fee600549dde5d4fb" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" highlight: dependency: transitive description: @@ -414,6 +614,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.0" + hooks: + dependency: transitive + description: + name: hooks + sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + hotreloader: + dependency: transitive + description: + name: hotreloader + sha256: "66871df468fc24eee81f1a0a7cb98acc104716f9b7376d355437b48d633c4ebf" + url: "https://pub.dev" + source: hosted + version: "4.4.0" html: dependency: transitive description: @@ -426,10 +642,18 @@ packages: dependency: "direct main" description: name: http - sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" http_parser: dependency: transitive description: @@ -438,6 +662,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + image: + dependency: "direct main" + description: + name: image + sha256: "6300175e00616bbc832e2fc91bfa4d776af5402c81c7151bee6905bb08473c52" + url: "https://pub.dev" + source: hosted + version: "4.9.1" image_picker: dependency: "direct main" description: @@ -510,6 +742,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" + jni: + dependency: transitive + description: + name: jni + sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f + url: "https://pub.dev" + source: hosted + version: "1.0.0" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" js: dependency: transitive description: @@ -550,6 +806,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + lean_builder: + dependency: transitive + description: + name: lean_builder + sha256: "123eef9fba96ec12a18b8eb4889850368d78e8c0a6a63eaa45ec4cf3e73fbded" + url: "https://pub.dev" + source: hosted + version: "1.2.0" linkify: dependency: transitive description: @@ -566,6 +830,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" markdown: dependency: "direct main" description: @@ -578,34 +850,42 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.18.0" mime: - dependency: transitive + dependency: "direct main" description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted version: "2.0.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: f59351d28f49520cd3a74eb1f41c5f19ae15e53c65a3231d14af672e46510a96 + url: "https://pub.dev" + source: hosted + version: "0.19.1" nested: dependency: transitive description: @@ -614,6 +894,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "6cb691c686fa2838c6deb34980d426145c2a5d537491cb83d463c33cdbc726ed" + url: "https://pub.dev" + source: hosted + version: "9.4.1" ogp_data_extract: dependency: "direct main" description: @@ -626,18 +914,26 @@ packages: dependency: "direct main" description: name: ollama_dart - sha256: df4acde50fc4a055134f91919505d801170c2e1e5df798056a18e2811f20307b + sha256: dd60bf042a9deeb616f2e03ff6c189fabc72ed06c2762b48363dab4cb668684f url: "https://pub.dev" source: hosted - version: "0.2.4" + version: "2.2.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" package_info_plus: dependency: "direct main" description: name: package_info_plus - sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" + sha256: "468c26b4254ab01979fa5e4a98cb343ea3631b9acee6f21028997419a80e1a20" url: "https://pub.dev" source: hosted - version: "8.3.1" + version: "9.0.1" package_info_plus_platform_interface: dependency: transitive description: @@ -662,6 +958,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" path_provider_linux: dependency: transitive description: @@ -746,10 +1066,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.2" photo_view: dependency: transitive description: @@ -774,6 +1094,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + url: "https://pub.dev" + source: hosted + version: "1.5.2" + posix: + dependency: transitive + description: + name: posix + sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" + url: "https://pub.dev" + source: hosted + version: "6.5.0" provider: dependency: transitive description: @@ -782,6 +1118,22 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" pwa_install: dependency: "direct main" description: @@ -790,6 +1142,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.6" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" scroll_to_index: dependency: "direct main" description: @@ -802,10 +1170,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.5.5" shared_preferences_android: dependency: transitive description: @@ -854,6 +1222,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" simple_icons: dependency: "direct main" description: @@ -875,14 +1259,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: ec37cc0e6694374cbef59ed79685572c870a54ede6fa30a3e420feb3adffea02 + url: "https://pub.dev" + source: hosted + version: "4.2.3" source_span: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.2" speech_to_text: dependency: "direct main" description: @@ -915,6 +1307,38 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + sqlcipher_flutter_libs: + dependency: transitive + description: + name: sqlcipher_flutter_libs + sha256: "38d62d659d2fb8739bf25a42c9a350d1fdd6c29a5a61f13a946778ec75d27929" + url: "https://pub.dev" + source: hosted + version: "0.7.0+eol" + sqlite3: + dependency: transitive + description: + name: sqlite3 + sha256: "9488c7d2cdb1091c91cacf7e207cff81b28bff8e366f042bad3afe7d34afe189" + url: "https://pub.dev" + source: hosted + version: "3.3.2" + sqlite3_flutter_libs: + dependency: transitive + description: + name: sqlite3_flutter_libs + sha256: "3ed7553eee7bb368f8950f58ba29f634e06e813c029aff6a0d60862b96de8454" + url: "https://pub.dev" + source: hosted + version: "0.6.0+eol" + sqlparser: + dependency: transitive + description: + name: sqlparser + sha256: ecdc06d4a7d79dcbc928d99afd2f7f5b0f98a637c46f89be83d911617f759978 + url: "https://pub.dev" + source: hosted + version: "0.44.4" stack_trace: dependency: transitive description: @@ -931,6 +1355,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" string_scanner: dependency: transitive description: @@ -959,10 +1391,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.11" time: dependency: transitive description: @@ -1103,10 +1535,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc + sha256: "7ee12e6dffe0fc8e755179d6d91b3b34f5924223fc104d85572ef9180d73d172" url: "https://pub.dev" source: hosted - version: "1.1.19" + version: "1.2.5" vector_math: dependency: transitive description: @@ -1139,6 +1571,14 @@ packages: url: "https://pub.dev" source: hosted version: "15.0.2" + watcher: + dependency: transitive + description: + name: watcher + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + url: "https://pub.dev" + source: hosted + version: "1.2.1" web: dependency: transitive description: @@ -1147,6 +1587,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" win32: dependency: transitive description: @@ -1167,10 +1623,26 @@ packages: dependency: transitive description: name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4" url: "https://pub.dev" source: hosted - version: "6.6.1" + version: "7.0.1" + xxh3: + dependency: transitive + description: + name: xxh3 + sha256: "399a0438f5d426785723c99da6b16e136f4953fb1e9db0bf270bd41dd4619916" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" sdks: - dart: ">=3.8.1 <4.0.0" - flutter: ">=3.35.0" + dart: ">=3.12.0 <4.0.0" + flutter: "3.44.7" diff --git a/pubspec.yaml b/pubspec.yaml index e0c23c9..f2c805c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,17 +4,22 @@ publish_to: 'none' version: 1.2.0+9 environment: - sdk: '>=3.8.1 <4.0.0' - flutter: 3.35.0 + sdk: '>=3.12.0 <4.0.0' + flutter: 3.44.7 dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter - ollama_dart: ^0.2.4 + flutter_web_plugins: + sdk: flutter + ollama_dart: ^2.2.0 intl: any - shared_preferences: ^2.2.3 + image: ^4.9.1 + mime: ^2.0.0 + get_time_ago: ^2.4.1 + shared_preferences: ^2.5.5 flutter_chat_ui: ^1.6.13 scroll_to_index: ^3.0.1 uuid: ^4.4.0 @@ -29,13 +34,13 @@ dependencies: file_picker: ^8.0.3 file_selector: ^1.0.3 bitsdojo_window: ^0.1.6 - flutter_install_referrer: ^2.0.2 - package_info_plus: ^8.0.0 + flutter_install_referrer: ^2.1.1 + package_info_plus: ^9.0.1 version: ^3.0.2 flutter_displaymode: ^0.6.0 duration_picker: ^1.2.0 - speech_to_text: ^7.0.0 - flutter_tts: ^4.2.3 + speech_to_text: ^7.3.0 + flutter_tts: ^4.2.5 permission_handler: ^11.3.1 datetime_loop: ^1.2.0 universal_html: ^2.2.4 @@ -48,14 +53,24 @@ dependencies: url: https://github.com/JHubi1/highlight.dart path: flutter_highlight ogp_data_extract: ^0.2.2 + auto_route: ^11.1.0 # dynamic_color: ^1.7.0 - dynamic_system_colors: ^1.8.0 + dynamic_system_colors: ^1.9.0 + drift: ^2.33.0 + drift_flutter: ^0.3.0 + path_provider: ^2.1.5 + + # dynamic_color: any + flutter_markdown: any dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^4.0.0 + drift_dev: ^2.33.0 + auto_route_generator: ^10.6.0 + build_runner: ^2.15.0 flutter: uses-material-design: true @@ -69,3 +84,9 @@ flutter: - assets/welcome/1dark.png - assets/welcome/2dark.png - assets/welcome/3dark.png + fonts: + - family: GoogleSansCode + fonts: + - asset: assets/fonts/GoogleSansCode-VariableFont_MONO,wght.ttf + - asset: assets/fonts/GoogleSansCode-Italic-VariableFont_MONO,wght.ttf + style: italic diff --git a/scripts/build.dart b/scripts/build.dart index d28ce08..80a68ea 100644 --- a/scripts/build.dart +++ b/scripts/build.dart @@ -4,7 +4,7 @@ import 'dart:io'; void main() async { Directory.current = Directory(Platform.script.toFilePath()).parent.parent; - var flutterExecutable = Platform.isWindows ? 'flutter.bat' : 'flutter'; + final flutterExecutable = Platform.isWindows ? 'flutter.bat' : 'flutter'; print("Build script for Ollama App by JHubi1"); print("Report issues at: https://github.com/JHubi1/ollama-app/issues"); @@ -12,14 +12,15 @@ void main() async { print('----------'); print('Extracting version from pubspec.yaml ...'); - var pubspec = File('pubspec.yaml'); - var versionLine = await pubspec - .readAsLines() - .then((lines) => lines.firstWhere((line) => line.contains('version'))); - var version = versionLine.split(':').last.trim().split('+').first.trim(); - var versionCode = versionLine.split(':').last.trim().split('+')[1].trim(); + final pubspec = File('pubspec.yaml'); + final versionLine = await pubspec.readAsLines().then( + (lines) => lines.firstWhere((line) => line.contains('version')), + ); + final version = versionLine.split(':').last.trim().split('+').first.trim(); + final versionCode = versionLine.split(':').last.trim().split('+')[1].trim(); print( - "Building Ollama App v$version (build $versionCode) - this may take a while"); + "Building Ollama App v$version (build $versionCode) - this may take a while", + ); print('----------'); @@ -27,7 +28,7 @@ void main() async { 'build', 'apk', '--obfuscate', - '--split-debug-info=build\\debugAndroid' + '--split-debug-info=build\\debugAndroid', ]); // ---------- @@ -71,17 +72,20 @@ void main() async { stdout.write('Copying build output to build\\.output '); try { - var outputDir = Directory('build\\.output'); + final outputDir = Directory('build\\.output'); if (await outputDir.exists()) { await outputDir.delete(recursive: true); } await outputDir.create(); - await copyFile('build\\app\\outputs\\flutter-apk\\app-release.apk', - 'build\\.output\\ollama-android-v$version.apk'); await copyFile( - 'build\\windows\\x64\\runner\\ollama-windows-x64-v$version.exe', - 'build\\.output\\ollama-windows-x64-v$version.exe'); + 'build\\app\\outputs\\flutter-apk\\app-release.apk', + 'build\\.output\\ollama-android-v$version.apk', + ); + await copyFile( + 'build\\windows\\x64\\runner\\ollama-windows-x64-v$version.exe', + 'build\\.output\\ollama-windows-x64-v$version.exe', + ); print('- done'); } catch (_) { print('- failed'); @@ -95,14 +99,18 @@ void main() async { } Future copyFile(String sourcePath, String destinationPath) async { - var sourceFile = File(sourcePath); + final sourceFile = File(sourcePath); if (await sourceFile.exists()) { await sourceFile.copy(destinationPath); } } -Future execute(String title, String command, List arguments, - [String? errorText]) async { +Future execute( + String title, + String command, + List arguments, [ + String? errorText, +]) async { stdout.write('$title '); ProcessResult process; try { diff --git a/test/functions.dart b/test/functions.dart index 90dc745..680cf52 100644 --- a/test/functions.dart +++ b/test/functions.dart @@ -1,8 +1,8 @@ import 'dart:math'; String random(int length) { - var rand = Random(); - var codeUnits = List.generate(length, (index) { + final rand = Random(); + final codeUnits = List.generate(length, (index) { return rand.nextInt(33) + 89; }); diff --git a/test/widget_test.dart b/test/widget_test.dart index fc0cc4b..a961f52 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -6,13 +6,17 @@ import 'functions.dart'; void main() { testWidgets("Widget: button", (WidgetTester tester) async { - var text = random(10); + final text = random(10); var clicked = false; - await tester.pumpWidget(MaterialApp( + await tester.pumpWidget( + MaterialApp( home: Scaffold( - body: button(text, Icons.add_rounded, () { - clicked = true; - })))); + body: button(text, Icons.add_rounded, () { + clicked = true; + }), + ), + ), + ); expect(find.text(text), findsOneWidget); expect(find.byIcon(Icons.add_rounded), findsOneWidget); @@ -23,14 +27,21 @@ void main() { expect(clicked, true); }); testWidgets("Widget: toggle", (WidgetTester tester) async { - var text = random(10); + final text = random(10); var toggled = false; await tester.pumpWidget( - MaterialApp(home: Scaffold(body: Builder(builder: (context) { - return toggle(context, text, toggled, (value) { - toggled = value; - }); - })))); + MaterialApp( + home: Scaffold( + body: Builder( + builder: (context) { + return toggle(context, text, toggled, (value) { + toggled = value; + }); + }, + ), + ), + ), + ); expect(find.textContaining(text), findsOneWidget); expect(find.byType(Switch), findsOneWidget); diff --git a/tools/base64.dart b/tool/base64.dart similarity index 100% rename from tools/base64.dart rename to tool/base64.dart diff --git a/tools/logid.dart b/tool/logid.dart similarity index 96% rename from tools/logid.dart rename to tool/logid.dart index 0d94708..3b67338 100644 --- a/tools/logid.dart +++ b/tool/logid.dart @@ -4,7 +4,7 @@ import 'dart:math'; void main() { - var random = Random.secure(); + final random = Random.secure(); var logId = ""; const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/untranslated_messages.json b/untranslated_messages.json index fa1646c..22943e8 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,41 +1,181 @@ { "de": [ + "optionChatDetails", + "optionChatDetailsNoChat", + "newChatGreeting1", + "newChatGreeting2", + "newChatGreeting3", + "newChatGreeting4", + "newChatGreeting5", + "newChatGreetingNameFallback", + "modelDialogTitle", + "modelDialogRefresh", "errorGuardTitle", "errorGuardDetails", "errorGuardException", "errorGuardStackTrace", - "errorGuardReport" + "errorGuardReport", + "settingsTitleOverview", + "settingsDescriptionOverview", + "settingsHostHeaderHeaderName", + "settingsHostHeaderHeaderValue", + "settingsHostHeaderUnsupported", + "settingsHostHeaderDuplicate" ], "fa": [ + "learnMore", + "optionNoChatFoundSearch", + "optionSearchChats", + "optionChatDetails", + "optionChatDetailsNoChat", + "newChatGreeting1", + "newChatGreeting2", + "newChatGreeting3", + "newChatGreeting4", + "newChatGreeting5", + "newChatGreetingNameFallback", + "messageInputPlaceholderModelPlaceholder", + "tooltipMessageOptions", + "modelDialogTitle", + "modelDialogAdd", + "modelDialogRefresh", + "modelDialogAddCurrently", + "modelDialogAddPromptNotFound", + "modelDialogAddPromptNetworkError", + "modelDialogAddPromptCorruptionError", + "modelDialogAddPromptCorruptionErrorSolution", + "modelDialogAddCancelTitle", + "modelDialogAddCancelConfirm", + "modelDialogAddCancelHide", "errorGuardTitle", "errorGuardDetails", "errorGuardException", "errorGuardStackTrace", - "errorGuardReport" + "errorGuardReport", + "settingsTitleOverview", + "settingsDescriptionOverview", + "settingsHostMissing", + "settingsHostHeaderHeaderName", + "settingsHostHeaderHeaderValue", + "settingsHostHeaderUnsupported", + "settingsHostHeaderDuplicate" ], "it": [ + "learnMore", + "optionNoChatFoundSearch", + "optionSearchChats", + "optionChatDetails", + "optionChatDetailsNoChat", + "newChatGreeting1", + "newChatGreeting2", + "newChatGreeting3", + "newChatGreeting4", + "newChatGreeting5", + "newChatGreetingNameFallback", + "messageInputPlaceholderModelPlaceholder", + "tooltipMessageOptions", + "modelDialogTitle", + "modelDialogAdd", + "modelDialogRefresh", + "modelDialogAddCurrently", + "modelDialogAddPromptNotFound", + "modelDialogAddPromptNetworkError", + "modelDialogAddPromptCorruptionError", + "modelDialogAddPromptCorruptionErrorSolution", + "modelDialogAddCancelTitle", + "modelDialogAddCancelConfirm", + "modelDialogAddCancelHide", "errorGuardTitle", "errorGuardDetails", "errorGuardException", "errorGuardStackTrace", - "errorGuardReport" + "errorGuardReport", + "settingsTitleOverview", + "settingsDescriptionOverview", + "settingsHostMissing", + "settingsHostHeaderHeaderName", + "settingsHostHeaderHeaderValue", + "settingsHostHeaderUnsupported", + "settingsHostHeaderDuplicate" ], "tr": [ + "learnMore", + "optionNoChatFoundSearch", + "optionSearchChats", + "optionChatDetails", + "optionChatDetailsNoChat", + "newChatGreeting1", + "newChatGreeting2", + "newChatGreeting3", + "newChatGreeting4", + "newChatGreeting5", + "newChatGreetingNameFallback", + "messageInputPlaceholderModelPlaceholder", + "tooltipMessageOptions", + "modelDialogTitle", + "modelDialogAdd", + "modelDialogRefresh", + "modelDialogAddCurrently", + "modelDialogAddPromptNotFound", + "modelDialogAddPromptNetworkError", + "modelDialogAddPromptCorruptionError", + "modelDialogAddPromptCorruptionErrorSolution", + "modelDialogAddCancelTitle", + "modelDialogAddCancelConfirm", + "modelDialogAddCancelHide", "errorGuardTitle", "errorGuardDetails", "errorGuardException", "errorGuardStackTrace", - "errorGuardReport" + "errorGuardReport", + "settingsTitleOverview", + "settingsDescriptionOverview", + "settingsHostMissing", + "settingsHostHeaderHeaderName", + "settingsHostHeaderHeaderValue", + "settingsHostHeaderUnsupported", + "settingsHostHeaderDuplicate" ], "zh": [ + "learnMore", + "optionNoChatFoundSearch", + "optionSearchChats", + "optionChatDetails", + "optionChatDetailsNoChat", + "newChatGreeting1", + "newChatGreeting2", + "newChatGreeting3", + "newChatGreeting4", + "newChatGreeting5", + "newChatGreetingNameFallback", + "messageInputPlaceholderModelPlaceholder", + "tooltipMessageOptions", + "modelDialogTitle", + "modelDialogAdd", + "modelDialogRefresh", + "modelDialogAddCurrently", + "modelDialogAddPromptNotFound", + "modelDialogAddPromptNetworkError", + "modelDialogAddPromptCorruptionError", + "modelDialogAddPromptCorruptionErrorSolution", + "modelDialogAddCancelTitle", + "modelDialogAddCancelConfirm", + "modelDialogAddCancelHide", "errorGuardTitle", "errorGuardDetails", "errorGuardException", "errorGuardStackTrace", - "errorGuardReport" + "errorGuardReport", + "settingsTitleOverview", + "settingsDescriptionOverview", + "settingsHostMissing", + "settingsHostHeaderHeaderName", + "settingsHostHeaderHeaderValue", + "settingsHostHeaderUnsupported", + "settingsHostHeaderDuplicate" ] } diff --git a/web/drift_worker.js b/web/drift_worker.js new file mode 100644 index 0000000..ff67c77 --- /dev/null +++ b/web/drift_worker.js @@ -0,0 +1,13271 @@ +(function dartProgram(){function copyProperties(a,b){var s=Object.keys(a) +for(var r=0;r=0)return true +if(typeof version=="function"&&version.length==0){var q=version() +if(/^\d+\.\d+\.\d+\.\d+$/.test(q))return true}}catch(p){}return false}() +function inherit(a,b){a.prototype.constructor=a +a.prototype["$i"+a.name]=a +if(b!=null){if(z){Object.setPrototypeOf(a.prototype,b.prototype) +return}var s=Object.create(b.prototype) +copyProperties(a.prototype,s) +a.prototype=s}}function inheritMany(a,b){for(var s=0;s4294967295)throw A.b(A.S(a,0,4294967295,"length",null)) +return J.tW(new Array(a),b)}, +pA(a,b){if(a<0)throw A.b(A.J("Length must be a non-negative integer: "+a,null)) +return A.f(new Array(a),b.h("u<0>"))}, +tW(a,b){var s=A.f(a,b.h("u<0>")) +s.$flags=1 +return s}, +tX(a,b){return J.tl(a,b)}, +pB(a){if(a<256)switch(a){case 9:case 10:case 11:case 12:case 13:case 32:case 133:case 160:return!0 +default:return!1}switch(a){case 5760:case 8192:case 8193:case 8194:case 8195:case 8196:case 8197:case 8198:case 8199:case 8200:case 8201:case 8202:case 8232:case 8233:case 8239:case 8287:case 12288:case 65279:return!0 +default:return!1}}, +tY(a,b){var s,r +for(s=a.length;b0;b=s){s=b-1 +r=a.charCodeAt(s) +if(r!==32&&r!==13&&!J.pB(r))break}return b}, +cW(a){if(typeof a=="number"){if(Math.floor(a)==a)return J.et.prototype +return J.hl.prototype}if(typeof a=="string")return J.bX.prototype +if(a==null)return J.eu.prototype +if(typeof a=="boolean")return J.hk.prototype +if(Array.isArray(a))return J.u.prototype +if(typeof a!="object"){if(typeof a=="function")return J.bz.prototype +if(typeof a=="symbol")return J.d7.prototype +if(typeof a=="bigint")return J.aK.prototype +return a}if(a instanceof A.e)return a +return J.nG(a)}, +a0(a){if(typeof a=="string")return J.bX.prototype +if(a==null)return a +if(Array.isArray(a))return J.u.prototype +if(typeof a!="object"){if(typeof a=="function")return J.bz.prototype +if(typeof a=="symbol")return J.d7.prototype +if(typeof a=="bigint")return J.aK.prototype +return a}if(a instanceof A.e)return a +return J.nG(a)}, +aS(a){if(a==null)return a +if(Array.isArray(a))return J.u.prototype +if(typeof a!="object"){if(typeof a=="function")return J.bz.prototype +if(typeof a=="symbol")return J.d7.prototype +if(typeof a=="bigint")return J.aK.prototype +return a}if(a instanceof A.e)return a +return J.nG(a)}, +wR(a){if(typeof a=="number")return J.d6.prototype +if(typeof a=="string")return J.bX.prototype +if(a==null)return a +if(!(a instanceof A.e))return J.cE.prototype +return a}, +iY(a){if(typeof a=="string")return J.bX.prototype +if(a==null)return a +if(!(a instanceof A.e))return J.cE.prototype +return a}, +rk(a){if(a==null)return a +if(typeof a!="object"){if(typeof a=="function")return J.bz.prototype +if(typeof a=="symbol")return J.d7.prototype +if(typeof a=="bigint")return J.aK.prototype +return a}if(a instanceof A.e)return a +return J.nG(a)}, +aj(a,b){if(a==null)return b==null +if(typeof a!="object")return b!=null&&a===b +return J.cW(a).W(a,b)}, +aJ(a,b){if(typeof b==="number")if(Array.isArray(a)||typeof a=="string"||A.rn(a,a[v.dispatchPropertyName]))if(b>>>0===b&&b>>0===b&&b").H(c).h("f4<1,2>")) +return new A.co(a,b.h("@<0>").H(c).h("co<1,2>"))}, +pC(a){return new A.d8("Field '"+a+"' has been assigned during initialization.")}, +pD(a){return new A.d8("Field '"+a+"' has not been initialized.")}, +u_(a){return new A.d8("Field '"+a+"' has already been initialized.")}, +nH(a){var s,r=a^48 +if(r<=9)return r +s=a|32 +if(97<=s&&s<=102)return s-87 +return-1}, +c9(a,b){a=a+b&536870911 +a=a+((a&524287)<<10)&536870911 +return a^a>>>6}, +ok(a){a=a+((a&67108863)<<3)&536870911 +a^=a>>>11 +return a+((a&16383)<<15)&536870911}, +cU(a,b,c){return a}, +oW(a){var s,r +for(s=$.cT.length,r=0;rc)A.C(A.S(b,0,c,"start",null))}return new A.cC(a,b,c,d.h("cC<0>"))}, +ht(a,b,c,d){if(t.Q.b(a))return new A.ct(a,b,c.h("@<0>").H(d).h("ct<1,2>")) +return new A.aE(a,b,c.h("@<0>").H(d).h("aE<1,2>"))}, +ol(a,b,c){var s="takeCount" +A.bT(b,s) +A.ab(b,s) +if(t.Q.b(a))return new A.el(a,b,c.h("el<0>")) +return new A.cD(a,b,c.h("cD<0>"))}, +pY(a,b,c){var s="count" +if(t.Q.b(a)){A.bT(b,s) +A.ab(b,s) +return new A.d3(a,b,c.h("d3<0>"))}A.bT(b,s) +A.ab(b,s) +return new A.bJ(a,b,c.h("bJ<0>"))}, +tU(a,b,c){return new A.cs(a,b,c.h("cs<0>"))}, +az(){return new A.aQ("No element")}, +py(){return new A.aQ("Too few elements")}, +ce:function ce(){}, +fU:function fU(a,b){this.a=a +this.$ti=b}, +co:function co(a,b){this.a=a +this.$ti=b}, +f4:function f4(a,b){this.a=a +this.$ti=b}, +f_:function f_(){}, +ak:function ak(a,b){this.a=a +this.$ti=b}, +d8:function d8(a){this.a=a}, +fV:function fV(a){this.a=a}, +nO:function nO(){}, +kR:function kR(){}, +q:function q(){}, +M:function M(){}, +cC:function cC(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.$ti=d}, +b3:function b3(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.d=null +_.$ti=c}, +aE:function aE(a,b,c){this.a=a +this.b=b +this.$ti=c}, +ct:function ct(a,b,c){this.a=a +this.b=b +this.$ti=c}, +d9:function d9(a,b,c){var _=this +_.a=null +_.b=a +_.c=b +_.$ti=c}, +E:function E(a,b,c){this.a=a +this.b=b +this.$ti=c}, +aY:function aY(a,b,c){this.a=a +this.b=b +this.$ti=c}, +eU:function eU(a,b){this.a=a +this.b=b}, +en:function en(a,b,c){this.a=a +this.b=b +this.$ti=c}, +ha:function ha(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=null +_.$ti=d}, +cD:function cD(a,b,c){this.a=a +this.b=b +this.$ti=c}, +el:function el(a,b,c){this.a=a +this.b=b +this.$ti=c}, +hR:function hR(a,b,c){this.a=a +this.b=b +this.$ti=c}, +bJ:function bJ(a,b,c){this.a=a +this.b=b +this.$ti=c}, +d3:function d3(a,b,c){this.a=a +this.b=b +this.$ti=c}, +hM:function hM(a,b){this.a=a +this.b=b}, +eK:function eK(a,b,c){this.a=a +this.b=b +this.$ti=c}, +hN:function hN(a,b){this.a=a +this.b=b +this.c=!1}, +cu:function cu(a){this.$ti=a}, +h7:function h7(){}, +eV:function eV(a,b){this.a=a +this.$ti=b}, +i7:function i7(a,b){this.a=a +this.$ti=b}, +by:function by(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cs:function cs(a,b,c){this.a=a +this.b=b +this.$ti=c}, +er:function er(a,b){this.a=a +this.b=b +this.c=-1}, +eo:function eo(){}, +hV:function hV(){}, +dr:function dr(){}, +eI:function eI(a,b){this.a=a +this.$ti=b}, +hQ:function hQ(a){this.a=a}, +fz:function fz(){}, +rw(a){var s=v.mangledGlobalNames[a] +if(s!=null)return s +return"minified:"+a}, +rn(a,b){var s +if(b!=null){s=b.x +if(s!=null)return s}return t.aU.b(a)}, +t(a){var s +if(typeof a=="string")return a +if(typeof a=="number"){if(a!==0)return""+a}else if(!0===a)return"true" +else if(!1===a)return"false" +else if(a==null)return"null" +s=J.b1(a) +return s}, +eG(a){var s,r=$.pI +if(r==null)r=$.pI=Symbol("identityHashCode") +s=a[r] +if(s==null){s=Math.random()*0x3fffffff|0 +a[r]=s}return s}, +pP(a,b){var s,r,q,p,o,n=null,m=/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(a) +if(m==null)return n +s=m[3] +if(b==null){if(s!=null)return parseInt(a,10) +if(m[2]!=null)return parseInt(a,16) +return n}if(b<2||b>36)throw A.b(A.S(b,2,36,"radix",n)) +if(b===10&&s!=null)return parseInt(a,10) +if(b<10||s==null){r=b<=10?47+b:86+b +q=m[1] +for(p=q.length,o=0;or)return n}return parseInt(a,b)}, +hG(a){var s,r,q,p +if(a instanceof A.e)return A.aZ(A.aT(a),null) +s=J.cW(a) +if(s===B.aB||s===B.aE||t.ak.b(a)){r=B.P(a) +if(r!=="Object"&&r!=="")return r +q=a.constructor +if(typeof q=="function"){p=q.name +if(typeof p=="string"&&p!=="Object"&&p!=="")return p}}return A.aZ(A.aT(a),null)}, +pQ(a){var s,r,q +if(a==null||typeof a=="number"||A.bQ(a))return J.b1(a) +if(typeof a=="string")return JSON.stringify(a) +if(a instanceof A.cp)return a.i(0) +if(a instanceof A.fi)return a.fO(!0) +s=$.t6() +for(r=0;r<1;++r){q=s[r].l9(a) +if(q!=null)return q}return"Instance of '"+A.hG(a)+"'"}, +u9(){if(!!self.location)return self.location.href +return null}, +pH(a){var s,r,q,p,o=a.length +if(o<=500)return String.fromCharCode.apply(null,a) +for(s="",r=0;r65535)return A.ud(a)}return A.pH(a)}, +ue(a,b,c){var s,r,q,p +if(c<=500&&b===0&&c===a.length)return String.fromCharCode.apply(null,a) +for(s=b,r="";s>>0,s&1023|56320)}}throw A.b(A.S(a,0,1114111,null,null))}, +aF(a){if(a.date===void 0)a.date=new Date(a.a) +return a.date}, +pO(a){return a.c?A.aF(a).getUTCFullYear()+0:A.aF(a).getFullYear()+0}, +pM(a){return a.c?A.aF(a).getUTCMonth()+1:A.aF(a).getMonth()+1}, +pJ(a){return a.c?A.aF(a).getUTCDate()+0:A.aF(a).getDate()+0}, +pK(a){return a.c?A.aF(a).getUTCHours()+0:A.aF(a).getHours()+0}, +pL(a){return a.c?A.aF(a).getUTCMinutes()+0:A.aF(a).getMinutes()+0}, +pN(a){return a.c?A.aF(a).getUTCSeconds()+0:A.aF(a).getSeconds()+0}, +ub(a){return a.c?A.aF(a).getUTCMilliseconds()+0:A.aF(a).getMilliseconds()+0}, +uc(a){return B.b.ac((a.c?A.aF(a).getUTCDay()+0:A.aF(a).getDay()+0)+6,7)+1}, +ua(a){var s=a.$thrownJsError +if(s==null)return null +return A.a1(s)}, +eH(a,b){var s +if(a.$thrownJsError==null){s=new Error() +A.aa(a,s) +a.$thrownJsError=s +s.stack=b.i(0)}}, +e3(a,b){var s,r="index" +if(!A.bv(b))return new A.bb(!0,b,r,null) +s=J.at(a) +if(b<0||b>=s)return A.hf(b,s,a,null,r) +return A.kN(b,r)}, +wL(a,b,c){if(a>c)return A.S(a,0,c,"start",null) +if(b!=null)if(bc)return A.S(b,a,c,"end",null) +return new A.bb(!0,b,"end",null)}, +e0(a){return new A.bb(!0,a,null,null)}, +b(a){return A.aa(a,new Error())}, +aa(a,b){var s +if(a==null)a=new A.bL() +b.dartException=a +s=A.xp +if("defineProperty" in Object){Object.defineProperty(b,"message",{get:s}) +b.name=""}else b.toString=s +return b}, +xp(){return J.b1(this.dartException)}, +C(a,b){throw A.aa(a,b==null?new Error():b)}, +y(a,b,c){var s +if(b==null)b=0 +if(c==null)c=0 +s=Error() +A.C(A.vA(a,b,c),s)}, +vA(a,b,c){var s,r,q,p,o,n,m,l,k +if(typeof b=="string")s=b +else{r="[]=;add;removeWhere;retainWhere;removeRange;setRange;setInt8;setInt16;setInt32;setUint8;setUint16;setUint32;setFloat32;setFloat64".split(";") +q=r.length +p=b +if(p>q){c=p/q|0 +p%=q}s=r[p]}o=typeof c=="string"?c:"modify;remove from;add to".split(";")[c] +n=t.j.b(a)?"list":"ByteData" +m=a.$flags|0 +l="a " +if((m&4)!==0)k="constant " +else if((m&2)!==0){k="unmodifiable " +l="an "}else k=(m&1)!==0?"fixed-length ":"" +return new A.eR("'"+s+"': Cannot "+o+" "+l+k+n)}, +a2(a){throw A.b(A.au(a))}, +bM(a){var s,r,q,p,o,n +a=A.rv(a.replace(String({}),"$receiver$")) +s=a.match(/\\\$[a-zA-Z]+\\\$/g) +if(s==null)s=A.f([],t.s) +r=s.indexOf("\\$arguments\\$") +q=s.indexOf("\\$argumentsExpr\\$") +p=s.indexOf("\\$expr\\$") +o=s.indexOf("\\$method\\$") +n=s.indexOf("\\$receiver\\$") +return new A.lv(a.replace(new RegExp("\\\\\\$arguments\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$argumentsExpr\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$expr\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$method\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$receiver\\\\\\$","g"),"((?:x|[^x])*)"),r,q,p,o,n)}, +lw(a){return function($expr$){var $argumentsExpr$="$arguments$" +try{$expr$.$method$($argumentsExpr$)}catch(s){return s.message}}(a)}, +q6(a){return function($expr$){try{$expr$.$method$}catch(s){return s.message}}(a)}, +oa(a,b){var s=b==null,r=s?null:b.method +return new A.hn(a,r,s?null:b.receiver)}, +G(a){if(a==null)return new A.hD(a) +if(a instanceof A.em)return A.cl(a,a.a) +if(typeof a!=="object")return a +if("dartException" in a)return A.cl(a,a.dartException) +return A.wi(a)}, +cl(a,b){if(t.C.b(b))if(b.$thrownJsError==null)b.$thrownJsError=a +return b}, +wi(a){var s,r,q,p,o,n,m,l,k,j,i,h,g +if(!("message" in a))return a +s=a.message +if("number" in a&&typeof a.number=="number"){r=a.number +q=r&65535 +if((B.b.O(r,16)&8191)===10)switch(q){case 438:return A.cl(a,A.oa(A.t(s)+" (Error "+q+")",null)) +case 445:case 5007:A.t(s) +return A.cl(a,new A.eC())}}if(a instanceof TypeError){p=$.rC() +o=$.rD() +n=$.rE() +m=$.rF() +l=$.rI() +k=$.rJ() +j=$.rH() +$.rG() +i=$.rL() +h=$.rK() +g=p.ar(s) +if(g!=null)return A.cl(a,A.oa(s,g)) +else{g=o.ar(s) +if(g!=null){g.method="call" +return A.cl(a,A.oa(s,g))}else if(n.ar(s)!=null||m.ar(s)!=null||l.ar(s)!=null||k.ar(s)!=null||j.ar(s)!=null||m.ar(s)!=null||i.ar(s)!=null||h.ar(s)!=null)return A.cl(a,new A.eC())}return A.cl(a,new A.hU(typeof s=="string"?s:""))}if(a instanceof RangeError){if(typeof s=="string"&&s.indexOf("call stack")!==-1)return new A.eM() +s=function(b){try{return String(b)}catch(f){}return null}(a) +return A.cl(a,new A.bb(!1,null,null,typeof s=="string"?s.replace(/^RangeError:\s*/,""):s))}if(typeof InternalError=="function"&&a instanceof InternalError)if(typeof s=="string"&&s==="too much recursion")return new A.eM() +return a}, +a1(a){var s +if(a instanceof A.em)return a.b +if(a==null)return new A.fm(a) +s=a.$cachedTrace +if(s!=null)return s +s=new A.fm(a) +if(typeof a==="object")a.$cachedTrace=s +return s}, +oY(a){if(a==null)return J.aC(a) +if(typeof a=="object")return A.eG(a) +return J.aC(a)}, +wN(a,b){var s,r,q,p=a.length +for(s=0;s=0 +else if(b instanceof A.cw){s=B.a.N(a,c) +return b.b.test(s)}else return!J.nX(b,B.a.N(a,c)).gB(0)}, +oT(a){if(a.indexOf("$",0)>=0)return a.replace(/\$/g,"$$$$") +return a}, +xl(a,b,c,d){var s=b.fd(a,d) +if(s==null)return a +return A.p2(a,s.b.index,s.gbw(),c)}, +rv(a){if(/[[\]{}()*+?.\\^$|]/.test(a))return a.replace(/[[\]{}()*+?.\\^$|]/g,"\\$&") +return a}, +bi(a,b,c){var s +if(typeof b=="string")return A.xk(a,b,c) +if(b instanceof A.cw){s=b.gfo() +s.lastIndex=0 +return a.replace(s,A.oT(c))}return A.xj(a,b,c)}, +xj(a,b,c){var s,r,q,p +for(s=J.nX(b,a),s=s.gq(s),r=0,q="";s.k();){p=s.gm() +q=q+a.substring(r,p.gco())+c +r=p.gbw()}s=q+a.substring(r) +return s.charCodeAt(0)==0?s:s}, +xk(a,b,c){var s,r,q +if(b===""){if(a==="")return c +s=a.length +for(r=c,q=0;q=0)return a.split(b).join(c) +return a.replace(new RegExp(A.rv(b),"g"),A.oT(c))}, +xm(a,b,c,d){var s,r,q,p +if(typeof b=="string"){s=a.indexOf(b,d) +if(s<0)return a +return A.p2(a,s,s+b.length,c)}if(b instanceof A.cw)return d===0?a.replace(b.b,A.oT(c)):A.xl(a,b,c,d) +r=J.ti(b,a,d) +q=r.gq(r) +if(!q.k())return a +p=q.gm() +return B.a.aL(a,p.gco(),p.gbw(),c)}, +p2(a,b,c,d){return a.substring(0,b)+d+a.substring(c)}, +ah:function ah(a,b){this.a=a +this.b=b}, +cO:function cO(a,b){this.a=a +this.b=b}, +iD:function iD(a,b){this.a=a +this.b=b}, +eg:function eg(){}, +eh:function eh(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cM:function cM(a,b){this.a=a +this.$ti=b}, +iw:function iw(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.d=null +_.$ti=c}, +kp:function kp(){}, +es:function es(a,b){this.a=a +this.$ti=b}, +eJ:function eJ(){}, +lv:function lv(a,b,c,d,e,f){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f}, +eC:function eC(){}, +hn:function hn(a,b,c){this.a=a +this.b=b +this.c=c}, +hU:function hU(a){this.a=a}, +hD:function hD(a){this.a=a}, +em:function em(a,b){this.a=a +this.b=b}, +fm:function fm(a){this.a=a +this.b=null}, +cp:function cp(){}, +jj:function jj(){}, +jk:function jk(){}, +ll:function ll(){}, +lb:function lb(){}, +eb:function eb(a,b){this.a=a +this.b=b}, +hJ:function hJ(a){this.a=a}, +bA:function bA(a){var _=this +_.a=0 +_.f=_.e=_.d=_.c=_.b=null +_.r=0 +_.$ti=a}, +kw:function kw(a){this.a=a}, +kz:function kz(a,b){var _=this +_.a=a +_.b=b +_.d=_.c=null}, +bB:function bB(a,b){this.a=a +this.$ti=b}, +hr:function hr(a,b,c){var _=this +_.a=a +_.b=b +_.c=c +_.d=null}, +ex:function ex(a,b){this.a=a +this.$ti=b}, +cx:function cx(a,b,c){var _=this +_.a=a +_.b=b +_.c=c +_.d=null}, +ew:function ew(a,b){this.a=a +this.$ti=b}, +hq:function hq(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=null +_.$ti=d}, +nI:function nI(a){this.a=a}, +nJ:function nJ(a){this.a=a}, +nK:function nK(a){this.a=a}, +fi:function fi(){}, +iC:function iC(){}, +cw:function cw(a,b){var _=this +_.a=a +_.b=b +_.e=_.d=_.c=null}, +dH:function dH(a){this.b=a}, +i8:function i8(a,b,c){this.a=a +this.b=b +this.c=c}, +m7:function m7(a,b,c){var _=this +_.a=a +_.b=b +_.c=c +_.d=null}, +dp:function dp(a,b){this.a=a +this.c=b}, +iL:function iL(a,b,c){this.a=a +this.b=b +this.c=c}, +n6:function n6(a,b,c){var _=this +_.a=a +_.b=b +_.c=c +_.d=null}, +xo(a){throw A.aa(A.pC(a),new Error())}, +x(){throw A.aa(A.pD(""),new Error())}, +j_(){throw A.aa(A.u_(""),new Error())}, +p4(){throw A.aa(A.pC(""),new Error())}, +mo(a){var s=new A.mn(a) +return s.b=s}, +mn:function mn(a){this.a=a +this.b=null}, +vy(a){return a}, +fA(a,b,c){}, +iV(a){var s,r,q +if(t.aP.b(a))return a +s=J.a0(a) +r=A.b4(s.gl(a),null,!1,t.z) +for(q=0;q>>0!==a||a>=c)throw A.b(A.e3(b,a))}, +ci(a,b,c){var s +if(!(a>>>0!==a))s=b>>>0!==b||a>b||b>c +else s=!0 +if(s)throw A.b(A.wL(a,b,c)) +return b}, +db:function db(){}, +da:function da(){}, +eA:function eA(){}, +iR:function iR(a){this.a=a}, +cy:function cy(){}, +dd:function dd(){}, +c_:function c_(){}, +aW:function aW(){}, +hu:function hu(){}, +hv:function hv(){}, +hw:function hw(){}, +dc:function dc(){}, +hx:function hx(){}, +hy:function hy(){}, +hz:function hz(){}, +eB:function eB(){}, +c0:function c0(){}, +fd:function fd(){}, +fe:function fe(){}, +ff:function ff(){}, +fg:function fg(){}, +og(a,b){var s=b.c +return s==null?b.c=A.fs(a,"D",[b.x]):s}, +pW(a){var s=a.w +if(s===6||s===7)return A.pW(a.x) +return s===11||s===12}, +ui(a){return a.as}, +aB(a){return A.nd(v.typeUniverse,a,!1)}, +wZ(a,b){var s,r,q,p,o +if(a==null)return null +s=b.y +r=a.Q +if(r==null)r=a.Q=new Map() +q=b.as +p=r.get(q) +if(p!=null)return p +o=A.cj(v.typeUniverse,a.x,s,0) +r.set(q,o) +return o}, +cj(a1,a2,a3,a4){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0=a2.w +switch(a0){case 5:case 1:case 2:case 3:case 4:return a2 +case 6:s=a2.x +r=A.cj(a1,s,a3,a4) +if(r===s)return a2 +return A.qz(a1,r,!0) +case 7:s=a2.x +r=A.cj(a1,s,a3,a4) +if(r===s)return a2 +return A.qy(a1,r,!0) +case 8:q=a2.y +p=A.dY(a1,q,a3,a4) +if(p===q)return a2 +return A.fs(a1,a2.x,p) +case 9:o=a2.x +n=A.cj(a1,o,a3,a4) +m=a2.y +l=A.dY(a1,m,a3,a4) +if(n===o&&l===m)return a2 +return A.oA(a1,n,l) +case 10:k=a2.x +j=a2.y +i=A.dY(a1,j,a3,a4) +if(i===j)return a2 +return A.qA(a1,k,i) +case 11:h=a2.x +g=A.cj(a1,h,a3,a4) +f=a2.y +e=A.wf(a1,f,a3,a4) +if(g===h&&e===f)return a2 +return A.qx(a1,g,e) +case 12:d=a2.y +a4+=d.length +c=A.dY(a1,d,a3,a4) +o=a2.x +n=A.cj(a1,o,a3,a4) +if(c===d&&n===o)return a2 +return A.oB(a1,n,c,!0) +case 13:b=a2.x +if(b") +for(r=1;r=0)p+=" "+r[q];++q}return p+"})"}, +qZ(a1,a2,a3){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a=", ",a0=null +if(a3!=null){s=a3.length +if(a2==null)a2=A.f([],t.s) +else a0=a2.length +r=a2.length +for(q=s;q>0;--q)a2.push("T"+(r+q)) +for(p=t.X,o="<",n="",q=0;q0){c+=b+"[" +for(b="",q=0;q0){c+=b+"{" +for(b="",q=0;q "+d}, +aZ(a,b){var s,r,q,p,o,n,m=a.w +if(m===5)return"erased" +if(m===2)return"dynamic" +if(m===3)return"void" +if(m===1)return"Never" +if(m===4)return"any" +if(m===6){s=a.x +r=A.aZ(s,b) +q=s.w +return(q===11||q===12?"("+r+")":r)+"?"}if(m===7)return"FutureOr<"+A.aZ(a.x,b)+">" +if(m===8){p=A.wh(a.x) +o=a.y +return o.length>0?p+("<"+A.r8(o,b)+">"):p}if(m===10)return A.w1(a,b) +if(m===11)return A.qZ(a,b,null) +if(m===12)return A.qZ(a.x,b,a.y) +if(m===13){n=a.x +return b[b.length-1-n]}return"?"}, +wh(a){var s=v.mangledGlobalNames[a] +if(s!=null)return s +return"minified:"+a}, +v4(a,b){var s=a.tR[b] +while(typeof s=="string")s=a.tR[s] +return s}, +v3(a,b){var s,r,q,p,o,n=a.eT,m=n[b] +if(m==null)return A.nd(a,b,!1) +else if(typeof m=="number"){s=m +r=A.ft(a,5,"#") +q=A.nl(s) +for(p=0;p0)p+="<"+A.fr(c)+">" +s=a.eC.get(p) +if(s!=null)return s +r=new A.be(null,null) +r.w=8 +r.x=b +r.y=c +if(c.length>0)r.c=c[0] +r.as=p +q=A.ch(a,r) +a.eC.set(p,q) +return q}, +oA(a,b,c){var s,r,q,p,o,n +if(b.w===9){s=b.x +r=b.y.concat(c)}else{r=c +s=b}q=s.as+(";<"+A.fr(r)+">") +p=a.eC.get(q) +if(p!=null)return p +o=new A.be(null,null) +o.w=9 +o.x=s +o.y=r +o.as=q +n=A.ch(a,o) +a.eC.set(q,n) +return n}, +qA(a,b,c){var s,r,q="+"+(b+"("+A.fr(c)+")"),p=a.eC.get(q) +if(p!=null)return p +s=new A.be(null,null) +s.w=10 +s.x=b +s.y=c +s.as=q +r=A.ch(a,s) +a.eC.set(q,r) +return r}, +qx(a,b,c){var s,r,q,p,o,n=b.as,m=c.a,l=m.length,k=c.b,j=k.length,i=c.c,h=i.length,g="("+A.fr(m) +if(j>0){s=l>0?",":"" +g+=s+"["+A.fr(k)+"]"}if(h>0){s=l>0?",":"" +g+=s+"{"+A.uX(i)+"}"}r=n+(g+")") +q=a.eC.get(r) +if(q!=null)return q +p=new A.be(null,null) +p.w=11 +p.x=b +p.y=c +p.as=r +o=A.ch(a,p) +a.eC.set(r,o) +return o}, +oB(a,b,c,d){var s,r=b.as+("<"+A.fr(c)+">"),q=a.eC.get(r) +if(q!=null)return q +s=A.uZ(a,b,c,r,d) +a.eC.set(r,s) +return s}, +uZ(a,b,c,d,e){var s,r,q,p,o,n,m,l +if(e){s=c.length +r=A.nl(s) +for(q=0,p=0;p0){n=A.cj(a,b,r,0) +m=A.dY(a,c,r,0) +return A.oB(a,n,m,c!==m)}}l=new A.be(null,null) +l.w=12 +l.x=b +l.y=c +l.as=d +return A.ch(a,l)}, +qr(a,b,c,d){return{u:a,e:b,r:c,s:[],p:0,n:d}}, +qt(a){var s,r,q,p,o,n,m,l=a.r,k=a.s +for(s=l.length,r=0;r=48&&q<=57)r=A.uP(r+1,q,l,k) +else if((((q|32)>>>0)-97&65535)<26||q===95||q===36||q===124)r=A.qs(a,r,l,k,!1) +else if(q===46)r=A.qs(a,r,l,k,!0) +else{++r +switch(q){case 44:break +case 58:k.push(!1) +break +case 33:k.push(!0) +break +case 59:k.push(A.cN(a.u,a.e,k.pop())) +break +case 94:k.push(A.v0(a.u,k.pop())) +break +case 35:k.push(A.ft(a.u,5,"#")) +break +case 64:k.push(A.ft(a.u,2,"@")) +break +case 126:k.push(A.ft(a.u,3,"~")) +break +case 60:k.push(a.p) +a.p=k.length +break +case 62:A.uR(a,k) +break +case 38:A.uQ(a,k) +break +case 63:p=a.u +k.push(A.qz(p,A.cN(p,a.e,k.pop()),a.n)) +break +case 47:p=a.u +k.push(A.qy(p,A.cN(p,a.e,k.pop()),a.n)) +break +case 40:k.push(-3) +k.push(a.p) +a.p=k.length +break +case 41:A.uO(a,k) +break +case 91:k.push(a.p) +a.p=k.length +break +case 93:o=k.splice(a.p) +A.qu(a.u,a.e,o) +a.p=k.pop() +k.push(o) +k.push(-1) +break +case 123:k.push(a.p) +a.p=k.length +break +case 125:o=k.splice(a.p) +A.uT(a.u,a.e,o) +a.p=k.pop() +k.push(o) +k.push(-2) +break +case 43:n=l.indexOf("(",r) +k.push(l.substring(r,n)) +k.push(-4) +k.push(a.p) +a.p=k.length +r=n+1 +break +default:throw"Bad character "+q}}}m=k.pop() +return A.cN(a.u,a.e,m)}, +uP(a,b,c,d){var s,r,q=b-48 +for(s=c.length;a=48&&r<=57))break +q=q*10+(r-48)}d.push(q) +return a}, +qs(a,b,c,d,e){var s,r,q,p,o,n,m=b+1 +for(s=c.length;m>>0)-97&65535)<26||r===95||r===36||r===124))q=r>=48&&r<=57 +else q=!0 +if(!q)break}}p=c.substring(b,m) +if(e){s=a.u +o=a.e +if(o.w===9)o=o.x +n=A.v4(s,o.x)[p] +if(n==null)A.C('No "'+p+'" in "'+A.ui(o)+'"') +d.push(A.fu(s,o,n))}else d.push(p) +return m}, +uR(a,b){var s,r=a.u,q=A.qq(a,b),p=b.pop() +if(typeof p=="string")b.push(A.fs(r,p,q)) +else{s=A.cN(r,a.e,p) +switch(s.w){case 11:b.push(A.oB(r,s,q,a.n)) +break +default:b.push(A.oA(r,s,q)) +break}}}, +uO(a,b){var s,r,q,p=a.u,o=b.pop(),n=null,m=null +if(typeof o=="number")switch(o){case-1:n=b.pop() +break +case-2:m=b.pop() +break +default:b.push(o) +break}else b.push(o) +s=A.qq(a,b) +o=b.pop() +switch(o){case-3:o=b.pop() +if(n==null)n=p.sEA +if(m==null)m=p.sEA +r=A.cN(p,a.e,o) +q=new A.iq() +q.a=s +q.b=n +q.c=m +b.push(A.qx(p,r,q)) +return +case-4:b.push(A.qA(p,b.pop(),s)) +return +default:throw A.b(A.e8("Unexpected state under `()`: "+A.t(o)))}}, +uQ(a,b){var s=b.pop() +if(0===s){b.push(A.ft(a.u,1,"0&")) +return}if(1===s){b.push(A.ft(a.u,4,"1&")) +return}throw A.b(A.e8("Unexpected extended operation "+A.t(s)))}, +qq(a,b){var s=b.splice(a.p) +A.qu(a.u,a.e,s) +a.p=b.pop() +return s}, +cN(a,b,c){if(typeof c=="string")return A.fs(a,c,a.sEA) +else if(typeof c=="number"){b.toString +return A.uS(a,b,c)}else return c}, +qu(a,b,c){var s,r=c.length +for(s=0;sn)return!1 +m=n-o +l=s.b +k=r.b +j=l.length +i=k.length +if(o+j=d)return!1 +a1=f[b] +b+=3 +if(a00?new Array(q):v.typeUniverse.sEA +for(o=0;o0?new Array(a):v.typeUniverse.sEA}, +be:function be(a,b){var _=this +_.a=a +_.b=b +_.r=_.f=_.d=_.c=null +_.w=0 +_.as=_.Q=_.z=_.y=_.x=null}, +iq:function iq(){this.c=this.b=this.a=null}, +nc:function nc(a){this.a=a}, +il:function il(){}, +fq:function fq(a){this.a=a}, +uC(){var s,r,q +if(self.scheduleImmediate!=null)return A.wl() +if(self.MutationObserver!=null&&self.document!=null){s={} +r=self.document.createElement("div") +q=self.document.createElement("span") +s.a=null +new self.MutationObserver(A.ck(new A.m9(s),1)).observe(r,{childList:true}) +return new A.m8(s,r,q)}else if(self.setImmediate!=null)return A.wm() +return A.wn()}, +uD(a){self.scheduleImmediate(A.ck(new A.ma(a),0))}, +uE(a){self.setImmediate(A.ck(new A.mb(a),0))}, +uF(a){A.om(B.y,a)}, +om(a,b){var s=B.b.J(a.a,1000) +return A.uV(s<0?0:s,b)}, +uV(a,b){var s=new A.iO() +s.hV(a,b) +return s}, +uW(a,b){var s=new A.iO() +s.hW(a,b) +return s}, +l(a){return new A.i9(new A.n($.h,a.h("n<0>")),a.h("i9<0>"))}, +k(a,b){a.$2(0,null) +b.b=!0 +return b.a}, +c(a,b){A.vp(a,b)}, +j(a,b){b.P(a)}, +i(a,b){b.bv(A.G(a),A.a1(a))}, +vp(a,b){var s,r,q=new A.nm(b),p=new A.nn(b) +if(a instanceof A.n)a.fM(q,p,t.z) +else{s=t.z +if(a instanceof A.n)a.bE(q,p,s) +else{r=new A.n($.h,t.eI) +r.a=8 +r.c=a +r.fM(q,p,s)}}}, +m(a){var s=function(b,c){return function(d,e){while(true){try{b(d,e) +break}catch(r){e=r +d=c}}}}(a,1) +return $.h.d6(new A.nA(s),t.H,t.S,t.z)}, +qw(a,b,c){return 0}, +fO(a){var s +if(t.C.b(a)){s=a.gbi() +if(s!=null)return s}return B.v}, +tS(a,b){var s=new A.n($.h,b.h("n<0>")) +A.q0(B.y,new A.ki(a,s)) +return s}, +kh(a,b){var s,r,q,p,o,n,m,l=null +try{l=a.$0()}catch(q){s=A.G(q) +r=A.a1(q) +p=new A.n($.h,b.h("n<0>")) +o=s +n=r +m=A.cS(o,n) +if(m==null)o=new A.U(o,n==null?A.fO(o):n) +else o=m +p.aN(o) +return p}return b.h("D<0>").b(l)?l:A.dC(l,b)}, +bc(a,b){var s=a==null?b.a(a):a,r=new A.n($.h,b.h("n<0>")) +r.b0(s) +return r}, +pu(a,b){var s +if(!b.b(null))throw A.b(A.ad(null,"computation","The type parameter is not nullable")) +s=new A.n($.h,b.h("n<0>")) +A.q0(a,new A.kg(null,s,b)) +return s}, +o4(a,b){var s,r,q,p,o,n,m,l,k,j,i={},h=null,g=!1,f=new A.n($.h,b.h("n>")) +i.a=null +i.b=0 +i.c=i.d=null +s=new A.kk(i,h,g,f) +try{for(n=J.a4(a),m=t.P;n.k();){r=n.gm() +q=i.b +r.bE(new A.kj(i,q,f,b,h,g),s,m);++i.b}n=i.b +if(n===0){n=f +n.bI(A.f([],b.h("u<0>"))) +return n}i.a=A.b4(n,null,!1,b.h("0?"))}catch(l){p=A.G(l) +o=A.a1(l) +if(i.b===0||g){n=f +m=p +k=o +j=A.cS(m,k) +if(j==null)m=new A.U(m,k==null?A.fO(m):k) +else m=j +n.aN(m) +return n}else{i.d=p +i.c=o}}return f}, +cS(a,b){var s,r,q,p=$.h +if(p===B.d)return null +s=p.h3(a,b) +if(s==null)return null +r=s.a +q=s.b +if(t.C.b(r))A.eH(r,q) +return s}, +ns(a,b){var s +if($.h!==B.d){s=A.cS(a,b) +if(s!=null)return s}if(b==null)if(t.C.b(a)){b=a.gbi() +if(b==null){A.eH(a,B.v) +b=B.v}}else b=B.v +else if(t.C.b(a))A.eH(a,b) +return new A.U(a,b)}, +uN(a,b,c){var s=new A.n(b,c.h("n<0>")) +s.a=8 +s.c=a +return s}, +dC(a,b){var s=new A.n($.h,b.h("n<0>")) +s.a=8 +s.c=a +return s}, +mH(a,b,c){var s,r,q,p={},o=p.a=a +while(s=o.a,(s&4)!==0){o=o.c +p.a=o}if(o===b){s=A.la() +b.aN(new A.U(new A.bb(!0,o,null,"Cannot complete a future with itself"),s)) +return}r=b.a&1 +s=o.a=s|r +if((s&24)===0){q=b.c +b.a=b.a&1|4 +b.c=o +o.fq(q) +return}if(!c)if(b.c==null)o=(s&16)===0||r!==0 +else o=!1 +else o=!0 +if(o){q=b.bP() +b.cs(p.a) +A.cJ(b,q) +return}b.a^=2 +b.b.aY(new A.mI(p,b))}, +cJ(a,b){var s,r,q,p,o,n,m,l,k,j,i,h,g={},f=g.a=a +for(;;){s={} +r=f.a +q=(r&16)===0 +p=!q +if(b==null){if(p&&(r&1)===0){r=f.c +f.b.c1(r.a,r.b)}return}s.a=b +o=b.a +for(f=b;o!=null;f=o,o=n){f.a=null +A.cJ(g.a,f) +s.a=o +n=o.a}r=g.a +m=r.c +s.b=p +s.c=m +if(q){l=f.c +l=(l&1)!==0||(l&15)===8}else l=!0 +if(l){k=f.b.b +if(p){f=r.b +f=!(f===k||f.gaI()===k.gaI())}else f=!1 +if(f){f=g.a +r=f.c +f.b.c1(r.a,r.b) +return}j=$.h +if(j!==k)$.h=k +else j=null +f=s.a.c +if((f&15)===8)new A.mM(s,g,p).$0() +else if(q){if((f&1)!==0)new A.mL(s,m).$0()}else if((f&2)!==0)new A.mK(g,s).$0() +if(j!=null)$.h=j +f=s.c +if(f instanceof A.n){r=s.a.$ti +r=r.h("D<2>").b(f)||!r.y[1].b(f)}else r=!1 +if(r){i=s.a.b +if((f.a&24)!==0){h=i.c +i.c=null +b=i.cC(h) +i.a=f.a&30|i.a&1 +i.c=f.c +g.a=f +continue}else A.mH(f,i,!0) +return}}i=s.a.b +h=i.c +i.c=null +b=i.cC(h) +f=s.b +r=s.c +if(!f){i.a=8 +i.c=r}else{i.a=i.a&1|16 +i.c=r}g.a=i +f=i}}, +w3(a,b){if(t._.b(a))return b.d6(a,t.z,t.K,t.l) +if(t.bI.b(a))return b.b9(a,t.z,t.K) +throw A.b(A.ad(a,"onError",u.c))}, +vW(){var s,r +for(s=$.dX;s!=null;s=$.dX){$.fC=null +r=s.b +$.dX=r +if(r==null)$.fB=null +s.a.$0()}}, +we(){$.oL=!0 +try{A.vW()}finally{$.fC=null +$.oL=!1 +if($.dX!=null)$.p7().$1(A.rg())}}, +ra(a){var s=new A.ia(a),r=$.fB +if(r==null){$.dX=$.fB=s +if(!$.oL)$.p7().$1(A.rg())}else $.fB=r.b=s}, +wb(a){var s,r,q,p=$.dX +if(p==null){A.ra(a) +$.fC=$.fB +return}s=new A.ia(a) +r=$.fC +if(r==null){s.b=p +$.dX=$.fC=s}else{q=r.b +s.b=q +$.fC=r.b=s +if(q==null)$.fB=s}}, +p_(a){var s,r=null,q=$.h +if(B.d===q){A.nx(r,r,B.d,a) +return}if(B.d===q.ge1().a)s=B.d.gaI()===q.gaI() +else s=!1 +if(s){A.nx(r,r,q,q.au(a,t.H)) +return}s=$.h +s.aY(s.cP(a))}, +xF(a){return new A.dO(A.cU(a,"stream",t.K))}, +eP(a,b,c,d){var s=null +return c?new A.dS(b,s,s,a,d.h("dS<0>")):new A.dw(b,s,s,a,d.h("dw<0>"))}, +iW(a){var s,r,q +if(a==null)return +try{a.$0()}catch(q){s=A.G(q) +r=A.a1(q) +$.h.c1(s,r)}}, +uM(a,b,c,d,e,f){var s=$.h,r=e?1:0,q=c!=null?32:0,p=A.ig(s,b,f),o=A.ih(s,c),n=d==null?A.rf():d +return new A.cf(a,p,o,s.au(n,t.H),s,r|q,f.h("cf<0>"))}, +ig(a,b,c){var s=b==null?A.wo():b +return a.b9(s,t.H,c)}, +ih(a,b){if(b==null)b=A.wp() +if(t.da.b(b))return a.d6(b,t.z,t.K,t.l) +if(t.d5.b(b))return a.b9(b,t.z,t.K) +throw A.b(A.J("handleError callback must take either an Object (the error), or both an Object (the error) and a StackTrace.",null))}, +vX(a){}, +vZ(a,b){$.h.c1(a,b)}, +vY(){}, +w9(a,b,c){var s,r,q,p +try{b.$1(a.$0())}catch(p){s=A.G(p) +r=A.a1(p) +q=A.cS(s,r) +if(q!=null)c.$2(q.a,q.b) +else c.$2(s,r)}}, +vv(a,b,c){var s=a.K() +if(s!==$.cm())s.ai(new A.np(b,c)) +else b.X(c)}, +vw(a,b){return new A.no(a,b)}, +qS(a,b,c){var s=a.K() +if(s!==$.cm())s.ai(new A.nq(b,c)) +else b.b1(c)}, +uU(a,b,c){return new A.dM(new A.n5(null,null,a,c,b),b.h("@<0>").H(c).h("dM<1,2>"))}, +q0(a,b){var s=$.h +if(s===B.d)return s.eh(a,b) +return s.eh(a,s.cP(b))}, +xf(a,b,c){return A.wa(a,b,null,c)}, +wa(a,b,c,d){return $.h.h6(c,b).bb(a,d)}, +w7(a,b,c,d,e){A.fD(d,e)}, +fD(a,b){A.wb(new A.nt(a,b))}, +nu(a,b,c,d){var s,r=$.h +if(r===c)return d.$0() +$.h=c +s=r +try{r=d.$0() +return r}finally{$.h=s}}, +nw(a,b,c,d,e){var s,r=$.h +if(r===c)return d.$1(e) +$.h=c +s=r +try{r=d.$1(e) +return r}finally{$.h=s}}, +nv(a,b,c,d,e,f){var s,r=$.h +if(r===c)return d.$2(e,f) +$.h=c +s=r +try{r=d.$2(e,f) +return r}finally{$.h=s}}, +r6(a,b,c,d){return d}, +r7(a,b,c,d){return d}, +r5(a,b,c,d){return d}, +w6(a,b,c,d,e){return null}, +nx(a,b,c,d){var s,r +if(B.d!==c){s=B.d.gaI() +r=c.gaI() +d=s!==r?c.cP(d):c.ed(d,t.H)}A.ra(d)}, +w5(a,b,c,d,e){return A.om(d,B.d!==c?c.ed(e,t.H):e)}, +w4(a,b,c,d,e){var s +if(B.d!==c)e=c.fW(e,t.H,t.aF) +s=B.b.J(d.a,1000) +return A.uW(s<0?0:s,e)}, +w8(a,b,c,d){A.oZ(d)}, +w0(a){$.h.hi(a)}, +r4(a,b,c,d,e){var s,r,q +$.rt=A.wq() +if(d==null)d=B.bC +if(e==null)s=c.gfl() +else{r=t.X +s=A.tT(e,r,r)}r=new A.ii(c.gfD(),c.gfF(),c.gfE(),c.gfz(),c.gfA(),c.gfw(),c.gfc(),c.ge1(),c.gf7(),c.gf6(),c.gfs(),c.gff(),c.gdS(),c,s) +q=d.a +if(q!=null)r.as=new A.ay(r,q) +return r}, +m9:function m9(a){this.a=a}, +m8:function m8(a,b,c){this.a=a +this.b=b +this.c=c}, +ma:function ma(a){this.a=a}, +mb:function mb(a){this.a=a}, +iO:function iO(){this.c=0}, +nb:function nb(a,b){this.a=a +this.b=b}, +na:function na(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +i9:function i9(a,b){this.a=a +this.b=!1 +this.$ti=b}, +nm:function nm(a){this.a=a}, +nn:function nn(a){this.a=a}, +nA:function nA(a){this.a=a}, +iM:function iM(a){var _=this +_.a=a +_.e=_.d=_.c=_.b=null}, +dR:function dR(a,b){this.a=a +this.$ti=b}, +U:function U(a,b){this.a=a +this.b=b}, +eZ:function eZ(a,b){this.a=a +this.$ti=b}, +cG:function cG(a,b,c,d,e,f,g){var _=this +_.ay=0 +_.CW=_.ch=null +_.w=a +_.a=b +_.b=c +_.c=d +_.d=e +_.e=f +_.r=_.f=null +_.$ti=g}, +cF:function cF(){}, +fp:function fp(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.r=_.f=_.e=_.d=null +_.$ti=c}, +n7:function n7(a,b){this.a=a +this.b=b}, +n9:function n9(a,b,c){this.a=a +this.b=b +this.c=c}, +n8:function n8(a){this.a=a}, +ki:function ki(a,b){this.a=a +this.b=b}, +kg:function kg(a,b,c){this.a=a +this.b=b +this.c=c}, +kk:function kk(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +kj:function kj(a,b,c,d,e,f){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f}, +dx:function dx(){}, +a6:function a6(a,b){this.a=a +this.$ti=b}, +a8:function a8(a,b){this.a=a +this.$ti=b}, +cg:function cg(a,b,c,d,e){var _=this +_.a=null +_.b=a +_.c=b +_.d=c +_.e=d +_.$ti=e}, +n:function n(a,b){var _=this +_.a=0 +_.b=a +_.c=null +_.$ti=b}, +mE:function mE(a,b){this.a=a +this.b=b}, +mJ:function mJ(a,b){this.a=a +this.b=b}, +mI:function mI(a,b){this.a=a +this.b=b}, +mG:function mG(a,b){this.a=a +this.b=b}, +mF:function mF(a,b){this.a=a +this.b=b}, +mM:function mM(a,b,c){this.a=a +this.b=b +this.c=c}, +mN:function mN(a,b){this.a=a +this.b=b}, +mO:function mO(a){this.a=a}, +mL:function mL(a,b){this.a=a +this.b=b}, +mK:function mK(a,b){this.a=a +this.b=b}, +ia:function ia(a){this.a=a +this.b=null}, +V:function V(){}, +li:function li(a,b){this.a=a +this.b=b}, +lj:function lj(a,b){this.a=a +this.b=b}, +lg:function lg(a){this.a=a}, +lh:function lh(a,b,c){this.a=a +this.b=b +this.c=c}, +le:function le(a,b){this.a=a +this.b=b}, +lf:function lf(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +lc:function lc(a,b){this.a=a +this.b=b}, +ld:function ld(a,b,c){this.a=a +this.b=b +this.c=c}, +hP:function hP(){}, +cP:function cP(){}, +n4:function n4(a){this.a=a}, +n3:function n3(a){this.a=a}, +iN:function iN(){}, +ib:function ib(){}, +dw:function dw(a,b,c,d,e){var _=this +_.a=null +_.b=0 +_.c=null +_.d=a +_.e=b +_.f=c +_.r=d +_.$ti=e}, +dS:function dS(a,b,c,d,e){var _=this +_.a=null +_.b=0 +_.c=null +_.d=a +_.e=b +_.f=c +_.r=d +_.$ti=e}, +ar:function ar(a,b){this.a=a +this.$ti=b}, +cf:function cf(a,b,c,d,e,f,g){var _=this +_.w=a +_.a=b +_.b=c +_.c=d +_.d=e +_.e=f +_.r=_.f=null +_.$ti=g}, +dP:function dP(a){this.a=a}, +ag:function ag(){}, +mm:function mm(a,b,c){this.a=a +this.b=b +this.c=c}, +ml:function ml(a){this.a=a}, +dN:function dN(){}, +ik:function ik(){}, +dy:function dy(a){this.b=a +this.a=null}, +f2:function f2(a,b){this.b=a +this.c=b +this.a=null}, +mw:function mw(){}, +fh:function fh(){this.a=0 +this.c=this.b=null}, +mU:function mU(a,b){this.a=a +this.b=b}, +f3:function f3(a){this.a=1 +this.b=a +this.c=null}, +dO:function dO(a){this.a=null +this.b=a +this.c=!1}, +np:function np(a,b){this.a=a +this.b=b}, +no:function no(a,b){this.a=a +this.b=b}, +nq:function nq(a,b){this.a=a +this.b=b}, +f8:function f8(){}, +dA:function dA(a,b,c,d,e,f,g){var _=this +_.w=a +_.x=null +_.a=b +_.b=c +_.c=d +_.d=e +_.e=f +_.r=_.f=null +_.$ti=g}, +fc:function fc(a,b,c){this.b=a +this.a=b +this.$ti=c}, +f5:function f5(a){this.a=a}, +dL:function dL(a,b,c,d,e,f){var _=this +_.w=$ +_.x=null +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.r=_.f=null +_.$ti=f}, +fo:function fo(){}, +eY:function eY(a,b,c){this.a=a +this.b=b +this.$ti=c}, +dD:function dD(a,b,c,d,e){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.$ti=e}, +dM:function dM(a,b){this.a=a +this.$ti=b}, +n5:function n5(a,b,c,d,e){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e}, +ay:function ay(a,b){this.a=a +this.b=b}, +iT:function iT(){}, +ii:function ii(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f +_.r=g +_.w=h +_.x=i +_.y=j +_.z=k +_.Q=l +_.as=m +_.at=null +_.ax=n +_.ay=o}, +mt:function mt(a,b,c){this.a=a +this.b=b +this.c=c}, +mv:function mv(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +ms:function ms(a,b){this.a=a +this.b=b}, +mu:function mu(a,b,c){this.a=a +this.b=b +this.c=c}, +iH:function iH(){}, +mZ:function mZ(a,b,c){this.a=a +this.b=b +this.c=c}, +n0:function n0(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +mY:function mY(a,b){this.a=a +this.b=b}, +n_:function n_(a,b,c){this.a=a +this.b=b +this.c=c}, +dU:function dU(a){this.a=a}, +nt:function nt(a,b){this.a=a +this.b=b}, +iU:function iU(a,b,c,d,e,f,g,h,i,j,k,l,m){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f +_.r=g +_.w=h +_.x=i +_.y=j +_.z=k +_.Q=l +_.as=m}, +pw(a,b){return new A.cK(a.h("@<0>").H(b).h("cK<1,2>"))}, +qp(a,b){var s=a[b] +return s===a?null:s}, +oy(a,b,c){if(c==null)a[b]=a +else a[b]=c}, +ox(){var s=Object.create(null) +A.oy(s,"",s) +delete s[""] +return s}, +u0(a,b){return new A.bA(a.h("@<0>").H(b).h("bA<1,2>"))}, +u1(a,b,c){return A.wN(a,new A.bA(b.h("@<0>").H(c).h("bA<1,2>")))}, +al(a,b){return new A.bA(a.h("@<0>").H(b).h("bA<1,2>"))}, +ob(a){return new A.fa(a.h("fa<0>"))}, +oz(){var s=Object.create(null) +s[""]=s +delete s[""] +return s}, +ix(a,b,c){var s=new A.dG(a,b,c.h("dG<0>")) +s.c=a.e +return s}, +tT(a,b,c){var s=A.pw(b,c) +a.ap(0,new A.kn(s,b,c)) +return s}, +oc(a){var s,r +if(A.oW(a))return"{...}" +s=new A.aA("") +try{r={} +$.cT.push(a) +s.a+="{" +r.a=!0 +a.ap(0,new A.kE(r,s)) +s.a+="}"}finally{$.cT.pop()}r=s.a +return r.charCodeAt(0)==0?r:r}, +cK:function cK(a){var _=this +_.a=0 +_.e=_.d=_.c=_.b=null +_.$ti=a}, +mP:function mP(a){this.a=a}, +dE:function dE(a){var _=this +_.a=0 +_.e=_.d=_.c=_.b=null +_.$ti=a}, +cL:function cL(a,b){this.a=a +this.$ti=b}, +ir:function ir(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.d=null +_.$ti=c}, +fa:function fa(a){var _=this +_.a=0 +_.f=_.e=_.d=_.c=_.b=null +_.r=0 +_.$ti=a}, +mT:function mT(a){this.a=a +this.c=this.b=null}, +dG:function dG(a,b,c){var _=this +_.a=a +_.b=b +_.d=_.c=null +_.$ti=c}, +kn:function kn(a,b,c){this.a=a +this.b=b +this.c=c}, +ey:function ey(a){var _=this +_.b=_.a=0 +_.c=null +_.$ti=a}, +iy:function iy(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=null +_.d=c +_.e=!1 +_.$ti=d}, +aL:function aL(){}, +v:function v(){}, +Q:function Q(){}, +kD:function kD(a){this.a=a}, +kE:function kE(a,b){this.a=a +this.b=b}, +fb:function fb(a,b){this.a=a +this.$ti=b}, +iz:function iz(a,b,c){var _=this +_.a=a +_.b=b +_.c=null +_.$ti=c}, +dl:function dl(){}, +fk:function fk(){}, +vh(a,b,c){var s,r,q,p,o=c-b +if(o<=4096)s=$.rW() +else s=new Uint8Array(o) +for(r=J.a0(a),q=0;q=16)return null +r=r*16+o}n=h-1 +i[h]=r +for(;s=16)return null +r=r*16+o}m=n-1 +i[n]=r}if(j===1&&i[0]===0)return $.ba() +l=A.aR(j,i) +return new A.a7(l===0?!1:c,i,l)}, +qn(a,b){var s,r,q,p,o +if(a==="")return null +s=$.rP().a8(a) +if(s==null)return null +r=s.b +q=r[1]==="-" +p=r[4] +o=r[3] +if(p!=null)return A.uJ(p,q) +if(o!=null)return A.uK(o,2,q) +return null}, +aR(a,b){for(;;){if(!(a>0&&b[a-1]===0))break;--a}return a}, +ou(a,b,c,d){var s,r=new Uint16Array(d),q=c-b +for(s=0;s>>0)+(o>>>4)-1075 +m=new Uint16Array(4) +m[0]=(r[1]<<8>>>0)+r[0] +m[1]=(r[3]<<8>>>0)+r[2] +m[2]=(r[5]<<8>>>0)+r[4] +m[3]=o&15|16 +l=new A.a7(!1,m,4) +if(n<0)k=l.bh(0,-n) +else k=n>0?l.b_(0,n):l +if(s)return k.aA(0) +return k}, +ov(a,b,c,d){var s,r,q +if(b===0)return 0 +if(c===0&&d===a)return b +for(s=b-1,r=d.$flags|0;s>=0;--s){q=a[s] +r&2&&A.y(d) +d[s+c]=q}for(s=c-1;s>=0;--s){r&2&&A.y(d) +d[s]=0}return b+c}, +ql(a,b,c,d){var s,r,q,p,o,n=B.b.J(c,16),m=B.b.ac(c,16),l=16-m,k=B.b.b_(1,l)-1 +for(s=b-1,r=d.$flags|0,q=0;s>=0;--s){p=a[s] +o=B.b.bh(p,l) +r&2&&A.y(d) +d[s+n+1]=(o|q)>>>0 +q=B.b.b_((p&k)>>>0,m)}r&2&&A.y(d) +d[n]=q}, +qg(a,b,c,d){var s,r,q,p,o=B.b.J(c,16) +if(B.b.ac(c,16)===0)return A.ov(a,b,o,d) +s=b+o+1 +A.ql(a,b,c,d) +for(r=d.$flags|0,q=o;--q,q>=0;){r&2&&A.y(d) +d[q]=0}p=s-1 +return d[p]===0?p:s}, +uL(a,b,c,d){var s,r,q,p,o=B.b.J(c,16),n=B.b.ac(c,16),m=16-n,l=B.b.b_(1,n)-1,k=B.b.bh(a[o],n),j=b-o-1 +for(s=d.$flags|0,r=0;r>>0,m) +s&2&&A.y(d) +d[r]=(p|k)>>>0 +k=B.b.bh(q,n)}s&2&&A.y(d) +d[j]=k}, +mi(a,b,c,d){var s,r=b-d +if(r===0)for(s=b-1;s>=0;--s){r=a[s]-c[s] +if(r!==0)return r}return r}, +uH(a,b,c,d,e){var s,r,q +for(s=e.$flags|0,r=0,q=0;q=0;e=o,c=q){q=c+1 +p=a*b[c]+d[e]+r +o=e+1 +s&2&&A.y(d) +d[e]=p&65535 +r=B.b.J(p,65536)}for(;r!==0;e=o){n=d[e]+r +o=e+1 +s&2&&A.y(d) +d[e]=n&65535 +r=B.b.J(n,65536)}}, +uI(a,b,c){var s,r=b[c] +if(r===a)return 65535 +s=B.b.eW((r<<16|b[c-1])>>>0,a) +if(s>65535)return 65535 +return s}, +tJ(a){throw A.b(A.ad(a,"object","Expandos are not allowed on strings, numbers, bools, records or null"))}, +mD(a,b){var s=$.rR() +s=s==null?null:new s(A.ck(A.xs(a,b),1)) +return new A.ip(s,b.h("ip<0>"))}, +bh(a,b){var s=A.pP(a,b) +if(s!=null)return s +throw A.b(A.af(a,null,null))}, +tI(a,b){a=A.aa(a,new Error()) +a.stack=b.i(0) +throw a}, +b4(a,b,c,d){var s,r=c?J.pA(a,d):J.pz(a,d) +if(a!==0&&b!=null)for(s=0;s")) +for(s=J.a4(a);s.k();)r.push(s.gm()) +r.$flags=1 +return r}, +aw(a,b){var s,r +if(Array.isArray(a))return A.f(a.slice(0),b.h("u<0>")) +s=A.f([],b.h("u<0>")) +for(r=J.a4(a);r.k();)s.push(r.gm()) +return s}, +aM(a,b){var s=A.u3(a,!1,b) +s.$flags=3 +return s}, +q_(a,b,c){var s,r,q,p,o +A.ab(b,"start") +s=c==null +r=!s +if(r){q=c-b +if(q<0)throw A.b(A.S(c,b,null,"end",null)) +if(q===0)return""}if(Array.isArray(a)){p=a +o=p.length +if(s)c=o +return A.pR(b>0||c0)a=J.e7(a,b) +s=A.aw(a,t.S) +return A.pR(s)}, +pZ(a){return A.aP(a)}, +um(a,b,c){var s=a.length +if(b>=s)return"" +return A.ue(a,b,c==null||c>s?s:c)}, +H(a,b,c,d,e){return new A.cw(a,A.o8(a,d,b,e,c,""))}, +oj(a,b,c){var s=J.a4(b) +if(!s.k())return a +if(c.length===0){do a+=A.t(s.gm()) +while(s.k())}else{a+=A.t(s.gm()) +while(s.k())a=a+c+A.t(s.gm())}return a}, +eS(){var s,r,q=A.u9() +if(q==null)throw A.b(A.a3("'Uri.base' is not supported")) +s=$.qb +if(s!=null&&q===$.qa)return s +r=A.bt(q) +$.qb=r +$.qa=q +return r}, +vf(a,b,c,d){var s,r,q,p,o,n="0123456789ABCDEF" +if(c===B.j){s=$.rT() +s=s.b.test(b)}else s=!1 +if(s)return b +r=B.i.a5(b) +for(s=r.length,q=0,p="";q>>4&15]+n[o&15]}return p.charCodeAt(0)==0?p:p}, +la(){return A.a1(new Error())}, +pn(a,b,c){var s="microsecond" +if(b>999)throw A.b(A.S(b,0,999,s,null)) +if(a<-864e13||a>864e13)throw A.b(A.S(a,-864e13,864e13,"millisecondsSinceEpoch",null)) +if(a===864e13&&b!==0)throw A.b(A.ad(b,s,"Time including microseconds is outside valid range")) +A.cU(c,"isUtc",t.y) +return a}, +tE(a){var s=Math.abs(a),r=a<0?"-":"" +if(s>=1000)return""+a +if(s>=100)return r+"0"+s +if(s>=10)return r+"00"+s +return r+"000"+s}, +pm(a){if(a>=100)return""+a +if(a>=10)return"0"+a +return"00"+a}, +h0(a){if(a>=10)return""+a +return"0"+a}, +po(a,b){return new A.bx(a+1000*b)}, +o1(a,b){var s,r +for(s=0;s<5;++s){r=a[s] +if(r.b===b)return r}throw A.b(A.ad(b,"name","No enum value with that name"))}, +tH(a,b){var s,r,q=A.al(t.N,b) +for(s=0;s<2;++s){r=a[s] +q.t(0,r.b,r)}return q}, +h9(a){if(typeof a=="number"||A.bQ(a)||a==null)return J.b1(a) +if(typeof a=="string")return JSON.stringify(a) +return A.pQ(a)}, +pr(a,b){A.cU(a,"error",t.K) +A.cU(b,"stackTrace",t.l) +A.tI(a,b)}, +e8(a){return new A.fN(a)}, +J(a,b){return new A.bb(!1,null,b,a)}, +ad(a,b,c){return new A.bb(!0,a,b,c)}, +bT(a,b){return a}, +kN(a,b){return new A.dh(null,null,!0,a,b,"Value not in range")}, +S(a,b,c,d,e){return new A.dh(b,c,!0,a,d,"Invalid value")}, +pU(a,b,c,d){if(ac)throw A.b(A.S(a,b,c,d,null)) +return a}, +ug(a,b,c,d){if(0>a||a>=d)A.C(A.hf(a,d,b,null,c)) +return a}, +bd(a,b,c){if(0>a||a>c)throw A.b(A.S(a,0,c,"start",null)) +if(b!=null){if(a>b||b>c)throw A.b(A.S(b,a,c,"end",null)) +return b}return c}, +ab(a,b){if(a<0)throw A.b(A.S(a,0,null,b,null)) +return a}, +px(a,b){var s=b.b +return new A.eq(s,!0,a,null,"Index out of range")}, +hf(a,b,c,d,e){return new A.eq(b,!0,a,e,"Index out of range")}, +a3(a){return new A.eR(a)}, +q7(a){return new A.hT(a)}, +B(a){return new A.aQ(a)}, +au(a){return new A.fW(a)}, +k6(a){return new A.io(a)}, +af(a,b,c){return new A.aD(a,b,c)}, +tV(a,b,c){var s,r +if(A.oW(a)){if(b==="("&&c===")")return"(...)" +return b+"..."+c}s=A.f([],t.s) +$.cT.push(a) +try{A.vV(a,s)}finally{$.cT.pop()}r=A.oj(b,s,", ")+c +return r.charCodeAt(0)==0?r:r}, +o7(a,b,c){var s,r +if(A.oW(a))return b+"..."+c +s=new A.aA(b) +$.cT.push(a) +try{r=s +r.a=A.oj(r.a,a,", ")}finally{$.cT.pop()}s.a+=c +r=s.a +return r.charCodeAt(0)==0?r:r}, +vV(a,b){var s,r,q,p,o,n,m,l=a.gq(a),k=0,j=0 +for(;;){if(!(k<80||j<3))break +if(!l.k())return +s=A.t(l.gm()) +b.push(s) +k+=s.length+2;++j}if(!l.k()){if(j<=5)return +r=b.pop() +q=b.pop()}else{p=l.gm();++j +if(!l.k()){if(j<=4){b.push(A.t(p)) +return}r=A.t(p) +q=b.pop() +k+=r.length+2}else{o=l.gm();++j +for(;l.k();p=o,o=n){n=l.gm();++j +if(j>100){for(;;){if(!(k>75&&j>3))break +k-=b.pop().length+2;--j}b.push("...") +return}}q=A.t(p) +r=A.t(o) +k+=r.length+q.length+4}}if(j>b.length+2){k+=5 +m="..."}else m=null +for(;;){if(!(k>80&&b.length>3))break +k-=b.pop().length+2 +if(m==null){k+=5 +m="..."}}if(m!=null)b.push(m) +b.push(q) +b.push(r)}, +eD(a,b,c,d){var s +if(B.f===c){s=J.aC(a) +b=J.aC(b) +return A.ok(A.c9(A.c9($.nV(),s),b))}if(B.f===d){s=J.aC(a) +b=J.aC(b) +c=J.aC(c) +return A.ok(A.c9(A.c9(A.c9($.nV(),s),b),c))}s=J.aC(a) +b=J.aC(b) +c=J.aC(c) +d=J.aC(d) +d=A.ok(A.c9(A.c9(A.c9(A.c9($.nV(),s),b),c),d)) +return d}, +xd(a){var s=A.t(a),r=$.rt +if(r==null)A.oZ(s) +else r.$1(s)}, +q9(a){var s,r=null,q=new A.aA(""),p=A.f([-1],t.t) +A.uv(r,r,r,q,p) +p.push(q.a.length) +q.a+="," +A.uu(256,B.ak.kr(a),q) +s=q.a +return new A.hY(s.charCodeAt(0)==0?s:s,p,r).geM()}, +bt(a5){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1,a2,a3=null,a4=a5.length +if(a4>=5){s=((a5.charCodeAt(4)^58)*3|a5.charCodeAt(0)^100|a5.charCodeAt(1)^97|a5.charCodeAt(2)^116|a5.charCodeAt(3)^97)>>>0 +if(s===0)return A.q8(a4=14)r[7]=a4 +q=r[1] +if(q>=0)if(A.r9(a5,0,q,20,r)===20)r[7]=q +p=r[2]+1 +o=r[3] +n=r[4] +m=r[5] +l=r[6] +if(lq+3)){i=o>0 +if(!(i&&o+1===n)){if(!B.a.C(a5,"\\",n))if(p>0)h=B.a.C(a5,"\\",p-1)||B.a.C(a5,"\\",p-2) +else h=!1 +else h=!0 +if(!h){if(!(mn+2&&B.a.C(a5,"/..",m-3) +else h=!0 +if(!h)if(q===4){if(B.a.C(a5,"file",0)){if(p<=0){if(!B.a.C(a5,"/",n)){g="file:///" +s=3}else{g="file://" +s=2}a5=g+B.a.p(a5,n,a4) +m+=s +l+=s +a4=a5.length +p=7 +o=7 +n=7}else if(n===m){++l +f=m+1 +a5=B.a.aL(a5,n,m,"/");++a4 +m=f}j="file"}else if(B.a.C(a5,"http",0)){if(i&&o+3===n&&B.a.C(a5,"80",o+1)){l-=3 +e=n-3 +m-=3 +a5=B.a.aL(a5,o,n,"") +a4-=3 +n=e}j="http"}}else if(q===5&&B.a.C(a5,"https",0)){if(i&&o+4===n&&B.a.C(a5,"443",o+1)){l-=4 +e=n-4 +m-=4 +a5=B.a.aL(a5,o,n,"") +a4-=3 +n=e}j="https"}k=!h}}}}if(k)return new A.b6(a40)j=A.nh(a5,0,q) +else{if(q===0)A.dT(a5,0,"Invalid empty scheme") +j=""}d=a3 +if(p>0){c=q+3 +b=c=c?0:a.charCodeAt(q) +m=n^48 +if(m<=9){if(o!==0||q===r){o=o*10+m +if(o<=255){++q +continue}A.hZ("each part must be in the range 0..255",a,r)}A.hZ("parts must not have leading zeros",a,r)}if(q===r){if(q===c)break +A.hZ(k,a,q)}l=p+1 +s&2&&A.y(d) +d[e+p]=o +if(n===46){if(l<4){++q +p=l +r=q +o=0 +continue}break}if(q===c){if(l===4)return +break}A.hZ(k,a,q) +p=l}A.hZ("IPv4 address should contain exactly 4 parts",a,q)}, +ux(a,b,c){var s +if(b===c)throw A.b(A.af("Empty IP address",a,b)) +if(a.charCodeAt(b)===118){s=A.uy(a,b,c) +if(s!=null)throw A.b(s) +return!1}A.qc(a,b,c) +return!0}, +uy(a,b,c){var s,r,q,p,o="Missing hex-digit in IPvFuture address";++b +for(s=b;;s=r){if(s=97&&p<=102)continue +if(q===46){if(r-1===b)return new A.aD(o,a,r) +s=r +break}return new A.aD("Unexpected character",a,r-1)}if(s-1===b)return new A.aD(o,a,s) +return new A.aD("Missing '.' in IPvFuture address",a,s)}if(s===c)return new A.aD("Missing address in IPvFuture address, host, cursor",null,null) +for(;;){if((u.v.charCodeAt(a.charCodeAt(s))&16)!==0){++s +if(s=a3?0:a1.charCodeAt(p) +A:{k=l^48 +j=!1 +if(k<=9)i=k +else{h=l|32 +if(h>=97&&h<=102)i=h-87 +else break A +m=j}if(po){if(l===46){if(m){if(q<=6){A.uw(a1,o,a3,s,q*2) +q+=2 +p=a3 +break}a0.$2(a,o)}break}g=q*2 +s[g]=B.b.O(n,8) +s[g+1]=n&255;++q +if(l===58){if(q<8){++p +o=p +n=0 +m=!0 +continue}a0.$2(a,p)}break}if(l===58){if(r<0){f=q+1;++p +r=q +q=f +o=p +continue}a0.$2("only one wildcard `::` is allowed",p)}if(r!==q-1)a0.$2("missing part",p) +break}if(p0){c=e*2 +b=16-d*2 +B.e.M(s,b,16,s,c) +B.e.el(s,c,b,0)}}return s}, +fw(a,b,c,d,e,f,g){return new A.fv(a,b,c,d,e,f,g)}, +am(a,b,c,d){var s,r,q,p,o,n,m,l,k=null +d=d==null?"":A.nh(d,0,d.length) +s=A.qK(k,0,0) +a=A.qH(a,0,a==null?0:a.length,!1) +r=A.qJ(k,0,0,k) +q=A.qG(k,0,0) +p=A.ng(k,d) +o=d==="file" +if(a==null)n=s.length!==0||p!=null||o +else n=!1 +if(n)a="" +n=a==null +m=!n +b=A.qI(b,0,b==null?0:b.length,c,d,m) +l=d.length===0 +if(l&&n&&!B.a.u(b,"/"))b=A.oE(b,!l||m) +else b=A.cQ(b) +return A.fw(d,s,n&&B.a.u(b,"//")?"":a,p,b,r,q)}, +qD(a){if(a==="http")return 80 +if(a==="https")return 443 +return 0}, +dT(a,b,c){throw A.b(A.af(c,a,b))}, +qC(a,b){return b?A.vb(a,!1):A.va(a,!1)}, +v6(a,b){var s,r,q +for(s=a.length,r=0;r")),r=r.h("M.E");s.k();){q=s.d +if(q==null)q=r.a(q) +if(B.a.I(q,A.H('["*/:<>?\\\\|]',!0,!1,!1,!1)))if(b)throw A.b(A.J("Illegal character in path",null)) +else throw A.b(A.a3("Illegal character in path: "+q))}}, +v7(a,b){var s,r="Illegal drive letter " +if(!(65<=a&&a<=90))s=97<=a&&a<=122 +else s=!0 +if(s)return +if(b)throw A.b(A.J(r+A.pZ(a),null)) +else throw A.b(A.a3(r+A.pZ(a)))}, +va(a,b){var s=null,r=A.f(a.split("/"),t.s) +if(B.a.u(a,"/"))return A.am(s,s,r,"file") +else return A.am(s,s,r,s)}, +vb(a,b){var s,r,q,p,o="\\",n=null,m="file" +if(B.a.u(a,"\\\\?\\"))if(B.a.C(a,"UNC\\",4))a=B.a.aL(a,0,7,o) +else{a=B.a.N(a,4) +if(a.length<3||a.charCodeAt(1)!==58||a.charCodeAt(2)!==92)throw A.b(A.ad(a,"path","Windows paths with \\\\?\\ prefix must be absolute"))}else a=A.bi(a,"/",o) +s=a.length +if(s>1&&a.charCodeAt(1)===58){A.v7(a.charCodeAt(0),!0) +if(s===2||a.charCodeAt(2)!==92)throw A.b(A.ad(a,"path","Windows paths with drive letter must be absolute")) +r=A.f(a.split(o),t.s) +A.ne(r,!0,1) +return A.am(n,n,r,m)}if(B.a.u(a,o))if(B.a.C(a,o,1)){q=B.a.aU(a,o,2) +s=q<0 +p=s?B.a.N(a,2):B.a.p(a,2,q) +r=A.f((s?"":B.a.N(a,q+1)).split(o),t.s) +A.ne(r,!0,0) +return A.am(p,n,r,m)}else{r=A.f(a.split(o),t.s) +A.ne(r,!0,0) +return A.am(n,n,r,m)}else{r=A.f(a.split(o),t.s) +A.ne(r,!0,0) +return A.am(n,n,r,n)}}, +ng(a,b){if(a!=null&&a===A.qD(b))return null +return a}, +qH(a,b,c,d){var s,r,q,p,o,n,m,l +if(a==null)return null +if(b===c)return"" +if(a.charCodeAt(b)===91){s=c-1 +if(a.charCodeAt(s)!==93)A.dT(a,b,"Missing end `]` to match `[` in host") +r=b+1 +q="" +if(a.charCodeAt(r)!==118){p=A.v8(a,r,s) +if(p=b&&s=b&&s=p){if(i==null)i=new A.aA("") +if(r=o){if(q==null)q=new A.aA("") +if(r")).aq(0,"/")}else if(d!=null)throw A.b(A.J("Both path and pathSegments specified",null)) +else s=A.fx(a,b,c,128,!0,!0) +if(s.length===0){if(r)return"/"}else if(q&&!B.a.u(s,"/"))s="/"+s +return A.vc(s,e,f)}, +vc(a,b,c){var s=b.length===0 +if(s&&!c&&!B.a.u(a,"/")&&!B.a.u(a,"\\"))return A.oE(a,!s||c) +return A.cQ(a)}, +qJ(a,b,c,d){if(a!=null)return A.fx(a,b,c,256,!0,!1) +return null}, +qG(a,b,c){if(a==null)return null +return A.fx(a,b,c,256,!0,!1)}, +oD(a,b,c){var s,r,q,p,o,n=b+2 +if(n>=a.length)return"%" +s=a.charCodeAt(b+1) +r=a.charCodeAt(n) +q=A.nH(s) +p=A.nH(r) +if(q<0||p<0)return"%" +o=q*16+p +if(o<127&&(u.v.charCodeAt(o)&1)!==0)return A.aP(c&&65<=o&&90>=o?(o|32)>>>0:o) +if(s>=97||r>=97)return B.a.p(a,b,b+3).toUpperCase() +return null}, +oC(a){var s,r,q,p,o,n="0123456789ABCDEF" +if(a<=127){s=new Uint8Array(3) +s[0]=37 +s[1]=n.charCodeAt(a>>>4) +s[2]=n.charCodeAt(a&15)}else{if(a>2047)if(a>65535){r=240 +q=4}else{r=224 +q=3}else{r=192 +q=2}s=new Uint8Array(3*q) +for(p=0;--q,q>=0;r=128){o=B.b.jl(a,6*q)&63|r +s[p]=37 +s[p+1]=n.charCodeAt(o>>>4) +s[p+2]=n.charCodeAt(o&15) +p+=3}}return A.q_(s,0,null)}, +fx(a,b,c,d,e,f){var s=A.qM(a,b,c,d,e,f) +return s==null?B.a.p(a,b,c):s}, +qM(a,b,c,d,e,f){var s,r,q,p,o,n,m,l,k,j=null,i=u.v +for(s=!e,r=b,q=r,p=j;r=2&&A.qF(a.charCodeAt(0)))for(s=1;s127||(u.v.charCodeAt(r)&8)===0)break}return a}, +ve(a,b){if(a.kC("package")&&a.c==null)return A.rb(b,0,b.length) +return-1}, +v9(a,b){var s,r,q +for(s=0,r=0;r<2;++r){q=a.charCodeAt(b+r) +if(48<=q&&q<=57)s=s*16+q-48 +else{q|=32 +if(97<=q&&q<=102)s=s*16+q-87 +else throw A.b(A.J("Invalid URL encoding",null))}}return s}, +oF(a,b,c,d,e){var s,r,q,p,o=b +for(;;){if(!(o127)throw A.b(A.J("Illegal percent encoding in URI",null)) +if(r===37){if(o+3>q)throw A.b(A.J("Truncated URI",null)) +p.push(A.v9(a,o+1)) +o+=2}else p.push(r)}}return d.cS(p)}, +qF(a){var s=a|32 +return 97<=s&&s<=122}, +uv(a,b,c,d,e){d.a=d.a}, +q8(a,b,c){var s,r,q,p,o,n,m,l,k="Invalid MIME type",j=A.f([b-1],t.t) +for(s=a.length,r=b,q=-1,p=null;rb)throw A.b(A.af(k,a,r)) +while(p!==44){j.push(r);++r +for(o=-1;r=0)j.push(o) +else{n=B.c.gE(j) +if(p!==44||r!==n+7||!B.a.C(a,"base64",n+1))throw A.b(A.af("Expecting '='",a,r)) +break}}j.push(r) +m=r+1 +if((j.length&1)===1)a=B.al.kM(a,m,s) +else{l=A.qM(a,m,s,256,!0,!1) +if(l!=null)a=B.a.aL(a,m,s,l)}return new A.hY(a,j,c)}, +uu(a,b,c){var s,r,q,p,o,n="0123456789ABCDEF" +for(s=b.length,r=0,q=0;q>>4)) +c.a+=o +o=A.aP(n.charCodeAt(p&15)) +c.a+=o}}if((r&4294967040)!==0)for(q=0;q255)throw A.b(A.ad(p,"non-byte value",null))}}, +r9(a,b,c,d,e){var s,r,q +for(s=b;s95)r=31 +q='\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe3\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x0e\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xea\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\n\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xeb\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xeb\xeb\xeb\x8b\xeb\xeb\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xeb\x83\xeb\xeb\x8b\xeb\x8b\xeb\xcd\x8b\xeb\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x92\x83\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xeb\x8b\xeb\x8b\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xebD\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x12D\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\xe5\xe5\xe5\x05\xe5D\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe8\x8a\xe5\xe5\x05\xe5\x05\xe5\xcd\x05\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x8a\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05f\x05\xe5\x05\xe5\xac\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\xe5\xe5\xe5\x05\xe5D\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\x8a\xe5\xe5\x05\xe5\x05\xe5\xcd\x05\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x8a\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05f\x05\xe5\x05\xe5\xac\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7D\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\xe7\xe7\xe7\xe7\xe7\xe7\xcd\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\xe7\x07\x07\x07\x07\x07\x07\x07\x07\x07\xe7\xe7\xe7\xe7\xe7\xac\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7D\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\xe7\xe7\xe7\xe7\xe7\xe7\xcd\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xe7\xe7\xe7\xe7\xe7\xac\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\x05\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x10\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x12\n\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\v\n\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xec\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\xec\xec\xec\f\xec\xec\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\xec\xec\xec\xec\f\xec\f\xec\xcd\f\xec\f\f\f\f\f\f\f\f\f\xec\f\f\f\f\f\f\f\f\f\f\xec\f\xec\f\xec\f\xed\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xed\xed\xed\r\xed\xed\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xed\xed\xed\xed\r\xed\r\xed\xed\r\xed\r\r\r\r\r\r\r\r\r\xed\r\r\r\r\r\r\r\r\r\r\xed\r\xed\r\xed\r\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xea\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x0f\xea\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe9\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\t\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x11\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xe9\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\v\t\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x13\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\v\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xf5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\x15\xf5\x15\x15\xf5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xf5\xf5\xf5\xf5\xf5\xf5'.charCodeAt(d*96+r) +d=q&31 +e[q>>>5]=s}return d}, +qv(a){if(a.b===7&&B.a.u(a.a,"package")&&a.c<=0)return A.rb(a.a,a.e,a.f) +return-1}, +rb(a,b,c){var s,r,q +for(s=b,r=0;s=1)return a.$1(b) +return a.$0()}, +vr(a,b,c,d){if(d>=2)return a.$2(b,c) +if(d===1)return a.$1(b) +return a.$0()}, +vs(a,b,c,d,e){if(e>=3)return a.$3(b,c,d) +if(e===2)return a.$2(b,c) +if(e===1)return a.$1(b) +return a.$0()}, +vt(a,b,c,d,e,f){if(f>=4)return a.$4(b,c,d,e) +if(f===3)return a.$3(b,c,d) +if(f===2)return a.$2(b,c) +if(f===1)return a.$1(b) +return a.$0()}, +vu(a,b,c,d,e,f,g){if(g>=5)return a.$5(b,c,d,e,f) +if(g===4)return a.$4(b,c,d,e) +if(g===3)return a.$3(b,c,d) +if(g===2)return a.$2(b,c) +if(g===1)return a.$1(b) +return a.$0()}, +r3(a){return a==null||A.bQ(a)||typeof a=="number"||typeof a=="string"||t.gj.b(a)||t.p.b(a)||t.go.b(a)||t.dQ.b(a)||t.h7.b(a)||t.an.b(a)||t.bv.b(a)||t.h4.b(a)||t.gN.b(a)||t.E.b(a)||t.fd.b(a)}, +x0(a){if(A.r3(a))return a +return new A.nM(new A.dE(t.hg)).$1(a)}, +oO(a,b,c){return a[b].apply(a,c)}, +e1(a,b){var s,r +if(b==null)return new a() +if(b instanceof Array)switch(b.length){case 0:return new a() +case 1:return new a(b[0]) +case 2:return new a(b[0],b[1]) +case 3:return new a(b[0],b[1],b[2]) +case 4:return new a(b[0],b[1],b[2],b[3])}s=[null] +B.c.aG(s,b) +r=a.bind.apply(a,s) +String(r) +return new r()}, +T(a,b){var s=new A.n($.h,b.h("n<0>")),r=new A.a6(s,b.h("a6<0>")) +a.then(A.ck(new A.nQ(r),1),A.ck(new A.nR(r),1)) +return s}, +r2(a){return a==null||typeof a==="boolean"||typeof a==="number"||typeof a==="string"||a instanceof Int8Array||a instanceof Uint8Array||a instanceof Uint8ClampedArray||a instanceof Int16Array||a instanceof Uint16Array||a instanceof Int32Array||a instanceof Uint32Array||a instanceof Float32Array||a instanceof Float64Array||a instanceof ArrayBuffer||a instanceof DataView}, +rh(a){if(A.r2(a))return a +return new A.nD(new A.dE(t.hg)).$1(a)}, +nM:function nM(a){this.a=a}, +nQ:function nQ(a){this.a=a}, +nR:function nR(a){this.a=a}, +nD:function nD(a){this.a=a}, +ro(a,b){return Math.max(a,b)}, +xh(a){return Math.sqrt(a)}, +xg(a){return Math.sin(a)}, +wI(a){return Math.cos(a)}, +xn(a){return Math.tan(a)}, +wj(a){return Math.acos(a)}, +wk(a){return Math.asin(a)}, +wE(a){return Math.atan(a)}, +mR:function mR(a){this.a=a}, +d2:function d2(){}, +h1:function h1(){}, +hs:function hs(){}, +hB:function hB(){}, +hW:function hW(){}, +tF(a,b){var s=new A.ek(a,b,A.al(t.S,t.aR),A.eP(null,null,!0,t.al),new A.a6(new A.n($.h,t.D),t.h)) +s.hP(a,!1,b) +return s}, +ek:function ek(a,b,c,d,e){var _=this +_.a=a +_.c=b +_.d=0 +_.e=c +_.f=d +_.r=!1 +_.w=e}, +jW:function jW(a){this.a=a}, +jX:function jX(a,b){this.a=a +this.b=b}, +iB:function iB(a,b){this.a=a +this.b=b}, +fX:function fX(){}, +h5:function h5(a){this.a=a}, +h4:function h4(){}, +jY:function jY(a){this.a=a}, +jZ:function jZ(a){this.a=a}, +bZ:function bZ(){}, +ap:function ap(a,b){this.a=a +this.b=b}, +bf:function bf(a,b){this.a=a +this.b=b}, +aO:function aO(a){this.a=a}, +bm:function bm(a,b,c){this.a=a +this.b=b +this.c=c}, +bw:function bw(a){this.a=a}, +de:function de(a,b){this.a=a +this.b=b}, +cB:function cB(a,b){this.a=a +this.b=b}, +bW:function bW(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +c2:function c2(a){this.a=a}, +bn:function bn(a,b){this.a=a +this.b=b}, +c1:function c1(a,b){this.a=a +this.b=b}, +c4:function c4(a,b){this.a=a +this.b=b}, +bV:function bV(a,b){this.a=a +this.b=b}, +c5:function c5(a){this.a=a}, +c3:function c3(a,b){this.a=a +this.b=b}, +bF:function bF(a){this.a=a}, +bI:function bI(a){this.a=a}, +uj(a,b,c){var s=null,r=t.S,q=A.f([],t.t) +r=new A.kS(a,!1,!0,A.al(r,t.x),A.al(r,t.g1),q,new A.fp(s,s,t.dn),A.ob(t.gw),new A.a6(new A.n($.h,t.D),t.h),A.eP(s,s,!1,t.bw)) +r.hR(a,!1,!0) +return r}, +kS:function kS(a,b,c,d,e,f,g,h,i,j){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.f=_.e=0 +_.r=e +_.w=f +_.x=g +_.y=!1 +_.z=h +_.Q=i +_.as=j}, +kX:function kX(a){this.a=a}, +kY:function kY(a,b){this.a=a +this.b=b}, +kZ:function kZ(a,b){this.a=a +this.b=b}, +kT:function kT(a,b){this.a=a +this.b=b}, +kU:function kU(a,b){this.a=a +this.b=b}, +kW:function kW(a,b){this.a=a +this.b=b}, +kV:function kV(a){this.a=a}, +fj:function fj(a,b,c){this.a=a +this.b=b +this.c=c}, +i6:function i6(a){this.a=a}, +m3:function m3(a,b){this.a=a +this.b=b}, +m4:function m4(a,b){this.a=a +this.b=b}, +m1:function m1(){}, +lY:function lY(a,b){this.a=a +this.b=b}, +lZ:function lZ(){}, +m_:function m_(){}, +lX:function lX(){}, +m2:function m2(){}, +m0:function m0(){}, +ds:function ds(a,b){this.a=a +this.b=b}, +bK:function bK(a,b){this.a=a +this.b=b}, +xe(a,b){var s,r,q={} +q.a=s +q.a=null +s=new A.bU(new A.a8(new A.n($.h,b.h("n<0>")),b.h("a8<0>")),A.f([],t.bT),b.h("bU<0>")) +q.a=s +r=t.X +A.xf(new A.nS(q,a,b),A.u1([B.a_,s],r,r),t.H) +return q.a}, +oP(){var s=$.h.j(0,B.a_) +if(s instanceof A.bU&&s.c)throw A.b(B.M)}, +nS:function nS(a,b,c){this.a=a +this.b=b +this.c=c}, +bU:function bU(a,b,c){var _=this +_.a=a +_.b=b +_.c=!1 +_.$ti=c}, +ed:function ed(){}, +ao:function ao(){}, +ea:function ea(a,b){this.a=a +this.b=b}, +d0:function d0(a,b){this.a=a +this.b=b}, +qW(a){return"SAVEPOINT s"+a}, +qU(a){return"RELEASE s"+a}, +qV(a){return"ROLLBACK TO s"+a}, +jN:function jN(){}, +kK:function kK(){}, +lu:function lu(){}, +kF:function kF(){}, +jQ:function jQ(){}, +hA:function hA(){}, +k4:function k4(){}, +ic:function ic(){}, +mc:function mc(a,b,c){this.a=a +this.b=b +this.c=c}, +mh:function mh(a,b,c){this.a=a +this.b=b +this.c=c}, +mf:function mf(a,b,c){this.a=a +this.b=b +this.c=c}, +mg:function mg(a,b,c){this.a=a +this.b=b +this.c=c}, +me:function me(a,b,c){this.a=a +this.b=b +this.c=c}, +md:function md(a,b){this.a=a +this.b=b}, +iP:function iP(){}, +fn:function fn(a,b,c,d,e,f,g,h,i){var _=this +_.y=a +_.z=null +_.Q=b +_.as=c +_.at=d +_.ax=e +_.ay=f +_.ch=g +_.e=h +_.a=i +_.b=0 +_.d=_.c=!1}, +n1:function n1(a){this.a=a}, +n2:function n2(a){this.a=a}, +h2:function h2(){}, +jV:function jV(a,b){this.a=a +this.b=b}, +jU:function jU(a){this.a=a}, +id:function id(a,b){var _=this +_.e=a +_.a=b +_.b=0 +_.d=_.c=!1}, +f7:function f7(a,b,c){var _=this +_.e=a +_.f=null +_.r=b +_.a=c +_.b=0 +_.d=_.c=!1}, +mA:function mA(a,b){this.a=a +this.b=b}, +pT(a,b){var s,r,q,p=A.al(t.N,t.S) +for(s=a.length,r=0;r3)throw A.b("Expected two or three arguments to regexp") +s=a.j(0,0) +q=a.j(0,1) +if(s==null||q==null)return null +if(typeof s!="string"||typeof q!="string")throw A.b("Expected two strings as parameters to regexp") +if(g===3){p=a.j(0,2) +if(A.bv(p)){k=(p&1)===1 +j=(p&2)!==2 +i=(p&4)===4 +h=(p&8)===8}}r=null +try{o=k +n=j +m=i +r=A.H(s,n,h,o,m)}catch(l){if(A.G(l) instanceof A.aD)throw A.b("Invalid regex") +else throw l}o=r.b +return o.test(q)}, +vz(a){var s,r,q=a.a.b +if(q<2||q>3)throw A.b("Expected 2 or 3 arguments to moor_contains") +s=a.j(0,0) +r=a.j(0,1) +if(s==null||r==null)return null +if(typeof s!="string"||typeof r!="string")throw A.b("First two args to contains must be strings") +return q===3&&a.j(0,2)===1?B.a.I(s,r):B.a.I(s.toLowerCase(),r.toLowerCase())}, +k5:function k5(){}, +ny:function ny(a){this.a=a}, +ho:function ho(a){var _=this +_.a=$ +_.b=!1 +_.d=null +_.e=a}, +kx:function kx(a,b){this.a=a +this.b=b}, +ky:function ky(a,b){this.a=a +this.b=b}, +bo:function bo(){this.a=null}, +kA:function kA(a,b,c,d,e){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e}, +kB:function kB(a,b,c){this.a=a +this.b=b +this.c=c}, +kC:function kC(a,b){this.a=a +this.b=b}, +uB(a,b,c,d){var s,r=null,q=new A.hO(t.a7),p=t.X,o=A.eP(r,r,!1,p),n=A.eP(r,r,!1,p),m=A.pv(new A.ar(n,A.r(n).h("ar<1>")),new A.dP(o),!0,p) +q.a=m +p=A.pv(new A.ar(o,A.r(o).h("ar<1>")),new A.dP(n),!0,p) +q.b=p +s=new A.i6(A.od(c)) +a.onmessage=A.bu(new A.lU(b,q,d,s)) +m=m.b +m===$&&A.x() +new A.ar(m,A.r(m).h("ar<1>")).ez(new A.lV(d,s,a),new A.lW(b,a)) +return p}, +lU:function lU(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +lV:function lV(a,b,c){this.a=a +this.b=b +this.c=c}, +lW:function lW(a,b){this.a=a +this.b=b}, +jR:function jR(a,b,c){var _=this +_.a=a +_.b=b +_.c=c +_.d=null}, +jT:function jT(a){this.a=a}, +jS:function jS(a,b){this.a=a +this.b=b}, +od(a){var s +A:{if(a<=0){s=B.r +break A}if(1===a){s=B.aR +break A}if(2===a){s=B.aS +break A}if(3===a){s=B.aT +break A}if(a>3){s=B.t +break A}s=A.C(A.e8(null))}return s}, +pS(a){if("v" in a)return A.od(A.A(A.X(a.v))) +else return B.r}, +on(a){var s,r,q,p,o,n,m,l,k,j=A.a_(a.type),i=a.payload +A:{if("Error"===j){s=new A.dv(A.a_(A.a9(i))) +break A}if("ServeDriftDatabase"===j){A.a9(i) +r=A.pS(i) +s=A.bt(A.a_(i.sqlite)) +q=A.a9(i.port) +p=A.o1(B.aG,A.a_(i.storage)) +o=A.a_(i.database) +n=A.oG(i.initPort) +m=r.c +l=m<2||A.bg(i.migrations) +s=new A.dk(s,q,p,o,n,r,l,m<3||A.bg(i.new_serialization)) +break A}if("StartFileSystemServer"===j){s=new A.eN(A.a9(i)) +break A}if("RequestCompatibilityCheck"===j){s=new A.di(A.a_(i)) +break A}if("DedicatedWorkerCompatibilityResult"===j){A.a9(i) +k=A.f([],t.L) +if("existing" in i)B.c.aG(k,A.pq(t.c.a(i.existing))) +s=A.bg(i.supportsNestedWorkers) +q=A.bg(i.canAccessOpfs) +p=A.bg(i.supportsSharedArrayBuffers) +o=A.bg(i.supportsIndexedDb) +n=A.bg(i.indexedDbExists) +m=A.bg(i.opfsExists) +m=new A.ej(s,q,p,o,k,A.pS(i),n,m) +s=m +break A}if("SharedWorkerCompatibilityResult"===j){s=A.uk(t.c.a(i)) +break A}if("DeleteDatabase"===j){s=i==null?A.oH(i):i +t.c.a(s) +q=$.p6().j(0,A.a_(s[0])) +q.toString +s=new A.h3(new A.ah(q,A.a_(s[1]))) +break A}s=A.C(A.J("Unknown type "+j,null))}return s}, +uk(a){var s,r,q=new A.l5(a) +if(a.length>5){s=A.pq(t.c.a(a[5])) +r=a.length>6?A.od(A.A(A.X(a[6]))):B.r}else{s=B.B +r=B.r}return new A.c6(q.$1(0),q.$1(1),q.$1(2),s,r,q.$1(3),q.$1(4))}, +pq(a){var s,r,q=A.f([],t.L),p=B.c.bu(a,t.m),o=p.$ti +p=new A.b3(p,p.gl(0),o.h("b3")) +o=o.h("v.E") +while(p.k()){s=p.d +if(s==null)s=o.a(s) +r=$.p6().j(0,A.a_(s.l)) +r.toString +q.push(new A.ah(r,A.a_(s.n)))}return q}, +pp(a){var s,r,q,p,o=A.f([],t.W) +for(s=a.length,r=0;r"))) +while(i.k()){l=i.gm() +if(J.aj(l.name,a)){q=!0 +s=1 +break A}}q=!1 +s=1 +break +case 8:k=n.open(a,1) +k.onupgradeneeded=A.bu(new A.nB(g,k)) +s=10 +return A.c(A.jm(k,t.m),$async$e2) +case 10:j=c +if(g.a==null)g.a=!0 +j.close() +s=g.a===!1?11:12 +break +case 11:s=13 +return A.c(A.jm(n.deleteDatabase(a),t.X),$async$e2) +case 13:case 12:p=2 +s=6 +break +case 4:p=3 +f=o.pop() +s=6 +break +case 3:s=2 +break +case 6:i=g.a +q=i===!0 +s=1 +break +case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$e2,r)}, +nE(a){var s=0,r=A.l(t.H),q +var $async$nE=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:q=v.G +s="indexedDB" in q?2:3 +break +case 2:s=4 +return A.c(A.jm(A.a9(q.indexedDB).deleteDatabase(a),t.X),$async$nE) +case 4:case 3:return A.j(null,r)}}) +return A.k($async$nE,r)}, +iZ(){var s=null +return A.xc()}, +xc(){var s=0,r=A.l(t.A),q,p=2,o=[],n,m,l,k,j,i,h +var $async$iZ=A.m(function(a,b){if(a===1){o.push(b) +s=p}for(;;)switch(s){case 0:j=null +i=A.p1() +if(i==null){q=null +s=1 +break}m=t.m +s=3 +return A.c(A.T(i.getDirectory(),m),$async$iZ) +case 3:n=b +p=5 +l=j +if(l==null)l={} +s=8 +return A.c(A.T(n.getDirectoryHandle("drift_db",l),m),$async$iZ) +case 8:m=b +q=m +s=1 +break +p=2 +s=7 +break +case 5:p=4 +h=o.pop() +q=null +s=1 +break +s=7 +break +case 4:s=2 +break +case 7:case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$iZ,r)}, +e5(){var s=0,r=A.l(t.u),q,p=2,o=[],n=[],m,l,k,j,i,h,g,f +var $async$e5=A.m(function(a,b){if(a===1){o.push(b) +s=p}for(;;)switch(s){case 0:s=3 +return A.c(A.iZ(),$async$e5) +case 3:g=b +if(g==null){q=B.A +s=1 +break}j=t.cO +if(!(v.G.Symbol.asyncIterator in g))A.C(A.J("Target object does not implement the async iterable interface",null)) +m=new A.fc(new A.nP(),new A.e9(g,j),j.h("fc")) +l=A.f([],t.s) +j=new A.dO(A.cU(m,"stream",t.K)) +p=4 +i=t.m +case 7:s=9 +return A.c(j.k(),$async$e5) +case 9:if(!b){s=8 +break}k=j.gm() +s=J.aj(k.kind,"directory")?10:11 +break +case 10:p=13 +s=16 +return A.c(A.T(k.getFileHandle("database"),i),$async$e5) +case 16:J.nW(l,k.name) +p=4 +s=15 +break +case 13:p=12 +f=o.pop() +s=15 +break +case 12:s=4 +break +case 15:case 11:s=7 +break +case 8:n.push(6) +s=5 +break +case 4:n=[2] +case 5:p=2 +s=17 +return A.c(j.K(),$async$e5) +case 17:s=n.pop() +break +case 6:q=l +s=1 +break +case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$e5,r)}, +fE(a){return A.wK(a)}, +wK(a){var s=0,r=A.l(t.H),q,p=2,o=[],n,m,l,k,j +var $async$fE=A.m(function(b,c){if(b===1){o.push(c) +s=p}for(;;)switch(s){case 0:k=A.p1() +if(k==null){s=1 +break}m=t.m +s=3 +return A.c(A.T(k.getDirectory(),m),$async$fE) +case 3:n=c +p=5 +s=8 +return A.c(A.T(n.getDirectoryHandle("drift_db"),m),$async$fE) +case 8:n=c +s=9 +return A.c(A.T(n.removeEntry(a,{recursive:!0}),t.X),$async$fE) +case 9:p=2 +s=7 +break +case 5:p=4 +j=o.pop() +s=7 +break +case 4:s=2 +break +case 7:case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$fE,r)}, +jm(a,b){var s=new A.n($.h,b.h("n<0>")),r=new A.a8(s,b.h("a8<0>")) +A.aI(a,"success",new A.jp(r,a,b),!1) +A.aI(a,"error",new A.jq(r,a),!1) +A.aI(a,"blocked",new A.jr(r,a),!1) +return s}, +nB:function nB(a,b){this.a=a +this.b=b}, +nP:function nP(){}, +h6:function h6(a,b){this.a=a +this.b=b}, +k3:function k3(a,b){this.a=a +this.b=b}, +k0:function k0(a){this.a=a}, +k_:function k_(a){this.a=a}, +k1:function k1(a,b,c){this.a=a +this.b=b +this.c=c}, +k2:function k2(a,b,c){this.a=a +this.b=b +this.c=c}, +mp:function mp(a,b){this.a=a +this.b=b}, +dj:function dj(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.d=c}, +kQ:function kQ(a){this.a=a}, +lH:function lH(a,b){this.a=a +this.b=b}, +jp:function jp(a,b,c){this.a=a +this.b=b +this.c=c}, +jq:function jq(a,b){this.a=a +this.b=b}, +jr:function jr(a,b){this.a=a +this.b=b}, +l_:function l_(a,b){this.a=a +this.b=null +this.c=b}, +l4:function l4(a){this.a=a}, +l0:function l0(a,b){this.a=a +this.b=b}, +l3:function l3(a,b,c){this.a=a +this.b=b +this.c=c}, +l1:function l1(a){this.a=a}, +l2:function l2(a,b,c){this.a=a +this.b=b +this.c=c}, +cc:function cc(a,b){this.a=a +this.b=b}, +bO:function bO(a,b){this.a=a +this.b=b}, +i3:function i3(a,b,c,d,e){var _=this +_.e=a +_.f=null +_.r=b +_.w=c +_.x=d +_.a=e +_.b=0 +_.d=_.c=!1}, +iS:function iS(a,b,c,d,e,f,g){var _=this +_.Q=a +_.as=b +_.at=c +_.b=null +_.d=_.c=!1 +_.e=d +_.f=e +_.r=f +_.x=g +_.y=$ +_.a=!1}, +jv(a,b){if(a==null)a="." +return new A.fY(b,a)}, +oM(a){return a}, +rc(a,b){var s,r,q,p,o,n,m,l +for(s=b.length,r=1;r=1;s=q){q=s-1 +if(b[q]!=null)break}p=new A.aA("") +o=a+"(" +p.a=o +n=A.N(b) +m=n.h("cC<1>") +l=new A.cC(b,0,s,m) +l.hS(b,0,s,n.c) +m=o+new A.E(l,new A.nz(),m.h("E")).aq(0,", ") +p.a=m +p.a=m+("): part "+(r-1)+" was null, but part "+r+" was not.") +throw A.b(A.J(p.i(0),null))}}, +fY:function fY(a,b){this.a=a +this.b=b}, +jw:function jw(){}, +jx:function jx(){}, +nz:function nz(){}, +dJ:function dJ(a){this.a=a}, +dK:function dK(a){this.a=a}, +kt:function kt(){}, +df(a,b){var s,r,q,p,o,n=b.hz(a) +b.a9(a) +if(n!=null)a=B.a.N(a,n.length) +s=t.s +r=A.f([],s) +q=A.f([],s) +s=a.length +if(s!==0&&b.D(a.charCodeAt(0))){q.push(a[0]) +p=1}else{q.push("") +p=0}for(o=p;o")),r=new A.a8(s,b.h("a8<0>")) +A.aI(a,"success",new A.jn(r,a,b),!1) +A.aI(a,"error",new A.jo(r,a),!1) +return s}, +tD(a,b){var s=new A.n($.h,b.h("n<0>")),r=new A.a8(s,b.h("a8<0>")) +A.aI(a,"success",new A.js(r,a,b),!1) +A.aI(a,"error",new A.jt(r,a),!1) +A.aI(a,"blocked",new A.ju(r,a),!1) +return s}, +cI:function cI(a,b){var _=this +_.c=_.b=_.a=null +_.d=a +_.$ti=b}, +mq:function mq(a,b){this.a=a +this.b=b}, +mr:function mr(a,b){this.a=a +this.b=b}, +jn:function jn(a,b,c){this.a=a +this.b=b +this.c=c}, +jo:function jo(a,b){this.a=a +this.b=b}, +js:function js(a,b,c){this.a=a +this.b=b +this.c=c}, +jt:function jt(a,b){this.a=a +this.b=b}, +ju:function ju(a,b){this.a=a +this.b=b}, +lN:function lN(a){this.a=a}, +lO:function lO(a){this.a=a}, +lQ(a){var s=0,r=A.l(t.ab),q,p,o,n +var $async$lQ=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:p=v.G +o=a.gha()?new p.URL(a.i(0)):new p.URL(a.i(0),A.eS().i(0)) +n=A +s=3 +return A.c(A.T(p.fetch(o,null),t.m),$async$lQ) +case 3:q=n.lP(c,null) +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$lQ,r)}, +lP(a,b){var s=0,r=A.l(t.ab),q,p,o,n,m +var $async$lP=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:p=new A.fZ(A.al(t.S,t.b9)) +o=A +n=A +m=A +s=3 +return A.c(new A.lN(p).d2(a),$async$lP) +case 3:q=new o.i5(new n.lR(m.uA(d,p))) +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$lP,r)}, +i5:function i5(a){this.a=a}, +du:function du(a,b,c,d,e){var _=this +_.d=a +_.e=b +_.r=c +_.b=d +_.a=e}, +i4:function i4(a,b){this.a=a +this.b=b +this.c=0}, +pV(a){var s=J.aj(a.byteLength,8) +if(!s)throw A.b(A.J("Must be 8 in length",null)) +s=v.G.Int32Array +return new A.kP(t.ha.a(A.e1(s,[a])))}, +u4(a){return B.h}, +u5(a){var s=a.b +return new A.P(s.getInt32(0,!1),s.getInt32(4,!1),s.getInt32(8,!1))}, +u6(a){var s=a.b +return new A.aV(B.j.cS(A.oi(a.a,16,s.getInt32(12,!1))),s.getInt32(0,!1),s.getInt32(4,!1),s.getInt32(8,!1))}, +kP:function kP(a){this.b=a}, +bp:function bp(a,b,c){this.a=a +this.b=b +this.c=c}, +ac:function ac(a,b,c,d,e){var _=this +_.c=a +_.d=b +_.a=c +_.b=d +_.$ti=e}, +bC:function bC(){}, +b2:function b2(){}, +P:function P(a,b,c){this.a=a +this.b=b +this.c=c}, +aV:function aV(a,b,c,d){var _=this +_.d=a +_.a=b +_.b=c +_.c=d}, +i2(a){var s=0,r=A.l(t.ei),q,p,o,n,m,l,k,j,i +var $async$i2=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:k=t.m +s=3 +return A.c(A.T(A.p0().getDirectory(),k),$async$i2) +case 3:j=c +i=$.fJ().aM(0,a.root) +p=i.length,o=0 +case 4:if(!(o")),A.xr(),r.h("aE<1,Z>")),t.a))}if(!B.a.I(a,q))return new A.bk(A.aM(A.f([A.q5(a)],t.J),t.a)) +return new A.bk(A.aM(new A.E(A.f(a.split(q),t.s),A.xq(),t.fe),t.a))}, +bk:function bk(a){this.a=a}, +jd:function jd(){}, +ji:function ji(){}, +jh:function jh(){}, +jf:function jf(){}, +jg:function jg(a){this.a=a}, +je:function je(a){this.a=a}, +tR(a){return A.pt(a)}, +pt(a){return A.hc(a,new A.kf(a))}, +tQ(a){return A.tN(a)}, +tN(a){return A.hc(a,new A.kd(a))}, +tK(a){return A.hc(a,new A.ka(a))}, +tO(a){return A.tL(a)}, +tL(a){return A.hc(a,new A.kb(a))}, +tP(a){return A.tM(a)}, +tM(a){return A.hc(a,new A.kc(a))}, +hd(a){if(B.a.I(a,$.rx()))return A.bt(a) +else if(B.a.I(a,$.ry()))return A.qC(a,!0) +else if(B.a.u(a,"/"))return A.qC(a,!1) +if(B.a.I(a,"\\"))return $.th().hs(a) +return A.bt(a)}, +hc(a,b){var s,r +try{s=b.$0() +return s}catch(r){if(A.G(r) instanceof A.aD)return new A.bs(A.am(null,"unparsed",null,null),a) +else throw r}}, +L:function L(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +kf:function kf(a){this.a=a}, +kd:function kd(a){this.a=a}, +ke:function ke(a){this.a=a}, +ka:function ka(a){this.a=a}, +kb:function kb(a){this.a=a}, +kc:function kc(a){this.a=a}, +hp:function hp(a){this.a=a +this.b=$}, +q4(a){if(t.a.b(a))return a +if(a instanceof A.bk)return a.hr() +return new A.hp(new A.lq(a))}, +q5(a){var s,r,q +try{if(a.length===0){r=A.q1(A.f([],t.e),null) +return r}if(B.a.I(a,$.ta())){r=A.uq(a) +return r}if(B.a.I(a,"\tat ")){r=A.up(a) +return r}if(B.a.I(a,$.t0())||B.a.I(a,$.rZ())){r=A.uo(a) +return r}if(B.a.I(a,u.q)){r=A.tx(a).hr() +return r}if(B.a.I(a,$.t3())){r=A.q2(a) +return r}r=A.q3(a) +return r}catch(q){r=A.G(q) +if(r instanceof A.aD){s=r +throw A.b(A.af(s.a+"\nStack trace:\n"+a,null,null))}else throw q}}, +us(a){return A.q3(a)}, +q3(a){var s=A.aM(A.ut(a),t.B) +return new A.Z(s)}, +ut(a){var s,r=B.a.eL(a),q=$.pa(),p=t.U,o=new A.aY(A.f(A.bi(r,q,"").split("\n"),t.s),new A.lr(),p) +if(!o.gq(0).k())return A.f([],t.e) +r=A.ol(o,o.gl(0)-1,p.h("d.E")) +r=A.ht(r,A.wQ(),A.r(r).h("d.E"),t.B) +s=A.aw(r,A.r(r).h("d.E")) +if(!B.a.ej(o.gE(0),".da"))s.push(A.pt(o.gE(0))) +return s}, +uq(a){var s=A.b5(A.f(a.split("\n"),t.s),1,null,t.N).hK(0,new A.lp()),r=t.B +r=A.aM(A.ht(s,A.rj(),s.$ti.h("d.E"),r),r) +return new A.Z(r)}, +up(a){var s=A.aM(new A.aE(new A.aY(A.f(a.split("\n"),t.s),new A.lo(),t.U),A.rj(),t.M),t.B) +return new A.Z(s)}, +uo(a){var s=A.aM(new A.aE(new A.aY(A.f(B.a.eL(a).split("\n"),t.s),new A.lm(),t.U),A.wO(),t.M),t.B) +return new A.Z(s)}, +ur(a){return A.q2(a)}, +q2(a){var s=a.length===0?A.f([],t.e):new A.aE(new A.aY(A.f(B.a.eL(a).split("\n"),t.s),new A.ln(),t.U),A.wP(),t.M) +s=A.aM(s,t.B) +return new A.Z(s)}, +q1(a,b){var s=A.aM(a,t.B) +return new A.Z(s)}, +Z:function Z(a){this.a=a}, +lq:function lq(a){this.a=a}, +lr:function lr(){}, +lp:function lp(){}, +lo:function lo(){}, +lm:function lm(){}, +ln:function ln(){}, +lt:function lt(){}, +ls:function ls(a){this.a=a}, +bs:function bs(a,b){this.a=a +this.w=b}, +ef:function ef(a){var _=this +_.b=_.a=$ +_.c=null +_.d=!1 +_.$ti=a}, +f1:function f1(a,b,c){this.a=a +this.b=b +this.$ti=c}, +f0:function f0(a,b){this.b=a +this.a=b}, +pv(a,b,c,d){var s,r={} +r.a=a +s=new A.ep(d.h("ep<0>")) +s.hQ(b,!0,r,d) +return s}, +ep:function ep(a){var _=this +_.b=_.a=$ +_.c=null +_.d=!1 +_.$ti=a}, +km:function km(a,b){this.a=a +this.b=b}, +kl:function kl(a){this.a=a}, +f9:function f9(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.e=_.d=!1 +_.r=_.f=null +_.w=d}, +hO:function hO(a){this.b=this.a=$ +this.$ti=a}, +eO:function eO(){}, +dq:function dq(){}, +iu:function iu(){}, +br:function br(a,b){this.a=a +this.b=b}, +aI(a,b,c,d){var s +if(c==null)s=null +else{s=A.rd(new A.my(c),t.m) +s=s==null?null:A.bu(s)}s=new A.im(a,b,s,!1) +s.e3() +return s}, +rd(a,b){var s=$.h +if(s===B.d)return a +return s.ee(a,b)}, +o2:function o2(a,b){this.a=a +this.$ti=b}, +f6:function f6(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.$ti=d}, +im:function im(a,b,c,d){var _=this +_.a=0 +_.b=a +_.c=b +_.d=c +_.e=d}, +my:function my(a){this.a=a}, +mz:function mz(a){this.a=a}, +oZ(a){if(typeof dartPrint=="function"){dartPrint(a) +return}if(typeof console=="object"&&typeof console.log!="undefined"){console.log(a) +return}if(typeof print=="function"){print(a) +return}throw"Unable to print message: "+String(a)}, +hm(a,b,c,d,e,f){var s +if(c==null)return a[b]() +else if(d==null)return a[b](c) +else if(e==null)return a[b](c,d) +else{s=a[b](c,d,e) +return s}}, +oS(){var s,r,q,p,o=null +try{o=A.eS()}catch(s){if(t.g8.b(A.G(s))){r=$.nr +if(r!=null)return r +throw s}else throw s}if(J.aj(o,$.qT)){r=$.nr +r.toString +return r}$.qT=o +if($.p5()===$.cY())r=$.nr=o.hp(".").i(0) +else{q=o.eK() +p=q.length-1 +r=$.nr=p===0?q:B.a.p(q,0,p)}return r}, +rm(a){var s +if(!(a>=65&&a<=90))s=a>=97&&a<=122 +else s=!0 +return s}, +ri(a,b){var s,r,q=null,p=a.length,o=b+2 +if(p0)throw A.b(A.k6("BigInt value exceeds the range of 64 bits")) +return a}, +uh(a){var s,r=a.a,q=a.b,p=r.d,o=p.sqlite3_value_type(q) +A:{s=null +if(1===o){r=A.A(v.G.Number(p.sqlite3_value_int64(q))) +break A}if(2===o){r=p.sqlite3_value_double(q) +break A}if(3===o){o=p.sqlite3_value_bytes(q) +o=A.cd(r.b,p.sqlite3_value_text(q),o) +r=o +break A}if(4===o){o=p.sqlite3_value_bytes(q) +o=A.qd(r.b,p.sqlite3_value_blob(q),o) +r=o +break A}r=s +break A}return r}, +o5(a,b){var s,r +for(s=b,r=0;r<16;++r)s+=A.aP("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789".charCodeAt(a.hf(61))) +return s.charCodeAt(0)==0?s:s}, +kO(a){var s=0,r=A.l(t.E),q +var $async$kO=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:s=3 +return A.c(A.T(a.arrayBuffer(),t.v),$async$kO) +case 3:q=c +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$kO,r)}, +pX(a,b,c){var s=v.G.DataView,r=[a] +r.push(b) +r.push(c) +return t.gT.a(A.e1(s,r))}, +oi(a,b,c){var s=v.G.Uint8Array,r=[a] +r.push(b) +r.push(c) +return t.Z.a(A.e1(s,r))}, +tu(a,b){v.G.Atomics.notify(a,b,1/0)}, +p0(){var s=v.G.navigator +if("storage" in s)return s.storage +return null}, +k7(a,b,c){var s=a.read(b,c) +return s}, +o3(a,b,c){var s=a.write(b,c) +return s}, +ps(a,b){return A.T(a.removeEntry(b,{recursive:!1}),t.X)}, +x2(){var s=v.G +if(A.ku(s,"DedicatedWorkerGlobalScope"))new A.jR(s,new A.bo(),new A.h6(A.al(t.N,t.fE),null)).T() +else if(A.ku(s,"SharedWorkerGlobalScope"))new A.l_(s,new A.h6(A.al(t.N,t.fE),null)).T()}},B={} +var w=[A,J,B] +var $={} +A.o9.prototype={} +J.hi.prototype={ +W(a,b){return a===b}, +gA(a){return A.eG(a)}, +i(a){return"Instance of '"+A.hG(a)+"'"}, +gV(a){return A.bR(A.oK(this))}} +J.hk.prototype={ +i(a){return String(a)}, +gA(a){return a?519018:218159}, +gV(a){return A.bR(t.y)}, +$iI:1, +$iK:1} +J.eu.prototype={ +W(a,b){return null==b}, +i(a){return"null"}, +gA(a){return 0}, +$iI:1, +$iR:1} +J.ev.prototype={$iz:1} +J.bY.prototype={ +gA(a){return 0}, +i(a){return String(a)}} +J.hF.prototype={} +J.cE.prototype={} +J.bz.prototype={ +i(a){var s=a[$.e6()] +if(s==null)return this.hL(a) +return"JavaScript function for "+J.b1(s)}} +J.aK.prototype={ +gA(a){return 0}, +i(a){return String(a)}} +J.d7.prototype={ +gA(a){return 0}, +i(a){return String(a)}} +J.u.prototype={ +bu(a,b){return new A.ak(a,A.N(a).h("@<1>").H(b).h("ak<1,2>"))}, +v(a,b){a.$flags&1&&A.y(a,29) +a.push(b)}, +d7(a,b){var s +a.$flags&1&&A.y(a,"removeAt",1) +s=a.length +if(b>=s)throw A.b(A.kN(b,null)) +return a.splice(b,1)[0]}, +cY(a,b,c){var s +a.$flags&1&&A.y(a,"insert",2) +s=a.length +if(b>s)throw A.b(A.kN(b,null)) +a.splice(b,0,c)}, +es(a,b,c){var s,r +a.$flags&1&&A.y(a,"insertAll",2) +A.pU(b,0,a.length,"index") +if(!t.Q.b(c))c=J.j4(c) +s=J.at(c) +a.length=a.length+s +r=b+s +this.M(a,r,a.length,a,b) +this.ad(a,b,r,c)}, +hl(a){a.$flags&1&&A.y(a,"removeLast",1) +if(a.length===0)throw A.b(A.e3(a,-1)) +return a.pop()}, +G(a,b){var s +a.$flags&1&&A.y(a,"remove",1) +for(s=0;s").H(c).h("E<1,2>"))}, +aq(a,b){var s,r=A.b4(a.length,"",!1,t.N) +for(s=0;ss)throw A.b(A.S(b,0,s,"start",null)) +if(cs)throw A.b(A.S(c,b,s,"end",null)) +if(b===c)return A.f([],A.N(a)) +return A.f(a.slice(b,c),A.N(a))}, +cm(a,b,c){A.bd(b,c,a.length) +return A.b5(a,b,c,A.N(a).c)}, +gF(a){if(a.length>0)return a[0] +throw A.b(A.az())}, +gE(a){var s=a.length +if(s>0)return a[s-1] +throw A.b(A.az())}, +M(a,b,c,d,e){var s,r,q,p,o +a.$flags&2&&A.y(a,5) +A.bd(b,c,a.length) +s=c-b +if(s===0)return +A.ab(e,"skipCount") +if(t.j.b(d)){r=d +q=e}else{r=J.e7(d,e).az(0,!1) +q=0}p=J.a0(r) +if(q+s>p.gl(r))throw A.b(A.py()) +if(q=0;--o)a[b+o]=p.j(r,q+o) +else for(o=0;o0){a[0]=q +a[1]=r}return}p=0 +if(A.N(a).c.b(null))for(o=0;o0)this.j6(a,p)}, +hG(a){return this.hH(a,null)}, +j6(a,b){var s,r=a.length +for(;s=r-1,r>0;r=s)if(a[s]===null){a[s]=void 0;--b +if(b===0)break}}, +d0(a,b){var s,r=a.length,q=r-1 +if(q<0)return-1 +q=0;--s)if(J.aj(a[s],b))return s +return-1}, +gB(a){return a.length===0}, +i(a){return A.o7(a,"[","]")}, +az(a,b){var s=A.f(a.slice(0),A.N(a)) +return s}, +cf(a){return this.az(a,!0)}, +gq(a){return new J.fK(a,a.length,A.N(a).h("fK<1>"))}, +gA(a){return A.eG(a)}, +gl(a){return a.length}, +j(a,b){if(!(b>=0&&b=0&&b=p){r.d=null +return!1}r.d=q[s] +r.c=s+1 +return!0}} +J.d6.prototype={ +ag(a,b){var s +if(ab)return 1 +else if(a===b){if(a===0){s=this.gew(b) +if(this.gew(a)===s)return 0 +if(this.gew(a))return-1 +return 1}return 0}else if(isNaN(a)){if(isNaN(b))return 0 +return 1}else return-1}, +gew(a){return a===0?1/a<0:a<0}, +l7(a){var s +if(a>=-2147483648&&a<=2147483647)return a|0 +if(isFinite(a)){s=a<0?Math.ceil(a):Math.floor(a) +return s+0}throw A.b(A.a3(""+a+".toInt()"))}, +jQ(a){var s,r +if(a>=0){if(a<=2147483647){s=a|0 +return a===s?s:s+1}}else if(a>=-2147483648)return a|0 +r=Math.ceil(a) +if(isFinite(r))return r +throw A.b(A.a3(""+a+".ceil()"))}, +i(a){if(a===0&&1/a<0)return"-0.0" +else return""+a}, +gA(a){var s,r,q,p,o=a|0 +if(a===o)return o&536870911 +s=Math.abs(a) +r=Math.log(s)/0.6931471805599453|0 +q=Math.pow(2,r) +p=s<1?s/q:q/s +return((p*9007199254740992|0)+(p*3542243181176521|0))*599197+r*1259&536870911}, +ac(a,b){var s=a%b +if(s===0)return 0 +if(s>0)return s +return s+b}, +eW(a,b){if((a|0)===a)if(b>=1||b<-1)return a/b|0 +return this.fK(a,b)}, +J(a,b){return(a|0)===a?a/b|0:this.fK(a,b)}, +fK(a,b){var s=a/b +if(s>=-2147483648&&s<=2147483647)return s|0 +if(s>0){if(s!==1/0)return Math.floor(s)}else if(s>-1/0)return Math.ceil(s) +throw A.b(A.a3("Result of truncating division is "+A.t(s)+": "+A.t(a)+" ~/ "+b))}, +b_(a,b){if(b<0)throw A.b(A.e0(b)) +return b>31?0:a<>>0}, +bh(a,b){var s +if(b<0)throw A.b(A.e0(b)) +if(a>0)s=this.e2(a,b) +else{s=b>31?31:b +s=a>>s>>>0}return s}, +O(a,b){var s +if(a>0)s=this.e2(a,b) +else{s=b>31?31:b +s=a>>s>>>0}return s}, +jl(a,b){if(0>b)throw A.b(A.e0(b)) +return this.e2(a,b)}, +e2(a,b){return b>31?0:a>>>b}, +gV(a){return A.bR(t.o)}, +$iF:1, +$ib0:1} +J.et.prototype={ +gfX(a){var s,r=a<0?-a-1:a,q=r +for(s=32;q>=4294967296;){q=this.J(q,4294967296) +s+=32}return s-Math.clz32(q)}, +gV(a){return A.bR(t.S)}, +$iI:1, +$ia:1} +J.hl.prototype={ +gV(a){return A.bR(t.i)}, +$iI:1} +J.bX.prototype={ +jS(a,b){if(b<0)throw A.b(A.e3(a,b)) +if(b>=a.length)A.C(A.e3(a,b)) +return a.charCodeAt(b)}, +cL(a,b,c){var s=b.length +if(c>s)throw A.b(A.S(c,0,s,null,null)) +return new A.iL(b,a,c)}, +eb(a,b){return this.cL(a,b,0)}, +hd(a,b,c){var s,r,q=null +if(c<0||c>b.length)throw A.b(A.S(c,0,b.length,q,q)) +s=a.length +if(c+s>b.length)return q +for(r=0;rr)return!1 +return b===this.N(a,r-s)}, +ho(a,b,c){A.pU(0,0,a.length,"startIndex") +return A.xm(a,b,c,0)}, +aM(a,b){var s +if(typeof b=="string")return A.f(a.split(b),t.s) +else{if(b instanceof A.cw){s=b.e +s=!(s==null?b.e=b.i9():s)}else s=!1 +if(s)return A.f(a.split(b.b),t.s) +else return this.ii(a,b)}}, +aL(a,b,c,d){var s=A.bd(b,c,a.length) +return A.p2(a,b,s,d)}, +ii(a,b){var s,r,q,p,o,n,m=A.f([],t.s) +for(s=J.nX(b,a),s=s.gq(s),r=0,q=1;s.k();){p=s.gm() +o=p.gco() +n=p.gbw() +q=n-o +if(q===0&&r===o)continue +m.push(this.p(a,r,o)) +r=n}if(r0)m.push(this.N(a,r)) +return m}, +C(a,b,c){var s +if(c<0||c>a.length)throw A.b(A.S(c,0,a.length,null,null)) +if(typeof b=="string"){s=c+b.length +if(s>a.length)return!1 +return b===a.substring(c,s)}return J.to(b,a,c)!=null}, +u(a,b){return this.C(a,b,0)}, +p(a,b,c){return a.substring(b,A.bd(b,c,a.length))}, +N(a,b){return this.p(a,b,null)}, +eL(a){var s,r,q,p=a.trim(),o=p.length +if(o===0)return p +if(p.charCodeAt(0)===133){s=J.tY(p,1) +if(s===o)return""}else s=0 +r=o-1 +q=p.charCodeAt(r)===133?J.tZ(p,r):o +if(s===0&&q===o)return p +return p.substring(s,q)}, +bG(a,b){var s,r +if(0>=b)return"" +if(b===1||a.length===0)return a +if(b!==b>>>0)throw A.b(B.aw) +for(s=a,r="";;){if((b&1)===1)r=s+r +b=b>>>1 +if(b===0)break +s+=s}return r}, +kR(a,b,c){var s=b-a.length +if(s<=0)return a +return this.bG(c,s)+a}, +hg(a,b){var s=b-a.length +if(s<=0)return a +return a+this.bG(" ",s)}, +aU(a,b,c){var s +if(c<0||c>a.length)throw A.b(A.S(c,0,a.length,null,null)) +s=a.indexOf(b,c) +return s}, +kx(a,b){return this.aU(a,b,0)}, +hc(a,b,c){var s,r +if(c==null)c=a.length +else if(c<0||c>a.length)throw A.b(A.S(c,0,a.length,null,null)) +s=b.length +r=a.length +if(c+s>r)c=r-s +return a.lastIndexOf(b,c)}, +d0(a,b){return this.hc(a,b,null)}, +I(a,b){return A.xi(a,b,0)}, +ag(a,b){var s +if(a===b)s=0 +else s=a>6}r=r+((r&67108863)<<3)&536870911 +r^=r>>11 +return r+((r&16383)<<15)&536870911}, +gV(a){return A.bR(t.N)}, +gl(a){return a.length}, +j(a,b){if(!(b>=0&&b"))}, +gl(a){return J.at(this.gam())}, +gB(a){return J.nY(this.gam())}, +Y(a,b){var s=A.r(this) +return A.ee(J.e7(this.gam(),b),s.c,s.y[1])}, +ah(a,b){var s=A.r(this) +return A.ee(J.j3(this.gam(),b),s.c,s.y[1])}, +L(a,b){return A.r(this).y[1].a(J.j1(this.gam(),b))}, +gF(a){return A.r(this).y[1].a(J.j2(this.gam()))}, +gE(a){return A.r(this).y[1].a(J.nZ(this.gam()))}, +i(a){return J.b1(this.gam())}} +A.fU.prototype={ +k(){return this.a.k()}, +gm(){return this.$ti.y[1].a(this.a.gm())}} +A.co.prototype={ +gam(){return this.a}} +A.f4.prototype={$iq:1} +A.f_.prototype={ +j(a,b){return this.$ti.y[1].a(J.aJ(this.a,b))}, +t(a,b,c){J.pb(this.a,b,this.$ti.c.a(c))}, +cm(a,b,c){var s=this.$ti +return A.ee(J.tn(this.a,b,c),s.c,s.y[1])}, +M(a,b,c,d,e){var s=this.$ti +J.tp(this.a,b,c,A.ee(d,s.y[1],s.c),e)}, +ad(a,b,c,d){return this.M(0,b,c,d,0)}, +$iq:1, +$ip:1} +A.ak.prototype={ +bu(a,b){return new A.ak(this.a,this.$ti.h("@<1>").H(b).h("ak<1,2>"))}, +gam(){return this.a}} +A.d8.prototype={ +i(a){return"LateInitializationError: "+this.a}} +A.fV.prototype={ +gl(a){return this.a.length}, +j(a,b){return this.a.charCodeAt(b)}} +A.nO.prototype={ +$0(){return A.bc(null,t.H)}, +$S:2} +A.kR.prototype={} +A.q.prototype={} +A.M.prototype={ +gq(a){var s=this +return new A.b3(s,s.gl(s),A.r(s).h("b3"))}, +gB(a){return this.gl(this)===0}, +gF(a){if(this.gl(this)===0)throw A.b(A.az()) +return this.L(0,0)}, +gE(a){var s=this +if(s.gl(s)===0)throw A.b(A.az()) +return s.L(0,s.gl(s)-1)}, +aq(a,b){var s,r,q,p=this,o=p.gl(p) +if(b.length!==0){if(o===0)return"" +s=A.t(p.L(0,0)) +if(o!==p.gl(p))throw A.b(A.au(p)) +for(r=s,q=1;q").H(c).h("E<1,2>"))}, +kv(a,b,c){var s,r,q=this,p=q.gl(q) +for(s=b,r=0;rs)throw A.b(A.S(r,0,s,"start",null))}}, +giq(){var s=J.at(this.a),r=this.c +if(r==null||r>s)return s +return r}, +gjq(){var s=J.at(this.a),r=this.b +if(r>s)return s +return r}, +gl(a){var s,r=J.at(this.a),q=this.b +if(q>=r)return 0 +s=this.c +if(s==null||s>=r)return r-q +return s-q}, +L(a,b){var s=this,r=s.gjq()+b +if(b<0||r>=s.giq())throw A.b(A.hf(b,s.gl(0),s,null,"index")) +return J.j1(s.a,r)}, +Y(a,b){var s,r,q=this +A.ab(b,"count") +s=q.b+b +r=q.c +if(r!=null&&s>=r)return new A.cu(q.$ti.h("cu<1>")) +return A.b5(q.a,s,r,q.$ti.c)}, +ah(a,b){var s,r,q,p=this +A.ab(b,"count") +s=p.c +r=p.b +q=r+b +if(s==null)return A.b5(p.a,r,q,p.$ti.c) +else{if(s=o){r.d=null +return!1}r.d=p.L(q,s);++r.c +return!0}} +A.aE.prototype={ +gq(a){var s=this.a +return new A.d9(s.gq(s),this.b,A.r(this).h("d9<1,2>"))}, +gl(a){var s=this.a +return s.gl(s)}, +gB(a){var s=this.a +return s.gB(s)}, +gF(a){var s=this.a +return this.b.$1(s.gF(s))}, +gE(a){var s=this.a +return this.b.$1(s.gE(s))}, +L(a,b){var s=this.a +return this.b.$1(s.L(s,b))}} +A.ct.prototype={$iq:1} +A.d9.prototype={ +k(){var s=this,r=s.b +if(r.k()){s.a=s.c.$1(r.gm()) +return!0}s.a=null +return!1}, +gm(){var s=this.a +return s==null?this.$ti.y[1].a(s):s}} +A.E.prototype={ +gl(a){return J.at(this.a)}, +L(a,b){return this.b.$1(J.j1(this.a,b))}} +A.aY.prototype={ +gq(a){return new A.eU(J.a4(this.a),this.b)}, +b8(a,b,c){return new A.aE(this,b,this.$ti.h("@<1>").H(c).h("aE<1,2>"))}} +A.eU.prototype={ +k(){var s,r +for(s=this.a,r=this.b;s.k();)if(r.$1(s.gm()))return!0 +return!1}, +gm(){return this.a.gm()}} +A.en.prototype={ +gq(a){return new A.ha(J.a4(this.a),this.b,B.O,this.$ti.h("ha<1,2>"))}} +A.ha.prototype={ +gm(){var s=this.d +return s==null?this.$ti.y[1].a(s):s}, +k(){var s,r,q=this,p=q.c +if(p==null)return!1 +for(s=q.a,r=q.b;!p.k();){q.d=null +if(s.k()){q.c=null +p=J.a4(r.$1(s.gm())) +q.c=p}else return!1}q.d=q.c.gm() +return!0}} +A.cD.prototype={ +gq(a){var s=this.a +return new A.hR(s.gq(s),this.b,A.r(this).h("hR<1>"))}} +A.el.prototype={ +gl(a){var s=this.a,r=s.gl(s) +s=this.b +if(r>s)return s +return r}, +$iq:1} +A.hR.prototype={ +k(){if(--this.b>=0)return this.a.k() +this.b=-1 +return!1}, +gm(){if(this.b<0){this.$ti.c.a(null) +return null}return this.a.gm()}} +A.bJ.prototype={ +Y(a,b){A.bT(b,"count") +A.ab(b,"count") +return new A.bJ(this.a,this.b+b,A.r(this).h("bJ<1>"))}, +gq(a){var s=this.a +return new A.hM(s.gq(s),this.b)}} +A.d3.prototype={ +gl(a){var s=this.a,r=s.gl(s)-this.b +if(r>=0)return r +return 0}, +Y(a,b){A.bT(b,"count") +A.ab(b,"count") +return new A.d3(this.a,this.b+b,this.$ti)}, +$iq:1} +A.hM.prototype={ +k(){var s,r +for(s=this.a,r=0;r"))}, +Y(a,b){A.ab(b,"count") +return this}, +ah(a,b){A.ab(b,"count") +return this}} +A.h7.prototype={ +k(){return!1}, +gm(){throw A.b(A.az())}} +A.eV.prototype={ +gq(a){return new A.i7(J.a4(this.a),this.$ti.h("i7<1>"))}} +A.i7.prototype={ +k(){var s,r +for(s=this.a,r=this.$ti.c;s.k();)if(r.b(s.gm()))return!0 +return!1}, +gm(){return this.$ti.c.a(this.a.gm())}} +A.by.prototype={ +gl(a){return J.at(this.a)}, +gB(a){return J.nY(this.a)}, +gF(a){return new A.ah(this.b,J.j2(this.a))}, +L(a,b){return new A.ah(b+this.b,J.j1(this.a,b))}, +ah(a,b){A.bT(b,"count") +A.ab(b,"count") +return new A.by(J.j3(this.a,b),this.b,A.r(this).h("by<1>"))}, +Y(a,b){A.bT(b,"count") +A.ab(b,"count") +return new A.by(J.e7(this.a,b),b+this.b,A.r(this).h("by<1>"))}, +gq(a){return new A.er(J.a4(this.a),this.b)}} +A.cs.prototype={ +gE(a){var s,r=this.a,q=J.a0(r),p=q.gl(r) +if(p<=0)throw A.b(A.az()) +s=q.gE(r) +if(p!==q.gl(r))throw A.b(A.au(this)) +return new A.ah(p-1+this.b,s)}, +ah(a,b){A.bT(b,"count") +A.ab(b,"count") +return new A.cs(J.j3(this.a,b),this.b,this.$ti)}, +Y(a,b){A.bT(b,"count") +A.ab(b,"count") +return new A.cs(J.e7(this.a,b),this.b+b,this.$ti)}, +$iq:1} +A.er.prototype={ +k(){if(++this.c>=0&&this.a.k())return!0 +this.c=-2 +return!1}, +gm(){var s=this.c +return s>=0?new A.ah(this.b+s,this.a.gm()):A.C(A.az())}} +A.eo.prototype={} +A.hV.prototype={ +t(a,b,c){throw A.b(A.a3("Cannot modify an unmodifiable list"))}, +M(a,b,c,d,e){throw A.b(A.a3("Cannot modify an unmodifiable list"))}, +ad(a,b,c,d){return this.M(0,b,c,d,0)}} +A.dr.prototype={} +A.eI.prototype={ +gl(a){return J.at(this.a)}, +L(a,b){var s=this.a,r=J.a0(s) +return r.L(s,r.gl(s)-1-b)}} +A.hQ.prototype={ +gA(a){var s=this._hashCode +if(s!=null)return s +s=664597*B.a.gA(this.a)&536870911 +this._hashCode=s +return s}, +i(a){return'Symbol("'+this.a+'")'}, +W(a,b){if(b==null)return!1 +return b instanceof A.hQ&&this.a===b.a}} +A.fz.prototype={} +A.ah.prototype={$r:"+(1,2)",$s:1} +A.cO.prototype={$r:"+file,outFlags(1,2)",$s:2} +A.iD.prototype={$r:"+result,resultCode(1,2)",$s:3} +A.eg.prototype={ +i(a){return A.oc(this)}, +gcU(){return new A.dR(this.ks(),A.r(this).h("dR>"))}, +ks(){var s=this +return function(){var r=0,q=1,p=[],o,n,m +return function $async$gcU(a,b,c){if(b===1){p.push(c) +r=q}for(;;)switch(r){case 0:o=s.ga_(),o=o.gq(o),n=A.r(s).h("aN<1,2>") +case 2:if(!o.k()){r=3 +break}m=o.gm() +r=4 +return a.b=new A.aN(m,s.j(0,m),n),1 +case 4:r=2 +break +case 3:return 0 +case 1:return a.c=p.at(-1),3}}}}, +$ian:1} +A.eh.prototype={ +gl(a){return this.b.length}, +gfk(){var s=this.$keys +if(s==null){s=Object.keys(this.a) +this.$keys=s}return s}, +a4(a){if(typeof a!="string")return!1 +if("__proto__"===a)return!1 +return this.a.hasOwnProperty(a)}, +j(a,b){if(!this.a4(b))return null +return this.b[this.a[b]]}, +ap(a,b){var s,r,q=this.gfk(),p=this.b +for(s=q.length,r=0;r"))}, +gbF(){return new A.cM(this.b,this.$ti.h("cM<2>"))}} +A.cM.prototype={ +gl(a){return this.a.length}, +gB(a){return 0===this.a.length}, +gq(a){var s=this.a +return new A.iw(s,s.length,this.$ti.h("iw<1>"))}} +A.iw.prototype={ +gm(){var s=this.d +return s==null?this.$ti.c.a(s):s}, +k(){var s=this,r=s.c +if(r>=s.b){s.d=null +return!1}s.d=s.a[r] +s.c=r+1 +return!0}} +A.kp.prototype={ +W(a,b){if(b==null)return!1 +return b instanceof A.es&&this.a.W(0,b.a)&&A.oU(this)===A.oU(b)}, +gA(a){return A.eD(this.a,A.oU(this),B.f,B.f)}, +i(a){var s=B.c.aq([A.bR(this.$ti.c)],", ") +return this.a.i(0)+" with "+("<"+s+">")}} +A.es.prototype={ +$2(a,b){return this.a.$1$2(a,b,this.$ti.y[0])}, +$4(a,b,c,d){return this.a.$1$4(a,b,c,d,this.$ti.y[0])}, +$S(){return A.wZ(A.nC(this.a),this.$ti)}} +A.eJ.prototype={} +A.lv.prototype={ +ar(a){var s,r,q=this,p=new RegExp(q.a).exec(a) +if(p==null)return null +s=Object.create(null) +r=q.b +if(r!==-1)s.arguments=p[r+1] +r=q.c +if(r!==-1)s.argumentsExpr=p[r+1] +r=q.d +if(r!==-1)s.expr=p[r+1] +r=q.e +if(r!==-1)s.method=p[r+1] +r=q.f +if(r!==-1)s.receiver=p[r+1] +return s}} +A.eC.prototype={ +i(a){return"Null check operator used on a null value"}} +A.hn.prototype={ +i(a){var s,r=this,q="NoSuchMethodError: method not found: '",p=r.b +if(p==null)return"NoSuchMethodError: "+r.a +s=r.c +if(s==null)return q+p+"' ("+r.a+")" +return q+p+"' on '"+s+"' ("+r.a+")"}} +A.hU.prototype={ +i(a){var s=this.a +return s.length===0?"Error":"Error: "+s}} +A.hD.prototype={ +i(a){return"Throw of null ('"+(this.a===null?"null":"undefined")+"' from JavaScript)"}, +$ia5:1} +A.em.prototype={} +A.fm.prototype={ +i(a){var s,r=this.b +if(r!=null)return r +r=this.a +s=r!==null&&typeof r==="object"?r.stack:null +return this.b=s==null?"":s}, +$iY:1} +A.cp.prototype={ +i(a){var s=this.constructor,r=s==null?null:s.name +return"Closure '"+A.rw(r==null?"unknown":r)+"'"}, +glI(){return this}, +$C:"$1", +$R:1, +$D:null} +A.jj.prototype={$C:"$0",$R:0} +A.jk.prototype={$C:"$2",$R:2} +A.ll.prototype={} +A.lb.prototype={ +i(a){var s=this.$static_name +if(s==null)return"Closure of unknown static method" +return"Closure '"+A.rw(s)+"'"}} +A.eb.prototype={ +W(a,b){if(b==null)return!1 +if(this===b)return!0 +if(!(b instanceof A.eb))return!1 +return this.$_target===b.$_target&&this.a===b.a}, +gA(a){return(A.oY(this.a)^A.eG(this.$_target))>>>0}, +i(a){return"Closure '"+this.$_name+"' of "+("Instance of '"+A.hG(this.a)+"'")}} +A.hJ.prototype={ +i(a){return"RuntimeError: "+this.a}} +A.bA.prototype={ +gl(a){return this.a}, +gB(a){return this.a===0}, +ga_(){return new A.bB(this,A.r(this).h("bB<1>"))}, +gbF(){return new A.ex(this,A.r(this).h("ex<2>"))}, +gcU(){return new A.ew(this,A.r(this).h("ew<1,2>"))}, +a4(a){var s,r +if(typeof a=="string"){s=this.b +if(s==null)return!1 +return s[a]!=null}else if(typeof a=="number"&&(a&0x3fffffff)===a){r=this.c +if(r==null)return!1 +return r[a]!=null}else return this.ky(a)}, +ky(a){var s=this.d +if(s==null)return!1 +return this.d_(s[this.cZ(a)],a)>=0}, +aG(a,b){b.ap(0,new A.kw(this))}, +j(a,b){var s,r,q,p,o=null +if(typeof b=="string"){s=this.b +if(s==null)return o +r=s[b] +q=r==null?o:r.b +return q}else if(typeof b=="number"&&(b&0x3fffffff)===b){p=this.c +if(p==null)return o +r=p[b] +q=r==null?o:r.b +return q}else return this.kz(b)}, +kz(a){var s,r,q=this.d +if(q==null)return null +s=q[this.cZ(a)] +r=this.d_(s,a) +if(r<0)return null +return s[r].b}, +t(a,b,c){var s,r,q=this +if(typeof b=="string"){s=q.b +q.eX(s==null?q.b=q.dW():s,b,c)}else if(typeof b=="number"&&(b&0x3fffffff)===b){r=q.c +q.eX(r==null?q.c=q.dW():r,b,c)}else q.kB(b,c)}, +kB(a,b){var s,r,q,p=this,o=p.d +if(o==null)o=p.d=p.dW() +s=p.cZ(a) +r=o[s] +if(r==null)o[s]=[p.dq(a,b)] +else{q=p.d_(r,a) +if(q>=0)r[q].b=b +else r.push(p.dq(a,b))}}, +hj(a,b){var s,r,q=this +if(q.a4(a)){s=q.j(0,a) +return s==null?A.r(q).y[1].a(s):s}r=b.$0() +q.t(0,a,r) +return r}, +G(a,b){var s=this +if(typeof b=="string")return s.eY(s.b,b) +else if(typeof b=="number"&&(b&0x3fffffff)===b)return s.eY(s.c,b) +else return s.kA(b)}, +kA(a){var s,r,q,p,o=this,n=o.d +if(n==null)return null +s=o.cZ(a) +r=n[s] +q=o.d_(r,a) +if(q<0)return null +p=r.splice(q,1)[0] +o.eZ(p) +if(r.length===0)delete n[s] +return p.b}, +ef(a){var s=this +if(s.a>0){s.b=s.c=s.d=s.e=s.f=null +s.a=0 +s.dn()}}, +ap(a,b){var s=this,r=s.e,q=s.r +while(r!=null){b.$2(r.a,r.b) +if(q!==s.r)throw A.b(A.au(s)) +r=r.c}}, +eX(a,b,c){var s=a[b] +if(s==null)a[b]=this.dq(b,c) +else s.b=c}, +eY(a,b){var s +if(a==null)return null +s=a[b] +if(s==null)return null +this.eZ(s) +delete a[b] +return s.b}, +dn(){this.r=this.r+1&1073741823}, +dq(a,b){var s,r=this,q=new A.kz(a,b) +if(r.e==null)r.e=r.f=q +else{s=r.f +s.toString +q.d=s +r.f=s.c=q}++r.a +r.dn() +return q}, +eZ(a){var s=this,r=a.d,q=a.c +if(r==null)s.e=q +else r.c=q +if(q==null)s.f=r +else q.d=r;--s.a +s.dn()}, +cZ(a){return J.aC(a)&1073741823}, +d_(a,b){var s,r +if(a==null)return-1 +s=a.length +for(r=0;r"]=s +delete s[""] +return s}} +A.kw.prototype={ +$2(a,b){this.a.t(0,a,b)}, +$S(){return A.r(this.a).h("~(1,2)")}} +A.kz.prototype={} +A.bB.prototype={ +gl(a){return this.a.a}, +gB(a){return this.a.a===0}, +gq(a){var s=this.a +return new A.hr(s,s.r,s.e)}} +A.hr.prototype={ +gm(){return this.d}, +k(){var s,r=this,q=r.a +if(r.b!==q.r)throw A.b(A.au(q)) +s=r.c +if(s==null){r.d=null +return!1}else{r.d=s.a +r.c=s.c +return!0}}} +A.ex.prototype={ +gl(a){return this.a.a}, +gB(a){return this.a.a===0}, +gq(a){var s=this.a +return new A.cx(s,s.r,s.e)}} +A.cx.prototype={ +gm(){return this.d}, +k(){var s,r=this,q=r.a +if(r.b!==q.r)throw A.b(A.au(q)) +s=r.c +if(s==null){r.d=null +return!1}else{r.d=s.b +r.c=s.c +return!0}}} +A.ew.prototype={ +gl(a){return this.a.a}, +gB(a){return this.a.a===0}, +gq(a){var s=this.a +return new A.hq(s,s.r,s.e,this.$ti.h("hq<1,2>"))}} +A.hq.prototype={ +gm(){var s=this.d +s.toString +return s}, +k(){var s,r=this,q=r.a +if(r.b!==q.r)throw A.b(A.au(q)) +s=r.c +if(s==null){r.d=null +return!1}else{r.d=new A.aN(s.a,s.b,r.$ti.h("aN<1,2>")) +r.c=s.c +return!0}}} +A.nI.prototype={ +$1(a){return this.a(a)}, +$S:114} +A.nJ.prototype={ +$2(a,b){return this.a(a,b)}, +$S:39} +A.nK.prototype={ +$1(a){return this.a(a)}, +$S:45} +A.fi.prototype={ +i(a){return this.fO(!1)}, +fO(a){var s,r,q,p,o,n=this.is(),m=this.fh(),l=(a?"Record ":"")+"(" +for(s=n.length,r="",q=0;q0;){--q;--s +k[q]=r[s]}}return A.aM(k,t.K)}} +A.iC.prototype={ +fh(){return[this.a,this.b]}, +W(a,b){if(b==null)return!1 +return b instanceof A.iC&&this.$s===b.$s&&J.aj(this.a,b.a)&&J.aj(this.b,b.b)}, +gA(a){return A.eD(this.$s,this.a,this.b,B.f)}} +A.cw.prototype={ +i(a){return"RegExp/"+this.a+"/"+this.b.flags}, +gfo(){var s=this,r=s.c +if(r!=null)return r +r=s.b +return s.c=A.o8(s.a,r.multiline,!r.ignoreCase,r.unicode,r.dotAll,"g")}, +giK(){var s=this,r=s.d +if(r!=null)return r +r=s.b +return s.d=A.o8(s.a,r.multiline,!r.ignoreCase,r.unicode,r.dotAll,"y")}, +i9(){var s,r=this.a +if(!B.a.I(r,"("))return!1 +s=this.b.unicode?"u":"" +return new RegExp("(?:)|"+r,s).exec("").length>1}, +a8(a){var s=this.b.exec(a) +if(s==null)return null +return new A.dH(s)}, +cL(a,b,c){var s=b.length +if(c>s)throw A.b(A.S(c,0,s,null,null)) +return new A.i8(this,b,c)}, +eb(a,b){return this.cL(0,b,0)}, +fd(a,b){var s,r=this.gfo() +r.lastIndex=b +s=r.exec(a) +if(s==null)return null +return new A.dH(s)}, +ir(a,b){var s,r=this.giK() +r.lastIndex=b +s=r.exec(a) +if(s==null)return null +return new A.dH(s)}, +hd(a,b,c){if(c<0||c>b.length)throw A.b(A.S(c,0,b.length,null,null)) +return this.ir(b,c)}} +A.dH.prototype={ +gco(){return this.b.index}, +gbw(){var s=this.b +return s.index+s[0].length}, +j(a,b){return this.b[b]}, +aK(a){var s,r=this.b.groups +if(r!=null){s=r[a] +if(s!=null||a in r)return s}throw A.b(A.ad(a,"name","Not a capture group name"))}, +$iez:1, +$ihH:1} +A.i8.prototype={ +gq(a){return new A.m7(this.a,this.b,this.c)}} +A.m7.prototype={ +gm(){var s=this.d +return s==null?t.cz.a(s):s}, +k(){var s,r,q,p,o,n,m=this,l=m.b +if(l==null)return!1 +s=m.c +r=l.length +if(s<=r){q=m.a +p=q.fd(l,s) +if(p!=null){m.d=p +o=p.gbw() +if(p.b.index===o){s=!1 +if(q.b.unicode){q=m.c +n=q+1 +if(n=55296&&r<=56319){s=l.charCodeAt(n) +s=s>=56320&&s<=57343}}}o=(s?o+1:o)+1}m.c=o +return!0}}m.b=m.d=null +return!1}} +A.dp.prototype={ +gbw(){return this.a+this.c.length}, +j(a,b){if(b!==0)A.C(A.kN(b,null)) +return this.c}, +$iez:1, +gco(){return this.a}} +A.iL.prototype={ +gq(a){return new A.n6(this.a,this.b,this.c)}, +gF(a){var s=this.b,r=this.a.indexOf(s,this.c) +if(r>=0)return new A.dp(r,s) +throw A.b(A.az())}} +A.n6.prototype={ +k(){var s,r,q=this,p=q.c,o=q.b,n=o.length,m=q.a,l=m.length +if(p+n>l){q.d=null +return!1}s=m.indexOf(o,p) +if(s<0){q.c=l+1 +q.d=null +return!1}r=s+n +q.d=new A.dp(s,o) +q.c=r===q.c?r+1:r +return!0}, +gm(){var s=this.d +s.toString +return s}} +A.mn.prototype={ +af(){var s=this.b +if(s===this)throw A.b(A.pD(this.a)) +return s}} +A.db.prototype={ +gV(a){return B.b2}, +fU(a,b,c){A.fA(a,b,c) +return c==null?new Uint8Array(a,b):new Uint8Array(a,b,c)}, +jM(a,b,c){var s +A.fA(a,b,c) +s=new DataView(a,b) +return s}, +fT(a){return this.jM(a,0,null)}, +$iI:1, +$iec:1} +A.da.prototype={$ida:1} +A.eA.prototype={ +gaS(a){if(((a.$flags|0)&2)!==0)return new A.iR(a.buffer) +else return a.buffer}, +iE(a,b,c,d){var s=A.S(b,0,c,d,null) +throw A.b(s)}, +f4(a,b,c,d){if(b>>>0!==b||b>c)this.iE(a,b,c,d)}} +A.iR.prototype={ +fU(a,b,c){var s=A.bE(this.a,b,c) +s.$flags=3 +return s}, +fT(a){var s=A.pE(this.a,0,null) +s.$flags=3 +return s}, +$iec:1} +A.cy.prototype={ +gV(a){return B.b3}, +$iI:1, +$icy:1, +$io_:1} +A.dd.prototype={ +gl(a){return a.length}, +fG(a,b,c,d,e){var s,r,q=a.length +this.f4(a,b,q,"start") +this.f4(a,c,q,"end") +if(b>c)throw A.b(A.S(b,0,c,null,null)) +s=c-b +if(e<0)throw A.b(A.J(e,null)) +r=d.length +if(r-e0){s=Date.now()-r.c +if(s>(p+1)*o)p=B.b.eW(s,o)}q.c=p +r.d.$1(q)}, +$S:5} +A.i9.prototype={ +P(a){var s,r=this +if(a==null)a=r.$ti.c.a(a) +if(!r.b)r.a.b0(a) +else{s=r.a +if(r.$ti.h("D<1>").b(a))s.f3(a) +else s.bI(a)}}, +bv(a,b){var s=this.a +if(this.b)s.X(new A.U(a,b)) +else s.aN(new A.U(a,b))}} +A.nm.prototype={ +$1(a){return this.a.$2(0,a)}, +$S:14} +A.nn.prototype={ +$2(a,b){this.a.$2(1,new A.em(a,b))}, +$S:40} +A.nA.prototype={ +$2(a,b){this.a(a,b)}, +$S:48} +A.iM.prototype={ +gm(){return this.b}, +j8(a,b){var s,r,q +a=a +b=b +s=this.a +for(;;)try{r=s(this,a,b) +return r}catch(q){b=q +a=1}}, +k(){var s,r,q,p,o=this,n=null,m=0 +for(;;){s=o.d +if(s!=null)try{if(s.k()){o.b=s.gm() +return!0}else o.d=null}catch(r){n=r +m=1 +o.d=null}q=o.j8(m,n) +if(1===q)return!0 +if(0===q){o.b=null +p=o.e +if(p==null||p.length===0){o.a=A.qw +return!1}o.a=p.pop() +m=0 +n=null +continue}if(2===q){m=0 +n=null +continue}if(3===q){n=o.c +o.c=null +p=o.e +if(p==null||p.length===0){o.b=null +o.a=A.qw +throw n +return!1}o.a=p.pop() +m=1 +continue}throw A.b(A.B("sync*"))}return!1}, +lJ(a){var s,r,q=this +if(a instanceof A.dR){s=a.a() +r=q.e +if(r==null)r=q.e=[] +r.push(q.a) +q.a=s +return 2}else{q.d=J.a4(a) +return 2}}} +A.dR.prototype={ +gq(a){return new A.iM(this.a())}} +A.U.prototype={ +i(a){return A.t(this.a)}, +$iO:1, +gbi(){return this.b}} +A.eZ.prototype={} +A.cG.prototype={ +ak(){}, +al(){}} +A.cF.prototype={ +gbK(){return this.c<4}, +fB(a){var s=a.CW,r=a.ch +if(s==null)this.d=r +else s.ch=r +if(r==null)this.e=s +else r.CW=s +a.CW=a +a.ch=a}, +fI(a,b,c,d){var s,r,q,p,o,n,m,l,k,j=this +if((j.c&4)!==0){s=$.h +r=new A.f3(s) +A.p_(r.gfp()) +if(c!=null)r.c=s.au(c,t.H) +return r}s=A.r(j) +r=$.h +q=d?1:0 +p=b!=null?32:0 +o=A.ig(r,a,s.c) +n=A.ih(r,b) +m=c==null?A.rf():c +l=new A.cG(j,o,n,r.au(m,t.H),r,q|p,s.h("cG<1>")) +l.CW=l +l.ch=l +l.ay=j.c&1 +k=j.e +j.e=l +l.ch=null +l.CW=k +if(k==null)j.d=l +else k.ch=l +if(j.d===l)A.iW(j.a) +return l}, +ft(a){var s,r=this +A.r(r).h("cG<1>").a(a) +if(a.ch===a)return null +s=a.ay +if((s&2)!==0)a.ay=s|4 +else{r.fB(a) +if((r.c&2)===0&&r.d==null)r.du()}return null}, +fu(a){}, +fv(a){}, +bH(){if((this.c&4)!==0)return new A.aQ("Cannot add new events after calling close") +return new A.aQ("Cannot add new events while doing an addStream")}, +v(a,b){if(!this.gbK())throw A.b(this.bH()) +this.b2(b)}, +a3(a,b){var s +if(!this.gbK())throw A.b(this.bH()) +s=A.ns(a,b) +this.b4(s.a,s.b)}, +n(){var s,r,q=this +if((q.c&4)!==0){s=q.r +s.toString +return s}if(!q.gbK())throw A.b(q.bH()) +q.c|=4 +r=q.r +if(r==null)r=q.r=new A.n($.h,t.D) +q.b3() +return r}, +dK(a){var s,r,q,p=this,o=p.c +if((o&2)!==0)throw A.b(A.B(u.o)) +s=p.d +if(s==null)return +r=o&1 +p.c=o^3 +while(s!=null){o=s.ay +if((o&1)===r){s.ay=o|2 +a.$1(s) +o=s.ay^=1 +q=s.ch +if((o&4)!==0)p.fB(s) +s.ay&=4294967293 +s=q}else s=s.ch}p.c&=4294967293 +if(p.d==null)p.du()}, +du(){if((this.c&4)!==0){var s=this.r +if((s.a&30)===0)s.b0(null)}A.iW(this.b)}, +$iae:1} +A.fp.prototype={ +gbK(){return A.cF.prototype.gbK.call(this)&&(this.c&2)===0}, +bH(){if((this.c&2)!==0)return new A.aQ(u.o) +return this.hN()}, +b2(a){var s=this,r=s.d +if(r==null)return +if(r===s.e){s.c|=2 +r.bm(a) +s.c&=4294967293 +if(s.d==null)s.du() +return}s.dK(new A.n7(s,a))}, +b4(a,b){if(this.d==null)return +this.dK(new A.n9(this,a,b))}, +b3(){var s=this +if(s.d!=null)s.dK(new A.n8(s)) +else s.r.b0(null)}} +A.n7.prototype={ +$1(a){a.bm(this.b)}, +$S(){return this.a.$ti.h("~(ag<1>)")}} +A.n9.prototype={ +$1(a){a.bk(this.b,this.c)}, +$S(){return this.a.$ti.h("~(ag<1>)")}} +A.n8.prototype={ +$1(a){a.ct()}, +$S(){return this.a.$ti.h("~(ag<1>)")}} +A.ki.prototype={ +$0(){var s,r,q,p,o,n,m=null +try{m=this.a.$0()}catch(q){s=A.G(q) +r=A.a1(q) +p=s +o=r +n=A.cS(p,o) +if(n==null)p=new A.U(p,o) +else p=n +this.b.X(p) +return}this.b.b1(m)}, +$S:0} +A.kg.prototype={ +$0(){this.c.a(null) +this.b.b1(null)}, +$S:0} +A.kk.prototype={ +$2(a,b){var s=this,r=s.a,q=--r.b +if(r.a!=null){r.a=null +r.d=a +r.c=b +if(q===0||s.c)s.d.X(new A.U(a,b))}else if(q===0&&!s.c){q=r.d +q.toString +r=r.c +r.toString +s.d.X(new A.U(q,r))}}, +$S:6} +A.kj.prototype={ +$1(a){var s,r,q,p,o,n,m=this,l=m.a,k=--l.b,j=l.a +if(j!=null){J.pb(j,m.b,a) +if(J.aj(k,0)){l=m.d +s=A.f([],l.h("u<0>")) +for(q=j,p=q.length,o=0;o")) +r=b==null?1:3 +this.cr(new A.cg(s,r,a,b,this.$ti.h("@<1>").H(c).h("cg<1,2>"))) +return s}, +ce(a,b){return this.bE(a,null,b)}, +fM(a,b,c){var s=new A.n($.h,c.h("n<0>")) +this.cr(new A.cg(s,19,a,b,this.$ti.h("@<1>").H(c).h("cg<1,2>"))) +return s}, +ai(a){var s=this.$ti,r=$.h,q=new A.n(r,s) +if(r!==B.d)a=r.au(a,t.z) +this.cr(new A.cg(q,8,a,null,s.h("cg<1,1>"))) +return q}, +jj(a){this.a=this.a&1|16 +this.c=a}, +cs(a){this.a=a.a&30|this.a&1 +this.c=a.c}, +cr(a){var s=this,r=s.a +if(r<=3){a.a=s.c +s.c=a}else{if((r&4)!==0){r=s.c +if((r.a&24)===0){r.cr(a) +return}s.cs(r)}s.b.aY(new A.mE(s,a))}}, +fq(a){var s,r,q,p,o,n=this,m={} +m.a=a +if(a==null)return +s=n.a +if(s<=3){r=n.c +n.c=a +if(r!=null){q=a.a +for(p=a;q!=null;p=q,q=o)o=q.a +p.a=r}}else{if((s&4)!==0){s=n.c +if((s.a&24)===0){s.fq(a) +return}n.cs(s)}m.a=n.cC(a) +n.b.aY(new A.mJ(m,n))}}, +bP(){var s=this.c +this.c=null +return this.cC(s)}, +cC(a){var s,r,q +for(s=a,r=null;s!=null;r=s,s=q){q=s.a +s.a=r}return r}, +b1(a){var s,r=this +if(r.$ti.h("D<1>").b(a))A.mH(a,r,!0) +else{s=r.bP() +r.a=8 +r.c=a +A.cJ(r,s)}}, +bI(a){var s=this,r=s.bP() +s.a=8 +s.c=a +A.cJ(s,r)}, +i7(a){var s,r,q,p=this +if((a.a&16)!==0){s=p.b +r=a.b +s=!(s===r||s.gaI()===r.gaI())}else s=!1 +if(s)return +q=p.bP() +p.cs(a) +A.cJ(p,q)}, +X(a){var s=this.bP() +this.jj(a) +A.cJ(this,s)}, +i6(a,b){this.X(new A.U(a,b))}, +b0(a){if(this.$ti.h("D<1>").b(a)){this.f3(a) +return}this.f2(a)}, +f2(a){this.a^=2 +this.b.aY(new A.mG(this,a))}, +f3(a){A.mH(a,this,!1) +return}, +aN(a){this.a^=2 +this.b.aY(new A.mF(this,a))}, +$iD:1} +A.mE.prototype={ +$0(){A.cJ(this.a,this.b)}, +$S:0} +A.mJ.prototype={ +$0(){A.cJ(this.b,this.a.a)}, +$S:0} +A.mI.prototype={ +$0(){A.mH(this.a.a,this.b,!0)}, +$S:0} +A.mG.prototype={ +$0(){this.a.bI(this.b)}, +$S:0} +A.mF.prototype={ +$0(){this.a.X(this.b)}, +$S:0} +A.mM.prototype={ +$0(){var s,r,q,p,o,n,m,l,k=this,j=null +try{q=k.a.a +j=q.b.b.bb(q.d,t.z)}catch(p){s=A.G(p) +r=A.a1(p) +if(k.c&&k.b.a.c.a===s){q=k.a +q.c=k.b.a.c}else{q=s +o=r +if(o==null)o=A.fO(q) +n=k.a +n.c=new A.U(q,o) +q=n}q.b=!0 +return}if(j instanceof A.n&&(j.a&24)!==0){if((j.a&16)!==0){q=k.a +q.c=j.c +q.b=!0}return}if(j instanceof A.n){m=k.b.a +l=new A.n(m.b,m.$ti) +j.bE(new A.mN(l,m),new A.mO(l),t.H) +q=k.a +q.c=l +q.b=!1}}, +$S:0} +A.mN.prototype={ +$1(a){this.a.i7(this.b)}, +$S:26} +A.mO.prototype={ +$2(a,b){this.a.X(new A.U(a,b))}, +$S:58} +A.mL.prototype={ +$0(){var s,r,q,p,o,n +try{q=this.a +p=q.a +o=p.$ti +q.c=p.b.b.bc(p.d,this.b,o.h("2/"),o.c)}catch(n){s=A.G(n) +r=A.a1(n) +q=s +p=r +if(p==null)p=A.fO(q) +o=this.a +o.c=new A.U(q,p) +o.b=!0}}, +$S:0} +A.mK.prototype={ +$0(){var s,r,q,p,o,n,m,l=this +try{s=l.a.a.c +p=l.b +if(p.a.kL(s)&&p.a.e!=null){p.c=p.a.kw(s) +p.b=!1}}catch(o){r=A.G(o) +q=A.a1(o) +p=l.a.a.c +if(p.a===r){n=l.b +n.c=p +p=n}else{p=r +n=q +if(n==null)n=A.fO(p) +m=l.b +m.c=new A.U(p,n) +p=m}p.b=!0}}, +$S:0} +A.ia.prototype={} +A.V.prototype={ +gl(a){var s={},r=new A.n($.h,t.gR) +s.a=0 +this.R(new A.li(s,this),!0,new A.lj(s,r),r.gdB()) +return r}, +gF(a){var s=new A.n($.h,A.r(this).h("n")),r=this.R(null,!0,new A.lg(s),s.gdB()) +r.c6(new A.lh(this,r,s)) +return s}, +ku(a,b){var s=new A.n($.h,A.r(this).h("n")),r=this.R(null,!0,new A.le(null,s),s.gdB()) +r.c6(new A.lf(this,b,r,s)) +return s}} +A.li.prototype={ +$1(a){++this.a.a}, +$S(){return A.r(this.b).h("~(V.T)")}} +A.lj.prototype={ +$0(){this.b.b1(this.a.a)}, +$S:0} +A.lg.prototype={ +$0(){var s,r=A.la(),q=new A.aQ("No element") +A.eH(q,r) +s=A.cS(q,r) +if(s==null)s=new A.U(q,r) +this.a.X(s)}, +$S:0} +A.lh.prototype={ +$1(a){A.qS(this.b,this.c,a)}, +$S(){return A.r(this.a).h("~(V.T)")}} +A.le.prototype={ +$0(){var s,r=A.la(),q=new A.aQ("No element") +A.eH(q,r) +s=A.cS(q,r) +if(s==null)s=new A.U(q,r) +this.b.X(s)}, +$S:0} +A.lf.prototype={ +$1(a){var s=this.c,r=this.d +A.w9(new A.lc(this.b,a),new A.ld(s,r,a),A.vw(s,r))}, +$S(){return A.r(this.a).h("~(V.T)")}} +A.lc.prototype={ +$0(){return this.a.$1(this.b)}, +$S:29} +A.ld.prototype={ +$1(a){if(a)A.qS(this.a,this.b,this.c)}, +$S:72} +A.hP.prototype={} +A.cP.prototype={ +giX(){if((this.b&8)===0)return this.a +return this.a.ge6()}, +dH(){var s,r=this +if((r.b&8)===0){s=r.a +return s==null?r.a=new A.fh():s}s=r.a.ge6() +return s}, +gaQ(){var s=this.a +return(this.b&8)!==0?s.ge6():s}, +ds(){if((this.b&4)!==0)return new A.aQ("Cannot add event after closing") +return new A.aQ("Cannot add event while adding a stream")}, +fa(){var s=this.c +if(s==null)s=this.c=(this.b&2)!==0?$.cm():new A.n($.h,t.D) +return s}, +v(a,b){var s=this,r=s.b +if(r>=4)throw A.b(s.ds()) +if((r&1)!==0)s.b2(b) +else if((r&3)===0)s.dH().v(0,new A.dy(b))}, +a3(a,b){var s,r,q=this +if(q.b>=4)throw A.b(q.ds()) +s=A.ns(a,b) +a=s.a +b=s.b +r=q.b +if((r&1)!==0)q.b4(a,b) +else if((r&3)===0)q.dH().v(0,new A.f2(a,b))}, +jK(a){return this.a3(a,null)}, +n(){var s=this,r=s.b +if((r&4)!==0)return s.fa() +if(r>=4)throw A.b(s.ds()) +r=s.b=r|4 +if((r&1)!==0)s.b3() +else if((r&3)===0)s.dH().v(0,B.x) +return s.fa()}, +fI(a,b,c,d){var s,r,q,p=this +if((p.b&3)!==0)throw A.b(A.B("Stream has already been listened to.")) +s=A.uM(p,a,b,c,d,A.r(p).c) +r=p.giX() +if(((p.b|=1)&8)!==0){q=p.a +q.se6(s) +q.ba()}else p.a=s +s.jk(r) +s.dL(new A.n4(p)) +return s}, +ft(a){var s,r,q,p,o,n,m,l=this,k=null +if((l.b&8)!==0)k=l.a.K() +l.a=null +l.b=l.b&4294967286|2 +s=l.r +if(s!=null)if(k==null)try{r=s.$0() +if(r instanceof A.n)k=r}catch(o){q=A.G(o) +p=A.a1(o) +n=new A.n($.h,t.D) +n.aN(new A.U(q,p)) +k=n}else k=k.ai(s) +m=new A.n3(l) +if(k!=null)k=k.ai(m) +else m.$0() +return k}, +fu(a){if((this.b&8)!==0)this.a.bA() +A.iW(this.e)}, +fv(a){if((this.b&8)!==0)this.a.ba() +A.iW(this.f)}, +$iae:1} +A.n4.prototype={ +$0(){A.iW(this.a.d)}, +$S:0} +A.n3.prototype={ +$0(){var s=this.a.c +if(s!=null&&(s.a&30)===0)s.b0(null)}, +$S:0} +A.iN.prototype={ +b2(a){this.gaQ().bm(a)}, +b4(a,b){this.gaQ().bk(a,b)}, +b3(){this.gaQ().ct()}} +A.ib.prototype={ +b2(a){this.gaQ().bl(new A.dy(a))}, +b4(a,b){this.gaQ().bl(new A.f2(a,b))}, +b3(){this.gaQ().bl(B.x)}} +A.dw.prototype={} +A.dS.prototype={} +A.ar.prototype={ +gA(a){return(A.eG(this.a)^892482866)>>>0}, +W(a,b){if(b==null)return!1 +if(this===b)return!0 +return b instanceof A.ar&&b.a===this.a}} +A.cf.prototype={ +cz(){return this.w.ft(this)}, +ak(){this.w.fu(this)}, +al(){this.w.fv(this)}} +A.dP.prototype={ +v(a,b){this.a.v(0,b)}, +a3(a,b){this.a.a3(a,b)}, +n(){return this.a.n()}, +$iae:1} +A.ag.prototype={ +jk(a){var s=this +if(a==null)return +s.r=a +if(a.c!=null){s.e=(s.e|128)>>>0 +a.cn(s)}}, +c6(a){this.a=A.ig(this.d,a,A.r(this).h("ag.T"))}, +eD(a){var s=this +s.e=(s.e&4294967263)>>>0 +s.b=A.ih(s.d,a)}, +bA(){var s,r,q=this,p=q.e +if((p&8)!==0)return +s=(p+256|4)>>>0 +q.e=s +if(p<256){r=q.r +if(r!=null)if(r.a===1)r.a=3}if((p&4)===0&&(s&64)===0)q.dL(q.gbL())}, +ba(){var s=this,r=s.e +if((r&8)!==0)return +if(r>=256){r=s.e=r-256 +if(r<256)if((r&128)!==0&&s.r.c!=null)s.r.cn(s) +else{r=(r&4294967291)>>>0 +s.e=r +if((r&64)===0)s.dL(s.gbM())}}}, +K(){var s=this,r=(s.e&4294967279)>>>0 +s.e=r +if((r&8)===0)s.dv() +r=s.f +return r==null?$.cm():r}, +dv(){var s,r=this,q=r.e=(r.e|8)>>>0 +if((q&128)!==0){s=r.r +if(s.a===1)s.a=3}if((q&64)===0)r.r=null +r.f=r.cz()}, +bm(a){var s=this.e +if((s&8)!==0)return +if(s<64)this.b2(a) +else this.bl(new A.dy(a))}, +bk(a,b){var s +if(t.C.b(a))A.eH(a,b) +s=this.e +if((s&8)!==0)return +if(s<64)this.b4(a,b) +else this.bl(new A.f2(a,b))}, +ct(){var s=this,r=s.e +if((r&8)!==0)return +r=(r|2)>>>0 +s.e=r +if(r<64)s.b3() +else s.bl(B.x)}, +ak(){}, +al(){}, +cz(){return null}, +bl(a){var s,r=this,q=r.r +if(q==null)q=r.r=new A.fh() +q.v(0,a) +s=r.e +if((s&128)===0){s=(s|128)>>>0 +r.e=s +if(s<256)q.cn(r)}}, +b2(a){var s=this,r=s.e +s.e=(r|64)>>>0 +s.d.cd(s.a,a,A.r(s).h("ag.T")) +s.e=(s.e&4294967231)>>>0 +s.dw((r&4)!==0)}, +b4(a,b){var s,r=this,q=r.e,p=new A.mm(r,a,b) +if((q&1)!==0){r.e=(q|16)>>>0 +r.dv() +s=r.f +if(s!=null&&s!==$.cm())s.ai(p) +else p.$0()}else{p.$0() +r.dw((q&4)!==0)}}, +b3(){var s,r=this,q=new A.ml(r) +r.dv() +r.e=(r.e|16)>>>0 +s=r.f +if(s!=null&&s!==$.cm())s.ai(q) +else q.$0()}, +dL(a){var s=this,r=s.e +s.e=(r|64)>>>0 +a.$0() +s.e=(s.e&4294967231)>>>0 +s.dw((r&4)!==0)}, +dw(a){var s,r,q=this,p=q.e +if((p&128)!==0&&q.r.c==null){p=q.e=(p&4294967167)>>>0 +s=!1 +if((p&4)!==0)if(p<256){s=q.r +s=s==null?null:s.c==null +s=s!==!1}if(s){p=(p&4294967291)>>>0 +q.e=p}}for(;;a=r){if((p&8)!==0){q.r=null +return}r=(p&4)!==0 +if(a===r)break +q.e=(p^64)>>>0 +if(r)q.ak() +else q.al() +p=(q.e&4294967231)>>>0 +q.e=p}if((p&128)!==0&&p<256)q.r.cn(q)}} +A.mm.prototype={ +$0(){var s,r,q,p=this.a,o=p.e +if((o&8)!==0&&(o&16)===0)return +p.e=(o|64)>>>0 +s=p.b +o=this.b +r=t.K +q=p.d +if(t.da.b(s))q.hq(s,o,this.c,r,t.l) +else q.cd(s,o,r) +p.e=(p.e&4294967231)>>>0}, +$S:0} +A.ml.prototype={ +$0(){var s=this.a,r=s.e +if((r&16)===0)return +s.e=(r|74)>>>0 +s.d.cc(s.c) +s.e=(s.e&4294967231)>>>0}, +$S:0} +A.dN.prototype={ +R(a,b,c,d){return this.a.fI(a,d,c,b===!0)}, +aV(a,b,c){return this.R(a,null,b,c)}, +kF(a){return this.R(a,null,null,null)}, +ez(a,b){return this.R(a,null,b,null)}} +A.ik.prototype={ +gc5(){return this.a}, +sc5(a){return this.a=a}} +A.dy.prototype={ +eF(a){a.b2(this.b)}} +A.f2.prototype={ +eF(a){a.b4(this.b,this.c)}} +A.mw.prototype={ +eF(a){a.b3()}, +gc5(){return null}, +sc5(a){throw A.b(A.B("No events after a done."))}} +A.fh.prototype={ +cn(a){var s=this,r=s.a +if(r===1)return +if(r>=1){s.a=1 +return}A.p_(new A.mU(s,a)) +s.a=1}, +v(a,b){var s=this,r=s.c +if(r==null)s.b=s.c=b +else{r.sc5(b) +s.c=b}}} +A.mU.prototype={ +$0(){var s,r,q=this.a,p=q.a +q.a=0 +if(p===3)return +s=q.b +r=s.gc5() +q.b=r +if(r==null)q.c=null +s.eF(this.b)}, +$S:0} +A.f3.prototype={ +c6(a){}, +eD(a){}, +bA(){var s=this.a +if(s>=0)this.a=s+2}, +ba(){var s=this,r=s.a-2 +if(r<0)return +if(r===0){s.a=1 +A.p_(s.gfp())}else s.a=r}, +K(){this.a=-1 +this.c=null +return $.cm()}, +iT(){var s,r=this,q=r.a-1 +if(q===0){r.a=-1 +s=r.c +if(s!=null){r.c=null +r.b.cc(s)}}else r.a=q}} +A.dO.prototype={ +gm(){if(this.c)return this.b +return null}, +k(){var s,r=this,q=r.a +if(q!=null){if(r.c){s=new A.n($.h,t.k) +r.b=s +r.c=!1 +q.ba() +return s}throw A.b(A.B("Already waiting for next."))}return r.iD()}, +iD(){var s,r,q=this,p=q.b +if(p!=null){s=new A.n($.h,t.k) +q.b=s +r=p.R(q.giN(),!0,q.giP(),q.giR()) +if(q.b!=null)q.a=r +return s}return $.rz()}, +K(){var s=this,r=s.a,q=s.b +s.b=null +if(r!=null){s.a=null +if(!s.c)q.b0(!1) +else s.c=!1 +return r.K()}return $.cm()}, +iO(a){var s,r,q=this +if(q.a==null)return +s=q.b +q.b=a +q.c=!0 +s.b1(!0) +if(q.c){r=q.a +if(r!=null)r.bA()}}, +iS(a,b){var s=this,r=s.a,q=s.b +s.b=s.a=null +if(r!=null)q.X(new A.U(a,b)) +else q.aN(new A.U(a,b))}, +iQ(){var s=this,r=s.a,q=s.b +s.b=s.a=null +if(r!=null)q.bI(!1) +else q.f2(!1)}} +A.np.prototype={ +$0(){return this.a.X(this.b)}, +$S:0} +A.no.prototype={ +$2(a,b){A.vv(this.a,this.b,new A.U(a,b))}, +$S:6} +A.nq.prototype={ +$0(){return this.a.b1(this.b)}, +$S:0} +A.f8.prototype={ +R(a,b,c,d){var s=this.$ti,r=$.h,q=b===!0?1:0,p=d!=null?32:0,o=A.ig(r,a,s.y[1]),n=A.ih(r,d) +s=new A.dA(this,o,n,r.au(c,t.H),r,q|p,s.h("dA<1,2>")) +s.x=this.a.aV(s.gdM(),s.gdO(),s.gdQ()) +return s}, +aV(a,b,c){return this.R(a,null,b,c)}} +A.dA.prototype={ +bm(a){if((this.e&2)!==0)return +this.dm(a)}, +bk(a,b){if((this.e&2)!==0)return +this.bj(a,b)}, +ak(){var s=this.x +if(s!=null)s.bA()}, +al(){var s=this.x +if(s!=null)s.ba()}, +cz(){var s=this.x +if(s!=null){this.x=null +return s.K()}return null}, +dN(a){this.w.ix(a,this)}, +dR(a,b){this.bk(a,b)}, +dP(){this.ct()}} +A.fc.prototype={ +ix(a,b){var s,r,q,p,o,n,m=null +try{m=this.b.$1(a)}catch(q){s=A.G(q) +r=A.a1(q) +p=s +o=r +n=A.cS(p,o) +if(n!=null){p=n.a +o=n.b}b.bk(p,o) +return}b.bm(m)}} +A.f5.prototype={ +v(a,b){var s=this.a +if((s.e&2)!==0)A.C(A.B("Stream is already closed")) +s.dm(b)}, +a3(a,b){var s=this.a +if((s.e&2)!==0)A.C(A.B("Stream is already closed")) +s.bj(a,b)}, +n(){var s=this.a +if((s.e&2)!==0)A.C(A.B("Stream is already closed")) +s.eV()}, +$iae:1} +A.dL.prototype={ +ak(){var s=this.x +if(s!=null)s.bA()}, +al(){var s=this.x +if(s!=null)s.ba()}, +cz(){var s=this.x +if(s!=null){this.x=null +return s.K()}return null}, +dN(a){var s,r,q,p +try{q=this.w +q===$&&A.x() +q.v(0,a)}catch(p){s=A.G(p) +r=A.a1(p) +if((this.e&2)!==0)A.C(A.B("Stream is already closed")) +this.bj(s,r)}}, +dR(a,b){var s,r,q,p,o=this,n="Stream is already closed" +try{q=o.w +q===$&&A.x() +q.a3(a,b)}catch(p){s=A.G(p) +r=A.a1(p) +if(s===a){if((o.e&2)!==0)A.C(A.B(n)) +o.bj(a,b)}else{if((o.e&2)!==0)A.C(A.B(n)) +o.bj(s,r)}}}, +dP(){var s,r,q,p,o=this +try{o.x=null +q=o.w +q===$&&A.x() +q.n()}catch(p){s=A.G(p) +r=A.a1(p) +if((o.e&2)!==0)A.C(A.B("Stream is already closed")) +o.bj(s,r)}}} +A.fo.prototype={ +ec(a){return new A.eY(this.a,a,this.$ti.h("eY<1,2>"))}} +A.eY.prototype={ +R(a,b,c,d){var s=this.$ti,r=$.h,q=b===!0?1:0,p=d!=null?32:0,o=A.ig(r,a,s.y[1]),n=A.ih(r,d),m=new A.dL(o,n,r.au(c,t.H),r,q|p,s.h("dL<1,2>")) +m.w=this.a.$1(new A.f5(m)) +m.x=this.b.aV(m.gdM(),m.gdO(),m.gdQ()) +return m}, +aV(a,b,c){return this.R(a,null,b,c)}} +A.dD.prototype={ +v(a,b){var s,r=this.d +if(r==null)throw A.b(A.B("Sink is closed")) +this.$ti.y[1].a(b) +s=r.a +if((s.e&2)!==0)A.C(A.B("Stream is already closed")) +s.dm(b)}, +a3(a,b){var s=this.d +if(s==null)throw A.b(A.B("Sink is closed")) +s.a3(a,b)}, +n(){var s=this.d +if(s==null)return +this.d=null +this.c.$1(s)}, +$iae:1} +A.dM.prototype={ +ec(a){return this.hO(a)}} +A.n5.prototype={ +$1(a){var s=this +return new A.dD(s.a,s.b,s.c,a,s.e.h("@<0>").H(s.d).h("dD<1,2>"))}, +$S(){return this.e.h("@<0>").H(this.d).h("dD<1,2>(ae<2>)")}} +A.ay.prototype={} +A.iT.prototype={ +bN(a,b,c){var s,r,q,p,o,n,m,l,k=this.gdS(),j=k.a +if(j===B.d){A.fD(b,c) +return}s=k.b +r=j.ga1() +m=j.ghh() +m.toString +q=m +p=$.h +try{$.h=q +s.$5(j,r,a,b,c) +$.h=p}catch(l){o=A.G(l) +n=A.a1(l) +$.h=p +m=b===o?c:n +q.bN(j,o,m)}}, +$iw:1} +A.ii.prototype={ +gf1(){var s=this.at +return s==null?this.at=new A.dU(this):s}, +ga1(){return this.ax.gf1()}, +gaI(){return this.as.a}, +cc(a){var s,r,q +try{this.bb(a,t.H)}catch(q){s=A.G(q) +r=A.a1(q) +this.bN(this,s,r)}}, +cd(a,b,c){var s,r,q +try{this.bc(a,b,t.H,c)}catch(q){s=A.G(q) +r=A.a1(q) +this.bN(this,s,r)}}, +hq(a,b,c,d,e){var s,r,q +try{this.eJ(a,b,c,t.H,d,e)}catch(q){s=A.G(q) +r=A.a1(q) +this.bN(this,s,r)}}, +ed(a,b){return new A.mt(this,this.au(a,b),b)}, +fW(a,b,c){return new A.mv(this,this.b9(a,b,c),c,b)}, +cP(a){return new A.ms(this,this.au(a,t.H))}, +ee(a,b){return new A.mu(this,this.b9(a,t.H,b),b)}, +j(a,b){var s,r=this.ay,q=r.j(0,b) +if(q!=null||r.a4(b))return q +s=this.ax.j(0,b) +if(s!=null)r.t(0,b,s) +return s}, +c1(a,b){this.bN(this,a,b)}, +h6(a,b){var s=this.Q,r=s.a +return s.b.$5(r,r.ga1(),this,a,b)}, +bb(a){var s=this.a,r=s.a +return s.b.$4(r,r.ga1(),this,a)}, +bc(a,b){var s=this.b,r=s.a +return s.b.$5(r,r.ga1(),this,a,b)}, +eJ(a,b,c){var s=this.c,r=s.a +return s.b.$6(r,r.ga1(),this,a,b,c)}, +au(a){var s=this.d,r=s.a +return s.b.$4(r,r.ga1(),this,a)}, +b9(a){var s=this.e,r=s.a +return s.b.$4(r,r.ga1(),this,a)}, +d6(a){var s=this.f,r=s.a +return s.b.$4(r,r.ga1(),this,a)}, +h3(a,b){var s=this.r,r=s.a +if(r===B.d)return null +return s.b.$5(r,r.ga1(),this,a,b)}, +aY(a){var s=this.w,r=s.a +return s.b.$4(r,r.ga1(),this,a)}, +eh(a,b){var s=this.x,r=s.a +return s.b.$5(r,r.ga1(),this,a,b)}, +hi(a){var s=this.z,r=s.a +return s.b.$4(r,r.ga1(),this,a)}, +gfD(){return this.a}, +gfF(){return this.b}, +gfE(){return this.c}, +gfz(){return this.d}, +gfA(){return this.e}, +gfw(){return this.f}, +gfc(){return this.r}, +ge1(){return this.w}, +gf7(){return this.x}, +gf6(){return this.y}, +gfs(){return this.z}, +gff(){return this.Q}, +gdS(){return this.as}, +ghh(){return this.ax}, +gfl(){return this.ay}} +A.mt.prototype={ +$0(){return this.a.bb(this.b,this.c)}, +$S(){return this.c.h("0()")}} +A.mv.prototype={ +$1(a){var s=this +return s.a.bc(s.b,a,s.d,s.c)}, +$S(){return this.d.h("@<0>").H(this.c).h("1(2)")}} +A.ms.prototype={ +$0(){return this.a.cc(this.b)}, +$S:0} +A.mu.prototype={ +$1(a){return this.a.cd(this.b,a,this.c)}, +$S(){return this.c.h("~(0)")}} +A.iH.prototype={ +gfD(){return B.bx}, +gfF(){return B.bz}, +gfE(){return B.by}, +gfz(){return B.bw}, +gfA(){return B.br}, +gfw(){return B.bB}, +gfc(){return B.bt}, +ge1(){return B.bA}, +gf7(){return B.bs}, +gf6(){return B.bq}, +gfs(){return B.bv}, +gff(){return B.bu}, +gdS(){return B.bp}, +ghh(){return null}, +gfl(){return $.rS()}, +gf1(){var s=$.mX +return s==null?$.mX=new A.dU(this):s}, +ga1(){var s=$.mX +return s==null?$.mX=new A.dU(this):s}, +gaI(){return this}, +cc(a){var s,r,q +try{if(B.d===$.h){a.$0() +return}A.nu(null,null,this,a)}catch(q){s=A.G(q) +r=A.a1(q) +A.fD(s,r)}}, +cd(a,b){var s,r,q +try{if(B.d===$.h){a.$1(b) +return}A.nw(null,null,this,a,b)}catch(q){s=A.G(q) +r=A.a1(q) +A.fD(s,r)}}, +hq(a,b,c){var s,r,q +try{if(B.d===$.h){a.$2(b,c) +return}A.nv(null,null,this,a,b,c)}catch(q){s=A.G(q) +r=A.a1(q) +A.fD(s,r)}}, +ed(a,b){return new A.mZ(this,a,b)}, +fW(a,b,c){return new A.n0(this,a,c,b)}, +cP(a){return new A.mY(this,a)}, +ee(a,b){return new A.n_(this,a,b)}, +j(a,b){return null}, +c1(a,b){A.fD(a,b)}, +h6(a,b){return A.r4(null,null,this,a,b)}, +bb(a){if($.h===B.d)return a.$0() +return A.nu(null,null,this,a)}, +bc(a,b){if($.h===B.d)return a.$1(b) +return A.nw(null,null,this,a,b)}, +eJ(a,b,c){if($.h===B.d)return a.$2(b,c) +return A.nv(null,null,this,a,b,c)}, +au(a){return a}, +b9(a){return a}, +d6(a){return a}, +h3(a,b){return null}, +aY(a){A.nx(null,null,this,a)}, +eh(a,b){return A.om(a,b)}, +hi(a){A.oZ(a)}} +A.mZ.prototype={ +$0(){return this.a.bb(this.b,this.c)}, +$S(){return this.c.h("0()")}} +A.n0.prototype={ +$1(a){var s=this +return s.a.bc(s.b,a,s.d,s.c)}, +$S(){return this.d.h("@<0>").H(this.c).h("1(2)")}} +A.mY.prototype={ +$0(){return this.a.cc(this.b)}, +$S:0} +A.n_.prototype={ +$1(a){return this.a.cd(this.b,a,this.c)}, +$S(){return this.c.h("~(0)")}} +A.dU.prototype={$iW:1} +A.nt.prototype={ +$0(){A.pr(this.a,this.b)}, +$S:0} +A.iU.prototype={$ioq:1} +A.cK.prototype={ +gl(a){return this.a}, +gB(a){return this.a===0}, +ga_(){return new A.cL(this,A.r(this).h("cL<1>"))}, +gbF(){var s=A.r(this) +return A.ht(new A.cL(this,s.h("cL<1>")),new A.mP(this),s.c,s.y[1])}, +a4(a){var s,r +if(typeof a=="string"&&a!=="__proto__"){s=this.b +return s==null?!1:s[a]!=null}else if(typeof a=="number"&&(a&1073741823)===a){r=this.c +return r==null?!1:r[a]!=null}else return this.ic(a)}, +ic(a){var s=this.d +if(s==null)return!1 +return this.aO(this.fg(s,a),a)>=0}, +j(a,b){var s,r,q +if(typeof b=="string"&&b!=="__proto__"){s=this.b +r=s==null?null:A.qp(s,b) +return r}else if(typeof b=="number"&&(b&1073741823)===b){q=this.c +r=q==null?null:A.qp(q,b) +return r}else return this.iv(b)}, +iv(a){var s,r,q=this.d +if(q==null)return null +s=this.fg(q,a) +r=this.aO(s,a) +return r<0?null:s[r+1]}, +t(a,b,c){var s,r,q=this +if(typeof b=="string"&&b!=="__proto__"){s=q.b +q.f0(s==null?q.b=A.ox():s,b,c)}else if(typeof b=="number"&&(b&1073741823)===b){r=q.c +q.f0(r==null?q.c=A.ox():r,b,c)}else q.ji(b,c)}, +ji(a,b){var s,r,q,p=this,o=p.d +if(o==null)o=p.d=A.ox() +s=p.dC(a) +r=o[s] +if(r==null){A.oy(o,s,[a,b]);++p.a +p.e=null}else{q=p.aO(r,a) +if(q>=0)r[q+1]=b +else{r.push(a,b);++p.a +p.e=null}}}, +ap(a,b){var s,r,q,p,o,n=this,m=n.f5() +for(s=m.length,r=A.r(n).y[1],q=0;q"))}} +A.ir.prototype={ +gm(){var s=this.d +return s==null?this.$ti.c.a(s):s}, +k(){var s=this,r=s.b,q=s.c,p=s.a +if(r!==p.e)throw A.b(A.au(p)) +else if(q>=r.length){s.d=null +return!1}else{s.d=r[q] +s.c=q+1 +return!0}}} +A.fa.prototype={ +gq(a){var s=this,r=new A.dG(s,s.r,s.$ti.h("dG<1>")) +r.c=s.e +return r}, +gl(a){return this.a}, +gB(a){return this.a===0}, +I(a,b){var s,r +if(b!=="__proto__"){s=this.b +if(s==null)return!1 +return s[b]!=null}else{r=this.ib(b) +return r}}, +ib(a){var s=this.d +if(s==null)return!1 +return this.aO(s[B.a.gA(a)&1073741823],a)>=0}, +gF(a){var s=this.e +if(s==null)throw A.b(A.B("No elements")) +return s.a}, +gE(a){var s=this.f +if(s==null)throw A.b(A.B("No elements")) +return s.a}, +v(a,b){var s,r,q=this +if(typeof b=="string"&&b!=="__proto__"){s=q.b +return q.f_(s==null?q.b=A.oz():s,b)}else if(typeof b=="number"&&(b&1073741823)===b){r=q.c +return q.f_(r==null?q.c=A.oz():r,b)}else return q.hX(b)}, +hX(a){var s,r,q=this,p=q.d +if(p==null)p=q.d=A.oz() +s=J.aC(a)&1073741823 +r=p[s] +if(r==null)p[s]=[q.dX(a)] +else{if(q.aO(r,a)>=0)return!1 +r.push(q.dX(a))}return!0}, +G(a,b){var s +if(typeof b=="string"&&b!=="__proto__")return this.j5(this.b,b) +else{s=this.j4(b) +return s}}, +j4(a){var s,r,q,p,o=this.d +if(o==null)return!1 +s=J.aC(a)&1073741823 +r=o[s] +q=this.aO(r,a) +if(q<0)return!1 +p=r.splice(q,1)[0] +if(0===r.length)delete o[s] +this.fQ(p) +return!0}, +f_(a,b){if(a[b]!=null)return!1 +a[b]=this.dX(b) +return!0}, +j5(a,b){var s +if(a==null)return!1 +s=a[b] +if(s==null)return!1 +this.fQ(s) +delete a[b] +return!0}, +fn(){this.r=this.r+1&1073741823}, +dX(a){var s,r=this,q=new A.mT(a) +if(r.e==null)r.e=r.f=q +else{s=r.f +s.toString +q.c=s +r.f=s.b=q}++r.a +r.fn() +return q}, +fQ(a){var s=this,r=a.c,q=a.b +if(r==null)s.e=q +else r.b=q +if(q==null)s.f=r +else q.c=r;--s.a +s.fn()}, +aO(a,b){var s,r +if(a==null)return-1 +s=a.length +for(r=0;r"))}, +gl(a){return this.b}, +gF(a){var s +if(this.b===0)throw A.b(A.B("No such element")) +s=this.c +s.toString +return s}, +gE(a){var s +if(this.b===0)throw A.b(A.B("No such element")) +s=this.c.c +s.toString +return s}, +gB(a){return this.b===0}, +dT(a,b,c){var s,r,q=this +if(b.a!=null)throw A.b(A.B("LinkedListEntry is already in a LinkedList"));++q.a +b.a=q +s=q.b +if(s===0){b.b=b +q.c=b.c=b +q.b=s+1 +return}r=a.c +r.toString +b.c=r +b.b=a +a.c=r.b=b +q.b=s+1}, +e4(a){var s,r,q=this;++q.a +s=a.b +s.c=a.c +a.c.b=s +r=--q.b +a.a=a.b=a.c=null +if(r===0)q.c=null +else if(a===q.c)q.c=s}} +A.iy.prototype={ +gm(){var s=this.c +return s==null?this.$ti.c.a(s):s}, +k(){var s=this,r=s.a +if(s.b!==r.a)throw A.b(A.au(s)) +if(r.b!==0)r=s.e&&s.d===r.gF(0) +else r=!0 +if(r){s.c=null +return!1}s.e=!0 +r=s.d +s.c=r +s.d=r.b +return!0}} +A.aL.prototype={ +gc8(){var s=this.a +if(s==null||this===s.gF(0))return null +return this.c}} +A.v.prototype={ +gq(a){return new A.b3(a,this.gl(a),A.aT(a).h("b3"))}, +L(a,b){return this.j(a,b)}, +gB(a){return this.gl(a)===0}, +gF(a){if(this.gl(a)===0)throw A.b(A.az()) +return this.j(a,0)}, +gE(a){if(this.gl(a)===0)throw A.b(A.az()) +return this.j(a,this.gl(a)-1)}, +b8(a,b,c){return new A.E(a,b,A.aT(a).h("@").H(c).h("E<1,2>"))}, +Y(a,b){return A.b5(a,b,null,A.aT(a).h("v.E"))}, +ah(a,b){return A.b5(a,0,A.cU(b,"count",t.S),A.aT(a).h("v.E"))}, +az(a,b){var s,r,q,p,o=this +if(o.gB(a)){s=J.pA(0,A.aT(a).h("v.E")) +return s}r=o.j(a,0) +q=A.b4(o.gl(a),r,!0,A.aT(a).h("v.E")) +for(p=1;p").H(b).h("ak<1,2>"))}, +a0(a,b,c){var s,r=this.gl(a) +A.bd(b,c,r) +s=A.aw(this.cm(a,b,c),A.aT(a).h("v.E")) +return s}, +cm(a,b,c){A.bd(b,c,this.gl(a)) +return A.b5(a,b,c,A.aT(a).h("v.E"))}, +el(a,b,c,d){var s +A.bd(b,c,this.gl(a)) +for(s=b;sp.gl(q))throw A.b(A.py()) +if(r=0;--o)this.t(a,b+o,p.j(q,r+o)) +else for(o=0;o"))}, +gl(a){return J.at(this.ga_())}, +gB(a){return J.nY(this.ga_())}, +gbF(){return new A.fb(this,A.r(this).h("fb"))}, +i(a){return A.oc(this)}, +$ian:1} +A.kD.prototype={ +$1(a){var s=this.a,r=s.j(0,a) +if(r==null)r=A.r(s).h("Q.V").a(r) +return new A.aN(a,r,A.r(s).h("aN"))}, +$S(){return A.r(this.a).h("aN(Q.K)")}} +A.kE.prototype={ +$2(a,b){var s,r=this.a +if(!r.a)this.b.a+=", " +r.a=!1 +r=this.b +s=A.t(a) +r.a=(r.a+=s)+": " +s=A.t(b) +r.a+=s}, +$S:113} +A.fb.prototype={ +gl(a){var s=this.a +return s.gl(s)}, +gB(a){var s=this.a +return s.gB(s)}, +gF(a){var s=this.a +s=s.j(0,J.j2(s.ga_())) +return s==null?this.$ti.y[1].a(s):s}, +gE(a){var s=this.a +s=s.j(0,J.nZ(s.ga_())) +return s==null?this.$ti.y[1].a(s):s}, +gq(a){var s=this.a +return new A.iz(J.a4(s.ga_()),s,this.$ti.h("iz<1,2>"))}} +A.iz.prototype={ +k(){var s=this,r=s.a +if(r.k()){s.c=s.b.j(0,r.gm()) +return!0}s.c=null +return!1}, +gm(){var s=this.c +return s==null?this.$ti.y[1].a(s):s}} +A.dl.prototype={ +gB(a){return this.a===0}, +b8(a,b,c){return new A.ct(this,b,this.$ti.h("@<1>").H(c).h("ct<1,2>"))}, +i(a){return A.o7(this,"{","}")}, +ah(a,b){return A.ol(this,b,this.$ti.c)}, +Y(a,b){return A.pY(this,b,this.$ti.c)}, +gF(a){var s,r=A.ix(this,this.r,this.$ti.c) +if(!r.k())throw A.b(A.az()) +s=r.d +return s==null?r.$ti.c.a(s):s}, +gE(a){var s,r,q=A.ix(this,this.r,this.$ti.c) +if(!q.k())throw A.b(A.az()) +s=q.$ti.c +do{r=q.d +if(r==null)r=s.a(r)}while(q.k()) +return r}, +L(a,b){var s,r,q,p=this +A.ab(b,"index") +s=A.ix(p,p.r,p.$ti.c) +for(r=b;s.k();){if(r===0){q=s.d +return q==null?s.$ti.c.a(q):q}--r}throw A.b(A.hf(b,b-r,p,null,"index"))}, +$iq:1, +$id:1} +A.fk.prototype={} +A.nj.prototype={ +$0(){var s,r +try{s=new TextDecoder("utf-8",{fatal:true}) +return s}catch(r){}return null}, +$S:21} +A.ni.prototype={ +$0(){var s,r +try{s=new TextDecoder("utf-8",{fatal:false}) +return s}catch(r){}return null}, +$S:21} +A.fL.prototype={ +kr(a){return B.aj.a5(a)}} +A.iQ.prototype={ +a5(a){var s,r,q,p=A.bd(0,null,a.length),o=new Uint8Array(p) +for(s=~this.a,r=0;r=0){g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(f) +if(g===k)continue +k=g}else{if(f===-1){if(o<0){e=p==null?null:p.a.length +if(e==null)e=0 +o=e+(r-q) +n=r}++m +if(k===61)continue}k=g}if(f!==-2){if(p==null){p=new A.aA("") +e=p}else e=p +e.a+=B.a.p(a0,q,r) +d=A.aP(k) +e.a+=d +q=l +continue}}throw A.b(A.af("Invalid base64 data",a0,r))}if(p!=null){e=B.a.p(a0,q,a2) +e=p.a+=e +d=e.length +if(o>=0)A.pd(a0,n,a2,o,m,d) +else{c=B.b.ac(d-1,4)+1 +if(c===1)throw A.b(A.af(a,a0,a2)) +while(c<4){e+="=" +p.a=e;++c}}e=p.a +return B.a.aL(a0,a1,a2,e.charCodeAt(0)==0?e:e)}b=a2-a1 +if(o>=0)A.pd(a0,n,a2,o,m,b) +else{c=B.b.ac(b,4) +if(c===1)throw A.b(A.af(a,a0,a2)) +if(c>1)a0=B.a.aL(a0,a2,a2,c===2?"==":"=")}return a0}} +A.fR.prototype={} +A.cq.prototype={} +A.cr.prototype={} +A.h8.prototype={} +A.i_.prototype={ +cS(a){return new A.fy(!1).dD(a,0,null,!0)}} +A.i0.prototype={ +a5(a){var s,r,q=A.bd(0,null,a.length) +if(q===0)return new Uint8Array(0) +s=new Uint8Array(q*3) +r=new A.nk(s) +if(r.iu(a,0,q)!==q)r.e7() +return B.e.a0(s,0,r.b)}} +A.nk.prototype={ +e7(){var s=this,r=s.c,q=s.b,p=s.b=q+1 +r.$flags&2&&A.y(r) +r[q]=239 +q=s.b=p+1 +r[p]=191 +s.b=q+1 +r[q]=189}, +jx(a,b){var s,r,q,p,o=this +if((b&64512)===56320){s=65536+((a&1023)<<10)|b&1023 +r=o.c +q=o.b +p=o.b=q+1 +r.$flags&2&&A.y(r) +r[q]=s>>>18|240 +q=o.b=p+1 +r[p]=s>>>12&63|128 +p=o.b=q+1 +r[q]=s>>>6&63|128 +o.b=p+1 +r[p]=s&63|128 +return!0}else{o.e7() +return!1}}, +iu(a,b,c){var s,r,q,p,o,n,m,l,k=this +if(b!==c&&(a.charCodeAt(c-1)&64512)===55296)--c +for(s=k.c,r=s.$flags|0,q=s.length,p=b;p=q)break +k.b=n+1 +r&2&&A.y(s) +s[n]=o}else{n=o&64512 +if(n===55296){if(k.b+4>q)break +m=p+1 +if(k.jx(o,a.charCodeAt(m)))p=m}else if(n===56320){if(k.b+3>q)break +k.e7()}else if(o<=2047){n=k.b +l=n+1 +if(l>=q)break +k.b=l +r&2&&A.y(s) +s[n]=o>>>6|192 +k.b=l+1 +s[l]=o&63|128}else{n=k.b +if(n+2>=q)break +l=k.b=n+1 +r&2&&A.y(s) +s[n]=o>>>12|224 +n=k.b=l+1 +s[l]=o>>>6&63|128 +k.b=n+1 +s[n]=o&63|128}}}return p}} +A.fy.prototype={ +dD(a,b,c,d){var s,r,q,p,o,n,m=this,l=A.bd(b,c,J.at(a)) +if(b===l)return"" +if(a instanceof Uint8Array){s=a +r=s +q=0}else{r=A.vh(a,b,l) +l-=b +q=b +b=0}if(d&&l-b>=15){p=m.a +o=A.vg(p,r,b,l) +if(o!=null){if(!p)return o +if(o.indexOf("\ufffd")<0)return o}}o=m.dF(r,b,l,d) +p=m.b +if((p&1)!==0){n=A.vi(p) +m.b=0 +throw A.b(A.af(n,a,q+m.c))}return o}, +dF(a,b,c,d){var s,r,q=this +if(c-b>1000){s=B.b.J(b+c,2) +r=q.dF(a,b,s,!1) +if((q.b&1)!==0)return r +return r+q.dF(a,s,c,d)}return q.jW(a,b,c,d)}, +jW(a,b,c,d){var s,r,q,p,o,n,m,l=this,k=65533,j=l.b,i=l.c,h=new A.aA(""),g=b+1,f=a[b] +A:for(s=l.a;;){for(;;g=p){r="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBKCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE".charCodeAt(f)&31 +i=j<=32?f&61694>>>r:(f&63|i<<6)>>>0 +j=" \x000:XECCCCCN:lDb \x000:XECCCCCNvlDb \x000:XECCCCCN:lDb AAAAA\x00\x00\x00\x00\x00AAAAA00000AAAAA:::::AAAAAGG000AAAAA00KKKAAAAAG::::AAAAA:IIIIAAAAA000\x800AAAAA\x00\x00\x00\x00 AAAAA".charCodeAt(j+r) +if(j===0){q=A.aP(i) +h.a+=q +if(g===c)break A +break}else if((j&1)!==0){if(s)switch(j){case 69:case 67:q=A.aP(k) +h.a+=q +break +case 65:q=A.aP(k) +h.a+=q;--g +break +default:q=A.aP(k) +h.a=(h.a+=q)+q +break}else{l.b=j +l.c=g-1 +return""}j=0}if(g===c)break A +p=g+1 +f=a[g]}p=g+1 +f=a[g] +if(f<128){for(;;){if(!(p=128){o=n-1 +p=n +break}p=n}if(o-g<20)for(m=g;m32)if(s){s=A.aP(k) +h.a+=s}else{l.b=77 +l.c=c +return""}l.b=j +l.c=i +s=h.a +return s.charCodeAt(0)==0?s:s}} +A.a7.prototype={ +aA(a){var s,r,q=this,p=q.c +if(p===0)return q +s=!q.a +r=q.b +p=A.aR(p,r) +return new A.a7(p===0?!1:s,r,p)}, +io(a){var s,r,q,p,o,n,m=this.c +if(m===0)return $.ba() +s=m+a +r=this.b +q=new Uint16Array(s) +for(p=m-1;p>=0;--p)q[p+a]=r[p] +o=this.a +n=A.aR(s,q) +return new A.a7(n===0?!1:o,q,n)}, +ip(a){var s,r,q,p,o,n,m,l=this,k=l.c +if(k===0)return $.ba() +s=k-a +if(s<=0)return l.a?$.p9():$.ba() +r=l.b +q=new Uint16Array(s) +for(p=a;p>>0!==0)return l.dl(0,$.fI()) +for(k=0;k=0)return q.cq(b,r) +return b.cq(q,!r)}, +dl(a,b){var s,r,q=this,p=q.c +if(p===0)return b.aA(0) +s=b.c +if(s===0)return q +r=q.a +if(r!==b.a)return q.dr(b,r) +if(A.mi(q.b,p,b.b,s)>=0)return q.cq(b,r) +return b.cq(q,!r)}, +bG(a,b){var s,r,q,p,o,n,m,l=this.c,k=b.c +if(l===0||k===0)return $.ba() +s=l+k +r=this.b +q=b.b +p=new Uint16Array(s) +for(o=0;o0?p.aA(0):p}, +j3(a){var s,r,q,p=this +if(p.c0)q=q.bh(0,$.ot.af()) +return p.a&&q.c>0?q.aA(0):q}, +f9(a){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c=this,b=c.c +if(b===$.qi&&a.c===$.qk&&c.b===$.qh&&a.b===$.qj)return +s=a.b +r=a.c +q=16-B.b.gfX(s[r-1]) +if(q>0){p=new Uint16Array(r+5) +o=A.qg(s,r,q,p) +n=new Uint16Array(b+5) +m=A.qg(c.b,b,q,n)}else{n=A.ou(c.b,0,b,b+2) +o=r +p=s +m=b}l=p[o-1] +k=m-o +j=new Uint16Array(m) +i=A.ov(p,o,k,j) +h=m+1 +g=n.$flags|0 +if(A.mi(n,m,j,i)>=0){g&2&&A.y(n) +n[m]=1 +A.ie(n,h,j,i,n)}else{g&2&&A.y(n) +n[m]=0}f=new Uint16Array(o+2) +f[o]=1 +A.ie(f,o+1,p,o,f) +e=m-1 +while(k>0){d=A.uI(l,n,e);--k +A.qm(d,f,0,n,k,o) +if(n[e]1){q=$.p8() +if(q.c===0)A.C(B.an) +p=r.j3(q).i(0) +s.push(p) +o=p.length +if(o===1)s.push("000") +if(o===2)s.push("00") +if(o===3)s.push("0") +r=r.im(q)}s.push(B.b.i(r.b[0])) +if(m)s.push("-") +return new A.eI(s,t.bJ).c2(0)}} +A.mj.prototype={ +$2(a,b){a=a+b&536870911 +a=a+((a&524287)<<10)&536870911 +return a^a>>>6}, +$S:87} +A.mk.prototype={ +$1(a){a=a+((a&67108863)<<3)&536870911 +a^=a>>>11 +return a+((a&16383)<<15)&536870911}, +$S:28} +A.ip.prototype={ +fV(a,b,c){var s=this.a +if(s!=null)s.register(a,b,c)}, +h1(a){var s=this.a +if(s!=null)s.unregister(a)}} +A.ei.prototype={ +W(a,b){if(b==null)return!1 +return b instanceof A.ei&&this.a===b.a&&this.b===b.b&&this.c===b.c}, +gA(a){return A.eD(this.a,this.b,B.f,B.f)}, +ag(a,b){var s=B.b.ag(this.a,b.a) +if(s!==0)return s +return B.b.ag(this.b,b.b)}, +i(a){var s=this,r=A.tE(A.pO(s)),q=A.h0(A.pM(s)),p=A.h0(A.pJ(s)),o=A.h0(A.pK(s)),n=A.h0(A.pL(s)),m=A.h0(A.pN(s)),l=A.pm(A.ub(s)),k=s.b,j=k===0?"":A.pm(k) +k=r+"-"+q +if(s.c)return k+"-"+p+" "+o+":"+n+":"+m+"."+l+j+"Z" +else return k+"-"+p+" "+o+":"+n+":"+m+"."+l+j}} +A.bx.prototype={ +W(a,b){if(b==null)return!1 +return b instanceof A.bx&&this.a===b.a}, +gA(a){return B.b.gA(this.a)}, +ag(a,b){return B.b.ag(this.a,b.a)}, +i(a){var s,r,q,p,o,n=this.a,m=B.b.J(n,36e8),l=n%36e8 +if(n<0){m=0-m +n=0-l +s="-"}else{n=l +s=""}r=B.b.J(n,6e7) +n%=6e7 +q=r<10?"0":"" +p=B.b.J(n,1e6) +o=p<10?"0":"" +return s+m+":"+q+r+":"+o+p+"."+B.a.kR(B.b.i(n%1e6),6,"0")}} +A.mx.prototype={ +i(a){return this.ae()}} +A.O.prototype={ +gbi(){return A.ua(this)}} +A.fN.prototype={ +i(a){var s=this.a +if(s!=null)return"Assertion failed: "+A.h9(s) +return"Assertion failed"}} +A.bL.prototype={} +A.bb.prototype={ +gdJ(){return"Invalid argument"+(!this.a?"(s)":"")}, +gdI(){return""}, +i(a){var s=this,r=s.c,q=r==null?"":" ("+r+")",p=s.d,o=p==null?"":": "+A.t(p),n=s.gdJ()+q+o +if(!s.a)return n +return n+s.gdI()+": "+A.h9(s.gev())}, +gev(){return this.b}} +A.dh.prototype={ +gev(){return this.b}, +gdJ(){return"RangeError"}, +gdI(){var s,r=this.e,q=this.f +if(r==null)s=q!=null?": Not less than or equal to "+A.t(q):"" +else if(q==null)s=": Not greater than or equal to "+A.t(r) +else if(q>r)s=": Not in inclusive range "+A.t(r)+".."+A.t(q) +else s=qe.length +else s=!1 +if(s)f=null +if(f==null){if(e.length>78)e=B.a.p(e,0,75)+"..." +return g+"\n"+e}for(r=1,q=0,p=!1,o=0;o1?g+(" (at line "+r+", character "+(f-q+1)+")\n"):g+(" (at character "+(f+1)+")\n") +m=e.length +for(o=f;o78){k="..." +if(f-q<75){j=q+75 +i=q}else{if(m-f<75){i=m-75 +j=m +k=""}else{i=f-36 +j=f+36}l="..."}}else{j=m +i=q +k=""}return g+l+B.a.p(e,i,j)+k+"\n"+B.a.bG(" ",f-i+l.length)+"^\n"}else return f!=null?g+(" (at offset "+A.t(f)+")"):g}, +$ia5:1} +A.hh.prototype={ +gbi(){return null}, +i(a){return"IntegerDivisionByZeroException"}, +$iO:1, +$ia5:1} +A.d.prototype={ +bu(a,b){return A.ee(this,A.r(this).h("d.E"),b)}, +b8(a,b,c){return A.ht(this,b,A.r(this).h("d.E"),c)}, +az(a,b){var s=A.r(this).h("d.E") +if(b)s=A.aw(this,s) +else{s=A.aw(this,s) +s.$flags=1 +s=s}return s}, +cf(a){return this.az(0,!0)}, +gl(a){var s,r=this.gq(this) +for(s=0;r.k();)++s +return s}, +gB(a){return!this.gq(this).k()}, +ah(a,b){return A.ol(this,b,A.r(this).h("d.E"))}, +Y(a,b){return A.pY(this,b,A.r(this).h("d.E"))}, +hF(a,b){return new A.eK(this,b,A.r(this).h("eK"))}, +gF(a){var s=this.gq(this) +if(!s.k())throw A.b(A.az()) +return s.gm()}, +gE(a){var s,r=this.gq(this) +if(!r.k())throw A.b(A.az()) +do s=r.gm() +while(r.k()) +return s}, +L(a,b){var s,r +A.ab(b,"index") +s=this.gq(this) +for(r=b;s.k();){if(r===0)return s.gm();--r}throw A.b(A.hf(b,b-r,this,null,"index"))}, +i(a){return A.tV(this,"(",")")}} +A.aN.prototype={ +i(a){return"MapEntry("+A.t(this.a)+": "+A.t(this.b)+")"}} +A.R.prototype={ +gA(a){return A.e.prototype.gA.call(this,0)}, +i(a){return"null"}} +A.e.prototype={$ie:1, +W(a,b){return this===b}, +gA(a){return A.eG(this)}, +i(a){return"Instance of '"+A.hG(this)+"'"}, +gV(a){return A.wT(this)}, +toString(){return this.i(this)}} +A.dQ.prototype={ +i(a){return this.a}, +$iY:1} +A.aA.prototype={ +gl(a){return this.a.length}, +i(a){var s=this.a +return s.charCodeAt(0)==0?s:s}} +A.lA.prototype={ +$2(a,b){throw A.b(A.af("Illegal IPv6 address, "+a,this.a,b))}, +$S:66} +A.fv.prototype={ +gfL(){var s,r,q,p,o=this,n=o.w +if(n===$){s=o.a +r=s.length!==0?s+":":"" +q=o.c +p=q==null +if(!p||s==="file"){s=r+"//" +r=o.b +if(r.length!==0)s=s+r+"@" +if(!p)s+=q +r=o.d +if(r!=null)s=s+":"+A.t(r)}else s=r +s+=o.e +r=o.f +if(r!=null)s=s+"?"+r +r=o.r +if(r!=null)s=s+"#"+r +n=o.w=s.charCodeAt(0)==0?s:s}return n}, +gkS(){var s,r,q=this,p=q.x +if(p===$){s=q.e +if(s.length!==0&&s.charCodeAt(0)===47)s=B.a.N(s,1) +r=s.length===0?B.A:A.aM(new A.E(A.f(s.split("/"),t.s),A.wH(),t.do),t.N) +q.x!==$&&A.p4() +p=q.x=r}return p}, +gA(a){var s,r=this,q=r.y +if(q===$){s=B.a.gA(r.gfL()) +r.y!==$&&A.p4() +r.y=s +q=s}return q}, +geN(){return this.b}, +gb7(){var s=this.c +if(s==null)return"" +if(B.a.u(s,"[")&&!B.a.C(s,"v",1))return B.a.p(s,1,s.length-1) +return s}, +gc7(){var s=this.d +return s==null?A.qD(this.a):s}, +gc9(){var s=this.f +return s==null?"":s}, +gcW(){var s=this.r +return s==null?"":s}, +kC(a){var s=this.a +if(a.length!==s.length)return!1 +return A.vx(a,s,0)>=0}, +hn(a){var s,r,q,p,o,n,m,l=this +a=A.nh(a,0,a.length) +s=a==="file" +r=l.b +q=l.d +if(a!==l.a)q=A.ng(q,a) +p=l.c +if(!(p!=null))p=r.length!==0||q!=null||s?"":null +o=l.e +if(!s)n=p!=null&&o.length!==0 +else n=!0 +if(n&&!B.a.u(o,"/"))o="/"+o +m=o +return A.fw(a,r,p,q,m,l.f,l.r)}, +gha(){if(this.a!==""){var s=this.r +s=(s==null?"":s)===""}else s=!1 +return s}, +fm(a,b){var s,r,q,p,o,n,m +for(s=0,r=0;B.a.C(b,"../",r);){r+=3;++s}q=B.a.d0(a,"/") +for(;;){if(!(q>0&&s>0))break +p=B.a.hc(a,"/",q-1) +if(p<0)break +o=q-p +n=o!==2 +m=!1 +if(!n||o===3)if(a.charCodeAt(p+1)===46)n=!n||a.charCodeAt(p+2)===46 +else n=m +else n=m +if(n)break;--s +q=p}return B.a.aL(a,q+1,null,B.a.N(b,r-3*s))}, +hp(a){return this.ca(A.bt(a))}, +ca(a){var s,r,q,p,o,n,m,l,k,j,i,h=this +if(a.gZ().length!==0)return a +else{s=h.a +if(a.geo()){r=a.hn(s) +return r}else{q=h.b +p=h.c +o=h.d +n=h.e +if(a.gh7())m=a.gcX()?a.gc9():h.f +else{l=A.ve(h,n) +if(l>0){k=B.a.p(n,0,l) +n=a.gen()?k+A.cQ(a.gaa()):k+A.cQ(h.fm(B.a.N(n,k.length),a.gaa()))}else if(a.gen())n=A.cQ(a.gaa()) +else if(n.length===0)if(p==null)n=s.length===0?a.gaa():A.cQ(a.gaa()) +else n=A.cQ("/"+a.gaa()) +else{j=h.fm(n,a.gaa()) +r=s.length===0 +if(!r||p!=null||B.a.u(n,"/"))n=A.cQ(j) +else n=A.oE(j,!r||p!=null)}m=a.gcX()?a.gc9():null}}}i=a.gep()?a.gcW():null +return A.fw(s,q,p,o,n,m,i)}, +geo(){return this.c!=null}, +gcX(){return this.f!=null}, +gep(){return this.r!=null}, +gh7(){return this.e.length===0}, +gen(){return B.a.u(this.e,"/")}, +eK(){var s,r=this,q=r.a +if(q!==""&&q!=="file")throw A.b(A.a3("Cannot extract a file path from a "+q+" URI")) +q=r.f +if((q==null?"":q)!=="")throw A.b(A.a3(u.y)) +q=r.r +if((q==null?"":q)!=="")throw A.b(A.a3(u.l)) +if(r.c!=null&&r.gb7()!=="")A.C(A.a3(u.j)) +s=r.gkS() +A.v6(s,!1) +q=A.oj(B.a.u(r.e,"/")?"/":"",s,"/") +q=q.charCodeAt(0)==0?q:q +return q}, +i(a){return this.gfL()}, +W(a,b){var s,r,q,p=this +if(b==null)return!1 +if(p===b)return!0 +s=!1 +if(t.dD.b(b))if(p.a===b.gZ())if(p.c!=null===b.geo())if(p.b===b.geN())if(p.gb7()===b.gb7())if(p.gc7()===b.gc7())if(p.e===b.gaa()){r=p.f +q=r==null +if(!q===b.gcX()){if(q)r="" +if(r===b.gc9()){r=p.r +q=r==null +if(!q===b.gep()){s=q?"":r +s=s===b.gcW()}}}}return s}, +$ihX:1, +gZ(){return this.a}, +gaa(){return this.e}} +A.nf.prototype={ +$1(a){return A.vf(64,a,B.j,!1)}, +$S:8} +A.hY.prototype={ +geM(){var s,r,q,p,o=this,n=null,m=o.c +if(m==null){m=o.a +s=o.b[0]+1 +r=B.a.aU(m,"?",s) +q=m.length +if(r>=0){p=A.fx(m,r+1,q,256,!1,!1) +q=r}else p=n +m=o.c=new A.ij("data","",n,n,A.fx(m,s,q,128,!1,!1),p,n)}return m}, +i(a){var s=this.a +return this.b[0]===-1?"data:"+s:s}} +A.b6.prototype={ +geo(){return this.c>0}, +geq(){return this.c>0&&this.d+10&&this.r>=this.a.length}, +gZ(){var s=this.w +return s==null?this.w=this.ia():s}, +ia(){var s,r=this,q=r.b +if(q<=0)return"" +s=q===4 +if(s&&B.a.u(r.a,"http"))return"http" +if(q===5&&B.a.u(r.a,"https"))return"https" +if(s&&B.a.u(r.a,"file"))return"file" +if(q===7&&B.a.u(r.a,"package"))return"package" +return B.a.p(r.a,0,q)}, +geN(){var s=this.c,r=this.b+3 +return s>r?B.a.p(this.a,r,s-1):""}, +gb7(){var s=this.c +return s>0?B.a.p(this.a,s,this.d):""}, +gc7(){var s,r=this +if(r.geq())return A.bh(B.a.p(r.a,r.d+1,r.e),null) +s=r.b +if(s===4&&B.a.u(r.a,"http"))return 80 +if(s===5&&B.a.u(r.a,"https"))return 443 +return 0}, +gaa(){return B.a.p(this.a,this.e,this.f)}, +gc9(){var s=this.f,r=this.r +return s=q.length)return s +return new A.b6(B.a.p(q,0,r),s.b,s.c,s.d,s.e,s.f,r,s.w)}, +hn(a){var s,r,q,p,o,n,m,l,k,j,i,h=this,g=null +a=A.nh(a,0,a.length) +s=!(h.b===a.length&&B.a.u(h.a,a)) +r=a==="file" +q=h.c +p=q>0?B.a.p(h.a,h.b+3,q):"" +o=h.geq()?h.gc7():g +if(s)o=A.ng(o,a) +q=h.c +if(q>0)n=B.a.p(h.a,q,h.d) +else n=p.length!==0||o!=null||r?"":g +q=h.a +m=h.f +l=B.a.p(q,h.e,m) +if(!r)k=n!=null&&l.length!==0 +else k=!0 +if(k&&!B.a.u(l,"/"))l="/"+l +k=h.r +j=m0)return b +s=b.c +if(s>0){r=a.b +if(r<=0)return b +q=r===4 +if(q&&B.a.u(a.a,"file"))p=b.e!==b.f +else if(q&&B.a.u(a.a,"http"))p=!b.fj("80") +else p=!(r===5&&B.a.u(a.a,"https"))||!b.fj("443") +if(p){o=r+1 +return new A.b6(B.a.p(a.a,0,o)+B.a.N(b.a,c+1),r,s+o,b.d+o,b.e+o,b.f+o,b.r+o,a.w)}else return this.fN().ca(b)}n=b.e +c=b.f +if(n===c){s=b.r +if(c0?l:m +o=k-n +return new A.b6(B.a.p(a.a,0,k)+B.a.N(s,n),a.b,a.c,a.d,m,c+o,b.r+o,a.w)}j=a.e +i=a.f +if(j===i&&a.c>0){while(B.a.C(s,"../",n))n+=3 +o=j-n+1 +return new A.b6(B.a.p(a.a,0,j)+"/"+B.a.N(s,n),a.b,a.c,a.d,j,c+o,b.r+o,a.w)}h=a.a +l=A.qv(this) +if(l>=0)g=l +else for(g=j;B.a.C(h,"../",g);)g+=3 +f=0 +for(;;){e=n+3 +if(!(e<=c&&B.a.C(s,"../",n)))break;++f +n=e}for(d="";i>g;){--i +if(h.charCodeAt(i)===47){if(f===0){d="/" +break}--f +d="/"}}if(i===g&&a.b<=0&&!B.a.C(h,"/",j)){n-=f*3 +d=""}o=i-n+d.length +return new A.b6(B.a.p(h,0,i)+d+B.a.N(s,n),a.b,a.c,a.d,j,c+o,b.r+o,a.w)}, +eK(){var s,r=this,q=r.b +if(q>=0){s=!(q===4&&B.a.u(r.a,"file")) +q=s}else q=!1 +if(q)throw A.b(A.a3("Cannot extract a file path from a "+r.gZ()+" URI")) +q=r.f +s=r.a +if(q0?s.gb7():r,n=s.geq()?s.gc7():r,m=s.a,l=s.f,k=B.a.p(m,s.e,l),j=s.r +l=l4294967296)throw A.b(new A.dh(k,k,!1,k,k,"max must be in range 0 < max \u2264 2^32, was "+a)) +if(a>255)if(a>65535)s=a>16777215?4:3 +else s=2 +else s=1 +r=this.a +r.$flags&2&&A.y(r,11) +r.setUint32(0,0,!1) +q=4-s +p=A.A(Math.pow(256,s)) +for(o=a-1,n=(a&o)===0;;){crypto.getRandomValues(J.cZ(B.aN.gaS(r),q,s)) +m=r.getUint32(0,!1) +if(n)return(m&o)>>>0 +l=m%a +if(m-l+a>>0)&2147483647 +r^=r>>>6}r=r+(r<<3>>>0)&2147483647 +r^=r>>>11 +return r+(r<<15>>>0)&2147483647}} +A.hB.prototype={} +A.hW.prototype={} +A.ek.prototype={ +hP(a,b,c){var s=this.a.a +s===$&&A.x() +s.ez(this.giz(),new A.jW(this))}, +he(){return this.d++}, +n(){var s=0,r=A.l(t.H),q,p=this,o +var $async$n=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:if(p.r||(p.w.a.a&30)!==0){s=1 +break}p.r=!0 +o=p.a.b +o===$&&A.x() +o.n() +s=3 +return A.c(p.w.a,$async$n) +case 3:case 1:return A.j(q,r)}}) +return A.k($async$n,r)}, +iA(a){var s,r=this +if(r.c){a.toString +a=B.N.ei(a)}if(a instanceof A.bf){s=r.e.G(0,a.a) +if(s!=null)s.a.P(a.b)}else if(a instanceof A.bm){s=r.e.G(0,a.a) +if(s!=null)s.fZ(new A.h5(a.b),a.c)}else if(a instanceof A.ap)r.f.v(0,a) +else if(a instanceof A.bw){s=r.e.G(0,a.a) +if(s!=null)s.fY(B.M)}}, +br(a){var s,r,q=this +if(q.r||(q.w.a.a&30)!==0)throw A.b(A.B("Tried to send "+a.i(0)+" over isolate channel, but the connection was closed!")) +s=q.a.b +s===$&&A.x() +r=q.c?B.N.dk(a):a +s.a.v(0,r)}, +kY(a,b,c){var s,r=this +if(r.r||(r.w.a.a&30)!==0)return +s=a.a +if(b instanceof A.ed)r.br(new A.bw(s)) +else r.br(new A.bm(s,b,c))}, +hC(a){var s=this.f +new A.ar(s,A.r(s).h("ar<1>")).kF(new A.jX(this,a))}} +A.jW.prototype={ +$0(){var s,r,q +for(s=this.a,r=s.e,q=new A.cx(r,r.r,r.e);q.k();)q.d.fY(B.am) +r.ef(0) +s.w.aT()}, +$S:0} +A.jX.prototype={ +$1(a){return this.hw(a)}, +hw(a){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h +var $async$$1=A.m(function(b,c){if(b===1){o.push(c) +s=p}for(;;)switch(s){case 0:i=null +p=4 +k=n.b.$1(a) +s=7 +return A.c(t.cG.b(k)?k:A.dC(k,t.O),$async$$1) +case 7:i=c +p=2 +s=6 +break +case 4:p=3 +h=o.pop() +m=A.G(h) +l=A.a1(h) +k=n.a.kY(a,m,l) +q=k +s=1 +break +s=6 +break +case 3:s=2 +break +case 6:k=n.a +if(!(k.r||(k.w.a.a&30)!==0))k.br(new A.bf(a.a,i)) +case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$$1,r)}, +$S:49} +A.iB.prototype={ +fZ(a,b){var s +if(b==null)s=this.b +else{s=A.f([],t.J) +if(b instanceof A.bk)B.c.aG(s,b.a) +else s.push(A.q4(b)) +s.push(A.q4(this.b)) +s=new A.bk(A.aM(s,t.a))}this.a.bv(a,s)}, +fY(a){return this.fZ(a,null)}} +A.fX.prototype={ +i(a){return"Channel was closed before receiving a response"}, +$ia5:1} +A.h5.prototype={ +i(a){return J.b1(this.a)}, +$ia5:1} +A.h4.prototype={ +dk(a){var s,r +if(a instanceof A.ap)return[0,a.a,this.h2(a.b)] +else if(a instanceof A.bm){s=J.b1(a.b) +r=a.c +r=r==null?null:r.i(0) +return[2,a.a,s,r]}else if(a instanceof A.bf)return[1,a.a,this.h2(a.b)] +else if(a instanceof A.bw)return A.f([3,a.a],t.t) +else return null}, +ei(a){var s,r,q,p +if(!t.j.b(a))throw A.b(B.aA) +s=J.a0(a) +r=A.A(s.j(a,0)) +q=A.A(s.j(a,1)) +switch(r){case 0:return new A.ap(q,t.ah.a(this.h0(s.j(a,2)))) +case 2:p=A.qR(s.j(a,3)) +s=s.j(a,2) +if(s==null)s=A.oH(s) +return new A.bm(q,s,p!=null?new A.dQ(p):null) +case 1:return new A.bf(q,t.O.a(this.h0(s.j(a,2)))) +case 3:return new A.bw(q)}throw A.b(B.az)}, +h2(a){var s,r,q,p,o,n,m,l,k,j,i,h,g,f +if(a==null)return a +if(a instanceof A.de)return a.a +else if(a instanceof A.bW){s=a.a +r=a.b +q=[] +for(p=a.c,o=p.length,n=0;n")),g=g.h("M.E");s.k();){a8=s.d +h.push(this.dE(a8==null?g.a(a8):a8))}m.push(new A.d0(i,h))}f=J.nZ(a7.a) +A:{if(f==null){s=a6 +break A}A.A(f) +s=f +break A}return new A.bn(new A.ea(n,m),s) +case 5:return new A.c4(B.V[q.$1(1)],p.$1(2)) +case 6:return new A.bV(q.$1(1),p.$1(2)) +case 13:s.toString +return new A.c5(A.o1(B.T,A.a_(J.aJ(s,1)))) +case 7:return new A.c3(new A.eE(p.$1(1),q.$1(2)),q.$1(3)) +case 8:e=A.f([],t.be) +s=t.j +k=1 +for(;;){l=a7.a +l.toString +if(!(k")).ku(0,new A.kV(r))}, +k9(a,b){var s,r,q +for(s=this.z,s=A.ix(s,s.r,s.$ti.c),r=s.$ti.c;s.k();){q=s.d +if(q==null)q=r.a(q) +if(q!==b)q.br(new A.ap(q.d++,a))}}} +A.kX.prototype={ +$1(a){var s=this.a +s.i4() +s.as.n()}, +$S:55} +A.kY.prototype={ +$1(a){return this.a.iC(this.b,a)}, +$S:62} +A.kZ.prototype={ +$1(a){return this.a.z.G(0,this.b)}, +$S:23} +A.kT.prototype={ +$0(){var s=this.b +return this.a.aD(s.a,s.b,s.c,s.d)}, +$S:68} +A.kU.prototype={ +$0(){return this.a.r.G(0,this.b.a)}, +$S:69} +A.kW.prototype={ +$0(){var s,r=this.b +if(r==null)return this.a.w.length===0 +else{s=this.a.w +return s.length!==0&&B.c.gF(s)===r}}, +$S:29} +A.kV.prototype={ +$1(a){return this.a.$0()}, +$S:23} +A.fj.prototype={ +cM(a,b){return this.jO(a,b)}, +jO(a,b){var s=0,r=A.l(t.H),q=1,p=[],o=[],n=this,m,l,k,j,i +var $async$cM=A.m(function(c,d){if(c===1){p.push(d) +s=q}for(;;)switch(s){case 0:j=n.a +i=j.dY(a,!0) +q=2 +m=n.b +l=m.he() +k=new A.n($.h,t.D) +m.e.t(0,l,new A.iB(new A.a6(k,t.h),A.la())) +m.br(new A.ap(l,new A.c3(b,i))) +s=5 +return A.c(k,$async$cM) +case 5:o.push(4) +s=3 +break +case 2:o=[1] +case 3:q=1 +j.cB(i) +s=o.pop() +break +case 4:return A.j(null,r) +case 1:return A.i(p.at(-1),r)}}) +return A.k($async$cM,r)}} +A.i6.prototype={ +dk(a1){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a=this,a0=null +A:{if(a1 instanceof A.ap){s=new A.ah(0,{i:a1.a,p:a.jf(a1.b)}) +break A}if(a1 instanceof A.bf){s=new A.ah(1,{i:a1.a,p:a.jg(a1.b)}) +break A}r=a1 instanceof A.bm +q=a0 +p=a0 +o=!1 +n=a0 +m=a0 +s=!1 +if(r){l=a1.a +q=a1.b +o=q instanceof A.c8 +if(o){t.f_.a(q) +p=a1.c +s=a.a.c>=4 +m=p +n=q}k=l}else{k=a0 +l=k}if(s){s=m==null?a0:m.i(0) +j=n.a +i=n.b +if(i==null)i=a0 +h=n.c +g=n.e +if(g==null)g=a0 +f=n.f +if(f==null)f=a0 +e=n.r +B:{if(e==null){d=a0 +break B}d=[] +for(c=e.length,b=0;b") +s=A.aw(new A.E(s,new A.lX(),q),q.h("M.E")) +s=new A.bF(s) +break A}s=A.C(A.J("Unknown request tag "+r,m))}return s}, +jg(a){var s,r +A:{s=null +if(a==null)break A +if(a instanceof A.aO){r=a.a +s=A.bQ(r)?r:A.A(r) +break A}if(a instanceof A.bI){s=this.jh(a) +break A}}return s}, +jh(a){var s,r,q,p=a.a,o=J.a0(p) +if(o.gB(p)){p=v.G +return{c:new p.Array(),r:new p.Array()}}else{s=J.d_(o.gF(p).ga_(),new A.m2(),t.N).cf(0) +r=A.f([],t.fk) +for(p=o.gq(p);p.k();){q=[] +for(o=J.a4(p.gm().gbF());o.k();)q.push(this.cE(o.gm())) +r.push(q)}return{c:s,r:r}}}, +il(a){var s,r,q,p,o,n,m,l,k,j +if(a==null)return null +else if(typeof a==="boolean")return new A.aO(A.bg(a)) +else if(typeof a==="number")return new A.aO(A.A(A.X(a))) +else{A.a9(a) +s=a.c +s=t.u.b(s)?s:new A.ak(s,A.N(s).h("ak<1,o>")) +r=t.N +s=J.d_(s,new A.m0(),r) +q=A.aw(s,s.$ti.h("M.E")) +p=A.f([],t.d) +s=a.r +s=J.a4(t.e9.b(s)?s:new A.ak(s,A.N(s).h("ak<1,u>"))) +o=t.X +while(s.k()){n=s.gm() +m=A.al(r,o) +n=A.tU(n,0,o) +l=J.a4(n.a) +n=n.b +k=new A.er(l,n) +while(k.k()){j=k.c +j=j>=0?new A.ah(n+j,l.gm()):A.C(A.az()) +m.t(0,q[j.a],this.cD(j.b))}p.push(m)}return new A.bI(p)}}, +cE(a){var s +A:{if(a==null){s=null +break A}if(A.bv(a)){s=a +break A}if(A.bQ(a)){s=a +break A}if(typeof a=="string"){s=a +break A}if(typeof a=="number"){s=A.f([15,a],t.n) +break A}if(a instanceof A.a7){s=A.f([14,a.i(0)],t.f) +break A}if(t.I.b(a)){s=new Uint8Array(A.iV(a)) +break A}s=A.C(A.J("Unknown db value: "+A.t(a),null))}return s}, +cD(a){var s,r,q,p=null +if(a!=null)if(typeof a==="number")return A.A(A.X(a)) +else if(typeof a==="boolean")return A.bg(a) +else if(typeof a==="string")return A.a_(a) +else if(A.ku(a,"Uint8Array"))return t.Z.a(a) +else{t.c.a(a) +s=a.length===2 +if(s){r=a[0] +q=a[1]}else{q=p +r=q}if(!s)throw A.b(A.B("Pattern matching error")) +if(r==14)return A.ow(A.a_(q),p) +else return A.X(q)}else return p}, +f8(a){var s,r=a!=null?A.a_(a):null +A:{if(r!=null){s=new A.dQ(r) +break A}s=null +break A}return s}, +ih(a){var s,r,q,p,o=null,n=a.length>=8,m=o,l=o,k=o,j=o,i=o,h=o,g=o +if(n){s=a[0] +m=a[1] +l=a[2] +k=a[3] +j=a[4] +i=a[5] +h=a[6] +g=a[7]}else s=o +if(!n)throw A.b(A.B("Pattern matching error")) +s=A.A(A.X(s)) +j=A.A(A.X(j)) +A.a_(l) +n=k!=null?A.a_(k):o +r=h!=null?A.a_(h):o +if(g!=null){q=[] +t.c.a(g) +p=B.c.gq(g) +while(p.k())q.push(this.cD(p.gm()))}else q=o +p=i!=null?A.a_(i):o +return new A.bm(s,new A.c8(l,n,j,o,p,r,q),this.f8(m))}} +A.m3.prototype={ +$0(){var s=A.a9(this.a.a) +return new A.ap(s.i,this.b.ik(s.p))}, +$S:70} +A.m4.prototype={ +$0(){var s=A.a9(this.a.a) +return new A.bf(s.i,this.b.il(s.p))}, +$S:77} +A.m1.prototype={ +$1(a){return a}, +$S:8} +A.lY.prototype={ +$0(){var s,r,q,p,o,n,m=this.b,l=J.a0(m),k=t.c,j=k.a(l.j(m,1)),i=t.u.b(j)?j:new A.ak(j,A.N(j).h("ak<1,o>")) +i=J.d_(i,new A.lZ(),t.N) +s=A.aw(i,i.$ti.h("M.E")) +i=l.gl(m) +r=A.f([],t.b) +for(i=l.Y(m,2).ah(0,i-3),k=A.ee(i,i.$ti.h("d.E"),k),k=A.ht(k,new A.m_(),A.r(k).h("d.E"),t.ee),i=k.a,q=A.r(k),k=new A.d9(i.gq(i),k.b,q.h("d9<1,2>")),i=this.a.gjv(),q=q.y[1];k.k();){p=k.a +if(p==null)p=q.a(p) +o=J.a0(p) +n=A.A(A.X(o.j(p,0))) +p=o.Y(p,1) +o=p.$ti.h("E") +p=A.aw(new A.E(p,i,o),o.h("M.E")) +r.push(new A.d0(n,p))}m=l.j(m,l.gl(m)-1) +m=m==null?null:A.A(A.X(m)) +return new A.bn(new A.ea(s,r),m)}, +$S:80} +A.lZ.prototype={ +$1(a){return a}, +$S:8} +A.m_.prototype={ +$1(a){return a}, +$S:91} +A.lX.prototype={ +$1(a){var s,r,q +t.c.a(a) +s=a.length===2 +if(s){r=a[0] +q=a[1]}else{r=null +q=null}if(!s)throw A.b(A.B("Pattern matching error")) +A.a_(r) +return new A.bK(q==null?null:B.R[A.A(A.X(q))],r)}, +$S:93} +A.m2.prototype={ +$1(a){return a}, +$S:8} +A.m0.prototype={ +$1(a){return a}, +$S:8} +A.ds.prototype={ +ae(){return"UpdateKind."+this.b}} +A.bK.prototype={ +gA(a){return A.eD(this.a,this.b,B.f,B.f)}, +W(a,b){if(b==null)return!1 +return b instanceof A.bK&&b.a==this.a&&b.b===this.b}, +i(a){return"TableUpdate("+this.b+", kind: "+A.t(this.a)+")"}} +A.nS.prototype={ +$0(){return this.a.a.a.P(A.kh(this.b,this.c))}, +$S:0} +A.bU.prototype={ +K(){var s,r +if(this.c)return +for(s=this.b,r=0;!1;++r)s[r].$0() +this.c=!0}} +A.ed.prototype={ +i(a){return"Operation was cancelled"}, +$ia5:1} +A.ao.prototype={ +n(){var s=0,r=A.l(t.H) +var $async$n=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:return A.j(null,r)}}) +return A.k($async$n,r)}} +A.ea.prototype={ +gA(a){return A.eD(B.o.h8(this.a),B.o.h8(this.b),B.f,B.f)}, +W(a,b){if(b==null)return!1 +return b instanceof A.ea&&B.o.ek(b.a,this.a)&&B.o.ek(b.b,this.b)}, +i(a){return"BatchedStatements("+A.t(this.a)+", "+A.t(this.b)+")"}} +A.d0.prototype={ +gA(a){return A.eD(this.a,B.o,B.f,B.f)}, +W(a,b){if(b==null)return!1 +return b instanceof A.d0&&b.a===this.a&&B.o.ek(b.b,this.b)}, +i(a){return"ArgumentsForBatchedStatement("+this.a+", "+A.t(this.b)+")"}} +A.jN.prototype={} +A.kK.prototype={} +A.lu.prototype={} +A.kF.prototype={} +A.jQ.prototype={} +A.hA.prototype={} +A.k4.prototype={} +A.ic.prototype={ +gex(){return!1}, +gc3(){return!1}, +fJ(a,b,c){if(this.gex()||this.b>0)return this.a.cp(new A.mc(b,a,c),c) +else return a.$0()}, +bs(a,b){return this.fJ(a,!0,b)}, +cv(a,b){this.gc3()}, +ab(a,b){return this.l4(a,b)}, +l4(a,b){var s=0,r=A.l(t.aS),q,p=this,o +var $async$ab=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:s=3 +return A.c(p.bs(new A.mh(p,a,b),t.aj),$async$ab) +case 3:o=d.gjN(0) +o=A.aw(o,o.$ti.h("M.E")) +q=o +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$ab,r)}, +cb(a,b){return this.bs(new A.mf(this,a,b),t.S)}, +aw(a,b){return this.bs(new A.mg(this,a,b),t.S)}, +a7(a,b){return this.bs(new A.me(this,b,a),t.H)}, +l0(a){return this.a7(a,null)}, +av(a){return this.bs(new A.md(this,a),t.H)}, +cN(){return new A.f7(this,new A.a6(new A.n($.h,t.D),t.h),new A.bo())}, +cO(){return this.aR(this)}} +A.mc.prototype={ +$0(){return this.hy(this.c)}, +hy(a){var s=0,r=A.l(a),q,p=this +var $async$$0=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:if(p.a)A.oP() +s=3 +return A.c(p.b.$0(),$async$$0) +case 3:q=c +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$$0,r)}, +$S(){return this.c.h("D<0>()")}} +A.mh.prototype={ +$0(){var s=this.a,r=this.b,q=this.c +s.cv(r,q) +return s.gaJ().ab(r,q)}, +$S:38} +A.mf.prototype={ +$0(){var s=this.a,r=this.b,q=this.c +s.cv(r,q) +return s.gaJ().d9(r,q)}, +$S:24} +A.mg.prototype={ +$0(){var s=this.a,r=this.b,q=this.c +s.cv(r,q) +return s.gaJ().aw(r,q)}, +$S:24} +A.me.prototype={ +$0(){var s,r,q=this.b +if(q==null)q=B.q +s=this.a +r=this.c +s.cv(r,q) +return s.gaJ().a7(r,q)}, +$S:2} +A.md.prototype={ +$0(){var s=this.a +s.gc3() +return s.gaJ().av(this.b)}, +$S:2} +A.iP.prototype={ +i3(){this.c=!0 +if(this.d)throw A.b(A.B("A transaction was used after being closed. Please check that you're awaiting all database operations inside a `transaction` block."))}, +aR(a){throw A.b(A.a3("Nested transactions aren't supported."))}, +gan(){return B.m}, +gc3(){return!1}, +gex(){return!0}, +$ihS:1} +A.fn.prototype={ +ao(a){var s,r,q=this +q.i3() +s=q.z +if(s==null){s=q.z=new A.a6(new A.n($.h,t.k),t.co) +r=q.as;++r.b +r.fJ(new A.n1(q),!1,t.P).ai(new A.n2(r))}return s.a}, +gaJ(){return this.e.e}, +aR(a){var s=this.at+1 +return new A.fn(this.y,new A.a6(new A.n($.h,t.D),t.h),a,s,A.qW(s),A.qU(s),A.qV(s),this.e,new A.bo())}, +bf(){var s=0,r=A.l(t.H),q,p=this +var $async$bf=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:if(!p.c){s=1 +break}s=3 +return A.c(p.a7(p.ay,B.q),$async$bf) +case 3:p.e0() +case 1:return A.j(q,r)}}) +return A.k($async$bf,r)}, +bC(){var s=0,r=A.l(t.H),q,p=2,o=[],n=[],m=this +var $async$bC=A.m(function(a,b){if(a===1){o.push(b) +s=p}for(;;)switch(s){case 0:if(!m.c){s=1 +break}p=3 +s=6 +return A.c(m.a7(m.ch,B.q),$async$bC) +case 6:n.push(5) +s=4 +break +case 3:n=[2] +case 4:p=2 +m.e0() +s=n.pop() +break +case 5:case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$bC,r)}, +e0(){var s=this +if(s.at===0)s.e.e.a=!1 +s.Q.aT() +s.d=!0}} +A.n1.prototype={ +$0(){var s=0,r=A.l(t.P),q=1,p=[],o=this,n,m,l,k,j +var $async$$0=A.m(function(a,b){if(a===1){p.push(b) +s=q}for(;;)switch(s){case 0:q=3 +A.oP() +l=o.a +s=6 +return A.c(l.l0(l.ax),$async$$0) +case 6:l.e.e.a=!0 +l.z.P(!0) +q=1 +s=5 +break +case 3:q=2 +j=p.pop() +n=A.G(j) +m=A.a1(j) +l=o.a +l.z.bv(n,m) +l.e0() +s=5 +break +case 2:s=1 +break +case 5:s=7 +return A.c(o.a.Q.a,$async$$0) +case 7:return A.j(null,r) +case 1:return A.i(p.at(-1),r)}}) +return A.k($async$$0,r)}, +$S:17} +A.n2.prototype={ +$0(){return this.a.b--}, +$S:41} +A.h2.prototype={ +gaJ(){return this.e}, +gan(){return B.m}, +ao(a){return this.x.cp(new A.jV(this,a),t.y)}, +bp(a){return this.jb(a)}, +jb(a){var s=0,r=A.l(t.H),q=this,p,o,n,m +var $async$bp=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:n=q.e +m=n.y +m===$&&A.x() +p=a.c +s=m instanceof A.hA?2:4 +break +case 2:o=p +s=3 +break +case 4:s=m instanceof A.fl?5:7 +break +case 5:s=8 +return A.c(A.bc(m.a.gla(),t.S),$async$bp) +case 8:o=c +s=6 +break +case 7:throw A.b(A.k6("Invalid delegate: "+n.i(0)+". The versionDelegate getter must not subclass DBVersionDelegate directly")) +case 6:case 3:if(o===0)o=null +s=9 +return A.c(a.cM(new A.id(q,new A.bo()),new A.eE(o,p)),$async$bp) +case 9:s=m instanceof A.fl&&o!==p?10:11 +break +case 10:m.a.h4("PRAGMA user_version = "+p+";") +s=12 +return A.c(A.bc(null,t.H),$async$bp) +case 12:case 11:return A.j(null,r)}}) +return A.k($async$bp,r)}, +aR(a){var s=$.h +return new A.fn(B.au,new A.a6(new A.n(s,t.D),t.h),a,0,"BEGIN TRANSACTION","COMMIT TRANSACTION","ROLLBACK TRANSACTION",this,new A.bo())}, +n(){return this.x.cp(new A.jU(this),t.H)}, +gc3(){return this.r}, +gex(){return this.w}} +A.jV.prototype={ +$0(){var s=0,r=A.l(t.y),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f,e +var $async$$0=A.m(function(a,b){if(a===1){o.push(b) +s=p}for(;;)switch(s){case 0:f=n.a +if(f.d){f=A.ns(new A.aQ("Can't re-open a database after closing it. Please create a new database connection and open that instead."),null) +k=new A.n($.h,t.k) +k.aN(f) +q=k +s=1 +break}j=f.f +if(j!=null)A.pr(j.a,j.b) +k=f.e +i=t.y +h=A.bc(k.d,i) +s=3 +return A.c(t.bF.b(h)?h:A.dC(h,i),$async$$0) +case 3:if(b){q=f.c=!0 +s=1 +break}i=n.b +s=4 +return A.c(k.bz(i),$async$$0) +case 4:f.c=!0 +p=6 +s=9 +return A.c(f.bp(i),$async$$0) +case 9:q=!0 +s=1 +break +p=2 +s=8 +break +case 6:p=5 +e=o.pop() +m=A.G(e) +l=A.a1(e) +f.f=new A.ah(m,l) +throw e +s=8 +break +case 5:s=2 +break +case 8:case 1:return A.j(q,r) +case 2:return A.i(o.at(-1),r)}}) +return A.k($async$$0,r)}, +$S:42} +A.jU.prototype={ +$0(){var s=this.a +if(s.c&&!s.d){s.d=!0 +s.c=!1 +return s.e.n()}else return A.bc(null,t.H)}, +$S:2} +A.id.prototype={ +aR(a){return this.e.aR(a)}, +ao(a){this.c=!0 +return A.bc(!0,t.y)}, +gaJ(){return this.e.e}, +gc3(){return!1}, +gan(){return B.m}} +A.f7.prototype={ +gan(){return this.e.gan()}, +ao(a){var s,r,q,p=this,o=p.f +if(o!=null)return o.a +else{p.c=!0 +s=new A.n($.h,t.k) +r=new A.a6(s,t.co) +p.f=r +q=p.e;++q.b +q.bs(new A.mA(p,r),t.P) +return s}}, +gaJ(){return this.e.gaJ()}, +aR(a){return this.e.aR(a)}, +n(){this.r.aT() +return A.bc(null,t.H)}} +A.mA.prototype={ +$0(){var s=0,r=A.l(t.P),q=this,p +var $async$$0=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:q.b.P(!0) +p=q.a +s=2 +return A.c(p.r.a,$async$$0) +case 2:--p.e.b +return A.j(null,r)}}) +return A.k($async$$0,r)}, +$S:17} +A.dg.prototype={ +gjN(a){var s=this.b +return new A.E(s,new A.kM(this),A.N(s).h("E<1,an>"))}} +A.kM.prototype={ +$1(a){var s,r,q,p,o,n,m,l=A.al(t.N,t.z) +for(s=this.a,r=s.a,q=r.length,s=s.c,p=J.a0(a),o=0;o")).gF(0)).n() +q.t(0,a,s)}return new A.ah(s,o.sqlite3_stmt_isexplain(r)===0)}} +A.fl.prototype={} +A.kJ.prototype={ +kq(){var s,r,q,p +for(s=this.b,r=new A.cx(s,s.r,s.e);r.k();){q=r.d +if(!q.r){q.r=!0 +if(!q.f){p=q.a +p.c.d.sqlite3_reset(p.b) +q.f=!0}q=q.a +p=q.c +p.d.sqlite3_finalize(q.b) +p=p.w +if(p!=null){p=p.a +if(p!=null)p.unregister(q.d)}}}s.ef(0)}} +A.k5.prototype={ +$1(a){return Date.now()}, +$S:44} +A.ny.prototype={ +$1(a){var s=a.j(0,0) +if(typeof s=="number")return this.a.$1(s) +else return null}, +$S:25} +A.ho.prototype={ +gij(){var s=this.a +s===$&&A.x() +return s}, +gan(){if(this.b){var s=this.a +s===$&&A.x() +s=B.m!==s.gan()}else s=!1 +if(s)throw A.b(A.k6("LazyDatabase created with "+B.m.i(0)+", but underlying database is "+this.gij().gan().i(0)+".")) +return B.m}, +hZ(){var s,r,q=this +if(q.b)return A.bc(null,t.H) +else{s=q.d +if(s!=null)return s.a +else{s=new A.n($.h,t.D) +r=q.d=new A.a6(s,t.h) +A.kh(q.e,t.x).bE(new A.kx(q,r),r.gjT(),t.P) +return s}}}, +cN(){var s=this.a +s===$&&A.x() +return s.cN()}, +cO(){var s=this.a +s===$&&A.x() +return s.cO()}, +ao(a){return this.hZ().ce(new A.ky(this,a),t.y)}, +av(a){var s=this.a +s===$&&A.x() +return s.av(a)}, +a7(a,b){var s=this.a +s===$&&A.x() +return s.a7(a,b)}, +cb(a,b){var s=this.a +s===$&&A.x() +return s.cb(a,b)}, +aw(a,b){var s=this.a +s===$&&A.x() +return s.aw(a,b)}, +ab(a,b){var s=this.a +s===$&&A.x() +return s.ab(a,b)}, +n(){var s=0,r=A.l(t.H),q,p=this,o,n +var $async$n=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:s=p.b?3:5 +break +case 3:o=p.a +o===$&&A.x() +s=6 +return A.c(o.n(),$async$n) +case 6:q=b +s=1 +break +s=4 +break +case 5:n=p.d +s=n!=null?7:8 +break +case 7:s=9 +return A.c(n.a,$async$n) +case 9:o=p.a +o===$&&A.x() +s=10 +return A.c(o.n(),$async$n) +case 10:case 8:case 4:case 1:return A.j(q,r)}}) +return A.k($async$n,r)}} +A.kx.prototype={ +$1(a){var s=this.a +s.a!==$&&A.j_() +s.a=a +s.b=!0 +this.b.aT()}, +$S:46} +A.ky.prototype={ +$1(a){var s=this.a.a +s===$&&A.x() +return s.ao(this.b)}, +$S:47} +A.bo.prototype={ +cp(a,b){var s,r=this.a,q=new A.n($.h,t.D) +this.a=q +s=new A.kA(this,a,new A.a6(q,t.h),q,b) +if(r!=null)return r.ce(new A.kC(s,b),b) +else return s.$0()}} +A.kA.prototype={ +$0(){var s=this +return A.kh(s.b,s.e).ai(new A.kB(s.a,s.c,s.d))}, +$S(){return this.e.h("D<0>()")}} +A.kB.prototype={ +$0(){this.b.aT() +var s=this.a +if(s.a===this.c)s.a=null}, +$S:5} +A.kC.prototype={ +$1(a){return this.a.$0()}, +$S(){return this.b.h("D<0>(~)")}} +A.lU.prototype={ +$1(a){var s,r=this,q=a.data +if(r.a&&J.aj(q,"_disconnect")){s=r.b.a +s===$&&A.x() +s=s.a +s===$&&A.x() +s.n()}else{s=r.b.a +if(r.c){s===$&&A.x() +s=s.a +s===$&&A.x() +s.v(0,r.d.ei(t.c.a(q)))}else{s===$&&A.x() +s=s.a +s===$&&A.x() +s.v(0,A.rh(q))}}}, +$S:9} +A.lV.prototype={ +$1(a){var s=this.c +if(this.a)s.postMessage(this.b.dk(t.fJ.a(a))) +else s.postMessage(A.x0(a))}, +$S:7} +A.lW.prototype={ +$0(){if(this.a)this.b.postMessage("_disconnect") +this.b.close()}, +$S:0} +A.jR.prototype={ +T(){A.aI(this.a,"message",new A.jT(this),!1)}, +aj(a){return this.iB(a)}, +iB(a6){var s=0,r=A.l(t.H),q=1,p=[],o=this,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1,a2,a3,a4,a5 +var $async$aj=A.m(function(a7,a8){if(a7===1){p.push(a8) +s=q}for(;;)switch(s){case 0:k=a6 instanceof A.di +j=k?a6.a:null +s=k?3:4 +break +case 3:i={} +i.a=i.b=!1 +s=5 +return A.c(o.b.cp(new A.jS(i,o),t.P),$async$aj) +case 5:h=o.c.a.j(0,j) +g=A.f([],t.L) +f=!1 +s=i.b?6:7 +break +case 6:a5=J +s=8 +return A.c(A.e5(),$async$aj) +case 8:k=a5.a4(a8) +case 9:if(!k.k()){s=10 +break}e=k.gm() +g.push(new A.ah(B.F,e)) +if(e===j)f=!0 +s=9 +break +case 10:case 7:s=h!=null?11:13 +break +case 11:k=h.a +d=k===B.u||k===B.E +f=k===B.a2||k===B.a3 +s=12 +break +case 13:a5=i.a +if(a5){s=14 +break}else a8=a5 +s=15 +break +case 14:s=16 +return A.c(A.e2(j),$async$aj) +case 16:case 15:d=a8 +case 12:k=v.G +c="Worker" in k +e=i.b +b=i.a +new A.ej(c,e,"SharedArrayBuffer" in k,b,g,B.t,d,f).di(o.a) +s=2 +break +case 4:if(a6 instanceof A.dk){o.c.eR(a6) +s=2 +break}k=a6 instanceof A.eN +a=k?a6.a:null +s=k?17:18 +break +case 17:s=19 +return A.c(A.i2(a),$async$aj) +case 19:a0=a8 +o.a.postMessage(!0) +s=20 +return A.c(a0.T(),$async$aj) +case 20:s=2 +break +case 18:n=null +m=null +a1=a6 instanceof A.h3 +if(a1){a2=a6.a +n=a2.a +m=a2.b}s=a1?21:22 +break +case 21:q=24 +case 27:switch(n){case B.a4:s=29 +break +case B.F:s=30 +break +default:s=28 +break}break +case 29:s=31 +return A.c(A.nE(m),$async$aj) +case 31:s=28 +break +case 30:s=32 +return A.c(A.fE(m),$async$aj) +case 32:s=28 +break +case 28:a6.di(o.a) +q=1 +s=26 +break +case 24:q=23 +a4=p.pop() +l=A.G(a4) +new A.dv(J.b1(l)).di(o.a) +s=26 +break +case 23:s=1 +break +case 26:s=2 +break +case 22:s=2 +break +case 2:return A.j(null,r) +case 1:return A.i(p.at(-1),r)}}) +return A.k($async$aj,r)}} +A.jT.prototype={ +$1(a){this.a.aj(A.on(A.a9(a.data)))}, +$S:1} +A.jS.prototype={ +$0(){var s=0,r=A.l(t.P),q=this,p,o,n,m,l +var $async$$0=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:o=q.b +n=o.d +m=q.a +s=n!=null?2:4 +break +case 2:m.b=n.b +m.a=n.a +s=3 +break +case 4:l=m +s=5 +return A.c(A.cV(),$async$$0) +case 5:l.b=b +s=6 +return A.c(A.iX(),$async$$0) +case 6:p=b +m.a=p +o.d=new A.lH(p,m.b) +case 3:return A.j(null,r)}}) +return A.k($async$$0,r)}, +$S:17} +A.cz.prototype={ +ae(){return"ProtocolVersion."+this.b}} +A.lJ.prototype={ +dj(a){this.aB(new A.lM(a))}, +eQ(a){this.aB(new A.lL(a))}, +di(a){this.aB(new A.lK(a))}} +A.lM.prototype={ +$2(a,b){var s=b==null?B.z:b +this.a.postMessage(a,s)}, +$S:18} +A.lL.prototype={ +$2(a,b){var s=b==null?B.z:b +this.a.postMessage(a,s)}, +$S:18} +A.lK.prototype={ +$2(a,b){var s=b==null?B.z:b +this.a.postMessage(a,s)}, +$S:18} +A.jl.prototype={} +A.c6.prototype={ +aB(a){var s=this +A.dV(a,"SharedWorkerCompatibilityResult",A.f([s.e,s.f,s.r,s.c,s.d,A.pp(s.a),s.b.c],t.f),null)}} +A.l5.prototype={ +$1(a){return A.bg(J.aJ(this.a,a))}, +$S:51} +A.dv.prototype={ +aB(a){A.dV(a,"Error",this.a,null)}, +i(a){return"Error in worker: "+this.a}, +$ia5:1} +A.dk.prototype={ +aB(a){var s,r,q=this,p={} +p.sqlite=q.a.i(0) +s=q.b +p.port=s +p.storage=q.c.b +p.database=q.d +r=q.e +p.initPort=r +p.migrations=q.r +p.new_serialization=q.w +p.v=q.f.c +s=A.f([s],t.W) +if(r!=null)s.push(r) +A.dV(a,"ServeDriftDatabase",p,s)}} +A.di.prototype={ +aB(a){A.dV(a,"RequestCompatibilityCheck",this.a,null)}} +A.ej.prototype={ +aB(a){var s=this,r={} +r.supportsNestedWorkers=s.e +r.canAccessOpfs=s.f +r.supportsIndexedDb=s.w +r.supportsSharedArrayBuffers=s.r +r.indexedDbExists=s.c +r.opfsExists=s.d +r.existing=A.pp(s.a) +r.v=s.b.c +A.dV(a,"DedicatedWorkerCompatibilityResult",r,null)}} +A.eN.prototype={ +aB(a){A.dV(a,"StartFileSystemServer",this.a,null)}} +A.h3.prototype={ +aB(a){var s=this.a +A.dV(a,"DeleteDatabase",A.f([s.a.b,s.b],t.s),null)}} +A.nB.prototype={ +$1(a){this.b.transaction.abort() +this.a.a=!1}, +$S:9} +A.nP.prototype={ +$1(a){return A.a9(a[1])}, +$S:52} +A.h6.prototype={ +eR(a){var s=a.f.c,r=a.w +this.a.hj(a.d,new A.k3(this,a)).hA(A.uB(a.b,s>=1,s,r),!r)}, +aW(a,b,c,d,e){return this.kP(a,b,c,d,e)}, +kP(a,b,c,d,e){var s=0,r=A.l(t.x),q,p=this,o,n,m,l,k,j,i,h +var $async$aW=A.m(function(f,g){if(f===1)return A.i(g,r) +for(;;)switch(s){case 0:s=3 +return A.c(A.lQ(d),$async$aW) +case 3:i=g +h=null +case 4:switch(e.a){case 0:s=6 +break +case 1:s=7 +break +case 3:s=8 +break +case 2:s=9 +break +case 4:s=10 +break +default:s=11 +break}break +case 6:s=12 +return A.c(A.l7("drift_db/"+a),$async$aW) +case 12:o=g +h=o.gb6() +s=5 +break +case 7:s=13 +return A.c(p.cu(a),$async$aW) +case 13:o=g +h=o.gb6() +s=5 +break +case 8:case 9:s=14 +return A.c(A.hg(a),$async$aW) +case 14:o=g +h=o.gb6() +s=5 +break +case 10:o=A.o6(null) +s=5 +break +case 11:o=null +case 5:s=c!=null&&o.cg("/database",0)===0?15:16 +break +case 15:n=c.$0() +s=17 +return A.c(t.eY.b(n)?n:A.dC(n,t.aD),$async$aW) +case 17:m=g +if(m!=null){l=o.aX(new A.eL("/database"),4).a +l.be(m,0) +l.ci()}case 16:i.h9() +n=i.a +n=n.a +k=n.d.dart_sqlite3_register_vfs(n.bZ(B.i.a5(o.a),1),o,1) +if(k===0)A.C(A.B("could not register vfs")) +n=$.rM() +n.a.set(o,k) +n=A.u0(t.N,t.eT) +j=new A.i3(new A.iS(i,"/database",null,p.b,!0,b,new A.kJ(n)),!1,!0,new A.bo(),new A.bo()) +if(h!=null){q=A.tt(j,new A.mp(h,j)) +s=1 +break}else{q=j +s=1 +break}case 1:return A.j(q,r)}}) +return A.k($async$aW,r)}, +cu(a){return this.iI(a)}, +iI(a){var s=0,r=A.l(t.aT),q,p,o,n,m,l,k,j,i +var $async$cu=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:k=v.G +j=new k.SharedArrayBuffer(8) +i=k.Int32Array +i=t.ha.a(A.e1(i,[j])) +k.Atomics.store(i,0,-1) +i={clientVersion:1,root:"drift_db/"+a,synchronizationBuffer:j,communicationBuffer:new k.SharedArrayBuffer(67584)} +p=new k.Worker(A.eS().i(0)) +new A.eN(i).dj(p) +s=3 +return A.c(new A.f6(p,"message",!1,t.fF).gF(0),$async$cu) +case 3:o=A.pV(i.synchronizationBuffer) +i=i.communicationBuffer +n=A.pX(i,65536,2048) +k=k.Uint8Array +k=t.Z.a(A.e1(k,[i])) +m=A.jv("/",$.cY()) +l=$.fG() +q=new A.du(o,new A.bp(i,n,k),m,l,"dart-sqlite3-vfs") +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$cu,r)}} +A.k3.prototype={ +$0(){var s=this.b,r=s.e,q=r!=null?new A.k0(r):null,p=this.a,o=A.uj(new A.ho(new A.k1(p,s,q)),!1,!0),n=new A.n($.h,t.D),m=new A.dj(s.c,o,new A.a8(n,t.F)) +n.ai(new A.k2(p,s,m)) +return m}, +$S:53} +A.k0.prototype={ +$0(){var s=new A.n($.h,t.fX),r=this.a +r.postMessage(!0) +r.onmessage=A.bu(new A.k_(new A.a6(s,t.fu))) +return s}, +$S:54} +A.k_.prototype={ +$1(a){var s=t.dE.a(a.data),r=s==null?null:s +this.a.P(r)}, +$S:9} +A.k1.prototype={ +$0(){var s=this.b +return this.a.aW(s.d,s.r,this.c,s.a,s.c)}, +$S:37} +A.k2.prototype={ +$0(){this.a.a.G(0,this.b.d) +this.c.b.hD()}, +$S:5} +A.mp.prototype={ +c_(a){return this.jR(a)}, +jR(a){var s=0,r=A.l(t.H),q=this,p +var $async$c_=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:s=2 +return A.c(a.n(),$async$c_) +case 2:s=q.b===a?3:4 +break +case 3:p=q.a.$0() +s=5 +return A.c(p instanceof A.n?p:A.dC(p,t.H),$async$c_) +case 5:case 4:return A.j(null,r)}}) +return A.k($async$c_,r)}} +A.dj.prototype={ +hA(a,b){var s,r,q;++this.c +s=t.X +s=A.uU(new A.kQ(this),s,s).gjP().$1(a.ghI()) +r=a.$ti +q=new A.ef(r.h("ef<1>")) +q.b=new A.f0(q,a.ghE()) +q.a=new A.f1(s,q,r.h("f1<1>")) +this.b.hB(q,b)}} +A.kQ.prototype={ +$1(a){var s=this.a +if(--s.c===0)s.d.aT() +s=a.a +if((s.e&2)!==0)A.C(A.B("Stream is already closed")) +s.eV()}, +$S:56} +A.lH.prototype={} +A.jp.prototype={ +$1(a){this.a.P(this.c.a(this.b.result))}, +$S:1} +A.jq.prototype={ +$1(a){var s=this.b.error +if(s==null)s=a +this.a.aH(s)}, +$S:1} +A.jr.prototype={ +$1(a){var s=this.b.error +if(s==null)s=a +this.a.aH(s)}, +$S:1} +A.l_.prototype={ +T(){A.aI(this.a,"connect",new A.l4(this),!1)}, +dV(a){return this.iM(a)}, +iM(a){var s=0,r=A.l(t.H),q=this,p,o +var $async$dV=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:p=a.ports +o=J.aJ(t.cl.b(p)?p:new A.ak(p,A.N(p).h("ak<1,z>")),0) +o.start() +A.aI(o,"message",new A.l0(q,o),!1) +return A.j(null,r)}}) +return A.k($async$dV,r)}, +cw(a,b){return this.iJ(a,b)}, +iJ(a,b){var s=0,r=A.l(t.H),q=1,p=[],o=this,n,m,l,k,j,i,h,g +var $async$cw=A.m(function(c,d){if(c===1){p.push(d) +s=q}for(;;)switch(s){case 0:q=3 +n=A.on(A.a9(b.data)) +m=n +l=null +i=m instanceof A.di +if(i)l=m.a +s=i?7:8 +break +case 7:s=9 +return A.c(o.bU(l),$async$cw) +case 9:k=d +k.eQ(a) +s=6 +break +case 8:if(m instanceof A.dk&&B.u===m.c){o.c.eR(n) +s=6 +break}if(m instanceof A.dk){i=o.b +i.toString +n.dj(i) +s=6 +break}i=A.J("Unknown message",null) +throw A.b(i) +case 6:q=1 +s=5 +break +case 3:q=2 +g=p.pop() +j=A.G(g) +new A.dv(J.b1(j)).eQ(a) +a.close() +s=5 +break +case 2:s=1 +break +case 5:return A.j(null,r) +case 1:return A.i(p.at(-1),r)}}) +return A.k($async$cw,r)}, +bU(a){return this.jp(a)}, +jp(a){var s=0,r=A.l(t.fL),q,p=this,o,n,m,l,k,j,i,h,g,f,e,d,c +var $async$bU=A.m(function(b,a0){if(b===1)return A.i(a0,r) +for(;;)switch(s){case 0:k=v.G +j="Worker" in k +s=3 +return A.c(A.iX(),$async$bU) +case 3:i=a0 +s=!j?4:6 +break +case 4:k=p.c.a.j(0,a) +if(k==null)o=null +else{k=k.a +k=k===B.u||k===B.E +o=k}h=A +g=!1 +f=!1 +e=i +d=B.B +c=B.t +s=o==null?7:9 +break +case 7:s=10 +return A.c(A.e2(a),$async$bU) +case 10:s=8 +break +case 9:a0=o +case 8:q=new h.c6(g,f,e,d,c,a0,!1) +s=1 +break +s=5 +break +case 6:n={} +m=p.b +if(m==null)m=p.b=new k.Worker(A.eS().i(0)) +new A.di(a).dj(m) +k=new A.n($.h,t.a9) +n.a=n.b=null +l=new A.l3(n,new A.a6(k,t.bi),i) +n.b=A.aI(m,"message",new A.l1(l),!1) +n.a=A.aI(m,"error",new A.l2(p,l,m),!1) +q=k +s=1 +break +case 5:case 1:return A.j(q,r)}}) +return A.k($async$bU,r)}} +A.l4.prototype={ +$1(a){return this.a.dV(a)}, +$S:1} +A.l0.prototype={ +$1(a){return this.a.cw(this.b,a)}, +$S:1} +A.l3.prototype={ +$4(a,b,c,d){var s,r=this.b +if((r.a.a&30)===0){r.P(new A.c6(!0,a,this.c,d,B.t,c,b)) +r=this.a +s=r.b +if(s!=null)s.K() +r=r.a +if(r!=null)r.K()}}, +$S:57} +A.l1.prototype={ +$1(a){var s=t.ed.a(A.on(A.a9(a.data))) +this.a.$4(s.f,s.d,s.c,s.a)}, +$S:1} +A.l2.prototype={ +$1(a){this.b.$4(!1,!1,!1,B.B) +this.c.terminate() +this.a.b=null}, +$S:1} +A.cc.prototype={ +ae(){return"WasmStorageImplementation."+this.b}} +A.bO.prototype={ +ae(){return"WebStorageApi."+this.b}} +A.i3.prototype={} +A.iS.prototype={ +kQ(){var s=this.Q.bz(this.as) +return s}, +bo(){var s=0,r=A.l(t.H),q +var $async$bo=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:q=A.dC(null,t.H) +s=2 +return A.c(q,$async$bo) +case 2:return A.j(null,r)}}) +return A.k($async$bo,r)}, +bq(a,b){return this.jd(a,b)}, +jd(a,b){var s=0,r=A.l(t.z),q=this +var $async$bq=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:q.l6(a,b) +s=!q.a?2:3 +break +case 2:s=4 +return A.c(q.bo(),$async$bq) +case 4:case 3:return A.j(null,r)}}) +return A.k($async$bq,r)}, +a7(a,b){return this.l1(a,b)}, +l1(a,b){var s=0,r=A.l(t.H),q=this +var $async$a7=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:s=2 +return A.c(q.bq(a,b),$async$a7) +case 2:return A.j(null,r)}}) +return A.k($async$a7,r)}, +aw(a,b){return this.l2(a,b)}, +l2(a,b){var s=0,r=A.l(t.S),q,p=this,o +var $async$aw=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:s=3 +return A.c(p.bq(a,b),$async$aw) +case 3:o=p.b.b +q=A.A(v.G.Number(o.a.d.sqlite3_last_insert_rowid(o.b))) +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$aw,r)}, +d9(a,b){return this.l5(a,b)}, +l5(a,b){var s=0,r=A.l(t.S),q,p=this,o +var $async$d9=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:s=3 +return A.c(p.bq(a,b),$async$d9) +case 3:o=p.b.b +q=o.a.d.sqlite3_changes(o.b) +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$d9,r)}, +av(a){return this.l_(a)}, +l_(a){var s=0,r=A.l(t.H),q=this +var $async$av=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:q.kZ(a) +s=!q.a?2:3 +break +case 2:s=4 +return A.c(q.bo(),$async$av) +case 4:case 3:return A.j(null,r)}}) +return A.k($async$av,r)}, +n(){var s=0,r=A.l(t.H),q=this +var $async$n=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:s=2 +return A.c(q.hM(),$async$n) +case 2:q.b.n() +s=3 +return A.c(q.bo(),$async$n) +case 3:return A.j(null,r)}}) +return A.k($async$n,r)}} +A.fY.prototype={ +fR(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var s +A.rc("absolute",A.f([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o],t.d4)) +s=this.a +s=s.S(a)>0&&!s.a9(a) +if(s)return a +s=this.b +return this.hb(0,s==null?A.oS():s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)}, +aF(a){var s=null +return this.fR(a,s,s,s,s,s,s,s,s,s,s,s,s,s,s)}, +hb(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){var s=A.f([b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q],t.d4) +A.rc("join",s) +return this.kE(new A.eV(s,t.eJ))}, +kD(a,b,c){var s=null +return this.hb(0,b,c,s,s,s,s,s,s,s,s,s,s,s,s,s,s)}, +kE(a){var s,r,q,p,o,n,m,l,k +for(s=a.gq(0),r=new A.eU(s,new A.jw()),q=this.a,p=!1,o=!1,n="";r.k();){m=s.gm() +if(q.a9(m)&&o){l=A.df(m,q) +k=n.charCodeAt(0)==0?n:n +n=B.a.p(k,0,q.bD(k,!0)) +l.b=n +if(q.c4(n))l.e[0]=q.gbg() +n=l.i(0)}else if(q.S(m)>0){o=!q.a9(m) +n=m}else{if(!(m.length!==0&&q.eg(m[0])))if(p)n+=q.gbg() +n+=m}p=q.c4(m)}return n.charCodeAt(0)==0?n:n}, +aM(a,b){var s=A.df(b,this.a),r=s.d,q=A.N(r).h("aY<1>") +r=A.aw(new A.aY(r,new A.jx(),q),q.h("d.E")) +s.d=r +q=s.b +if(q!=null)B.c.cY(r,0,q) +return s.d}, +by(a){var s +if(!this.iL(a))return a +s=A.df(a,this.a) +s.eC() +return s.i(0)}, +iL(a){var s,r,q,p,o,n,m,l=this.a,k=l.S(a) +if(k!==0){if(l===$.fH())for(s=0;s0)return o.by(a) +if(m.S(a)<=0||m.a9(a))a=o.aF(a) +if(m.S(a)<=0&&m.S(b)>0)throw A.b(A.pG(n+a+'" from "'+b+'".')) +s=A.df(b,m) +s.eC() +r=A.df(a,m) +r.eC() +q=s.d +if(q.length!==0&&q[0]===".")return r.i(0) +q=s.b +p=r.b +if(q!=p)q=q==null||p==null||!m.eE(q,p) +else q=!1 +if(q)return r.i(0) +for(;;){q=s.d +if(q.length!==0){p=r.d +q=p.length!==0&&m.eE(q[0],p[0])}else q=!1 +if(!q)break +B.c.d7(s.d,0) +B.c.d7(s.e,1) +B.c.d7(r.d,0) +B.c.d7(r.e,1)}q=s.d +p=q.length +if(p!==0&&q[0]==="..")throw A.b(A.pG(n+a+'" from "'+b+'".')) +q=t.N +B.c.es(r.d,0,A.b4(p,"..",!1,q)) +p=r.e +p[0]="" +B.c.es(p,1,A.b4(s.d.length,m.gbg(),!1,q)) +m=r.d +q=m.length +if(q===0)return"." +if(q>1&&B.c.gE(m)==="."){B.c.hl(r.d) +m=r.e +m.pop() +m.pop() +m.push("")}r.b="" +r.hm() +return r.i(0)}, +kW(a){return this.eH(a,null)}, +iF(a,b){var s,r,q,p,o,n,m,l,k=this +a=a +b=b +r=k.a +q=r.S(a)>0 +p=r.S(b)>0 +if(q&&!p){b=k.aF(b) +if(r.a9(a))a=k.aF(a)}else if(p&&!q){a=k.aF(a) +if(r.a9(b))b=k.aF(b)}else if(p&&q){o=r.a9(b) +n=r.a9(a) +if(o&&!n)b=k.aF(b) +else if(n&&!o)a=k.aF(a)}m=k.iG(a,b) +if(m!==B.n)return m +s=null +try{s=k.eH(b,a)}catch(l){if(A.G(l) instanceof A.eF)return B.k +else throw l}if(r.S(s)>0)return B.k +if(J.aj(s,"."))return B.J +if(J.aj(s,".."))return B.k +return J.at(s)>=3&&J.tq(s,"..")&&r.D(J.tk(s,2))?B.k:B.K}, +iG(a,b){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e=this +if(a===".")a="" +s=e.a +r=s.S(a) +q=s.S(b) +if(r!==q)return B.k +for(p=0;pq.aM(0,s).length?s:r}} +A.jw.prototype={ +$1(a){return a!==""}, +$S:3} +A.jx.prototype={ +$1(a){return a.length!==0}, +$S:3} +A.nz.prototype={ +$1(a){return a==null?"null":'"'+a+'"'}, +$S:59} +A.dJ.prototype={ +i(a){return this.a}} +A.dK.prototype={ +i(a){return this.a}} +A.kt.prototype={ +hz(a){var s=this.S(a) +if(s>0)return B.a.p(a,0,s) +return this.a9(a)?a[0]:null}, +hk(a){var s,r=null,q=a.length +if(q===0)return A.am(r,r,r,r) +s=A.jv(r,this).aM(0,a) +if(this.D(a.charCodeAt(q-1)))B.c.v(s,"") +return A.am(r,r,s,r)}, +cQ(a,b){return a===b}, +eE(a,b){return a===b}} +A.kH.prototype={ +ger(){var s=this.d +if(s.length!==0)s=B.c.gE(s)===""||B.c.gE(this.e)!=="" +else s=!1 +return s}, +hm(){var s,r,q=this +for(;;){s=q.d +if(!(s.length!==0&&B.c.gE(s)===""))break +B.c.hl(q.d) +q.e.pop()}s=q.e +r=s.length +if(r!==0)s[r-1]=""}, +eC(){var s,r,q,p,o,n=this,m=A.f([],t.s) +for(s=n.d,r=s.length,q=0,p=0;p0){s=B.a.aU(a,"\\",s+1) +if(s>0)return s}return r}if(r<3)return 0 +if(!A.rm(a.charCodeAt(0)))return 0 +if(a.charCodeAt(1)!==58)return 0 +r=a.charCodeAt(2) +if(!(r===47||r===92))return 0 +return 3}, +S(a){return this.bD(a,!1)}, +a9(a){return this.S(a)===1}, +d4(a){var s,r +if(a.gZ()!==""&&a.gZ()!=="file")throw A.b(A.J("Uri "+a.i(0)+" must have scheme 'file:'.",null)) +s=a.gaa() +if(a.gb7()===""){if(s.length>=3&&B.a.u(s,"/")&&A.ri(s,1)!=null)s=B.a.ho(s,"/","")}else s="\\\\"+a.gb7()+s +r=A.bi(s,"/","\\") +return A.oF(r,0,r.length,B.j,!1)}, +ea(a){var s,r,q=A.df(a,this),p=q.b +p.toString +if(B.a.u(p,"\\\\")){s=new A.aY(A.f(p.split("\\"),t.s),new A.m6(),t.U) +B.c.cY(q.d,0,s.gE(0)) +if(q.ger())B.c.v(q.d,"") +return A.am(s.gF(0),null,q.d,"file")}else{if(q.d.length===0||q.ger())B.c.v(q.d,"") +p=q.d +r=q.b +r.toString +r=A.bi(r,"/","") +B.c.cY(p,0,A.bi(r,"\\","")) +return A.am(null,null,q.d,"file")}}, +cQ(a,b){var s +if(a===b)return!0 +if(a===47)return b===92 +if(a===92)return b===47 +if((a^b)!==32)return!1 +s=a|32 +return s>=97&&s<=122}, +eE(a,b){var s,r +if(a===b)return!0 +s=a.length +if(s!==b.length)return!1 +for(r=0;r")).aq(0,", ")):s}return p.charCodeAt(0)==0?p:p}, +$ia5:1} +A.l9.prototype={ +$1(a){if(t.p.b(a))return"blob ("+a.length+" bytes)" +else return J.b1(a)}, +$S:60} +A.cn.prototype={} +A.h_.prototype={ +gla(){var s,r,q=this.kT("PRAGMA user_version;") +try{s=q.eP(new A.cv(B.aJ)) +r=A.A(J.j2(s).b[0]) +return r}finally{q.n()}}, +h_(a,b,c,d,e){var s,r,q,p,o,n=null,m=this.b,l=B.i.a5(e) +if(l.length>255)A.C(A.ad(e,"functionName","Must not exceed 255 bytes when utf-8 encoded")) +s=new Uint8Array(A.iV(l)) +r=c?526337:2049 +q=m.a +p=q.bZ(s,1) +s=q.d +o=A.oO(s,"dart_sqlite3_create_function_v2",[m.b,p,a.a,r,0,new A.bG(new A.jP(d),n,n)]) +s.dart_sqlite3_free(p) +if(o!==0)A.fF(this,o,n,n,n)}, +a6(a,b,c,d){return this.h_(a,b,!0,c,d)}, +n(){var s,r,q,p,o,n=this +if(n.r)return +n.r=!0 +s=n.b +r=s.b +q=s.a.d +q.dart_sqlite3_updates(r,null) +q.dart_sqlite3_commits(r,null) +q.dart_sqlite3_rollbacks(r,null) +p=s.eS() +o=p!==0?A.oR(n.a,s,p,"closing database",null,null):null +if(o!=null)throw A.b(o)}, +h4(a){var s,r,q,p=this,o=B.q +if(J.at(o)===0){if(p.r)A.C(A.B("This database has already been closed")) +r=p.b +q=r.a +s=q.bZ(B.i.a5(a),1) +q=q.d +r=A.oO(q,"sqlite3_exec",[r.b,s,0,0,0]) +q.dart_sqlite3_free(s) +if(r!==0)A.fF(p,r,"executing",a,o)}else{s=p.d5(a,!0) +try{s.h5(new A.cv(o))}finally{s.n()}}}, +iY(a,b,c,d,a0){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e=this +if(e.r)A.C(A.B("This database has already been closed")) +s=B.i.a5(a) +r=e.b +q=r.a +p=q.bt(s) +o=q.d +n=o.dart_sqlite3_malloc(4) +o=o.dart_sqlite3_malloc(4) +m=new A.lT(r,p,n,o) +l=A.f([],t.bb) +k=new A.jO(m,l) +for(r=s.length,q=q.b,j=0;j."))}, +dt(a){A:{this.i0(a.a) +break A}}, +eI(){if(!this.f){var s=this.a +s.c.d.sqlite3_reset(s.b) +this.f=!0}}, +n(){var s,r,q=this +if(!q.r){q.r=!0 +q.eI() +s=q.a +r=s.c +r.d.sqlite3_finalize(s.b) +r=r.w +if(r!=null)r.h1(s.d)}}, +eP(a){var s=this +s.fb() +s.eI() +s.dt(a) +return s.je()}, +h5(a){var s=this +s.fb() +s.eI() +s.dt(a) +s.fe()}} +A.he.prototype={ +cg(a,b){return this.d.a4(a)?1:0}, +dc(a,b){this.d.G(0,a)}, +dd(a){return $.fJ().by("/"+a)}, +aX(a,b){var s,r=a.a +if(r==null)r=A.o5(this.b,"/") +s=this.d +if(!s.a4(r))if((b&4)!==0)s.t(0,r,new A.br(new Uint8Array(0),0)) +else throw A.b(A.ca(14)) +return new A.cO(new A.is(this,r,(b&8)!==0),0)}, +df(a){}} +A.is.prototype={ +eG(a,b){var s,r=this.a.d.j(0,this.b) +if(r==null||r.b<=b)return 0 +s=Math.min(a.length,r.b-b) +B.e.M(a,0,s,J.cZ(B.e.gaS(r.a),0,r.b),b) +return s}, +da(){return this.d>=2?1:0}, +ci(){if(this.c)this.a.d.G(0,this.b)}, +ck(){return this.a.d.j(0,this.b).b}, +de(a){this.d=a}, +dg(a){}, +cl(a){var s=this.a.d,r=this.b,q=s.j(0,r) +if(q==null){s.t(0,r,new A.br(new Uint8Array(0),0)) +s.j(0,r).sl(0,a)}else q.sl(0,a)}, +dh(a){this.d=a}, +be(a,b){var s,r=this.a.d,q=this.b,p=r.j(0,q) +if(p==null){p=new A.br(new Uint8Array(0),0) +r.t(0,q,p)}s=b+a.length +if(s>p.b)p.sl(0,s) +p.ad(0,b,s,a)}} +A.jy.prototype={ +i2(){var s,r,q,p,o=A.al(t.N,t.S) +for(s=this.a,r=s.length,q=0;qq.d)throw A.b(A.ca(14)) +s=q.a.b +s===$&&A.x() +s=A.bE(s.buffer,0,null) +r=q.e +B.e.aZ(s,r,p) +s.$flags&2&&A.y(s) +s[r+o]=0}, +$S:0} +A.jG.prototype={ +$0(){var s,r=this,q=r.a.b +q===$&&A.x() +s=A.bE(q.buffer,r.b,r.c) +q=r.d +if(q!=null)A.pe(s,q.b) +else return A.pe(s,null)}, +$S:0} +A.jI.prototype={ +$0(){this.a.df(A.po(this.b,0))}, +$S:0} +A.jB.prototype={ +$0(){return this.a.ci()}, +$S:0} +A.jH.prototype={ +$0(){var s=this,r=s.a.b +r===$&&A.x() +s.b.eO(A.bE(r.buffer,s.c,s.d),A.A(v.G.Number(s.e)))}, +$S:0} +A.jM.prototype={ +$0(){var s=this,r=s.a.b +r===$&&A.x() +s.b.be(A.bE(r.buffer,s.c,s.d),A.A(v.G.Number(s.e)))}, +$S:0} +A.jK.prototype={ +$0(){return this.a.cl(A.A(v.G.Number(this.b)))}, +$S:0} +A.jJ.prototype={ +$0(){return this.a.dg(this.b)}, +$S:0} +A.jD.prototype={ +$0(){var s,r=this.b.ck(),q=this.a.b +q===$&&A.x() +q=A.bD(q.buffer,0,null) +s=B.b.O(this.c,2) +q.$flags&2&&A.y(q) +q[s]=r}, +$S:0} +A.jF.prototype={ +$0(){return this.a.de(this.b)}, +$S:0} +A.jL.prototype={ +$0(){return this.a.dh(this.b)}, +$S:0} +A.jA.prototype={ +$0(){var s,r=this.b.da(),q=this.a.b +q===$&&A.x() +q=A.bD(q.buffer,0,null) +s=B.b.O(this.c,2) +q.$flags&2&&A.y(q) +q[s]=r}, +$S:0} +A.bG.prototype={} +A.e9.prototype={ +R(a,b,c,d){var s,r=null,q={},p=A.a9(A.hm(this.a,v.G.Symbol.asyncIterator,r,r,r,r)),o=A.eP(r,r,!0,this.$ti.c) +q.a=null +s=new A.j5(q,this,p,o) +o.d=s +o.f=new A.j6(q,o,s) +return new A.ar(o,A.r(o).h("ar<1>")).R(a,b,c,d)}, +aV(a,b,c){return this.R(a,null,b,c)}} +A.j5.prototype={ +$0(){var s,r=this,q=r.c.next(),p=r.a +p.a=q +s=r.d +A.T(q,t.m).bE(new A.j7(p,r.b,s,r),s.gfS(),t.P)}, +$S:0} +A.j7.prototype={ +$1(a){var s,r,q=this,p=a.done +if(p==null)p=null +s=a.value +r=q.c +if(p===!0){r.n() +q.a.a=null}else{r.v(0,s==null?q.b.$ti.c.a(s):s) +q.a.a=null +p=r.b +if(!((p&1)!==0?(r.gaQ().e&4)!==0:(p&2)===0))q.d.$0()}}, +$S:9} +A.j6.prototype={ +$0(){var s,r +if(this.a.a==null){s=this.b +r=s.b +s=!((r&1)!==0?(s.gaQ().e&4)!==0:(r&2)===0)}else s=!1 +if(s)this.c.$0()}, +$S:0} +A.cI.prototype={ +K(){var s=0,r=A.l(t.H),q=this,p +var $async$K=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:p=q.b +if(p!=null)p.K() +p=q.c +if(p!=null)p.K() +q.c=q.b=null +return A.j(null,r)}}) +return A.k($async$K,r)}, +gm(){var s=this.a +return s==null?A.C(A.B("Await moveNext() first")):s}, +k(){var s,r,q=this,p=q.a +if(p!=null)p.continue() +p=new A.n($.h,t.k) +s=new A.a8(p,t.fa) +r=q.d +q.b=A.aI(r,"success",new A.mq(q,s),!1) +q.c=A.aI(r,"error",new A.mr(q,s),!1) +return p}} +A.mq.prototype={ +$1(a){var s,r=this.a +r.K() +s=r.$ti.h("1?").a(r.d.result) +r.a=s +this.b.P(s!=null)}, +$S:1} +A.mr.prototype={ +$1(a){var s=this.a +s.K() +s=s.d.error +if(s==null)s=a +this.b.aH(s)}, +$S:1} +A.jn.prototype={ +$1(a){this.a.P(this.c.a(this.b.result))}, +$S:1} +A.jo.prototype={ +$1(a){var s=this.b.error +if(s==null)s=a +this.a.aH(s)}, +$S:1} +A.js.prototype={ +$1(a){this.a.P(this.c.a(this.b.result))}, +$S:1} +A.jt.prototype={ +$1(a){var s=this.b.error +if(s==null)s=a +this.a.aH(s)}, +$S:1} +A.ju.prototype={ +$1(a){var s=this.b.error +if(s==null)s=a +this.a.aH(s)}, +$S:1} +A.lN.prototype={ +jV(){var s={} +s.dart=new A.lO(this).$0() +return s}, +d2(a){return this.kG(a)}, +kG(a){var s=0,r=A.l(t.m),q,p=this,o,n +var $async$d2=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:s=3 +return A.c(A.T(v.G.WebAssembly.instantiateStreaming(a,p.jV()),t.m),$async$d2) +case 3:o=c +n=o.instance.exports +if("_initialize" in n)t.g.a(n._initialize).call() +q=o.instance +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$d2,r)}} +A.lO.prototype={ +$0(){var s=this.a.a,r=A.a9(v.G.Object),q=A.a9(r.create.apply(r,[null])) +q.error_log=A.bu(s.gkJ()) +q.localtime=A.b8(s.gkH()) +q.xOpen=A.oJ(s.gls()) +q.xDelete=A.oI(s.glj()) +q.xAccess=A.dW(s.glb()) +q.xFullPathname=A.dW(s.glo()) +q.xRandomness=A.oI(s.glu()) +q.xSleep=A.b8(s.gly()) +q.xCurrentTimeInt64=A.b8(s.glh()) +q.xClose=A.bu(s.glf()) +q.xRead=A.dW(s.glw()) +q.xWrite=A.dW(s.glG()) +q.xTruncate=A.b8(s.glC()) +q.xSync=A.b8(s.glA()) +q.xFileSize=A.b8(s.glm()) +q.xLock=A.b8(s.glq()) +q.xUnlock=A.b8(s.glE()) +q.xCheckReservedLock=A.b8(s.gld()) +q.xDeviceCharacteristics=A.bu(s.gcj()) +q["dispatch_()v"]=A.bu(s.gkc()) +q["dispatch_()i"]=A.bu(s.gk7()) +q.dispatch_update=A.oJ(s.gka()) +q.dispatch_xFunc=A.dW(s.gki()) +q.dispatch_xStep=A.dW(s.gkm()) +q.dispatch_xInverse=A.dW(s.gkk()) +q.dispatch_xValue=A.b8(s.gko()) +q.dispatch_xFinal=A.b8(s.gkg()) +q.dispatch_compare=A.oJ(s.gke()) +q.dispatch_busy=A.b8(s.gk5()) +q.changeset_apply_filter=A.b8(s.gk_()) +q.changeset_apply_conflict=A.oI(s.gjY()) +return q}, +$S:82} +A.i5.prototype={} +A.du.prototype={ +ja(a,b){var s,r,q=this.e +q.ht(b) +s=this.d.b +r=v.G +r.Atomics.store(s,1,-1) +r.Atomics.store(s,0,a.a) +A.tu(s,0) +r.Atomics.wait(s,1,-1) +s=r.Atomics.load(s,1) +if(s!==0)throw A.b(A.ca(s)) +return a.d.$1(q)}, +a2(a,b){var s=t.cb +return this.ja(a,b,s,s)}, +cg(a,b){return this.a2(B.a5,new A.aV(a,b,0,0)).a}, +dc(a,b){this.a2(B.a6,new A.aV(a,b,0,0))}, +dd(a){var s=this.r.aF(a) +if($.j0().iF("/",s)!==B.K)throw A.b(B.a0) +return s}, +aX(a,b){var s=a.a,r=this.a2(B.ah,new A.aV(s==null?A.o5(this.b,"/"):s,b,0,0)) +return new A.cO(new A.i4(this,r.b),r.a)}, +df(a){this.a2(B.ab,new A.P(B.b.J(a.a,1000),0,0))}, +n(){this.a2(B.a7,B.h)}} +A.i4.prototype={ +gcj(){return 2048}, +eG(a,b){var s,r,q,p,o,n,m,l,k,j,i=a.length +for(s=this.a,r=this.b,q=s.e.a,p=v.G,o=t.Z,n=0;i>0;){m=Math.min(65536,i) +i-=m +l=s.a2(B.af,new A.P(r,b+n,m)).a +k=p.Uint8Array +j=[q] +j.push(0) +j.push(l) +A.hm(a,"set",o.a(A.e1(k,j)),n,null,null) +n+=l +if(l0;){o=Math.min(65536,n) +A.hm(r,"set",o===n&&p===0?a:J.cZ(B.e.gaS(a),a.byteOffset+p,o),0,null,null) +s.a2(B.aa,new A.P(q,b+p,o)) +p+=o +n-=o}}} +A.kP.prototype={} +A.bp.prototype={ +ht(a){var s,r +if(!(a instanceof A.b2))if(a instanceof A.P){s=this.b +s.$flags&2&&A.y(s,8) +s.setInt32(0,a.a,!1) +s.setInt32(4,a.b,!1) +s.setInt32(8,a.c,!1) +if(a instanceof A.aV){r=B.i.a5(a.d) +s.setInt32(12,r.length,!1) +B.e.aZ(this.c,16,r)}}else throw A.b(A.a3("Message "+a.i(0)))}} +A.ac.prototype={ +ae(){return"WorkerOperation."+this.b}} +A.bC.prototype={} +A.b2.prototype={} +A.P.prototype={} +A.aV.prototype={} +A.iE.prototype={} +A.eT.prototype={ +bQ(a,b){return this.j7(a,b)}, +fC(a){return this.bQ(a,!1)}, +j7(a,b){var s=0,r=A.l(t.eg),q,p=this,o,n,m,l,k,j,i,h,g +var $async$bQ=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:j=$.fJ() +i=j.eH(a,"/") +h=j.aM(0,i) +g=h.length +j=g>=1 +o=null +if(j){n=g-1 +m=B.c.a0(h,0,n) +o=h[n]}else m=null +if(!j)throw A.b(A.B("Pattern matching error")) +l=p.c +j=m.length,n=t.m,k=0 +case 3:if(!(k") +l=A.aw(new A.bB(j,m),m.h("d.E")) +B.c.hG(l) +s=3 +return A.c(A.o4(new A.E(l,new A.j9(new A.ja(o,a),b),A.N(l).h("E<1,D<~>>")),t.H),$async$b5) +case 3:s=b.c!==n.length?4:5 +break +case 4:k=new A.cI(p.objectStore("files").openCursor(a),t.V) +s=6 +return A.c(k.k(),$async$b5) +case 6:s=7 +return A.c(A.bl(k.gm().update({name:n.name,length:b.c}),t.X),$async$b5) +case 7:case 5:return A.j(null,r)}}) +return A.k($async$b5,r)}, +bd(a,b,c){return this.l8(0,b,c)}, +l8(a,b,c){var s=0,r=A.l(t.H),q=this,p,o,n,m,l,k +var $async$bd=A.m(function(d,e){if(d===1)return A.i(e,r) +for(;;)switch(s){case 0:k=q.a +k.toString +p=k.transaction($.nT(),"readwrite") +o=p.objectStore("files") +n=p.objectStore("blocks") +s=2 +return A.c(q.e_(p,b),$async$bd) +case 2:m=e +s=m.length>c?3:4 +break +case 3:s=5 +return A.c(A.bl(n.delete(q.j_(b,B.b.J(c,4096)*4096+1)),t.X),$async$bd) +case 5:case 4:l=new A.cI(o.openCursor(b),t.V) +s=6 +return A.c(l.k(),$async$bd) +case 6:s=7 +return A.c(A.bl(l.gm().update({name:m.name,length:c}),t.X),$async$bd) +case 7:return A.j(null,r)}}) +return A.k($async$bd,r)}, +cT(a){return this.jX(a)}, +jX(a){var s=0,r=A.l(t.H),q=this,p,o,n +var $async$cT=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:n=q.a +n.toString +p=n.transaction(A.f(["files","blocks"],t.s),"readwrite") +o=q.dZ(a,9007199254740992,0) +n=t.X +s=2 +return A.c(A.o4(A.f([A.bl(p.objectStore("blocks").delete(o),n),A.bl(p.objectStore("files").delete(a),n)],t.fG),t.H),$async$cT) +case 2:return A.j(null,r)}}) +return A.k($async$cT,r)}} +A.jb.prototype={ +$1(a){var s=A.a9(this.a.result) +if(J.aj(a.oldVersion,0)){s.createObjectStore("files",{autoIncrement:!0}).createIndex("fileName","name",{unique:!0}) +s.createObjectStore("blocks")}}, +$S:9} +A.j8.prototype={ +$1(a){if(a==null)throw A.b(A.ad(this.a,"fileId","File not found in database")) +else return a}, +$S:84} +A.jc.prototype={ +$0(){var s=0,r=A.l(t.H),q=this,p,o +var $async$$0=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:p=q.a +s=A.ku(p.value,"Blob")?2:4 +break +case 2:s=5 +return A.c(A.kO(A.a9(p.value)),$async$$0) +case 5:s=3 +break +case 4:b=t.v.a(p.value) +case 3:o=b +B.e.aZ(q.b,q.c,J.cZ(o,0,q.d)) +return A.j(null,r)}}) +return A.k($async$$0,r)}, +$S:2} +A.ja.prototype={ +hv(a,b){var s=0,r=A.l(t.H),q=this,p,o,n,m,l,k +var $async$$2=A.m(function(c,d){if(c===1)return A.i(d,r) +for(;;)switch(s){case 0:p=q.a +o=q.b +n=t.n +s=2 +return A.c(A.bl(p.openCursor(v.G.IDBKeyRange.only(A.f([o,a],n))),t.A),$async$$2) +case 2:m=d +l=t.v.a(B.e.gaS(b)) +k=t.X +s=m==null?3:5 +break +case 3:s=6 +return A.c(A.bl(p.put(l,A.f([o,a],n)),k),$async$$2) +case 6:s=4 +break +case 5:s=7 +return A.c(A.bl(m.update(l),k),$async$$2) +case 7:case 4:return A.j(null,r)}}) +return A.k($async$$2,r)}, +$2(a,b){return this.hv(a,b)}, +$S:85} +A.j9.prototype={ +$1(a){var s=this.b.b.j(0,a) +s.toString +return this.a.$2(a,s)}, +$S:86} +A.mB.prototype={ +jt(a,b,c){B.e.aZ(this.b.hj(a,new A.mC(this,a)),b,c)}, +jL(a,b){var s,r,q,p,o,n,m,l +for(s=b.length,r=0;rp)B.e.aZ(s,0,J.cZ(B.e.gaS(r),r.byteOffset+p,Math.min(4096,q-p))) +return s}, +$S:120} +A.iA.prototype={} +A.d5.prototype={ +bV(a){var s=this +if(s.e||s.d.a==null)A.C(A.ca(10)) +if(a.eu(s.w)){s.fH() +return a.d.a}else return A.bc(null,t.H)}, +fH(){var s,r,q=this +if(q.f==null&&!q.w.gB(0)){s=q.w +r=q.f=s.gF(0) +s.G(0,r) +r.d.P(A.tS(r.gd8(),t.H).ai(new A.ko(q)))}}, +n(){var s=0,r=A.l(t.H),q,p=this,o,n +var $async$n=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:if(!p.e){o=p.bV(new A.dB(p.d.gb6(),new A.a8(new A.n($.h,t.D),t.F))) +p.e=!0 +q=o +s=1 +break}else{n=p.w +if(!n.gB(0)){q=n.gE(0).d.a +s=1 +break}}case 1:return A.j(q,r)}}) +return A.k($async$n,r)}, +bn(a){return this.it(a)}, +it(a){var s=0,r=A.l(t.S),q,p=this,o,n +var $async$bn=A.m(function(b,c){if(b===1)return A.i(c,r) +for(;;)switch(s){case 0:n=p.y +s=n.a4(a)?3:5 +break +case 3:n=n.j(0,a) +n.toString +q=n +s=1 +break +s=4 +break +case 5:s=6 +return A.c(p.d.cV(a),$async$bn) +case 6:o=c +o.toString +n.t(0,a,o) +q=o +s=1 +break +case 4:case 1:return A.j(q,r)}}) +return A.k($async$bn,r)}, +bO(){var s=0,r=A.l(t.H),q=this,p,o,n,m,l,k,j,i,h,g +var $async$bO=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:h=q.d +s=2 +return A.c(h.d1(),$async$bO) +case 2:g=b +q.y.aG(0,g) +p=g.gcU(),p=p.gq(p),o=q.r.d +case 3:if(!p.k()){s=4 +break}n=p.gm() +m=n.a +l=n.b +k=new A.br(new Uint8Array(0),0) +s=5 +return A.c(h.bB(l),$async$bO) +case 5:j=b +n=j.length +k.sl(0,n) +i=k.b +if(n>i)A.C(A.S(n,0,i,null,null)) +B.e.M(k.a,0,n,j,0) +o.t(0,m,k) +s=3 +break +case 4:return A.j(null,r)}}) +return A.k($async$bO,r)}, +cg(a,b){return this.r.d.a4(a)?1:0}, +dc(a,b){var s=this +s.r.d.G(0,a) +if(!s.x.G(0,a))s.bV(new A.dz(s,a,new A.a8(new A.n($.h,t.D),t.F)))}, +dd(a){return $.fJ().by("/"+a)}, +aX(a,b){var s,r,q,p=this,o=a.a +if(o==null)o=A.o5(p.b,"/") +s=p.r +r=s.d.a4(o)?1:0 +q=s.aX(new A.eL(o),b) +if(r===0)if((b&8)!==0)p.x.v(0,o) +else p.bV(new A.cH(p,o,new A.a8(new A.n($.h,t.D),t.F))) +return new A.cO(new A.it(p,q.a,o),0)}, +df(a){}} +A.ko.prototype={ +$0(){var s=this.a +s.f=null +s.fH()}, +$S:5} +A.it.prototype={ +eO(a,b){this.b.eO(a,b)}, +gcj(){return 0}, +da(){return this.b.d>=2?1:0}, +ci(){}, +ck(){return this.b.ck()}, +de(a){this.b.d=a +return null}, +dg(a){}, +cl(a){var s=this,r=s.a +if(r.e||r.d.a==null)A.C(A.ca(10)) +s.b.cl(a) +if(!r.x.I(0,s.c))r.bV(new A.dB(new A.mQ(s,a),new A.a8(new A.n($.h,t.D),t.F)))}, +dh(a){this.b.d=a +return null}, +be(a,b){var s,r,q,p,o,n,m=this,l=m.a +if(l.e||l.d.a==null)A.C(A.ca(10)) +s=m.c +if(l.x.I(0,s)){m.b.be(a,b) +return}r=l.r.d.j(0,s) +if(r==null)r=new A.br(new Uint8Array(0),0) +q=J.cZ(B.e.gaS(r.a),0,r.b) +m.b.be(a,b) +p=new Uint8Array(a.length) +B.e.aZ(p,0,a) +o=A.f([],t.gQ) +n=$.h +o.push(new A.iA(b,p)) +l.bV(new A.cR(l,s,q,o,new A.a8(new A.n(n,t.D),t.F)))}, +$iaH:1} +A.mQ.prototype={ +$0(){var s=0,r=A.l(t.H),q,p=this,o,n,m +var $async$$0=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:o=p.a +n=o.a +m=n.d +s=3 +return A.c(n.bn(o.c),$async$$0) +case 3:q=m.bd(0,b,p.b) +s=1 +break +case 1:return A.j(q,r)}}) +return A.k($async$$0,r)}, +$S:2} +A.as.prototype={ +eu(a){a.dT(a.c,this,!1) +return!0}} +A.dB.prototype={ +U(){return this.w.$0()}} +A.dz.prototype={ +eu(a){var s,r,q,p +if(!a.gB(0)){s=a.gE(0) +for(r=this.x;s!=null;)if(s instanceof A.dz)if(s.x===r)return!1 +else s=s.gc8() +else if(s instanceof A.cR){q=s.gc8() +if(s.x===r){p=s.a +p.toString +p.e4(A.r(s).h("aL.E").a(s))}s=q}else if(s instanceof A.cH){if(s.x===r){r=s.a +r.toString +r.e4(A.r(s).h("aL.E").a(s)) +return!1}s=s.gc8()}else break}a.dT(a.c,this,!1) +return!0}, +U(){var s=0,r=A.l(t.H),q=this,p,o,n +var $async$U=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:p=q.w +o=q.x +s=2 +return A.c(p.bn(o),$async$U) +case 2:n=b +p.y.G(0,o) +s=3 +return A.c(p.d.cT(n),$async$U) +case 3:return A.j(null,r)}}) +return A.k($async$U,r)}} +A.cH.prototype={ +U(){var s=0,r=A.l(t.H),q=this,p,o,n,m +var $async$U=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:p=q.w +o=q.x +n=p.y +m=o +s=2 +return A.c(p.d.cR(o),$async$U) +case 2:n.t(0,m,b) +return A.j(null,r)}}) +return A.k($async$U,r)}} +A.cR.prototype={ +eu(a){var s,r=a.b===0?null:a.gE(0) +for(s=this.x;r!=null;)if(r instanceof A.cR)if(r.x===s){B.c.aG(r.z,this.z) +return!1}else r=r.gc8() +else if(r instanceof A.cH){if(r.x===s)break +r=r.gc8()}else break +a.dT(a.c,this,!1) +return!0}, +U(){var s=0,r=A.l(t.H),q=this,p,o,n,m,l,k +var $async$U=A.m(function(a,b){if(a===1)return A.i(b,r) +for(;;)switch(s){case 0:m=q.y +l=new A.mB(m,A.al(t.S,t.p),m.length) +for(m=q.z,p=m.length,o=0;o=2?1:0}, +ci(){var s=this +s.c.flush() +if(s.d)s.a.dU(s.b,!1)}, +ck(){return this.c.getSize()}, +de(a){this.e=a}, +dg(a){this.c.flush()}, +cl(a){this.c.truncate(a)}, +dh(a){this.e=a}, +be(a,b){if(A.o3(this.c,a,{at:b})")),null)}, +i(a){var s=this.a,r=A.N(s) +return new A.E(s,new A.jg(new A.E(s,new A.jh(),r.h("E<1,a>")).em(0,0,B.w)),r.h("E<1,o>")).aq(0,u.q)}, +$iY:1} +A.jd.prototype={ +$1(a){return a.length!==0}, +$S:3} +A.ji.prototype={ +$1(a){return a.gc0()}, +$S:89} +A.jh.prototype={ +$1(a){var s=a.gc0() +return new A.E(s,new A.jf(),A.N(s).h("E<1,a>")).em(0,0,B.w)}, +$S:90} +A.jf.prototype={ +$1(a){return a.gbx().length}, +$S:36} +A.jg.prototype={ +$1(a){var s=a.gc0() +return new A.E(s,new A.je(this.a),A.N(s).h("E<1,o>")).c2(0)}, +$S:92} +A.je.prototype={ +$1(a){return B.a.hg(a.gbx(),this.a)+" "+A.t(a.geA())+"\n"}, +$S:22} +A.L.prototype={ +gey(){var s=this.a +if(s.gZ()==="data")return"data:..." +return $.j0().kU(s)}, +gbx(){var s,r=this,q=r.b +if(q==null)return r.gey() +s=r.c +if(s==null)return r.gey()+" "+A.t(q) +return r.gey()+" "+A.t(q)+":"+A.t(s)}, +i(a){return this.gbx()+" in "+A.t(this.d)}, +geA(){return this.d}} +A.kf.prototype={ +$0(){var s,r,q,p,o,n,m,l=null,k=this.a +if(k==="...")return new A.L(A.am(l,l,l,l),l,l,"...") +s=$.td().a8(k) +if(s==null)return new A.bs(A.am(l,"unparsed",l,l),k) +k=s.b +r=k[1] +r.toString +q=$.rX() +r=A.bi(r,q,"") +p=A.bi(r,"","") +r=k[2] +q=r +q.toString +if(B.a.u(q,"1?A.bh(n[1],l):l +return new A.L(o,m,k>2?A.bh(n[2],l):l,p)}, +$S:12} +A.kd.prototype={ +$0(){var s,r,q,p,o,n="",m=this.a,l=$.tc().a8(m) +if(l!=null){s=l.aK("member") +m=l.aK("uri") +m.toString +r=A.hd(m) +m=l.aK("index") +m.toString +q=l.aK("offset") +q.toString +p=A.bh(q,16) +if(!(s==null))m=s +return new A.L(r,1,p+1,m)}l=$.t8().a8(m) +if(l!=null){m=new A.ke(m) +q=l.b +o=q[2] +if(o!=null){o=o +o.toString +q=q[1] +q.toString +q=A.bi(q,"",n) +q=A.bi(q,"Anonymous function",n) +return m.$2(o,A.bi(q,"(anonymous function)",n))}else{q=q[3] +q.toString +return m.$2(q,n)}}return new A.bs(A.am(null,"unparsed",null,null),m)}, +$S:12} +A.ke.prototype={ +$2(a,b){var s,r,q,p,o,n=null,m=$.t7(),l=m.a8(a) +for(;l!=null;a=s){s=l.b[1] +s.toString +l=m.a8(s)}if(a==="native")return new A.L(A.bt("native"),n,n,b) +r=$.t9().a8(a) +if(r==null)return new A.bs(A.am(n,"unparsed",n,n),this.a) +m=r.b +s=m[1] +s.toString +q=A.hd(s) +s=m[2] +s.toString +p=A.bh(s,n) +o=m[3] +return new A.L(q,p,o!=null?A.bh(o,n):n,b)}, +$S:95} +A.ka.prototype={ +$0(){var s,r,q,p,o=null,n=this.a,m=$.rY().a8(n) +if(m==null)return new A.bs(A.am(o,"unparsed",o,o),n) +n=m.b +s=n[1] +s.toString +r=A.bi(s,"/<","") +s=n[2] +s.toString +q=A.hd(s) +n=n[3] +n.toString +p=A.bh(n,o) +return new A.L(q,p,o,r.length===0||r==="anonymous"?"":r)}, +$S:12} +A.kb.prototype={ +$0(){var s,r,q,p,o,n,m,l,k=null,j=this.a,i=$.t_().a8(j) +if(i!=null){s=i.b +r=s[3] +q=r +q.toString +if(B.a.I(q," line "))return A.tK(j) +j=r +j.toString +p=A.hd(j) +o=s[1] +if(o!=null){j=s[2] +j.toString +o+=B.c.c2(A.b4(B.a.eb("/",j).gl(0),".",!1,t.N)) +if(o==="")o="" +o=B.a.ho(o,$.t4(),"")}else o="" +j=s[4] +if(j==="")n=k +else{j=j +j.toString +n=A.bh(j,k)}j=s[5] +if(j==null||j==="")m=k +else{j=j +j.toString +m=A.bh(j,k)}return new A.L(p,n,m,o)}i=$.t1().a8(j) +if(i!=null){j=i.aK("member") +j.toString +s=i.aK("uri") +s.toString +p=A.hd(s) +s=i.aK("index") +s.toString +r=i.aK("offset") +r.toString +l=A.bh(r,16) +if(!(j.length!==0))j=s +return new A.L(p,1,l+1,j)}i=$.t5().a8(j) +if(i!=null){j=i.aK("member") +j.toString +return new A.L(A.am(k,"wasm code",k,k),k,k,j)}return new A.bs(A.am(k,"unparsed",k,k),j)}, +$S:12} +A.kc.prototype={ +$0(){var s,r,q,p,o=null,n=this.a,m=$.t2().a8(n) +if(m==null)throw A.b(A.af("Couldn't parse package:stack_trace stack trace line '"+n+"'.",o,o)) +n=m.b +s=n[1] +if(s==="data:...")r=A.q9("") +else{s=s +s.toString +r=A.bt(s)}if(r.gZ()===""){s=$.j0() +r=s.hs(s.fR(s.a.d4(A.oM(r)),o,o,o,o,o,o,o,o,o,o,o,o,o,o))}s=n[2] +if(s==null)q=o +else{s=s +s.toString +q=A.bh(s,o)}s=n[3] +if(s==null)p=o +else{s=s +s.toString +p=A.bh(s,o)}return new A.L(r,q,p,n[4])}, +$S:12} +A.hp.prototype={ +gfP(){var s,r=this,q=r.b +if(q===$){s=r.a.$0() +r.b!==$&&A.p4() +r.b=s +q=s}return q}, +gc0(){return this.gfP().gc0()}, +i(a){return this.gfP().i(0)}, +$iY:1, +$iZ:1} +A.Z.prototype={ +i(a){var s=this.a,r=A.N(s) +return new A.E(s,new A.ls(new A.E(s,new A.lt(),r.h("E<1,a>")).em(0,0,B.w)),r.h("E<1,o>")).c2(0)}, +$iY:1, +gc0(){return this.a}} +A.lq.prototype={ +$0(){return A.q5(this.a.i(0))}, +$S:96} +A.lr.prototype={ +$1(a){return a.length!==0}, +$S:3} +A.lp.prototype={ +$1(a){return!B.a.u(a,$.tb())}, +$S:3} +A.lo.prototype={ +$1(a){return a!=="\tat "}, +$S:3} +A.lm.prototype={ +$1(a){return a.length!==0&&a!=="[native code]"}, +$S:3} +A.ln.prototype={ +$1(a){return!B.a.u(a,"=====")}, +$S:3} +A.lt.prototype={ +$1(a){return a.gbx().length}, +$S:36} +A.ls.prototype={ +$1(a){if(a instanceof A.bs)return a.i(0)+"\n" +return B.a.hg(a.gbx(),this.a)+" "+A.t(a.geA())+"\n"}, +$S:22} +A.bs.prototype={ +i(a){return this.w}, +$iL:1, +gbx(){return"unparsed"}, +geA(){return this.w}} +A.ef.prototype={} +A.f1.prototype={ +R(a,b,c,d){var s,r=this.b +if(r.d){a=null +d=null}s=this.a.R(a,b,c,d) +if(!r.d)r.c=s +return s}, +aV(a,b,c){return this.R(a,null,b,c)}, +ez(a,b){return this.R(a,null,b,null)}} +A.f0.prototype={ +n(){var s,r=this.hJ(),q=this.b +q.d=!0 +s=q.c +if(s!=null){s.c6(null) +s.eD(null)}return r}} +A.ep.prototype={ +ghI(){var s=this.b +s===$&&A.x() +return new A.ar(s,A.r(s).h("ar<1>"))}, +ghE(){var s=this.a +s===$&&A.x() +return s}, +hQ(a,b,c,d){var s=this,r=$.h +s.a!==$&&A.j_() +s.a=new A.f9(a,s,new A.a6(new A.n(r,t.D),t.h),!0) +r=A.eP(null,new A.km(c,s),!0,d) +s.b!==$&&A.j_() +s.b=r}, +iU(){var s,r +this.d=!0 +s=this.c +if(s!=null)s.K() +r=this.b +r===$&&A.x() +r.n()}} +A.km.prototype={ +$0(){var s,r,q=this.b +if(q.d)return +s=this.a.a +r=q.b +r===$&&A.x() +q.c=s.aV(r.gjJ(r),new A.kl(q),r.gfS())}, +$S:0} +A.kl.prototype={ +$0(){var s=this.a,r=s.a +r===$&&A.x() +r.iV() +s=s.b +s===$&&A.x() +s.n()}, +$S:0} +A.f9.prototype={ +v(a,b){if(this.e)throw A.b(A.B("Cannot add event after closing.")) +if(this.d)return +this.a.a.v(0,b)}, +a3(a,b){if(this.e)throw A.b(A.B("Cannot add event after closing.")) +if(this.d)return +this.iw(a,b)}, +iw(a,b){this.a.a.a3(a,b) +return}, +n(){var s=this +if(s.e)return s.c.a +s.e=!0 +if(!s.d){s.b.iU() +s.c.P(s.a.a.n())}return s.c.a}, +iV(){this.d=!0 +var s=this.c +if((s.a.a&30)===0)s.aT() +return}, +$iae:1} +A.hO.prototype={} +A.eO.prototype={} +A.dq.prototype={ +gl(a){return this.b}, +j(a,b){if(b>=this.b)throw A.b(A.px(b,this)) +return this.a[b]}, +t(a,b,c){var s +if(b>=this.b)throw A.b(A.px(b,this)) +s=this.a +s.$flags&2&&A.y(s) +s[b]=c}, +sl(a,b){var s,r,q,p,o=this,n=o.b +if(bn){if(n===0)p=new Uint8Array(b) +else p=o.ie(b) +B.e.ad(p,0,o.b,o.a) +o.a=p}}o.b=b}, +ie(a){var s=this.a.length*2 +if(a!=null&&ss)throw A.b(A.S(c,0,s,null,null)) +s=this.a +if(d instanceof A.br)B.e.M(s,b,c,d.a,e) +else B.e.M(s,b,c,d,e)}, +ad(a,b,c,d){return this.M(0,b,c,d,0)}} +A.iu.prototype={} +A.br.prototype={} +A.o2.prototype={} +A.f6.prototype={ +R(a,b,c,d){return A.aI(this.a,this.b,a,!1)}, +aV(a,b,c){return this.R(a,null,b,c)}} +A.im.prototype={ +K(){var s=this,r=A.bc(null,t.H) +if(s.b==null)return r +s.e5() +s.d=s.b=null +return r}, +c6(a){var s,r=this +if(r.b==null)throw A.b(A.B("Subscription has been canceled.")) +r.e5() +if(a==null)s=null +else{s=A.rd(new A.mz(a),t.m) +s=s==null?null:A.bu(s)}r.d=s +r.e3()}, +eD(a){}, +bA(){if(this.b==null)return;++this.a +this.e5()}, +ba(){var s=this +if(s.b==null||s.a<=0)return;--s.a +s.e3()}, +e3(){var s=this,r=s.d +if(r!=null&&s.a<=0)s.b.addEventListener(s.c,r,!1)}, +e5(){var s=this.d +if(s!=null)this.b.removeEventListener(this.c,s,!1)}} +A.my.prototype={ +$1(a){return this.a.$1(a)}, +$S:1} +A.mz.prototype={ +$1(a){return this.a.$1(a)}, +$S:1};(function aliases(){var s=J.bY.prototype +s.hL=s.i +s=A.cF.prototype +s.hN=s.bH +s=A.ag.prototype +s.dm=s.bm +s.bj=s.bk +s.eV=s.ct +s=A.fo.prototype +s.hO=s.ec +s=A.v.prototype +s.eU=s.M +s=A.d.prototype +s.hK=s.hF +s=A.d2.prototype +s.hJ=s.n +s=A.cA.prototype +s.hM=s.n})();(function installTearOffs(){var s=hunkHelpers._static_2,r=hunkHelpers._static_1,q=hunkHelpers._static_0,p=hunkHelpers.installStaticTearOff,o=hunkHelpers._instance_0u,n=hunkHelpers.installInstanceTearOff,m=hunkHelpers._instance_2u,l=hunkHelpers._instance_1i,k=hunkHelpers._instance_1u +s(J,"vJ","tX",97) +r(A,"wl","uD",16) +r(A,"wm","uE",16) +r(A,"wn","uF",16) +q(A,"rg","we",0) +r(A,"wo","vX",14) +s(A,"wp","vZ",6) +q(A,"rf","vY",0) +p(A,"wv",5,null,["$5"],["w7"],98,0) +p(A,"wA",4,null,["$1$4","$4"],["nu",function(a,b,c,d){return A.nu(a,b,c,d,t.z)}],99,0) +p(A,"wC",5,null,["$2$5","$5"],["nw",function(a,b,c,d,e){var i=t.z +return A.nw(a,b,c,d,e,i,i)}],100,0) +p(A,"wB",6,null,["$3$6","$6"],["nv",function(a,b,c,d,e,f){var i=t.z +return A.nv(a,b,c,d,e,f,i,i,i)}],101,0) +p(A,"wy",4,null,["$1$4","$4"],["r6",function(a,b,c,d){return A.r6(a,b,c,d,t.z)}],102,0) +p(A,"wz",4,null,["$2$4","$4"],["r7",function(a,b,c,d){var i=t.z +return A.r7(a,b,c,d,i,i)}],103,0) +p(A,"wx",4,null,["$3$4","$4"],["r5",function(a,b,c,d){var i=t.z +return A.r5(a,b,c,d,i,i,i)}],104,0) +p(A,"wt",5,null,["$5"],["w6"],105,0) +p(A,"wD",4,null,["$4"],["nx"],106,0) +p(A,"ws",5,null,["$5"],["w5"],107,0) +p(A,"wr",5,null,["$5"],["w4"],108,0) +p(A,"ww",4,null,["$4"],["w8"],109,0) +r(A,"wq","w0",110) +p(A,"wu",5,null,["$5"],["r4"],111,0) +var j +o(j=A.cG.prototype,"gbL","ak",0) +o(j,"gbM","al",0) +n(A.dx.prototype,"gjT",0,1,null,["$2","$1"],["bv","aH"],27,0,0) +m(A.n.prototype,"gdB","i6",6) +l(j=A.cP.prototype,"gjJ","v",7) +n(j,"gfS",0,1,null,["$2","$1"],["a3","jK"],27,0,0) +o(j=A.cf.prototype,"gbL","ak",0) +o(j,"gbM","al",0) +o(j=A.ag.prototype,"gbL","ak",0) +o(j,"gbM","al",0) +o(A.f3.prototype,"gfp","iT",0) +k(j=A.dO.prototype,"giN","iO",7) +m(j,"giR","iS",6) +o(j,"giP","iQ",0) +o(j=A.dA.prototype,"gbL","ak",0) +o(j,"gbM","al",0) +k(j,"gdM","dN",7) +m(j,"gdQ","dR",76) +o(j,"gdO","dP",0) +o(j=A.dL.prototype,"gbL","ak",0) +o(j,"gbM","al",0) +k(j,"gdM","dN",7) +m(j,"gdQ","dR",6) +o(j,"gdO","dP",0) +k(A.dM.prototype,"gjP","ec","V<2>(e?)") +r(A,"wH","uz",8) +p(A,"x8",2,null,["$1$2","$2"],["ro",function(a,b){return A.ro(a,b,t.o)}],112,0) +r(A,"xa","xh",4) +r(A,"x9","xg",4) +r(A,"x7","wI",4) +r(A,"xb","xn",4) +r(A,"x4","wj",4) +r(A,"x5","wk",4) +r(A,"x6","wE",4) +k(A.ek.prototype,"giz","iA",7) +k(A.h4.prototype,"gig","dE",15) +k(A.i6.prototype,"gjv","cD",15) +r(A,"yz","qW",20) +r(A,"yx","qU",20) +r(A,"yy","qV",20) +r(A,"rq","w_",25) +r(A,"rr","w2",115) +r(A,"rp","vz",116) +k(j=A.fZ.prototype,"gkJ","kK",10) +m(j,"gkH","kI",63) +n(j,"gls",0,5,null,["$5"],["lt"],64,0,0) +n(j,"glj",0,3,null,["$3"],["lk"],65,0,0) +n(j,"glb",0,4,null,["$4"],["lc"],30,0,0) +n(j,"glo",0,4,null,["$4"],["lp"],30,0,0) +n(j,"glu",0,3,null,["$3"],["lv"],67,0,0) +m(j,"gly","lz",31) +m(j,"glh","li",31) +k(j,"glf","lg",32) +n(j,"glw",0,4,null,["$4"],["lx"],33,0,0) +n(j,"glG",0,4,null,["$4"],["lH"],33,0,0) +m(j,"glC","lD",71) +m(j,"glA","lB",11) +m(j,"glm","ln",11) +m(j,"glq","lr",11) +m(j,"glE","lF",11) +m(j,"gld","le",11) +k(j,"gcj","ll",32) +k(j,"gkc","kd",16) +k(j,"gk7","k8",74) +n(j,"gka",0,5,null,["$5"],["kb"],75,0,0) +n(j,"gki",0,4,null,["$4"],["kj"],19,0,0) +n(j,"gkm",0,4,null,["$4"],["kn"],19,0,0) +n(j,"gkk",0,4,null,["$4"],["kl"],19,0,0) +m(j,"gko","kp",34) +m(j,"gkg","kh",34) +n(j,"gke",0,5,null,["$5"],["kf"],78,0,0) +m(j,"gk5","k6",79) +m(j,"gk_","k0",121) +n(j,"gjY",0,3,null,["$3"],["jZ"],81,0,0) +o(A.du.prototype,"gb6","n",0) +r(A,"bS","u4",117) +r(A,"b9","u5",118) +r(A,"p3","u6",119) +k(A.eT.prototype,"gj1","j2",83) +o(A.fP.prototype,"gb6","n",0) +o(A.d5.prototype,"gb6","n",2) +o(A.dB.prototype,"gd8","U",0) +o(A.dz.prototype,"gd8","U",2) +o(A.cH.prototype,"gd8","U",2) +o(A.cR.prototype,"gd8","U",2) +o(A.dm.prototype,"gb6","n",0) +r(A,"wQ","tR",13) +r(A,"rj","tQ",13) +r(A,"wO","tO",13) +r(A,"wP","tP",13) +r(A,"xr","us",35) +r(A,"xq","ur",35)})();(function inheritance(){var s=hunkHelpers.mixin,r=hunkHelpers.inherit,q=hunkHelpers.inheritMany +r(A.e,null) +q(A.e,[A.o9,J.hi,A.eJ,J.fK,A.d,A.fU,A.O,A.v,A.cp,A.kR,A.b3,A.d9,A.eU,A.ha,A.hR,A.hM,A.hN,A.h7,A.i7,A.er,A.eo,A.hV,A.hQ,A.fi,A.eg,A.iw,A.lv,A.hD,A.em,A.fm,A.Q,A.kz,A.hr,A.cx,A.hq,A.cw,A.dH,A.m7,A.dp,A.n6,A.mn,A.iR,A.be,A.iq,A.nc,A.iO,A.i9,A.iM,A.U,A.V,A.ag,A.cF,A.dx,A.cg,A.n,A.ia,A.hP,A.cP,A.iN,A.ib,A.dP,A.ik,A.mw,A.fh,A.f3,A.dO,A.f5,A.dD,A.ay,A.iT,A.dU,A.iU,A.ir,A.dl,A.mT,A.dG,A.iy,A.aL,A.iz,A.cq,A.cr,A.nk,A.fy,A.a7,A.ip,A.ei,A.bx,A.mx,A.hE,A.eM,A.io,A.aD,A.hh,A.aN,A.R,A.dQ,A.aA,A.fv,A.hY,A.b6,A.hb,A.hC,A.mR,A.d2,A.h1,A.hs,A.hB,A.hW,A.ek,A.iB,A.fX,A.h5,A.h4,A.bZ,A.aO,A.bW,A.c2,A.bn,A.c4,A.bV,A.c5,A.c3,A.bF,A.bI,A.kS,A.fj,A.i6,A.bK,A.bU,A.ed,A.ao,A.ea,A.d0,A.kK,A.lu,A.jQ,A.dg,A.kL,A.eE,A.kJ,A.bo,A.jR,A.lJ,A.h6,A.dj,A.lH,A.l_,A.fY,A.dJ,A.dK,A.lk,A.kH,A.eF,A.c8,A.cn,A.h_,A.l8,A.d1,A.aq,A.fS,A.jy,A.iI,A.mW,A.cv,A.aG,A.eL,A.lR,A.lI,A.lT,A.lS,A.cb,A.bN,A.fZ,A.bG,A.cI,A.lN,A.kP,A.bp,A.bC,A.iE,A.eT,A.dI,A.fP,A.mB,A.iA,A.it,A.lC,A.bk,A.L,A.hp,A.Z,A.bs,A.eO,A.f9,A.hO,A.o2,A.im]) +q(J.hi,[J.hk,J.eu,J.ev,J.aK,J.d7,J.d6,J.bX]) +q(J.ev,[J.bY,J.u,A.db,A.eA]) +q(J.bY,[J.hF,J.cE,J.bz]) +r(J.hj,A.eJ) +r(J.kv,J.u) +q(J.d6,[J.et,J.hl]) +q(A.d,[A.ce,A.q,A.aE,A.aY,A.en,A.cD,A.bJ,A.eK,A.eV,A.by,A.cM,A.i8,A.iL,A.dR,A.ey]) +q(A.ce,[A.co,A.fz]) +r(A.f4,A.co) +r(A.f_,A.fz) +r(A.ak,A.f_) +q(A.O,[A.d8,A.bL,A.hn,A.hU,A.hJ,A.il,A.fN,A.bb,A.eR,A.hT,A.aQ,A.fW]) +q(A.v,[A.dr,A.i1,A.dt,A.dq]) +r(A.fV,A.dr) +q(A.cp,[A.jj,A.kp,A.jk,A.ll,A.nI,A.nK,A.m9,A.m8,A.nm,A.n7,A.n9,A.n8,A.kj,A.mN,A.li,A.lh,A.lf,A.ld,A.n5,A.mv,A.mu,A.n0,A.n_,A.mP,A.kD,A.mk,A.nf,A.nM,A.nQ,A.nR,A.nD,A.jX,A.jY,A.jZ,A.kX,A.kY,A.kZ,A.kV,A.m1,A.lZ,A.m_,A.lX,A.m2,A.m0,A.kM,A.k5,A.ny,A.kx,A.ky,A.kC,A.lU,A.lV,A.jT,A.l5,A.nB,A.nP,A.k_,A.kQ,A.jp,A.jq,A.jr,A.l4,A.l0,A.l3,A.l1,A.l2,A.jw,A.jx,A.nz,A.m6,A.l9,A.j7,A.mq,A.mr,A.jn,A.jo,A.js,A.jt,A.ju,A.jb,A.j8,A.j9,A.l6,A.lD,A.lE,A.lF,A.lG,A.jd,A.ji,A.jh,A.jf,A.jg,A.je,A.lr,A.lp,A.lo,A.lm,A.ln,A.lt,A.ls,A.my,A.mz]) +q(A.jj,[A.nO,A.ma,A.mb,A.nb,A.na,A.ki,A.kg,A.mE,A.mJ,A.mI,A.mG,A.mF,A.mM,A.mL,A.mK,A.lj,A.lg,A.le,A.lc,A.n4,A.n3,A.mm,A.ml,A.mU,A.np,A.nq,A.mt,A.ms,A.mZ,A.mY,A.nt,A.nj,A.ni,A.jW,A.kT,A.kU,A.kW,A.m3,A.m4,A.lY,A.nS,A.mc,A.mh,A.mf,A.mg,A.me,A.md,A.n1,A.n2,A.jV,A.jU,A.mA,A.kA,A.kB,A.lW,A.jS,A.k3,A.k0,A.k1,A.k2,A.jO,A.jC,A.jz,A.jE,A.jG,A.jI,A.jB,A.jH,A.jM,A.jK,A.jJ,A.jD,A.jF,A.jL,A.jA,A.j5,A.j6,A.lO,A.jc,A.mC,A.ko,A.mQ,A.kf,A.kd,A.ka,A.kb,A.kc,A.lq,A.km,A.kl]) +q(A.q,[A.M,A.cu,A.bB,A.ex,A.ew,A.cL,A.fb]) +q(A.M,[A.cC,A.E,A.eI]) +r(A.ct,A.aE) +r(A.el,A.cD) +r(A.d3,A.bJ) +r(A.cs,A.by) +r(A.iC,A.fi) +q(A.iC,[A.ah,A.cO,A.iD]) +r(A.eh,A.eg) +r(A.es,A.kp) +r(A.eC,A.bL) +q(A.ll,[A.lb,A.eb]) +q(A.Q,[A.bA,A.cK]) +q(A.jk,[A.kw,A.nJ,A.nn,A.nA,A.kk,A.mO,A.no,A.kn,A.kE,A.mj,A.lA,A.lM,A.lL,A.lK,A.jP,A.ja,A.ke]) +r(A.da,A.db) +q(A.eA,[A.cy,A.dd]) +q(A.dd,[A.fd,A.ff]) +r(A.fe,A.fd) +r(A.c_,A.fe) +r(A.fg,A.ff) +r(A.aW,A.fg) +q(A.c_,[A.hu,A.hv]) +q(A.aW,[A.hw,A.dc,A.hx,A.hy,A.hz,A.eB,A.c0]) +r(A.fq,A.il) +q(A.V,[A.dN,A.f8,A.eY,A.e9,A.f1,A.f6]) +r(A.ar,A.dN) +r(A.eZ,A.ar) +q(A.ag,[A.cf,A.dA,A.dL]) +r(A.cG,A.cf) +r(A.fp,A.cF) +q(A.dx,[A.a6,A.a8]) +q(A.cP,[A.dw,A.dS]) +q(A.ik,[A.dy,A.f2]) +r(A.fc,A.f8) +r(A.fo,A.hP) +r(A.dM,A.fo) +q(A.iT,[A.ii,A.iH]) +r(A.dE,A.cK) +r(A.fk,A.dl) +r(A.fa,A.fk) +q(A.cq,[A.h8,A.fQ]) +q(A.h8,[A.fL,A.i_]) +q(A.cr,[A.iQ,A.fR,A.i0]) +r(A.fM,A.iQ) +q(A.bb,[A.dh,A.eq]) +r(A.ij,A.fv) +q(A.bZ,[A.ap,A.bf,A.bm,A.bw]) +q(A.mx,[A.de,A.cB,A.c1,A.ds,A.c7,A.cz,A.cc,A.bO,A.kG,A.ac,A.d4]) +r(A.jN,A.kK) +r(A.kF,A.lu) +q(A.jQ,[A.hA,A.k4]) +q(A.ao,[A.ic,A.dF,A.ho]) +q(A.ic,[A.iP,A.h2,A.id,A.f7]) +r(A.fn,A.iP) +r(A.iv,A.dF) +r(A.cA,A.jN) +r(A.fl,A.k4) +q(A.lJ,[A.jl,A.dv,A.dk,A.di,A.eN,A.h3]) +q(A.jl,[A.c6,A.ej]) +r(A.mp,A.kL) +r(A.i3,A.h2) +r(A.iS,A.cA) +r(A.kt,A.lk) +q(A.kt,[A.kI,A.lB,A.m5]) +r(A.dn,A.d1) +r(A.fT,A.aq) +q(A.fT,[A.he,A.du,A.d5,A.dm]) +q(A.fS,[A.is,A.i4,A.iK]) +r(A.iF,A.jy) +r(A.iG,A.iF) +r(A.hI,A.iG) +r(A.iJ,A.iI) +r(A.bq,A.iJ) +r(A.i5,A.l8) +q(A.bC,[A.b2,A.P]) +r(A.aV,A.P) +r(A.as,A.aL) +q(A.as,[A.dB,A.dz,A.cH,A.cR]) +q(A.eO,[A.ef,A.ep]) +r(A.f0,A.d2) +r(A.iu,A.dq) +r(A.br,A.iu) +s(A.dr,A.hV) +s(A.fz,A.v) +s(A.fd,A.v) +s(A.fe,A.eo) +s(A.ff,A.v) +s(A.fg,A.eo) +s(A.dw,A.ib) +s(A.dS,A.iN) +s(A.iF,A.v) +s(A.iG,A.hB) +s(A.iI,A.hW) +s(A.iJ,A.Q)})() +var v={G:typeof self!="undefined"?self:globalThis,typeUniverse:{eC:new Map(),tR:{},eT:{},tPV:{},sEA:[]},mangledGlobalNames:{a:"int",F:"double",b0:"num",o:"String",K:"bool",R:"Null",p:"List",e:"Object",an:"Map",z:"JSObject"},mangledNames:{},types:["~()","~(z)","D<~>()","K(o)","F(b0)","R()","~(e,Y)","~(e?)","o(o)","R(z)","~(a)","a(aH,a)","L()","L(o)","~(@)","e?(e?)","~(~())","D()","~(z?,p?)","~(bG,a,a,a)","o(a)","@()","o(L)","K(~)","D()","b0?(p)","R(@)","~(e[Y?])","a(a)","K()","a(aq,a,a,a)","a(aq,a)","a(aH)","a(aH,a,a,aK)","~(bG,a)","Z(o)","a(L)","D()","D()","@(@,o)","R(@,Y)","a()","D()","an(p)","a(p)","@(o)","R(ao)","D(~)","~(a,@)","D<~>(ap)","a?(a)","K(a)","z(u)","dj()","D()","R(~)","~(ae)","~(K,K,K,p<+(bO,o)>)","R(e,Y)","o(o?)","o(e?)","~(oe,p)","bH?/(ap)","~(aK,a)","aH?(aq,a,a,a,a)","a(aq,a,a)","0&(o,a?)","a(aq?,a,a)","D()","bU<@>?()","ap()","a(aH,aK)","R(K)","R(~())","a(a())","~(~(a,o,a),a,a,a,aK)","~(@,Y)","bf()","a(bG,a,a,a,a)","a(a(a),a)","bn()","a(oh,a,a)","z()","~(dI)","z(z?)","D<~>(a,aX)","D<~>(a)","a(a,a)","D(o)","p(Z)","a(Z)","p(u)","o(Z)","bK(e?)","~(@,@)","L(o,o)","Z()","a(@,@)","~(w?,W?,w,e,Y)","0^(w?,W?,w,0^())","0^(w?,W?,w,0^(1^),1^)","0^(w?,W?,w,0^(1^,2^),1^,2^)","0^()(w,W,w,0^())","0^(1^)(w,W,w,0^(1^))","0^(1^,2^)(w,W,w,0^(1^,2^))","U?(w,W,w,e,Y?)","~(w?,W?,w,~())","eQ(w,W,w,bx,~())","eQ(w,W,w,bx,~(eQ))","~(w,W,w,o)","~(o)","w(w?,W?,w,oq?,an?)","0^(0^,0^)","~(e?,e?)","@(@)","K?(p)","K?(p<@>)","b2(bp)","P(bp)","aV(bp)","aX()","a(oh,a)"],interceptorsByTag:null,leafTags:null,arrayRti:Symbol("$ti"),rttc:{"2;":(a,b)=>c=>c instanceof A.ah&&a.b(c.a)&&b.b(c.b),"2;file,outFlags":(a,b)=>c=>c instanceof A.cO&&a.b(c.a)&&b.b(c.b),"2;result,resultCode":(a,b)=>c=>c instanceof A.iD&&a.b(c.a)&&b.b(c.b)}} +A.v2(v.typeUniverse,JSON.parse('{"hF":"bY","cE":"bY","bz":"bY","xC":"db","u":{"p":["1"],"q":["1"],"z":[],"d":["1"],"av":["1"]},"hk":{"K":[],"I":[]},"eu":{"R":[],"I":[]},"ev":{"z":[]},"bY":{"z":[]},"hj":{"eJ":[]},"kv":{"u":["1"],"p":["1"],"q":["1"],"z":[],"d":["1"],"av":["1"]},"d6":{"F":[],"b0":[]},"et":{"F":[],"a":[],"b0":[],"I":[]},"hl":{"F":[],"b0":[],"I":[]},"bX":{"o":[],"av":["@"],"I":[]},"ce":{"d":["2"]},"co":{"ce":["1","2"],"d":["2"],"d.E":"2"},"f4":{"co":["1","2"],"ce":["1","2"],"q":["2"],"d":["2"],"d.E":"2"},"f_":{"v":["2"],"p":["2"],"ce":["1","2"],"q":["2"],"d":["2"]},"ak":{"f_":["1","2"],"v":["2"],"p":["2"],"ce":["1","2"],"q":["2"],"d":["2"],"v.E":"2","d.E":"2"},"d8":{"O":[]},"fV":{"v":["a"],"p":["a"],"q":["a"],"d":["a"],"v.E":"a"},"q":{"d":["1"]},"M":{"q":["1"],"d":["1"]},"cC":{"M":["1"],"q":["1"],"d":["1"],"d.E":"1","M.E":"1"},"aE":{"d":["2"],"d.E":"2"},"ct":{"aE":["1","2"],"q":["2"],"d":["2"],"d.E":"2"},"E":{"M":["2"],"q":["2"],"d":["2"],"d.E":"2","M.E":"2"},"aY":{"d":["1"],"d.E":"1"},"en":{"d":["2"],"d.E":"2"},"cD":{"d":["1"],"d.E":"1"},"el":{"cD":["1"],"q":["1"],"d":["1"],"d.E":"1"},"bJ":{"d":["1"],"d.E":"1"},"d3":{"bJ":["1"],"q":["1"],"d":["1"],"d.E":"1"},"eK":{"d":["1"],"d.E":"1"},"cu":{"q":["1"],"d":["1"],"d.E":"1"},"eV":{"d":["1"],"d.E":"1"},"by":{"d":["+(a,1)"],"d.E":"+(a,1)"},"cs":{"by":["1"],"q":["+(a,1)"],"d":["+(a,1)"],"d.E":"+(a,1)"},"dr":{"v":["1"],"p":["1"],"q":["1"],"d":["1"]},"eI":{"M":["1"],"q":["1"],"d":["1"],"d.E":"1","M.E":"1"},"eg":{"an":["1","2"]},"eh":{"eg":["1","2"],"an":["1","2"]},"cM":{"d":["1"],"d.E":"1"},"eC":{"bL":[],"O":[]},"hn":{"O":[]},"hU":{"O":[]},"hD":{"a5":[]},"fm":{"Y":[]},"hJ":{"O":[]},"bA":{"Q":["1","2"],"an":["1","2"],"Q.V":"2","Q.K":"1"},"bB":{"q":["1"],"d":["1"],"d.E":"1"},"ex":{"q":["1"],"d":["1"],"d.E":"1"},"ew":{"q":["aN<1,2>"],"d":["aN<1,2>"],"d.E":"aN<1,2>"},"dH":{"hH":[],"ez":[]},"i8":{"d":["hH"],"d.E":"hH"},"dp":{"ez":[]},"iL":{"d":["ez"],"d.E":"ez"},"da":{"z":[],"ec":[],"I":[]},"cy":{"o_":[],"z":[],"I":[]},"dc":{"aW":[],"kr":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"c0":{"aW":[],"aX":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"db":{"z":[],"ec":[],"I":[]},"eA":{"z":[]},"iR":{"ec":[]},"dd":{"aU":["1"],"z":[],"av":["1"]},"c_":{"v":["F"],"p":["F"],"aU":["F"],"q":["F"],"z":[],"av":["F"],"d":["F"]},"aW":{"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"]},"hu":{"c_":[],"k8":[],"v":["F"],"p":["F"],"aU":["F"],"q":["F"],"z":[],"av":["F"],"d":["F"],"I":[],"v.E":"F"},"hv":{"c_":[],"k9":[],"v":["F"],"p":["F"],"aU":["F"],"q":["F"],"z":[],"av":["F"],"d":["F"],"I":[],"v.E":"F"},"hw":{"aW":[],"kq":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"hx":{"aW":[],"ks":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"hy":{"aW":[],"lx":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"hz":{"aW":[],"ly":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"eB":{"aW":[],"lz":[],"v":["a"],"p":["a"],"aU":["a"],"q":["a"],"z":[],"av":["a"],"d":["a"],"I":[],"v.E":"a"},"il":{"O":[]},"fq":{"bL":[],"O":[]},"U":{"O":[]},"ag":{"ag.T":"1"},"dD":{"ae":["1"]},"dR":{"d":["1"],"d.E":"1"},"eZ":{"ar":["1"],"dN":["1"],"V":["1"],"V.T":"1"},"cG":{"cf":["1"],"ag":["1"],"ag.T":"1"},"cF":{"ae":["1"]},"fp":{"cF":["1"],"ae":["1"]},"a6":{"dx":["1"]},"a8":{"dx":["1"]},"n":{"D":["1"]},"cP":{"ae":["1"]},"dw":{"cP":["1"],"ae":["1"]},"dS":{"cP":["1"],"ae":["1"]},"ar":{"dN":["1"],"V":["1"],"V.T":"1"},"cf":{"ag":["1"],"ag.T":"1"},"dP":{"ae":["1"]},"dN":{"V":["1"]},"f8":{"V":["2"]},"dA":{"ag":["2"],"ag.T":"2"},"fc":{"f8":["1","2"],"V":["2"],"V.T":"2"},"f5":{"ae":["1"]},"dL":{"ag":["2"],"ag.T":"2"},"eY":{"V":["2"],"V.T":"2"},"dM":{"fo":["1","2"]},"iT":{"w":[]},"ii":{"w":[]},"iH":{"w":[]},"dU":{"W":[]},"iU":{"oq":[]},"cK":{"Q":["1","2"],"an":["1","2"],"Q.V":"2","Q.K":"1"},"dE":{"cK":["1","2"],"Q":["1","2"],"an":["1","2"],"Q.V":"2","Q.K":"1"},"cL":{"q":["1"],"d":["1"],"d.E":"1"},"fa":{"fk":["1"],"dl":["1"],"q":["1"],"d":["1"]},"ey":{"d":["1"],"d.E":"1"},"v":{"p":["1"],"q":["1"],"d":["1"]},"Q":{"an":["1","2"]},"fb":{"q":["2"],"d":["2"],"d.E":"2"},"dl":{"q":["1"],"d":["1"]},"fk":{"dl":["1"],"q":["1"],"d":["1"]},"fL":{"cq":["o","p"]},"iQ":{"cr":["o","p"]},"fM":{"cr":["o","p"]},"fQ":{"cq":["p","o"]},"fR":{"cr":["p","o"]},"h8":{"cq":["o","p"]},"i_":{"cq":["o","p"]},"i0":{"cr":["o","p"]},"F":{"b0":[]},"a":{"b0":[]},"p":{"q":["1"],"d":["1"]},"hH":{"ez":[]},"fN":{"O":[]},"bL":{"O":[]},"bb":{"O":[]},"dh":{"O":[]},"eq":{"O":[]},"eR":{"O":[]},"hT":{"O":[]},"aQ":{"O":[]},"fW":{"O":[]},"hE":{"O":[]},"eM":{"O":[]},"io":{"a5":[]},"aD":{"a5":[]},"hh":{"a5":[],"O":[]},"dQ":{"Y":[]},"fv":{"hX":[]},"b6":{"hX":[]},"ij":{"hX":[]},"hC":{"a5":[]},"d2":{"ae":["1"]},"fX":{"a5":[]},"h5":{"a5":[]},"ap":{"bZ":[]},"bf":{"bZ":[]},"bn":{"ax":[]},"bF":{"ax":[]},"aO":{"bH":[]},"bm":{"bZ":[]},"bw":{"bZ":[]},"de":{"ax":[]},"bW":{"ax":[]},"c2":{"ax":[]},"c4":{"ax":[]},"bV":{"ax":[]},"c5":{"ax":[]},"c3":{"ax":[]},"bI":{"bH":[]},"ed":{"a5":[]},"ic":{"ao":[]},"iP":{"hS":[],"ao":[]},"fn":{"hS":[],"ao":[]},"h2":{"ao":[]},"id":{"ao":[]},"f7":{"ao":[]},"dF":{"ao":[]},"iv":{"hS":[],"ao":[]},"ho":{"ao":[]},"dv":{"a5":[]},"i3":{"ao":[]},"iS":{"cA":["o0"],"cA.0":"o0"},"eF":{"a5":[]},"c8":{"a5":[]},"h_":{"o0":[]},"i1":{"v":["e?"],"p":["e?"],"q":["e?"],"d":["e?"],"v.E":"e?"},"dn":{"d1":[]},"he":{"aq":[]},"is":{"aH":[]},"bq":{"Q":["o","@"],"an":["o","@"],"Q.V":"@","Q.K":"o"},"hI":{"v":["bq"],"p":["bq"],"q":["bq"],"d":["bq"],"v.E":"bq"},"aG":{"a5":[]},"fT":{"aq":[]},"fS":{"aH":[]},"bN":{"of":[]},"cb":{"oe":[]},"dt":{"v":["bN"],"p":["bN"],"q":["bN"],"d":["bN"],"v.E":"bN"},"e9":{"V":["1"],"V.T":"1"},"du":{"aq":[]},"i4":{"aH":[]},"b2":{"bC":[]},"P":{"bC":[]},"aV":{"P":[],"bC":[]},"d5":{"aq":[]},"as":{"aL":["as"]},"it":{"aH":[]},"dB":{"as":[],"aL":["as"],"aL.E":"as"},"dz":{"as":[],"aL":["as"],"aL.E":"as"},"cH":{"as":[],"aL":["as"],"aL.E":"as"},"cR":{"as":[],"aL":["as"],"aL.E":"as"},"dm":{"aq":[]},"iK":{"aH":[]},"bk":{"Y":[]},"hp":{"Z":[],"Y":[]},"Z":{"Y":[]},"bs":{"L":[]},"ef":{"eO":["1"]},"f1":{"V":["1"],"V.T":"1"},"f0":{"ae":["1"]},"ep":{"eO":["1"]},"f9":{"ae":["1"]},"br":{"dq":["a"],"v":["a"],"p":["a"],"q":["a"],"d":["a"],"v.E":"a"},"dq":{"v":["1"],"p":["1"],"q":["1"],"d":["1"]},"iu":{"dq":["a"],"v":["a"],"p":["a"],"q":["a"],"d":["a"]},"f6":{"V":["1"],"V.T":"1"},"ks":{"p":["a"],"q":["a"],"d":["a"]},"aX":{"p":["a"],"q":["a"],"d":["a"]},"lz":{"p":["a"],"q":["a"],"d":["a"]},"kq":{"p":["a"],"q":["a"],"d":["a"]},"lx":{"p":["a"],"q":["a"],"d":["a"]},"kr":{"p":["a"],"q":["a"],"d":["a"]},"ly":{"p":["a"],"q":["a"],"d":["a"]},"k8":{"p":["F"],"q":["F"],"d":["F"]},"k9":{"p":["F"],"q":["F"],"d":["F"]}}')) +A.v1(v.typeUniverse,JSON.parse('{"eU":1,"hM":1,"hN":1,"h7":1,"er":1,"eo":1,"hV":1,"dr":1,"fz":2,"hr":1,"cx":1,"dd":1,"ae":1,"iM":1,"hP":2,"iN":1,"ib":1,"dP":1,"ik":1,"dy":1,"fh":1,"f3":1,"dO":1,"f5":1,"ay":1,"hb":1,"d2":1,"h1":1,"hs":1,"hB":1,"hW":2,"ts":1,"f0":1,"f9":1,"im":1}')) +var u={v:"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u03f6\x00\u0404\u03f4 \u03f4\u03f6\u01f6\u01f6\u03f6\u03fc\u01f4\u03ff\u03ff\u0584\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u05d4\u01f4\x00\u01f4\x00\u0504\u05c4\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0400\x00\u0400\u0200\u03f7\u0200\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0200\u0200\u0200\u03f7\x00",q:"===== asynchronous gap ===========================\n",l:"Cannot extract a file path from a URI with a fragment component",y:"Cannot extract a file path from a URI with a query component",j:"Cannot extract a non-Windows file path from a file URI with an authority",o:"Cannot fire new event. Controller is already firing an event",c:"Error handler must accept one Object or one Object and a StackTrace as arguments, and return a value of the returned future's type",D:"Tried to operate on a released prepared statement"} +var t=(function rtii(){var s=A.aB +return{b9:s("ts"),cO:s("e9>"),E:s("ec"),fd:s("o_"),g1:s("bU<@>"),eT:s("d1"),ed:s("ej"),gw:s("ek"),Q:s("q<@>"),q:s("b2"),C:s("O"),g8:s("a5"),ez:s("d4"),G:s("P"),h4:s("k8"),gN:s("k9"),B:s("L"),b8:s("xz"),bF:s("D"),cG:s("D"),eY:s("D"),bd:s("d5"),dQ:s("kq"),an:s("kr"),gj:s("ks"),hf:s("d<@>"),b:s("u"),cf:s("u"),e:s("u"),fG:s("u>"),fk:s("u>"),W:s("u"),gP:s("u>"),gz:s("u>"),d:s("u>"),f:s("u"),L:s("u<+(bO,o)>"),bb:s("u"),s:s("u"),be:s("u"),J:s("u"),gQ:s("u"),n:s("u"),gn:s("u<@>"),t:s("u"),c:s("u"),d4:s("u"),r:s("u"),Y:s("u"),bT:s("u<~()>"),aP:s("av<@>"),T:s("eu"),m:s("z"),g:s("bz"),aU:s("aU<@>"),au:s("ey"),e9:s("p>"),cl:s("p"),aS:s("p>"),u:s("p"),j:s("p<@>"),I:s("p"),ee:s("p"),g6:s("an"),eO:s("an<@,@>"),M:s("aE"),fe:s("E"),do:s("E"),fJ:s("bZ"),cb:s("bC"),eN:s("aV"),v:s("da"),gT:s("cy"),ha:s("dc"),aV:s("c_"),eB:s("aW"),Z:s("c0"),bw:s("bF"),P:s("R"),K:s("e"),x:s("ao"),aj:s("dg"),fl:s("xE"),bQ:s("+()"),e1:s("+(z?,z)"),cV:s("+(e?,a)"),cz:s("hH"),al:s("ap"),cc:s("bH"),bJ:s("eI"),fE:s("dj"),fL:s("c6"),gW:s("dm"),f_:s("c8"),l:s("Y"),a7:s("hO"),N:s("o"),aF:s("eQ"),a:s("Z"),w:s("hS"),dm:s("I"),eK:s("bL"),h7:s("lx"),bv:s("ly"),go:s("lz"),p:s("aX"),ak:s("cE"),dD:s("hX"),ei:s("eT"),ab:s("i5"),aT:s("du"),U:s("aY"),eJ:s("eV"),R:s("ac"),dx:s("ac"),b0:s("ac"),bi:s("a6"),co:s("a6"),fu:s("a6"),h:s("a6<~>"),V:s("cI"),fF:s("f6"),et:s("n"),a9:s("n"),k:s("n"),eI:s("n<@>"),gR:s("n"),fX:s("n"),D:s("n<~>"),hg:s("dE"),cT:s("dI"),aR:s("iB"),eg:s("iE"),dn:s("fp<~>"),eC:s("a8"),fa:s("a8"),F:s("a8<~>"),y:s("K"),i:s("F"),z:s("@"),bI:s("@(e)"),_:s("@(e,Y)"),S:s("a"),eH:s("D?"),A:s("z?"),dE:s("c0?"),X:s("e?"),ah:s("ax?"),O:s("bH?"),dk:s("o?"),fN:s("br?"),aD:s("aX?"),fQ:s("K?"),cD:s("F?"),h6:s("a?"),cg:s("b0?"),o:s("b0"),H:s("~"),d5:s("~(e)"),da:s("~(e,Y)")}})();(function constants(){var s=hunkHelpers.makeConstList +B.aB=J.hi.prototype +B.c=J.u.prototype +B.b=J.et.prototype +B.aC=J.d6.prototype +B.a=J.bX.prototype +B.aD=J.bz.prototype +B.aE=J.ev.prototype +B.aN=A.cy.prototype +B.e=A.c0.prototype +B.Z=J.hF.prototype +B.D=J.cE.prototype +B.ai=new A.cn(0) +B.l=new A.cn(1) +B.p=new A.cn(2) +B.L=new A.cn(3) +B.bD=new A.cn(-1) +B.aj=new A.fM(127) +B.w=new A.es(A.x8(),A.aB("es")) +B.ak=new A.fL() +B.bE=new A.fR() +B.al=new A.fQ() +B.M=new A.ed() +B.am=new A.fX() +B.bF=new A.h1() +B.N=new A.h4() +B.O=new A.h7() +B.h=new A.b2() +B.an=new A.hh() +B.P=function getTagFallback(o) { + var s = Object.prototype.toString.call(o); + return s.substring(8, s.length - 1); +} +B.ao=function() { + var toStringFunction = Object.prototype.toString; + function getTag(o) { + var s = toStringFunction.call(o); + return s.substring(8, s.length - 1); + } + function getUnknownTag(object, tag) { + if (/^HTML[A-Z].*Element$/.test(tag)) { + var name = toStringFunction.call(object); + if (name == "[object Object]") return null; + return "HTMLElement"; + } + } + function getUnknownTagGenericBrowser(object, tag) { + if (object instanceof HTMLElement) return "HTMLElement"; + return getUnknownTag(object, tag); + } + function prototypeForTag(tag) { + if (typeof window == "undefined") return null; + if (typeof window[tag] == "undefined") return null; + var constructor = window[tag]; + if (typeof constructor != "function") return null; + return constructor.prototype; + } + function discriminator(tag) { return null; } + var isBrowser = typeof HTMLElement == "function"; + return { + getTag: getTag, + getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag, + prototypeForTag: prototypeForTag, + discriminator: discriminator }; +} +B.at=function(getTagFallback) { + return function(hooks) { + if (typeof navigator != "object") return hooks; + var userAgent = navigator.userAgent; + if (typeof userAgent != "string") return hooks; + if (userAgent.indexOf("DumpRenderTree") >= 0) return hooks; + if (userAgent.indexOf("Chrome") >= 0) { + function confirm(p) { + return typeof window == "object" && window[p] && window[p].name == p; + } + if (confirm("Window") && confirm("HTMLElement")) return hooks; + } + hooks.getTag = getTagFallback; + }; +} +B.ap=function(hooks) { + if (typeof dartExperimentalFixupGetTag != "function") return hooks; + hooks.getTag = dartExperimentalFixupGetTag(hooks.getTag); +} +B.as=function(hooks) { + if (typeof navigator != "object") return hooks; + var userAgent = navigator.userAgent; + if (typeof userAgent != "string") return hooks; + if (userAgent.indexOf("Firefox") == -1) return hooks; + var getTag = hooks.getTag; + var quickMap = { + "BeforeUnloadEvent": "Event", + "DataTransfer": "Clipboard", + "GeoGeolocation": "Geolocation", + "Location": "!Location", + "WorkerMessageEvent": "MessageEvent", + "XMLDocument": "!Document"}; + function getTagFirefox(o) { + var tag = getTag(o); + return quickMap[tag] || tag; + } + hooks.getTag = getTagFirefox; +} +B.ar=function(hooks) { + if (typeof navigator != "object") return hooks; + var userAgent = navigator.userAgent; + if (typeof userAgent != "string") return hooks; + if (userAgent.indexOf("Trident/") == -1) return hooks; + var getTag = hooks.getTag; + var quickMap = { + "BeforeUnloadEvent": "Event", + "DataTransfer": "Clipboard", + "HTMLDDElement": "HTMLElement", + "HTMLDTElement": "HTMLElement", + "HTMLPhraseElement": "HTMLElement", + "Position": "Geoposition" + }; + function getTagIE(o) { + var tag = getTag(o); + var newTag = quickMap[tag]; + if (newTag) return newTag; + if (tag == "Object") { + if (window.DataView && (o instanceof window.DataView)) return "DataView"; + } + return tag; + } + function prototypeForTagIE(tag) { + var constructor = window[tag]; + if (constructor == null) return null; + return constructor.prototype; + } + hooks.getTag = getTagIE; + hooks.prototypeForTag = prototypeForTagIE; +} +B.aq=function(hooks) { + var getTag = hooks.getTag; + var prototypeForTag = hooks.prototypeForTag; + function getTagFixed(o) { + var tag = getTag(o); + if (tag == "Document") { + if (!!o.xmlVersion) return "!Document"; + return "!HTMLDocument"; + } + return tag; + } + function prototypeForTagFixed(tag) { + if (tag == "Document") return null; + return prototypeForTag(tag); + } + hooks.getTag = getTagFixed; + hooks.prototypeForTag = prototypeForTagFixed; +} +B.Q=function(hooks) { return hooks; } + +B.o=new A.hs() +B.au=new A.kF() +B.av=new A.hA() +B.aw=new A.hE() +B.f=new A.kR() +B.j=new A.i_() +B.i=new A.i0() +B.x=new A.mw() +B.d=new A.iH() +B.y=new A.bx(0) +B.az=new A.aD("Unknown tag",null,null) +B.aA=new A.aD("Cannot read message",null,null) +B.aF=s([11],t.t) +B.F=new A.bO(0,"opfs") +B.a2=new A.cc(0,"opfsShared") +B.a3=new A.cc(1,"opfsLocks") +B.a4=new A.bO(1,"indexedDb") +B.u=new A.cc(2,"sharedIndexedDb") +B.E=new A.cc(3,"unsafeIndexedDb") +B.bn=new A.cc(4,"inMemory") +B.aG=s([B.a2,B.a3,B.u,B.E,B.bn],A.aB("u")) +B.be=new A.ds(0,"insert") +B.bf=new A.ds(1,"update") +B.bg=new A.ds(2,"delete") +B.R=s([B.be,B.bf,B.bg],A.aB("u")) +B.aH=s([B.F,B.a4],A.aB("u")) +B.z=s([],t.W) +B.aI=s([],t.gz) +B.aJ=s([],t.f) +B.A=s([],t.s) +B.q=s([],t.c) +B.B=s([],t.L) +B.ax=new A.d4("/database",0,"database") +B.ay=new A.d4("/database-journal",1,"journal") +B.S=s([B.ax,B.ay],A.aB("u")) +B.a5=new A.ac(A.p3(),A.b9(),0,"xAccess",t.b0) +B.a6=new A.ac(A.p3(),A.bS(),1,"xDelete",A.aB("ac")) +B.ah=new A.ac(A.p3(),A.b9(),2,"xOpen",t.b0) +B.af=new A.ac(A.b9(),A.b9(),3,"xRead",t.dx) +B.aa=new A.ac(A.b9(),A.bS(),4,"xWrite",t.R) +B.ab=new A.ac(A.b9(),A.bS(),5,"xSleep",t.R) +B.ac=new A.ac(A.b9(),A.bS(),6,"xClose",t.R) +B.ag=new A.ac(A.b9(),A.b9(),7,"xFileSize",t.dx) +B.ad=new A.ac(A.b9(),A.bS(),8,"xSync",t.R) +B.ae=new A.ac(A.b9(),A.bS(),9,"xTruncate",t.R) +B.a8=new A.ac(A.b9(),A.bS(),10,"xLock",t.R) +B.a9=new A.ac(A.b9(),A.bS(),11,"xUnlock",t.R) +B.a7=new A.ac(A.bS(),A.bS(),12,"stopServer",A.aB("ac")) +B.aL=s([B.a5,B.a6,B.ah,B.af,B.aa,B.ab,B.ac,B.ag,B.ad,B.ae,B.a8,B.a9,B.a7],A.aB("u>")) +B.m=new A.c7(0,"sqlite") +B.aV=new A.c7(1,"mysql") +B.aW=new A.c7(2,"postgres") +B.aX=new A.c7(3,"duckdb") +B.aY=new A.c7(4,"mariadb") +B.T=s([B.m,B.aV,B.aW,B.aX,B.aY],A.aB("u")) +B.aZ=new A.cB(0,"custom") +B.b_=new A.cB(1,"deleteOrUpdate") +B.b0=new A.cB(2,"insert") +B.b1=new A.cB(3,"select") +B.U=s([B.aZ,B.b_,B.b0,B.b1],A.aB("u")) +B.W=new A.c1(0,"beginTransaction") +B.aO=new A.c1(1,"commit") +B.aP=new A.c1(2,"rollback") +B.X=new A.c1(3,"startExclusive") +B.Y=new A.c1(4,"endExclusive") +B.V=s([B.W,B.aO,B.aP,B.X,B.Y],A.aB("u")) +B.aQ={} +B.aM=new A.eh(B.aQ,[],A.aB("eh")) +B.C=new A.de(0,"terminateAll") +B.bG=new A.kG(2,"readWriteCreate") +B.r=new A.cz(0,0,"legacy") +B.aR=new A.cz(1,1,"v1") +B.aS=new A.cz(2,2,"v2") +B.aT=new A.cz(3,3,"v3") +B.t=new A.cz(4,4,"v4") +B.aK=s([],t.d) +B.aU=new A.bI(B.aK) +B.a_=new A.hQ("drift.runtime.cancellation") +B.b2=A.bj("ec") +B.b3=A.bj("o_") +B.b4=A.bj("k8") +B.b5=A.bj("k9") +B.b6=A.bj("kq") +B.b7=A.bj("kr") +B.b8=A.bj("ks") +B.b9=A.bj("e") +B.ba=A.bj("lx") +B.bb=A.bj("ly") +B.bc=A.bj("lz") +B.bd=A.bj("aX") +B.bh=new A.aG(10) +B.bi=new A.aG(12) +B.a0=new A.aG(14) +B.bj=new A.aG(2570) +B.bk=new A.aG(3850) +B.bl=new A.aG(522) +B.a1=new A.aG(778) +B.bm=new A.aG(8) +B.bo=new A.dJ("reaches root") +B.G=new A.dJ("below root") +B.H=new A.dJ("at root") +B.I=new A.dJ("above root") +B.k=new A.dK("different") +B.J=new A.dK("equal") +B.n=new A.dK("inconclusive") +B.K=new A.dK("within") +B.v=new A.dQ("") +B.bp=new A.ay(B.d,A.wv()) +B.bq=new A.ay(B.d,A.wr()) +B.br=new A.ay(B.d,A.wz()) +B.bs=new A.ay(B.d,A.ws()) +B.bt=new A.ay(B.d,A.wt()) +B.bu=new A.ay(B.d,A.wu()) +B.bv=new A.ay(B.d,A.ww()) +B.bw=new A.ay(B.d,A.wy()) +B.bx=new A.ay(B.d,A.wA()) +B.by=new A.ay(B.d,A.wB()) +B.bz=new A.ay(B.d,A.wC()) +B.bA=new A.ay(B.d,A.wD()) +B.bB=new A.ay(B.d,A.wx()) +B.bC=new A.iU(null,null,null,null,null,null,null,null,null,null,null,null,null)})();(function staticFields(){$.mS=null +$.cT=A.f([],t.f) +$.rt=null +$.pI=null +$.pj=null +$.pi=null +$.rl=null +$.re=null +$.ru=null +$.nF=null +$.nL=null +$.oV=null +$.mV=A.f([],A.aB("u?>")) +$.dX=null +$.fB=null +$.fC=null +$.oL=!1 +$.h=B.d +$.mX=null +$.qh=null +$.qi=null +$.qj=null +$.qk=null +$.or=A.mo("_lastQuoRemDigits") +$.os=A.mo("_lastQuoRemUsed") +$.eX=A.mo("_lastRemUsed") +$.ot=A.mo("_lastRem_nsh") +$.qa="" +$.qb=null +$.qT=null +$.nr=null})();(function lazyInitializers(){var s=hunkHelpers.lazyFinal,r=hunkHelpers.lazy +s($,"xv","e6",()=>A.wS("_$dart_dartClosure")) +s($,"yA","tg",()=>B.d.bb(new A.nO(),A.aB("D<~>"))) +s($,"yl","t6",()=>A.f([new J.hj()],A.aB("u"))) +s($,"xK","rC",()=>A.bM(A.lw({ +toString:function(){return"$receiver$"}}))) +s($,"xL","rD",()=>A.bM(A.lw({$method$:null, +toString:function(){return"$receiver$"}}))) +s($,"xM","rE",()=>A.bM(A.lw(null))) +s($,"xN","rF",()=>A.bM(function(){var $argumentsExpr$="$arguments$" +try{null.$method$($argumentsExpr$)}catch(q){return q.message}}())) +s($,"xQ","rI",()=>A.bM(A.lw(void 0))) +s($,"xR","rJ",()=>A.bM(function(){var $argumentsExpr$="$arguments$" +try{(void 0).$method$($argumentsExpr$)}catch(q){return q.message}}())) +s($,"xP","rH",()=>A.bM(A.q6(null))) +s($,"xO","rG",()=>A.bM(function(){try{null.$method$}catch(q){return q.message}}())) +s($,"xT","rL",()=>A.bM(A.q6(void 0))) +s($,"xS","rK",()=>A.bM(function(){try{(void 0).$method$}catch(q){return q.message}}())) +s($,"xW","p7",()=>A.uC()) +s($,"xB","cm",()=>$.tg()) +s($,"xA","rz",()=>A.uN(!1,B.d,t.y)) +s($,"y5","rS",()=>{var q=t.z +return A.pw(q,q)}) +s($,"y9","rW",()=>A.pF(4096)) +s($,"y7","rU",()=>new A.nj().$0()) +s($,"y8","rV",()=>new A.ni().$0()) +s($,"xX","rN",()=>A.u7(A.iV(A.f([-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-2,-2,-2,-2,-2,62,-2,62,-2,63,52,53,54,55,56,57,58,59,60,61,-2,-2,-2,-1,-2,-2,-2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-2,-2,-2,-2,63,-2,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-2,-2,-2,-2,-2],t.t)))) +s($,"y3","ba",()=>A.eW(0)) +s($,"y1","fI",()=>A.eW(1)) +s($,"y2","rQ",()=>A.eW(2)) +s($,"y_","p9",()=>$.fI().aA(0)) +s($,"xY","p8",()=>A.eW(1e4)) +r($,"y0","rP",()=>A.H("^\\s*([+-]?)((0x[a-f0-9]+)|(\\d+)|([a-z0-9]+))\\s*$",!1,!1,!1,!1)) +s($,"xZ","rO",()=>A.pF(8)) +s($,"y4","rR",()=>typeof FinalizationRegistry=="function"?FinalizationRegistry:null) +s($,"y6","rT",()=>A.H("^[\\-\\.0-9A-Z_a-z~]*$",!0,!1,!1,!1)) +s($,"yi","nV",()=>A.oY(B.b9)) +s($,"xD","rA",()=>{var q=new A.mR(new DataView(new ArrayBuffer(A.vy(8)))) +q.hU() +return q}) +s($,"xV","p6",()=>A.tH(B.aH,A.aB("bO"))) +s($,"yD","th",()=>A.jv(null,$.fH())) +s($,"yB","fJ",()=>A.jv(null,$.cY())) +s($,"yv","j0",()=>new A.fY($.p5(),null)) +s($,"xH","rB",()=>new A.kI(A.H("/",!0,!1,!1,!1),A.H("[^/]$",!0,!1,!1,!1),A.H("^/",!0,!1,!1,!1))) +s($,"xJ","fH",()=>new A.m5(A.H("[/\\\\]",!0,!1,!1,!1),A.H("[^/\\\\]$",!0,!1,!1,!1),A.H("^(\\\\\\\\[^\\\\]+\\\\[^\\\\/]+|[a-zA-Z]:[/\\\\])",!0,!1,!1,!1),A.H("^[/\\\\](?![/\\\\])",!0,!1,!1,!1))) +s($,"xI","cY",()=>new A.lB(A.H("/",!0,!1,!1,!1),A.H("(^[a-zA-Z][-+.a-zA-Z\\d]*://|[^/])$",!0,!1,!1,!1),A.H("[a-zA-Z][-+.a-zA-Z\\d]*://[^/]*",!0,!1,!1,!1),A.H("^/",!0,!1,!1,!1))) +s($,"xG","p5",()=>A.un()) +s($,"yu","tf",()=>A.pg("-9223372036854775808")) +s($,"yt","te",()=>A.pg("9223372036854775807")) +s($,"xu","fG",()=>$.rA()) +s($,"xU","rM",()=>new A.hb(new WeakMap())) +s($,"xt","nT",()=>A.u2(A.f(["files","blocks"],t.s))) +s($,"xw","nU",()=>{var q,p,o=A.al(t.N,t.ez) +for(q=0;q<2;++q){p=B.S[q] +o.t(0,p.c,p)}return o}) +s($,"ys","td",()=>A.H("^#\\d+\\s+(\\S.*) \\((.+?)((?::\\d+){0,2})\\)$",!0,!1,!1,!1)) +s($,"yn","t8",()=>A.H("^\\s*at (?:(\\S.*?)(?: \\[as [^\\]]+\\])? \\((.*)\\)|(.*))$",!0,!1,!1,!1)) +s($,"yo","t9",()=>A.H("^(.*?):(\\d+)(?::(\\d+))?$|native$",!0,!1,!1,!1)) +s($,"yr","tc",()=>A.H("^\\s*at (?:(?.+) )?(?:\\(?(?:(?\\S+):wasm-function\\[(?\\d+)\\]\\:0x(?[0-9a-fA-F]+))\\)?)$",!0,!1,!1,!1)) +s($,"ym","t7",()=>A.H("^eval at (?:\\S.*?) \\((.*)\\)(?:, .*?:\\d+:\\d+)?$",!0,!1,!1,!1)) +s($,"yb","rY",()=>A.H("(\\S+)@(\\S+) line (\\d+) >.* (Function|eval):\\d+:\\d+",!0,!1,!1,!1)) +s($,"yd","t_",()=>A.H("^(?:([^@(/]*)(?:\\(.*\\))?((?:/[^/]*)*)(?:\\(.*\\))?@)?(.*?):(\\d*)(?::(\\d*))?$",!0,!1,!1,!1)) +s($,"yf","t1",()=>A.H("^(?.*?)@(?:(?\\S+).*?:wasm-function\\[(?\\d+)\\]:0x(?[0-9a-fA-F]+))$",!0,!1,!1,!1)) +s($,"yk","t5",()=>A.H("^.*?wasm-function\\[(?.*)\\]@\\[wasm code\\]$",!0,!1,!1,!1)) +s($,"yg","t2",()=>A.H("^(\\S+)(?: (\\d+)(?::(\\d+))?)?\\s+([^\\d].*)$",!0,!1,!1,!1)) +s($,"ya","rX",()=>A.H("<(|[^>]+)_async_body>",!0,!1,!1,!1)) +s($,"yj","t4",()=>A.H("^\\.",!0,!1,!1,!1)) +s($,"xx","rx",()=>A.H("^[a-zA-Z][-+.a-zA-Z\\d]*://",!0,!1,!1,!1)) +s($,"xy","ry",()=>A.H("^([a-zA-Z]:[\\\\/]|\\\\\\\\)",!0,!1,!1,!1)) +s($,"yp","ta",()=>A.H("\\n ?at ",!0,!1,!1,!1)) +s($,"yq","tb",()=>A.H(" ?at ",!0,!1,!1,!1)) +s($,"yc","rZ",()=>A.H("@\\S+ line \\d+ >.* (Function|eval):\\d+:\\d+",!0,!1,!1,!1)) +s($,"ye","t0",()=>A.H("^(([.0-9A-Za-z_$/<]|\\(.*\\))*@)?[^\\s]*:\\d*$",!0,!1,!0,!1)) +s($,"yh","t3",()=>A.H("^[^\\s<][^\\s]*( \\d+(:\\d+)?)?[ \\t]+[^\\s]+$",!0,!1,!0,!1)) +s($,"yC","pa",()=>A.H("^\\n?$",!0,!1,!0,!1))})();(function nativeSupport(){!function(){var s=function(a){var m={} +m[a]=1 +return Object.keys(hunkHelpers.convertToFastObject(m))[0]} +v.getIsolateTag=function(a){return s("___dart_"+a+v.isolateTag)} +var r="___dart_isolate_tags_" +var q=Object[r]||(Object[r]=Object.create(null)) +var p="_ZxYxX" +for(var o=0;;o++){var n=s(p+"_"+o+"_") +if(!(n in q)){q[n]=1 +v.isolateTag=n +break}}v.dispatchPropertyName=v.getIsolateTag("dispatch_record")}() +hunkHelpers.setOrUpdateInterceptorsByTag({SharedArrayBuffer:A.db,ArrayBuffer:A.da,ArrayBufferView:A.eA,DataView:A.cy,Float32Array:A.hu,Float64Array:A.hv,Int16Array:A.hw,Int32Array:A.dc,Int8Array:A.hx,Uint16Array:A.hy,Uint32Array:A.hz,Uint8ClampedArray:A.eB,CanvasPixelArray:A.eB,Uint8Array:A.c0}) +hunkHelpers.setOrUpdateLeafTags({SharedArrayBuffer:true,ArrayBuffer:true,ArrayBufferView:false,DataView:true,Float32Array:true,Float64Array:true,Int16Array:true,Int32Array:true,Int8Array:true,Uint16Array:true,Uint32Array:true,Uint8ClampedArray:true,CanvasPixelArray:true,Uint8Array:false}) +A.dd.$nativeSuperclassTag="ArrayBufferView" +A.fd.$nativeSuperclassTag="ArrayBufferView" +A.fe.$nativeSuperclassTag="ArrayBufferView" +A.c_.$nativeSuperclassTag="ArrayBufferView" +A.ff.$nativeSuperclassTag="ArrayBufferView" +A.fg.$nativeSuperclassTag="ArrayBufferView" +A.aW.$nativeSuperclassTag="ArrayBufferView"})() +Function.prototype.$0=function(){return this()} +Function.prototype.$1=function(a){return this(a)} +Function.prototype.$2=function(a,b){return this(a,b)} +Function.prototype.$1$1=function(a){return this(a)} +Function.prototype.$3=function(a,b,c){return this(a,b,c)} +Function.prototype.$4=function(a,b,c,d){return this(a,b,c,d)} +Function.prototype.$3$1=function(a){return this(a)} +Function.prototype.$2$1=function(a){return this(a)} +Function.prototype.$3$3=function(a,b,c){return this(a,b,c)} +Function.prototype.$2$2=function(a,b){return this(a,b)} +Function.prototype.$2$3=function(a,b,c){return this(a,b,c)} +Function.prototype.$1$2=function(a,b){return this(a,b)} +Function.prototype.$5=function(a,b,c,d,e){return this(a,b,c,d,e)} +Function.prototype.$6=function(a,b,c,d,e,f){return this(a,b,c,d,e,f)} +Function.prototype.$1$0=function(){return this()} +convertAllToFastObject(w) +convertToFastObject($);(function(a){if(typeof document==="undefined"){a(null) +return}if(typeof document.currentScript!="undefined"){a(document.currentScript) +return}var s=document.scripts +function onLoad(b){for(var q=0;q - + diff --git a/web/sqlite3.wasm b/web/sqlite3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c4c1a9742ba3b78730ee873632ed6e4dbc20cc37 GIT binary patch literal 744131 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 z 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 BBf$Uw literal 0 HcmV?d00001 diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 5e1e076..2602ff1 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -13,6 +13,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + jni ) set(PLUGIN_BUNDLED_LIBRARIES)