32ede5388bb6c66c5d5679c2d73fd6ec6b2342bf..489419f3b133c4725d1ffdf5fb320898a55e9544
9 days ago Matthias Nott
fix: increase MQTT keepalive to 120s to prevent iOS network throttle drops
489419 diff | tree
9 days ago Matthias Nott
fix: faster notification tap - immediate catch_up, reduced sync delay to 200ms
52ecd9 diff | tree
9 days ago Matthias Nott
fix: re-enable autoReconnect, simple resume handler, stable connection life...
8b82df diff | tree
9 days ago Matthias Nott
fix: always rebuild index from log on startup, flush index after every append
a4f64f diff | tree
9 days ago Matthias Nott
fix: disable MQTT autoReconnect to prevent connection flickering on resume
e0606b diff | tree
9 days ago Matthias Nott
fix: markdown links open in browser/app instead of copying to clipboard
d420bf diff | tree
9 days ago Matthias Nott
feat: rewrite message store - append-only log, sync routing, eliminates asy...
06bb73 diff | tree
9 days ago Matthias Nott
docs: message system rewrite spec - append-only log, sync routing, state ma...
66e5a4 diff | tree
9 days ago Matthias Nott
fix: single pailot/out topic, per-session file locks, merge protection, res...
6cbbea diff | tree
9 days ago Matthias Nott
fix: immediate disk writes, notification tap skip same session, catch_up tr...
90fc31 diff | tree
9 days ago Matthias Nott
fix: resume message reload, direct session writes, MQTT trace pipe to server
1bf6e7 diff | tree
9 days ago Matthias Nott
fix: explicit per-session MQTT subscriptions, lifecycle observer, resume re...
34b82f diff | tree
9 days ago Matthias Nott
feat: animated splash screen with P logo reveal and plane fly-in
525030 diff | tree
10 days ago Matthias Nott
feat: add message trace log for end-to-end delivery diagnostics
8d1f94 diff | tree
2026-04-05 Matthias Nott
fix: suppress push notification banner in foreground, show only when backgr...
3233e3 diff | tree
2026-04-05 Matthias Nott
fix: dark launch screen background to prevent white flash on startup
0cfa6e diff | tree
2026-04-05 Matthias Nott
fix: disable connectivity listener causing spurious reconnects, rely on MQT...
b2fef1 diff | tree
2026-04-04 Matthias Nott
fix: remove sessionReady gate - process messages immediately to fix deliver...
7b1e06 diff | tree
2026-04-03 Matthias Nott
fix: force pro=true and clear stale cache from earlier IAP testing
316524 diff | tree
2026-04-01 Matthias Nott
fix: default isPro=true for dev builds, graceful StoreKit unavailable handling
b6df48 diff | tree
2026-04-01 Matthias Nott
fix: notification tap uses full _switchSession for proper session routing
d54dc1 diff | tree
2026-04-01 Matthias Nott
feat: StoreKit 2 IAP — free tier with 2 sessions and 15min message TTL
98e569 diff | tree
2026-04-01 Matthias Nott
fix: always show date in message timestamps
4f8a5f diff | tree
2026-04-01 Matthias Nott
feat: show date on message timestamps for older messages
b33ef0 diff | tree
2026-04-01 Matthias Nott
feat: auto-reconnect on network change (WiFi/cellular/VPN switch)
3e19d6 diff | tree
2026-04-01 Matthias Nott
feat: show connection method (Local/VPN/Remote/Discovered) in app bar and s...
1f5e59 diff | tree
2026-04-01 Matthias Nott
fix: L1 privacy manifest, L2 privacy policy, M3-M5 code quality, version/ic...
59a991 diff | tree
2026-04-01 Matthias Nott
feat: smart badge counting, persisted unreads, flutter_app_badger, race con...
0af998 diff | tree
2026-04-01 Matthias Nott
fix: clear badge on app open and foreground
f6f948 diff | tree
2026-04-01 Matthias Nott
fix: clear badge on app open, add clearBadge method
e7c5b5 diff | tree
2026-04-01 Matthias Nott
fix: race configured hosts first, scan network only as fallback, 500ms prob...
058511 diff | tree
2026-04-01 Matthias Nott
feat: add APNs push notification support
f68a98 diff | tree
2026-03-25 Matthias Nott
fix: M1 M2 M6 M7 L3 L5 - subnet batching, scroll debounce, error logging, t...
29f7a2 diff | tree
2026-03-25 Matthias Nott
fix: C3 debug logs, H1-H5 image cache, temp files, controller leak, validat...
d6cf94 diff | tree
2026-03-25 Matthias Nott
feat: show connection status detail in app bar during connect
9aea0e diff | tree
2026-03-25 Matthias Nott
fix: parallel host probing then single connect to winner
0682ae diff | tree
2026-03-25 Matthias Nott
feat: TOFU cert pinning - trust on first use with reset in settings
650b02 diff | tree
2026-03-25 Matthias Nott
fix: add SecurityContext for TLS, fix onBadCertificate type
b78a19 diff | tree
2026-03-25 Matthias Nott
chore: tick off completed App Store checklist items
7cb638 diff | tree
2026-03-25 Matthias Nott
fix: remove NSAllowsArbitraryLoads, add App Store readiness checklist
0c119c diff | tree
2026-03-25 Matthias Nott
fix: cache discovered host to prevent repeated subnet scan floods
a7b094 diff | tree
2026-03-25 Matthias Nott
feat: extend subnet scan to full /24 (254 hosts) for home network coverage
4aef37 diff | tree
2026-03-25 Matthias Nott
feat: subnet scan fallback when Bonjour fails (handles iOS Personal Hotspot)
9e5953 diff | tree
2026-03-24 Matthias Nott
feat: Bonjour auto-discovery + VPN IP field in connection flow
96c8bb diff | tree
2026-03-24 Matthias Nott
fix: stop + 150ms delay between queue tracks for iOS audio player reset
5de43f diff | tree
2026-03-24 Matthias Nott
fix: audio queue debug logging, 200ms playback state delay
d17b63 diff | tree
2026-03-24 Matthias Nott
fix: only set playingMessageId on first auto-played chunk to prevent race
a8aa30 diff | tree
2026-03-24 Matthias Nott
fix: forward voiceMessageId in bundle MQTT publish for transcript reflection
08f92e diff | tree
2026-03-24 Matthias Nott
fix: reflect voice transcript into image caption via voiceMessageId
66a18b diff | tree
2026-03-24 Matthias Nott
fix: combine voice+image into single bubble, no separate voice message
780b01 diff | tree
182 files added
1 files modified
45 files deleted
changed files
.gitignore patch | view | blame | history
.metadata patch | view | blame | history
Notes/PAI.md patch | view | blame | history
Notes/SPEC-message-rewrite.md patch | view | blame | history
Notes/TODO.md patch | view | blame | history
PRIVACY.md patch | view | blame | history
README.md patch | view | blame | history
TODO-appstore.md patch | view | blame | history
TODO.md patch | view | blame | history
analysis_options.yaml patch | view | blame | history
android/.gitignore patch | view | blame | history
android/app/build.gradle.kts patch | view | blame | history
android/app/src/debug/AndroidManifest.xml patch | view | blame | history
android/app/src/main/AndroidManifest.xml patch | view | blame | history
android/app/src/main/kotlin/com/tekmidian/pailot/MainActivity.kt patch | view | blame | history
android/app/src/main/res/drawable-v21/launch_background.xml patch | view | blame | history
android/app/src/main/res/drawable/launch_background.xml patch | view | blame | history
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml patch | view | blame | history
android/app/src/main/res/mipmap-hdpi/ic_launcher.png patch | view | blame | history
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png patch | view | blame | history
android/app/src/main/res/mipmap-mdpi/ic_launcher.png patch | view | blame | history
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png patch | view | blame | history
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png patch | view | blame | history
android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png patch | view | blame | history
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png patch | view | blame | history
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png patch | view | blame | history
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png patch | view | blame | history
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png patch | view | blame | history
android/app/src/main/res/values-night/styles.xml patch | view | blame | history
android/app/src/main/res/values/colors.xml patch | view | blame | history
android/app/src/main/res/values/styles.xml patch | view | blame | history
android/app/src/profile/AndroidManifest.xml patch | view | blame | history
android/build.gradle.kts patch | view | blame | history
android/gradle.properties patch | view | blame | history
android/gradle/wrapper/gradle-wrapper.properties patch | view | blame | history
android/settings.gradle.kts patch | view | blame | history
app.json patch | view | blame | history
app/_layout.tsx patch | view | blame | history
app/chat.tsx patch | view | blame | history
app/index.tsx patch | view | blame | history
app/navigate.tsx patch | view | blame | history
app/settings.tsx patch | view | blame | history
assets/PAILot.ai patch | view | blame | history
assets/PAILot.svg patch | view | blame | history
assets/PAILot2.ai patch | view | blame | history
assets/android-icon-background.png patch | view | blame | history
assets/android-icon-foreground.png patch | view | blame | history
assets/android-icon-monochrome.png patch | view | blame | history
assets/favicon.png patch | view | blame | history
assets/icon.png patch | view | blame | history
assets/splash-icon.png patch | view | blame | history
babel.config.js patch | view | blame | history
bun.lock patch | view | blame | history
components/SessionDrawer.tsx patch | view | blame | history
components/SessionPicker.tsx patch | view | blame | history
components/chat/CommandBar.tsx patch | view | blame | history
components/chat/ImageCaptionModal.tsx patch | view | blame | history
components/chat/ImageViewer.tsx patch | view | blame | history
components/chat/InputBar.tsx patch | view | blame | history
components/chat/MessageBubble.tsx patch | view | blame | history
components/chat/MessageList.tsx patch | view | blame | history
components/chat/TypingIndicator.tsx patch | view | blame | history
components/chat/VoiceButton.tsx patch | view | blame | history
components/ui/IconButton.tsx patch | view | blame | history
components/ui/IncomingToast.tsx patch | view | blame | history
components/ui/StatusDot.tsx patch | view | blame | history
contexts/ChatContext.tsx patch | view | blame | history
contexts/ConnectionContext.tsx patch | view | blame | history
contexts/ThemeContext.tsx patch | view | blame | history
global.css patch | view | blame | history
ios/.gitignore patch | view | blame | history
ios/Flutter/AppFrameworkInfo.plist patch | view | blame | history
ios/Flutter/Debug.xcconfig patch | view | blame | history
ios/Flutter/Release.xcconfig patch | view | blame | history
ios/Podfile patch | view | blame | history
ios/Podfile.lock patch | view | blame | history
ios/Runner.xcodeproj/project.pbxproj patch | view | blame | history
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata patch | view | blame | history
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist patch | view | blame | history
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings patch | view | blame | history
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme patch | view | blame | history
ios/Runner.xcworkspace/contents.xcworkspacedata patch | view | blame | history
ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist patch | view | blame | history
ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings patch | view | blame | history
ios/Runner/AppDelegate.swift patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json patch | view | blame | history
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png patch | view | blame | history
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png patch | view | blame | history
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png patch | view | blame | history
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md patch | view | blame | history
ios/Runner/Base.lproj/LaunchScreen.storyboard patch | view | blame | history
ios/Runner/Base.lproj/Main.storyboard patch | view | blame | history
ios/Runner/Configuration.storekit patch | view | blame | history
ios/Runner/Info.plist patch | view | blame | history
ios/Runner/PrivacyInfo.xcprivacy patch | view | blame | history
ios/Runner/Runner-Bridging-Header.h patch | view | blame | history
ios/Runner/Runner.entitlements patch | view | blame | history
ios/Runner/SceneDelegate.swift patch | view | blame | history
ios/RunnerTests/RunnerTests.swift patch | view | blame | history
lib/main.dart patch | view | blame | history
lib/models/message.dart patch | view | blame | history
lib/models/server_config.dart patch | view | blame | history
lib/models/session.dart patch | view | blame | history
lib/providers/providers.dart patch | view | blame | history
lib/router.dart patch | view | blame | history
lib/screens/chat_screen.dart patch | view | blame | history
lib/screens/navigate_screen.dart patch | view | blame | history
lib/screens/settings_screen.dart patch | view | blame | history
lib/screens/splash_screen.dart patch | view | blame | history
lib/screens/trace_screen.dart patch | view | blame | history
lib/services/audio_service.dart patch | view | blame | history
lib/services/message_store.dart patch | view | blame | history
lib/services/mqtt_service.dart patch | view | blame | history
lib/services/navigate_notifier.dart patch | view | blame | history
lib/services/purchase_service.dart patch | view | blame | history
lib/services/push_service.dart patch | view | blame | history
lib/services/trace_service.dart patch | view | blame | history
lib/services/wol_service.dart patch | view | blame | history
lib/theme/app_theme.dart patch | view | blame | history
lib/widgets/command_bar.dart patch | view | blame | history
lib/widgets/image_viewer.dart patch | view | blame | history
lib/widgets/input_bar.dart patch | view | blame | history
lib/widgets/message_bubble.dart patch | view | blame | history
lib/widgets/paywall_banner.dart patch | view | blame | history
lib/widgets/session_drawer.dart patch | view | blame | history
lib/widgets/status_dot.dart patch | view | blame | history
lib/widgets/toast_overlay.dart patch | view | blame | history
lib/widgets/typing_indicator.dart patch | view | blame | history
lib/widgets/voice_button.dart patch | view | blame | history
linux/.gitignore patch | view | blame | history
linux/CMakeLists.txt patch | view | blame | history
linux/flutter/CMakeLists.txt patch | view | blame | history
linux/flutter/generated_plugin_registrant.cc patch | view | blame | history
linux/flutter/generated_plugin_registrant.h patch | view | blame | history
linux/flutter/generated_plugins.cmake patch | view | blame | history
linux/runner/CMakeLists.txt patch | view | blame | history
linux/runner/main.cc patch | view | blame | history
linux/runner/my_application.cc patch | view | blame | history
linux/runner/my_application.h patch | view | blame | history
macos/.gitignore patch | view | blame | history
macos/Flutter/Flutter-Debug.xcconfig patch | view | blame | history
macos/Flutter/Flutter-Release.xcconfig patch | view | blame | history
macos/Flutter/GeneratedPluginRegistrant.swift patch | view | blame | history
macos/Podfile patch | view | blame | history
macos/Runner.xcodeproj/project.pbxproj patch | view | blame | history
macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist patch | view | blame | history
macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme patch | view | blame | history
macos/Runner.xcworkspace/contents.xcworkspacedata patch | view | blame | history
macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist patch | view | blame | history
macos/Runner/AppDelegate.swift patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png patch | view | blame | history
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png patch | view | blame | history
macos/Runner/Base.lproj/MainMenu.xib patch | view | blame | history
macos/Runner/Configs/AppInfo.xcconfig patch | view | blame | history
macos/Runner/Configs/Debug.xcconfig patch | view | blame | history
macos/Runner/Configs/Release.xcconfig patch | view | blame | history
macos/Runner/Configs/Warnings.xcconfig patch | view | blame | history
macos/Runner/DebugProfile.entitlements patch | view | blame | history
macos/Runner/Info.plist patch | view | blame | history
macos/Runner/MainFlutterWindow.swift patch | view | blame | history
macos/Runner/Release.entitlements patch | view | blame | history
macos/RunnerTests/RunnerTests.swift patch | view | blame | history
memory/MEMORY.md patch | view | blame | history
metro.config.js patch | view | blame | history
nativewind-env.d.ts patch | view | blame | history
package-lock.json patch | view | blame | history
package.json patch | view | blame | history
pubspec.lock patch | view | blame | history
pubspec.yaml patch | view | blame | history
services/audio.ts patch | view | blame | history
services/notifications.ts patch | view | blame | history
services/websocket.ts patch | view | blame | history
services/wol.ts patch | view | blame | history
tailwind.config.js patch | view | blame | history
test/widget_test.dart patch | view | blame | history
tools/build-android.sh patch | view | blame | history
tools/build.sh patch | view | blame | history
tools/deploy-android.sh patch | view | blame | history
tools/deploy.sh patch | view | blame | history
tsconfig.json patch | view | blame | history
types/index.ts patch | view | blame | history
web/favicon.png patch | view | blame | history
web/icons/Icon-192.png patch | view | blame | history
web/icons/Icon-512.png patch | view | blame | history
web/icons/Icon-maskable-192.png patch | view | blame | history
web/icons/Icon-maskable-512.png patch | view | blame | history
web/index.html patch | view | blame | history
web/manifest.json patch | view | blame | history
windows/.gitignore patch | view | blame | history
windows/CMakeLists.txt patch | view | blame | history
windows/flutter/CMakeLists.txt patch | view | blame | history
windows/flutter/generated_plugin_registrant.cc patch | view | blame | history
windows/flutter/generated_plugin_registrant.h patch | view | blame | history
windows/flutter/generated_plugins.cmake patch | view | blame | history
windows/runner/CMakeLists.txt patch | view | blame | history
windows/runner/Runner.rc patch | view | blame | history
windows/runner/flutter_window.cpp patch | view | blame | history
windows/runner/flutter_window.h patch | view | blame | history
windows/runner/main.cpp patch | view | blame | history
windows/runner/resource.h patch | view | blame | history
windows/runner/resources/app_icon.ico patch | view | blame | history
windows/runner/runner.exe.manifest patch | view | blame | history
windows/runner/utils.cpp patch | view | blame | history
windows/runner/utils.h patch | view | blame | history
windows/runner/win32_window.cpp patch | view | blame | history
windows/runner/win32_window.h patch | view | blame | history
.gitignore
....@@ -1,41 +1,45 @@
1
-# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2
-
3
-# dependencies
4
-node_modules/
5
-
6
-# Expo
7
-.expo/
8
-dist/
9
-web-build/
10
-expo-env.d.ts
11
-
12
-# Native
13
-.kotlin/
14
-*.orig.*
15
-*.jks
16
-*.p8
17
-*.p12
18
-*.key
19
-*.mobileprovision
20
-
21
-# Metro
22
-.metro-health-check*
23
-
24
-# debug
25
-npm-debug.*
26
-yarn-debug.*
27
-yarn-error.*
28
-
29
-# macOS
1
+# Miscellaneous
2
+*.class
3
+*.log
4
+*.pyc
5
+*.swp
306 .DS_Store
31
-*.pem
7
+.atom/
8
+.build/
9
+.buildlog/
10
+.history
11
+.svn/
12
+.swiftpm/
13
+migrate_working_dir/
3214
33
-# local env files
34
-.env*.local
15
+# IntelliJ related
16
+*.iml
17
+*.ipr
18
+*.iws
19
+.idea/
3520
36
-# typescript
37
-*.tsbuildinfo
21
+# The .vscode folder contains launch configuration and tasks you configure in
22
+# VS Code which you may wish to be included in version control, so this line
23
+# is commented out by default.
24
+#.vscode/
3825
39
-# generated native folders
40
-/ios
41
-/android
26
+# Flutter/Dart/Pub related
27
+**/doc/api/
28
+**/ios/Flutter/.last_build_id
29
+.dart_tool/
30
+.flutter-plugins-dependencies
31
+.pub-cache/
32
+.pub/
33
+/build/
34
+/coverage/
35
+
36
+# Symbolication related
37
+app.*.symbols
38
+
39
+# Obfuscation related
40
+app.*.map.json
41
+
42
+# Android Studio will place build artifacts here
43
+/android/app/debug
44
+/android/app/profile
45
+/android/app/release
.metadata
....@@ -0,0 +1,45 @@
1
+# This file tracks properties of this Flutter project.
2
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
3
+#
4
+# This file should be version controlled and should not be manually edited.
5
+
6
+version:
7
+ revision: "ff37bef603469fb030f2b72995ab929ccfc227f0"
8
+ channel: "stable"
9
+
10
+project_type: app
11
+
12
+# Tracks metadata for the flutter migrate command
13
+migration:
14
+ platforms:
15
+ - platform: root
16
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
17
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
18
+ - platform: android
19
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
20
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
21
+ - platform: ios
22
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
23
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
24
+ - platform: linux
25
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
26
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
27
+ - platform: macos
28
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
29
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
30
+ - platform: web
31
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
32
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
33
+ - platform: windows
34
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
35
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
36
+
37
+ # User provided section
38
+
39
+ # List of Local paths (relative to this file) that should be
40
+ # ignored by the migrate tool.
41
+ #
42
+ # Files that are not part of the templates will be ignored by default.
43
+ unmanaged_files:
44
+ - 'lib/main.dart'
45
+ - 'ios/Runner.xcodeproj/project.pbxproj'
Notes/PAI.md
deleted file mode 100644
....@@ -1,13 +0,0 @@
1
----
2
-pai:
3
- slug: "pailot"
4
- registered: "2026-03-05"
5
- last_indexed: null
6
- status: active
7
----
8
-
9
-# pailot
10
-
11
-<!-- Everything below the YAML frontmatter is yours — PAI never modifies content here. -->
12
-<!-- Use this file for project notes, decisions, preferences, or anything you want. -->
13
-<!-- PAI only reads and updates the `pai:` block in the frontmatter above. -->
Notes/SPEC-message-rewrite.md
....@@ -0,0 +1,141 @@
1
+# PAILot Message System Rewrite Spec
2
+
3
+## Problem
4
+
5
+The current message handling has accumulated race conditions from incremental fixes:
6
+- `switchSession` is async — messages arriving during the async gap get overwritten by `loadAll`
7
+- iOS kills the MQTT socket in background but the client reports "connected"
8
+- File corruption from concurrent read/write on the same session file
9
+- Notification tap triggers `switchSession` which reloads from disk, losing in-memory messages
10
+- `addMessage` and `switchSession` compete on the same state and disk files
11
+
12
+## Architecture: Single Message Bus
13
+
14
+### 1. One MQTT topic for everything
15
+
16
+- **Server**: publish ALL outbound messages to `pailot/out` (DONE)
17
+- **App**: subscribe to `pailot/out` + `pailot/sessions` + `pailot/status` + `pailot/control/out`
18
+- Every message carries `type`, `sessionId`, `seq` in the payload
19
+- Client routes by `sessionId` — never by topic
20
+
21
+### 2. MessageStore redesign
22
+
23
+Replace per-session debounced saves with a single append-only log:
24
+
25
+```
26
+~/.../messages/log.jsonl — append-only, one JSON line per message
27
+~/.../messages/index.json — { sessionId: [lineNumbers] } for fast lookup
28
+```
29
+
30
+**Operations:**
31
+- `append(message)` — append one line to log.jsonl (sync, atomic, no race)
32
+- `loadSession(sessionId)` — read index, seek to lines, return messages
33
+- `compact()` — rewrite log removing old messages (run on app start, not during use)
34
+
35
+**Benefits:**
36
+- No per-session files — no file-level races
37
+- Append-only — no read-modify-write cycle
38
+- No debounce needed — each append is a single `writeAsStringSync` with `mode: FileMode.append`
39
+
40
+### 3. Connection state machine
41
+
42
+```
43
+States: disconnected → connecting → connected → suspended → reconnecting → connected
44
+ ↑ |
45
+ └──────────────────────────┘
46
+
47
+Transitions:
48
+- App launch: disconnected → connecting → connected
49
+- App background: connected → suspended (keep client, mark state)
50
+- App resume: suspended → reconnecting → connected (always force-reconnect)
51
+- Connection lost: connected → reconnecting → connected (autoReconnect)
52
+- User disconnect: any → disconnected
53
+```
54
+
55
+**Key rule:** In `suspended` state, do NOT process buffered MQTT messages. Process them only after reconnect + catch_up completes. This prevents the race where a buffered message is added to state before `loadAll` overwrites it.
56
+
57
+### 4. Message routing (synchronous, no async gaps)
58
+
59
+```dart
60
+void _onMessage(Map<String, dynamic> json) {
61
+ final type = json['type'] as String?;
62
+ final sessionId = json['sessionId'] as String?;
63
+ final currentId = _currentSessionId;
64
+
65
+ if (type == 'text' || type == 'voice' || type == 'image') {
66
+ // Append to log immediately (sync)
67
+ MessageStore.append(Message.fromMqtt(json));
68
+
69
+ // Display only if for current session
70
+ if (sessionId == currentId) {
71
+ _messages.add(Message.fromMqtt(json));
72
+ notifyListeners(); // or setState
73
+ } else {
74
+ _incrementUnread(sessionId);
75
+ }
76
+ }
77
+}
78
+```
79
+
80
+No async. No switchSession during message handling. No race.
81
+
82
+### 5. Session switching
83
+
84
+```dart
85
+void switchSession(String sessionId) {
86
+ _currentSessionId = sessionId;
87
+ _messages = MessageStore.loadSession(sessionId); // sync read from index
88
+ notifyListeners();
89
+}
90
+```
91
+
92
+Synchronous. No async gap. No race with incoming messages.
93
+
94
+### 6. Resume flow
95
+
96
+```dart
97
+void onResume() {
98
+ state = suspended;
99
+ // Kill old client (disable autoReconnect first)
100
+ _client?.autoReconnect = false;
101
+ _client?.disconnect();
102
+ _client = null;
103
+
104
+ // Fast reconnect to last host
105
+ await _fastReconnect(connectedHost);
106
+
107
+ // Now process: sync → sessions → catch_up
108
+ // catch_up messages go through same _onMessage path (append + display if current)
109
+ state = connected;
110
+}
111
+```
112
+
113
+### 7. Notification tap
114
+
115
+```dart
116
+void onNotificationTap(String sessionId) {
117
+ if (sessionId != _currentSessionId) {
118
+ switchSession(sessionId); // sync, no async
119
+ }
120
+ // Message is already in the log from MQTT delivery or catch_up
121
+ // switchSession loads it
122
+}
123
+```
124
+
125
+## Migration path
126
+
127
+1. Create `MessageStoreV2` with append-only log
128
+2. Create `ConnectionStateMachine` with explicit states
129
+3. Rewrite `_handleIncomingMessage` to use sync append
130
+4. Rewrite `switchSession` to be sync
131
+5. Remove debounced saves, per-session file locks, merge protection
132
+6. Test each step before moving to next
133
+
134
+## What stays the same
135
+
136
+- MQTT transport (mqtt_client package)
137
+- aedes broker with loopback client on server
138
+- Single `pailot/out` topic
139
+- APNs push notifications
140
+- Splash screen
141
+- UI components (chat bubbles, drawer, settings)
Notes/TODO.md
deleted file mode 100644
....@@ -1,20 +0,0 @@
1
-# PAILot TODO
2
-
3
-## Bugs
4
-
5
-- [ ] **Auto-scroll hijacks reading position** — `MessageList.tsx` fires `scrollToEnd` on every `onContentSizeChange` and on `messages.length` change. If you're scrolled up reading older messages, new incoming messages yank you to the bottom. Fix: only auto-scroll when already near the bottom (track scroll offset, threshold ~100px).
6
-- [ ] **Text not selectable in message bubbles** — `MessageBubble.tsx` uses plain `<Text>` without `selectable={true}`. Cannot long-press to select/copy text from AI responses or own messages.
7
-
8
-## UX Improvements
9
-
10
-- [ ] **Show session name on each message** — Currently each bubble only shows the time (e.g. "13:42"). Since PAILot runs parallel sessions on one screen, each message should also display which session it came from or went to (e.g. "13:42 · whazaa" or "13:42 · AIBroker"). Requires: add `sessionId`/`sessionName` to the `Message` type, have the gateway include session info with each message, render it in `MessageBubble.tsx` next to the timestamp.
11
-
12
-## Features
13
-
14
-- [ ] **Multimodal upload (send images/photos/video/audio from phone)** — The app can *receive* images and voice, but there's no UI to *send* media from the phone to the AI session. Needs: image picker / camera access, new `WsOutgoing` type for images/files, gateway handler to route media to the active session, and backend support to process multimodal input.
15
-- [ ] **Relay-based connectivity** — PAILot currently only works on the local network (WebSocket to `localhost:8765`). For use outside home network: self-hosted relay on a VPS with encrypted tunnel (Tailscale, cloudflared), or APNs push relay. See AIBroker `PLAN-adapter-architecture.md` sections on relay.
16
-- [ ] **Session lifecycle from mobile** — List named PAI sessions, see which are running, launch/stop/switch from the phone. "Remote desktop for AI sessions." See AIBroker TODO.
17
-
18
----
19
-
20
-*Created: 2026-03-05*
PRIVACY.md
....@@ -0,0 +1,63 @@
1
+# Privacy Policy for PAILot
2
+
3
+**Last updated: April 1, 2026**
4
+
5
+## Overview
6
+
7
+PAILot is a voice-first AI communication client that connects to your own self-hosted AIBroker server. This privacy policy explains how PAILot handles your data.
8
+
9
+## Data Collection and Use
10
+
11
+**PAILot does not collect, transmit, or share your data with any third party.** The app communicates exclusively with your own AIBroker server, which you host and control.
12
+
13
+### What PAILot Accesses
14
+
15
+**Microphone**
16
+PAILot requests microphone access to record voice messages. Recorded audio is transmitted only to your own AIBroker server. No audio is sent to any third-party service.
17
+
18
+**Camera and Photo Library**
19
+PAILot requests camera and photo library access to allow you to attach images to messages. Images are transmitted only to your own AIBroker server.
20
+
21
+**Local Network**
22
+PAILot uses Bonjour/mDNS (via the local network) to discover your AIBroker server on the local network. No network scanning data is transmitted outside your local network.
23
+
24
+**Push Notifications**
25
+PAILot uses Apple Push Notification service (APNs) to receive notifications when messages arrive while the app is in the background. Your device token is transmitted only to your own AIBroker server, which uses it to send notifications via APNs on your behalf. The device token is not shared with any third party.
26
+
27
+### What PAILot Stores Locally
28
+
29
+**Messages**
30
+Conversation messages are stored locally on your device in the app's Documents directory. This includes text content and image attachments you have received or sent. Audio messages are stored as temporary files and cleaned up after playback.
31
+
32
+**Settings and Preferences**
33
+Connection settings (server address, port, authentication token) and app preferences are stored in the iOS Keychain (for the authentication token) and UserDefaults (for other settings).
34
+
35
+**No Analytics or Tracking**
36
+PAILot contains no analytics SDKs, no tracking libraries, no advertising SDKs, and no crash-reporting services that transmit data to third parties.
37
+
38
+## iCloud Backup
39
+
40
+Message data stored in the Documents directory may be included in iCloud backups if iCloud Backup is enabled on your device. This data is encrypted by Apple as part of the standard iCloud Backup encryption. You can disable iCloud Backup for PAILot in iOS Settings.
41
+
42
+## Data Sharing
43
+
44
+PAILot does not share any data with third parties. All communication is between your device and your own self-hosted AIBroker server.
45
+
46
+## Your Control
47
+
48
+Because all data is stored locally on your device or on your own server, you have full control:
49
+- Delete the app to remove all locally stored data
50
+- Manage your AIBroker server to control server-side data
51
+- Use iOS Settings to revoke microphone, camera, or notification permissions at any time
52
+
53
+## Children's Privacy
54
+
55
+PAILot is not directed at children under 13 and does not knowingly collect information from children.
56
+
57
+## Changes to This Policy
58
+
59
+If this policy changes in a meaningful way, the updated date at the top of this document will reflect the change.
60
+
61
+## Contact
62
+
63
+PAILot is a personal tool. For questions, contact the developer directly through the App Store listing.
README.md
....@@ -0,0 +1,17 @@
1
+# pailot
2
+
3
+A new Flutter project.
4
+
5
+## Getting Started
6
+
7
+This project is a starting point for a Flutter application.
8
+
9
+A few resources to get you started if this is your first Flutter project:
10
+
11
+- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
12
+- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
13
+- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
14
+
15
+For help getting started with Flutter development, view the
16
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
17
+samples, guidance on mobile development, and a full API reference.
TODO-appstore.md
....@@ -0,0 +1,66 @@
1
+# PAILot App Store Readiness Checklist
2
+
3
+Date: 2026-03-25
4
+Source: Security & Code Quality Review
5
+
6
+## CRITICAL (Must fix before submission)
7
+
8
+- [x] **C1: Remove NSAllowsArbitraryLoads** — ATS bypass, Apple will reject. Use NSAllowsLocalNetworking only *(fixed 2026-03-25)*
9
+- [x] **C2: Add TLS to MQTT** — All conversations and auth token travel in plaintext. Set `client.secure = true`, configure TLS on AIBroker broker *(fixed 2026-03-25 — self-signed cert auto-generated at ~/.aibroker/tls/, onBadCertificate accepts it; TODO: pin cert fingerprint)*
10
+- [x] **C3: Remove debug log files in production** — `mqtt_debug.log` and `_chatLog` write truncated message content to Documents. Wrap in `kDebugMode` or remove entirely *(fixed 2026-03-25)*
11
+
12
+## HIGH (Should fix before submission)
13
+
14
+- [x] **H1: Unbounded image cache** — `_imageCache` in message_bubble.dart grows without limit. Add LRU eviction (cap at 50) *(fixed 2026-03-25)*
15
+- [x] **H2: Audio temp files never cleaned** — `_base64ToFile` creates .m4a files never deleted. Clean up after playback completes *(fixed 2026-03-25)*
16
+- [x] **H3: TextEditingController leak** — Rename dialog in session_drawer.dart creates controller but never disposes it *(fixed 2026-03-25)*
17
+- [x] **H4: Input validation on settings** — No validation on host IPs, port range, MAC format. Add regex validators *(fixed 2026-03-25)*
18
+- [x] **H5: LifecycleObserver never removed** — AudioService.init() adds observer but dispose() doesn't remove it *(fixed 2026-03-25)*
19
+- [ ] **H6: MQTT token in memory** — Acceptable for personal use, document as known limitation
20
+
21
+## MEDIUM (Improve before submission)
22
+
23
+- [x] **M1: Subnet scan hammers 254 hosts** — Batched in groups of 20 with early exit *(fixed 2026-03-25)*
24
+- [x] **M2: No loadMore debounce** — Added isLoadingMore guard *(fixed 2026-03-25)*
25
+- [x] **M3: NavigateNotifier global singleton** — Moved to `navigateNotifierProvider` (StateProvider) in providers.dart; NavigateNotifier class extracted to `lib/services/navigate_notifier.dart` *(fixed 2026-04-01)*
26
+- [x] **M4: Unbounded _seenSeqs set** — Replaced O(n log n) sort-based eviction with FIFO List+Set pair; O(1) eviction by removing oldest entry from list front *(fixed 2026-04-01)*
27
+- [x] **M5: Screenshots bloat iCloud backup** — Messages directory excluded from iCloud/iTunes backup via NSURLIsExcludedFromBackupKey (MethodChannel com.mnsoft.pailot/backup registered in SceneDelegate); screenshots are in-memory only (never persisted) *(fixed 2026-04-01)*
28
+- [x] **M6: Unused import** — Already removed *(fixed 2026-03-25)*
29
+- [x] **M7: Silent error swallowing** — Added debugPrint on config load failure *(fixed 2026-03-25)*
30
+
31
+## LOW (Nice-to-haves)
32
+
33
+- [x] **L1: PrivacyInfo.xcprivacy** — Created `ios/Runner/PrivacyInfo.xcprivacy` declaring UserDefaults (CA92.1), FileTimestamp (C617.1), DiskSpace (E174.1); added to Xcode project Copy Bundle Resources phase *(fixed 2026-04-01)*
34
+- [x] **L2: Privacy policy** — Created `PRIVACY.md` at repo root; describes self-hosted server model, no third-party data collection *(fixed 2026-04-01)*
35
+- [x] **L3: Unused dependencies** — Removed web_socket_channel and wakelock_plus *(fixed 2026-03-25)*
36
+- [x] **L4: Unnecessary _http._tcp** — Removed from NSBonjourServices *(fixed 2026-03-25)*
37
+- [x] **L5: Typing indicator timeout** — Auto-clear after 10s *(fixed 2026-03-25)*
38
+- [x] **L6: Version number** — Already `1.0.0+1` in pubspec.yaml *(confirmed 2026-04-01)*
39
+- [x] **L7: App icon** — All required sizes present (20x20 through 1024x1024, iPhone + iPad); Flutter-generated icons have no alpha channel *(confirmed 2026-04-01)*
40
+
41
+## APNs Push Notifications (implemented 2026-04-01)
42
+
43
+- [x] **APNs server side** — `src/apns/client.ts` in AIBroker: ApnsClient initialised from APNS_KEY_PATH/APNS_KEY_ID/APNS_TEAM_ID env vars, sandbox by default. Token storage in `~/.aibroker/apns-tokens.json`. `sendPush()` fires when `getMqttClientCount() == 0`.
44
+- [x] **APNs Flutter side** — `lib/services/push_service.dart`: `push` package (3.3.3, no Firebase). Requests permission on app start, publishes token to `pailot/device/token` MQTT topic. Re-registers on reconnect.
45
+- [x] **Entitlements** — `ios/Runner/Runner.entitlements` with `aps-environment=development`. All three build configs have `CODE_SIGN_ENTITLEMENTS` set.
46
+- [x] **UIBackgroundModes** — `remote-notification` added to Info.plist.
47
+- [x] **AppDelegate** — forwards UNUserNotificationCenter delegate methods to push plugin.
48
+- [ ] **Provisioning profile** — APNs requires an explicit provisioning profile from Apple Developer portal that includes Push Notifications capability. Must update in Xcode before deployment. Switch `aps-environment` to `production` in entitlements for App Store builds.
49
+
50
+## App Store Requirements
51
+
52
+| Requirement | Status | Action |
53
+|------------|--------|--------|
54
+| NSMicrophoneUsageDescription | PASS | - |
55
+| NSCameraUsageDescription | PASS | - |
56
+| NSPhotoLibraryUsageDescription | PASS | - |
57
+| NSLocalNetworkUsageDescription | PASS | - |
58
+| NSBonjourServices | PASS | Fixed - removed _http._tcp |
59
+| NSAppTransportSecurity | PASS | Fixed - removed NSAllowsArbitraryLoads |
60
+| UIBackgroundModes: audio | PASS | - |
61
+| UIBackgroundModes: remote-notification | PASS | Added 2026-04-01 |
62
+| Push Notifications entitlement | PASS | Added Runner.entitlements 2026-04-01 |
63
+| APNs provisioning profile | FAIL | Must update in Xcode / Developer Portal |
64
+| Privacy Policy | PASS | Fixed L2 - PRIVACY.md created |
65
+| PrivacyInfo.xcprivacy | PASS | Fixed L1 - declared UserDefaults/FileTimestamp/DiskSpace |
66
+| TLS for network | PASS | Fixed C2 - self-signed cert, onBadCertificate=true |
TODO.md
....@@ -0,0 +1,71 @@
1
+# PAILot Flutter - TODO
2
+
3
+## High Priority
4
+
5
+### MQTT Protocol Migration — NEXT MAJOR TASK
6
+Replace ad-hoc WebSocket protocol with MQTT for reliable, ordered messaging.
7
+
8
+**Why:** Current protocol has no delivery guarantees, no message ordering, no offline queuing.
9
+Messages get lost on daemon restart, duplicated on catch_up, and arrive out of order.
10
+
11
+**Server (AIBroker):**
12
+- Embed MQTT broker (aedes) in daemon alongside existing WebSocket
13
+- Topics: `pailot/{sessionId}/out` (server→app), `pailot/{sessionId}/in` (app→server)
14
+- System topics: `pailot/sessions`, `pailot/status`, `pailot/typing/{sessionId}`
15
+- QoS 1 (at-least-once) for messages, QoS 0 for typing indicators
16
+- Retained messages for session list and last screenshot
17
+- Clean session=false so broker queues messages for offline clients
18
+- Bridge MQTT messages to/from existing AIBP routing
19
+
20
+**Flutter App:**
21
+- Replace WebSocket client with mqtt_client package
22
+- Subscribe to `pailot/+/out` for all session messages
23
+- Publish to `pailot/{sessionId}/in` for user messages
24
+- Message ID-based dedup (MQTT can deliver duplicates with QoS 1)
25
+- Ordered by broker — no client-side sorting needed
26
+- Offline messages delivered automatically on reconnect
27
+
28
+**Migration:**
29
+- Phase 1: Add MQTT alongside WebSocket, dual-publish
30
+- Phase 2: Flutter app switches to MQTT
31
+- Phase 3: Remove WebSocket from PAILot gateway
32
+
33
+## Pending Features
34
+
35
+### File Transfer (send/receive arbitrary files)
36
+- File picker in app (PDFs, Word docs, attachments, etc.)
37
+- New `file` message type in WebSocket protocol
38
+- Gateway handler to save received files and route to session
39
+- Session can send files back via `pailot_send_file`
40
+- Display file attachments in chat bubbles (icon + filename + tap to open)
41
+
42
+### Voice+Image Combined Message
43
+- When voice caption is recorded with images, hold images on server until voice transcript arrives
44
+- Deliver transcript + images together as one message to Claude
45
+- Ensures voice prefix sets reply channel correctly
46
+
47
+### Push Notifications (iOS APNs) — NEXT SESSION with user at computer
48
+- **Step 1**: User creates APNs key in Apple Developer Portal (needs login)
49
+- **Step 2**: Save `.p8` key to `~/.aibroker/apns-key.p8`, add env vars (key ID, team ID)
50
+- **Step 3**: Server-side APNs HTTP/2 sender (`src/daemon/apns.ts`) with JWT auth
51
+- **Step 4**: App sends device token on WebSocket connect
52
+- **Step 5**: Gateway buffers messages when no WS clients, sends push notification
53
+- **Step 6**: App receives push → user taps → opens app → catch_up drains messages
54
+- Optional: silent push to wake app briefly for critical messages
55
+
56
+### App Name Renaming (Runner → PAILot)
57
+- Rename Xcode target from Runner to PAILot (like Glidr did)
58
+- Update scheme names, bundle paths
59
+
60
+## Known Issues
61
+
62
+### Audio
63
+- Background audio may not survive full app termination (only screen lock)
64
+- Audio session category may conflict with phone calls
65
+
66
+### UI
67
+- Launch image still uses default Flutter placeholder
68
+- No app splash screen with PAILot branding
69
+
70
+### Navigation
71
+- vi keys (0, G, dd) are sent as literal text paste — works for Claude Code but may not for other terminals
analysis_options.yaml
....@@ -0,0 +1,28 @@
1
+# This file configures the analyzer, which statically analyzes Dart code to
2
+# check for errors, warnings, and lints.
3
+#
4
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6
+# invoked from the command line by running `flutter analyze`.
7
+
8
+# The following line activates a set of recommended lints for Flutter apps,
9
+# packages, and plugins designed to encourage good coding practices.
10
+include: package:flutter_lints/flutter.yaml
11
+
12
+linter:
13
+ # The lint rules applied to this project can be customized in the
14
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15
+ # included above or to enable additional rules. A list of all available lints
16
+ # and their documentation is published at https://dart.dev/lints.
17
+ #
18
+ # Instead of disabling a lint rule for the entire project in the
19
+ # section below, it can also be suppressed for a single line of code
20
+ # or a specific dart file by using the `// ignore: name_of_lint` and
21
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
22
+ # producing the lint.
23
+ rules:
24
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
25
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
26
+
27
+# Additional information about this file can be found at
28
+# https://dart.dev/guides/language/analysis-options
android/.gitignore
....@@ -0,0 +1,14 @@
1
+gradle-wrapper.jar
2
+/.gradle
3
+/captures/
4
+/gradlew
5
+/gradlew.bat
6
+/local.properties
7
+GeneratedPluginRegistrant.java
8
+.cxx/
9
+
10
+# Remember to never publicly share your keystore.
11
+# See https://flutter.dev/to/reference-keystore
12
+key.properties
13
+**/*.keystore
14
+**/*.jks
android/app/build.gradle.kts
....@@ -0,0 +1,44 @@
1
+plugins {
2
+ id("com.android.application")
3
+ id("kotlin-android")
4
+ // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
5
+ id("dev.flutter.flutter-gradle-plugin")
6
+}
7
+
8
+android {
9
+ namespace = "com.tekmidian.pailot"
10
+ compileSdk = flutter.compileSdkVersion
11
+ ndkVersion = flutter.ndkVersion
12
+
13
+ compileOptions {
14
+ sourceCompatibility = JavaVersion.VERSION_17
15
+ targetCompatibility = JavaVersion.VERSION_17
16
+ }
17
+
18
+ kotlinOptions {
19
+ jvmTarget = JavaVersion.VERSION_17.toString()
20
+ }
21
+
22
+ defaultConfig {
23
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
24
+ applicationId = "com.tekmidian.pailot"
25
+ // You can update the following values to match your application needs.
26
+ // For more information, see: https://flutter.dev/to/review-gradle-config.
27
+ minSdk = flutter.minSdkVersion
28
+ targetSdk = flutter.targetSdkVersion
29
+ versionCode = flutter.versionCode
30
+ versionName = flutter.versionName
31
+ }
32
+
33
+ buildTypes {
34
+ release {
35
+ // TODO: Add your own signing config for the release build.
36
+ // Signing with the debug keys for now, so `flutter run --release` works.
37
+ signingConfig = signingConfigs.getByName("debug")
38
+ }
39
+ }
40
+}
41
+
42
+flutter {
43
+ source = "../.."
44
+}
android/app/src/debug/AndroidManifest.xml
....@@ -0,0 +1,7 @@
1
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <!-- The INTERNET permission is required for development. Specifically,
3
+ the Flutter tool needs it to communicate with the running application
4
+ to allow setting breakpoints, to provide hot reload, etc.
5
+ -->
6
+ <uses-permission android:name="android.permission.INTERNET"/>
7
+</manifest>
android/app/src/main/AndroidManifest.xml
....@@ -0,0 +1,40 @@
1
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.INTERNET"/>
3
+ <uses-permission android:name="android.permission.RECORD_AUDIO"/>
4
+ <uses-permission android:name="android.permission.CAMERA"/>
5
+ <uses-permission android:name="android.permission.VIBRATE"/>
6
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
7
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
8
+ <application
9
+ android:label="PAILot"
10
+ android:name="${applicationName}"
11
+ android:icon="@mipmap/ic_launcher">
12
+ <activity
13
+ android:name=".MainActivity"
14
+ android:exported="true"
15
+ android:launchMode="singleTop"
16
+ android:taskAffinity=""
17
+ android:theme="@style/LaunchTheme"
18
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
19
+ android:hardwareAccelerated="true"
20
+ android:windowSoftInputMode="adjustResize">
21
+ <meta-data
22
+ android:name="io.flutter.embedding.android.NormalTheme"
23
+ android:resource="@style/NormalTheme"
24
+ />
25
+ <intent-filter>
26
+ <action android:name="android.intent.action.MAIN"/>
27
+ <category android:name="android.intent.category.LAUNCHER"/>
28
+ </intent-filter>
29
+ </activity>
30
+ <meta-data
31
+ android:name="flutterEmbedding"
32
+ android:value="2" />
33
+ </application>
34
+ <queries>
35
+ <intent>
36
+ <action android:name="android.intent.action.PROCESS_TEXT"/>
37
+ <data android:mimeType="text/plain"/>
38
+ </intent>
39
+ </queries>
40
+</manifest>
android/app/src/main/kotlin/com/tekmidian/pailot/MainActivity.kt
....@@ -0,0 +1,5 @@
1
+package com.tekmidian.pailot
2
+
3
+import io.flutter.embedding.android.FlutterActivity
4
+
5
+class MainActivity : FlutterActivity()
android/app/src/main/res/drawable-v21/launch_background.xml
....@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!-- Modify this file to customize your launch splash screen -->
3
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <item android:drawable="?android:colorBackground" />
5
+
6
+ <!-- You can insert your own image assets here -->
7
+ <!-- <item>
8
+ <bitmap
9
+ android:gravity="center"
10
+ android:src="@mipmap/launch_image" />
11
+ </item> -->
12
+</layer-list>
android/app/src/main/res/drawable/launch_background.xml
....@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!-- Modify this file to customize your launch splash screen -->
3
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <item android:drawable="@android:color/white" />
5
+
6
+ <!-- You can insert your own image assets here -->
7
+ <!-- <item>
8
+ <bitmap
9
+ android:gravity="center"
10
+ android:src="@mipmap/launch_image" />
11
+ </item> -->
12
+</layer-list>
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
....@@ -0,0 +1,5 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@color/ic_launcher_background"/>
4
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5
+</adaptive-icon>
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Binary files differ
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Binary files differ
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Binary files differ
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
Binary files differ
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Binary files differ
android/app/src/main/res/values-night/styles.xml
....@@ -0,0 +1,18 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<resources>
3
+ <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
4
+ <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
5
+ <!-- Show a splash screen on the activity. Automatically removed when
6
+ the Flutter engine draws its first frame -->
7
+ <item name="android:windowBackground">@drawable/launch_background</item>
8
+ </style>
9
+ <!-- Theme applied to the Android Window as soon as the process has started.
10
+ This theme determines the color of the Android Window while your
11
+ Flutter UI initializes, as well as behind your Flutter UI while its
12
+ running.
13
+
14
+ This Theme is only used starting with V2 of Flutter's Android embedding. -->
15
+ <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
16
+ <item name="android:windowBackground">?android:colorBackground</item>
17
+ </style>
18
+</resources>
android/app/src/main/res/values/colors.xml
....@@ -0,0 +1,4 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<resources>
3
+ <color name="ic_launcher_background">#0A0A1A</color>
4
+</resources>
android/app/src/main/res/values/styles.xml
....@@ -0,0 +1,18 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<resources>
3
+ <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
4
+ <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
5
+ <!-- Show a splash screen on the activity. Automatically removed when
6
+ the Flutter engine draws its first frame -->
7
+ <item name="android:windowBackground">@drawable/launch_background</item>
8
+ </style>
9
+ <!-- Theme applied to the Android Window as soon as the process has started.
10
+ This theme determines the color of the Android Window while your
11
+ Flutter UI initializes, as well as behind your Flutter UI while its
12
+ running.
13
+
14
+ This Theme is only used starting with V2 of Flutter's Android embedding. -->
15
+ <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
16
+ <item name="android:windowBackground">?android:colorBackground</item>
17
+ </style>
18
+</resources>
android/app/src/profile/AndroidManifest.xml
....@@ -0,0 +1,7 @@
1
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <!-- The INTERNET permission is required for development. Specifically,
3
+ the Flutter tool needs it to communicate with the running application
4
+ to allow setting breakpoints, to provide hot reload, etc.
5
+ -->
6
+ <uses-permission android:name="android.permission.INTERNET"/>
7
+</manifest>
android/build.gradle.kts
....@@ -0,0 +1,24 @@
1
+allprojects {
2
+ repositories {
3
+ google()
4
+ mavenCentral()
5
+ }
6
+}
7
+
8
+val newBuildDir: Directory =
9
+ rootProject.layout.buildDirectory
10
+ .dir("../../build")
11
+ .get()
12
+rootProject.layout.buildDirectory.value(newBuildDir)
13
+
14
+subprojects {
15
+ val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
16
+ project.layout.buildDirectory.value(newSubprojectBuildDir)
17
+}
18
+subprojects {
19
+ project.evaluationDependsOn(":app")
20
+}
21
+
22
+tasks.register<Delete>("clean") {
23
+ delete(rootProject.layout.buildDirectory)
24
+}
android/gradle.properties
....@@ -0,0 +1,2 @@
1
+org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
2
+android.useAndroidX=true
android/gradle/wrapper/gradle-wrapper.properties
....@@ -0,0 +1,5 @@
1
+distributionBase=GRADLE_USER_HOME
2
+distributionPath=wrapper/dists
3
+zipStoreBase=GRADLE_USER_HOME
4
+zipStorePath=wrapper/dists
5
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
android/settings.gradle.kts
....@@ -0,0 +1,26 @@
1
+pluginManagement {
2
+ val flutterSdkPath =
3
+ run {
4
+ val properties = java.util.Properties()
5
+ file("local.properties").inputStream().use { properties.load(it) }
6
+ val flutterSdkPath = properties.getProperty("flutter.sdk")
7
+ require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
8
+ flutterSdkPath
9
+ }
10
+
11
+ includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
12
+
13
+ repositories {
14
+ google()
15
+ mavenCentral()
16
+ gradlePluginPortal()
17
+ }
18
+}
19
+
20
+plugins {
21
+ id("dev.flutter.flutter-plugin-loader") version "1.0.0"
22
+ id("com.android.application") version "8.11.1" apply false
23
+ id("org.jetbrains.kotlin.android") version "2.2.20" apply false
24
+}
25
+
26
+include(":app")
app.json
deleted file mode 100644
....@@ -1,70 +0,0 @@
1
-{
2
- "expo": {
3
- "name": "PAILot",
4
- "slug": "pailot",
5
- "version": "1.0.0",
6
- "orientation": "portrait",
7
- "icon": "./assets/icon.png",
8
- "userInterfaceStyle": "automatic",
9
- "newArchEnabled": true,
10
- "scheme": "pailot",
11
- "splash": {
12
- "image": "./assets/icon.png",
13
- "resizeMode": "contain",
14
- "backgroundColor": "#0A0A0F"
15
- },
16
- "ios": {
17
- "supportsTablet": true,
18
- "bundleIdentifier": "org.mnsoft.pailot",
19
- "appleTeamId": "7KU642K5ZL",
20
- "infoPlist": {
21
- "NSMicrophoneUsageDescription": "PAILot needs microphone access for voice input.",
22
- "NSPhotoLibraryUsageDescription": "PAILot needs photo library access to send images.",
23
- "NSCameraUsageDescription": "PAILot needs camera access to take photos.",
24
- "UIBackgroundModes": [
25
- "audio"
26
- ]
27
- }
28
- },
29
- "android": {
30
- "adaptiveIcon": {
31
- "backgroundColor": "#0A0A0F",
32
- "foregroundImage": "./assets/android-icon-foreground.png",
33
- "backgroundImage": "./assets/android-icon-background.png",
34
- "monochromeImage": "./assets/android-icon-monochrome.png"
35
- },
36
- "package": "org.mnsoft.pailot",
37
- "permissions": [
38
- "RECORD_AUDIO",
39
- "READ_MEDIA_IMAGES",
40
- "CAMERA"
41
- ]
42
- },
43
- "web": {
44
- "favicon": "./assets/favicon.png",
45
- "bundler": "metro"
46
- },
47
- "plugins": [
48
- ["expo-splash-screen", {
49
- "image": "./assets/icon.png",
50
- "backgroundColor": "#0A0A0F",
51
- "imageWidth": 200
52
- }],
53
- "expo-router",
54
- [
55
- "expo-audio",
56
- {
57
- "microphonePermission": "PAILot needs microphone access for voice input."
58
- }
59
- ],
60
- "expo-secure-store",
61
- [
62
- "expo-image-picker",
63
- {
64
- "photosPermission": "PAILot needs photo library access to send images.",
65
- "cameraPermission": "PAILot needs camera access to take photos."
66
- }
67
- ]
68
- ]
69
- }
70
-}
app/_layout.tsx
deleted file mode 100644
....@@ -1,34 +0,0 @@
1
-import "../global.css";
2
-import { Stack } from "expo-router";
3
-import { ConnectionProvider } from "../contexts/ConnectionContext";
4
-import { ChatProvider } from "../contexts/ChatContext";
5
-import { ThemeProvider, useTheme } from "../contexts/ThemeContext";
6
-import { StatusBar } from "expo-status-bar";
7
-
8
-function InnerLayout() {
9
- const { isDark, colors } = useTheme();
10
- return (
11
- <>
12
- <StatusBar style={isDark ? "light" : "dark"} backgroundColor={colors.bg} />
13
- <Stack
14
- screenOptions={{
15
- headerShown: false,
16
- contentStyle: { backgroundColor: colors.bg },
17
- animation: "slide_from_right",
18
- }}
19
- />
20
- </>
21
- );
22
-}
23
-
24
-export default function RootLayout() {
25
- return (
26
- <ThemeProvider>
27
- <ConnectionProvider>
28
- <ChatProvider>
29
- <InnerLayout />
30
- </ChatProvider>
31
- </ConnectionProvider>
32
- </ThemeProvider>
33
- );
34
-}
app/chat.tsx
deleted file mode 100644
....@@ -1,363 +0,0 @@
1
-import React, { useCallback, useEffect, useRef, useState } from "react";
2
-import { ActionSheetIOS, Alert, KeyboardAvoidingView, Platform, Pressable, Text, View } from "react-native";
3
-import { SafeAreaView } from "react-native-safe-area-context";
4
-import { router } from "expo-router";
5
-import { useChat } from "../contexts/ChatContext";
6
-import { useConnection } from "../contexts/ConnectionContext";
7
-import { useTheme } from "../contexts/ThemeContext";
8
-import { MessageList } from "../components/chat/MessageList";
9
-import { InputBar } from "../components/chat/InputBar";
10
-import { CommandBar, TextModeCommandBar } from "../components/chat/CommandBar";
11
-import { ImageCaptionModal } from "../components/chat/ImageCaptionModal";
12
-import { StatusDot } from "../components/ui/StatusDot";
13
-import { IncomingToast } from "../components/ui/IncomingToast";
14
-import { SessionDrawer } from "../components/SessionDrawer";
15
-import { playAudio, stopPlayback, isPlaying, onPlayingChange } from "../services/audio";
16
-
17
-interface StagedImage {
18
- base64: string;
19
- uri: string;
20
- mimeType: string;
21
-}
22
-
23
-export default function ChatScreen() {
24
- const { messages, sendTextMessage, sendVoiceMessage, sendImageMessage, deleteMessage, clearMessages, isTyping, requestScreenshot, sessions, switchSession, loadMoreMessages, hasMoreMessages, incomingToast, dismissToast } =
25
- useChat();
26
- const { status } = useConnection();
27
- const { colors, mode, cycleMode } = useTheme();
28
- const themeIcon = mode === "dark" ? "🌙" : mode === "light" ? "☀️" : "📱";
29
- const activeSessionName = sessions.find((s) => s.isActive)?.name ?? "PAILot";
30
- const [isTextMode, setIsTextMode] = useState(false);
31
- const [showSessions, setShowSessions] = useState(false);
32
- const [audioPlaying, setAudioPlaying] = useState(false);
33
- const [stagedImages, setStagedImages] = useState<StagedImage[]>([]);
34
-
35
- useEffect(() => {
36
- return onPlayingChange((uri) => setAudioPlaying(uri !== null));
37
- }, []);
38
-
39
- const handleToastTap = useCallback(() => {
40
- if (incomingToast) {
41
- switchSession(incomingToast.sessionId);
42
- dismissToast();
43
- }
44
- }, [incomingToast, switchSession, dismissToast]);
45
-
46
- const handleScreenshot = useCallback(() => {
47
- requestScreenshot();
48
- }, [requestScreenshot]);
49
-
50
- const handleHelp = useCallback(() => {
51
- sendTextMessage("/h");
52
- }, [sendTextMessage]);
53
-
54
- const handleNavigate = useCallback(() => {
55
- router.push("/navigate");
56
- }, []);
57
-
58
- const handleClear = useCallback(() => {
59
- clearMessages();
60
- }, [clearMessages]);
61
-
62
- // Resolve picked assets into StagedImage array
63
- const stageAssets = useCallback(async (assets: Array<{ base64?: string | null; uri: string; mimeType?: string | null }>) => {
64
- const staged: StagedImage[] = [];
65
- for (const asset of assets) {
66
- const mimeType = asset.mimeType ?? (asset.uri.endsWith(".png") ? "image/png" : "image/jpeg");
67
- let base64 = asset.base64 ?? "";
68
- if (!base64 && asset.uri) {
69
- const { readAsStringAsync } = await import("expo-file-system/legacy");
70
- base64 = await readAsStringAsync(asset.uri, { encoding: "base64" });
71
- }
72
- if (base64) staged.push({ base64, uri: asset.uri, mimeType });
73
- }
74
- if (staged.length > 0) setStagedImages(staged);
75
- }, []);
76
-
77
- const pickFromLibrary = useCallback(async () => {
78
- try {
79
- const ImagePicker = await import("expo-image-picker");
80
- const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
81
- if (status !== "granted") {
82
- Alert.alert("Permission needed", "Please allow photo library access in Settings.");
83
- return;
84
- }
85
- const result = await ImagePicker.launchImageLibraryAsync({
86
- mediaTypes: ["images"],
87
- allowsMultipleSelection: true,
88
- selectionLimit: 10,
89
- quality: 0.7,
90
- base64: true,
91
- });
92
- if (result.canceled || !result.assets?.length) return;
93
- await stageAssets(result.assets);
94
- } catch (err: any) {
95
- Alert.alert("Image Error", err?.message ?? String(err));
96
- }
97
- }, [stageAssets]);
98
-
99
- const pickFromCamera = useCallback(async () => {
100
- try {
101
- const ImagePicker = await import("expo-image-picker");
102
- const { status } = await ImagePicker.requestCameraPermissionsAsync();
103
- if (status !== "granted") {
104
- Alert.alert("Permission needed", "Please allow camera access in Settings.");
105
- return;
106
- }
107
- const result = await ImagePicker.launchCameraAsync({
108
- quality: 0.7,
109
- base64: true,
110
- });
111
- if (result.canceled || !result.assets?.[0]) return;
112
- await stageAssets([result.assets[0]]);
113
- } catch (err: any) {
114
- Alert.alert("Camera Error", err?.message ?? String(err));
115
- }
116
- }, [stageAssets]);
117
-
118
- const handlePickImage = useCallback(() => {
119
- if (Platform.OS === "ios") {
120
- ActionSheetIOS.showActionSheetWithOptions(
121
- {
122
- options: ["Cancel", "Take Photo", "Choose from Library"],
123
- cancelButtonIndex: 0,
124
- },
125
- (index) => {
126
- if (index === 1) pickFromCamera();
127
- else if (index === 2) pickFromLibrary();
128
- },
129
- );
130
- } else {
131
- // Android: just open library (camera is accessible from there)
132
- pickFromLibrary();
133
- }
134
- }, [pickFromCamera, pickFromLibrary]);
135
-
136
- const handleImageSend = useCallback(
137
- (caption: string) => {
138
- if (stagedImages.length === 0) return;
139
- // Send each image as a separate message; caption on the first only
140
- stagedImages.forEach((img, i) => {
141
- sendImageMessage(img.base64, i === 0 ? caption : "", img.mimeType);
142
- });
143
- setStagedImages([]);
144
- },
145
- [stagedImages, sendImageMessage],
146
- );
147
-
148
- const handleReplay = useCallback(async () => {
149
- if (isPlaying()) {
150
- stopPlayback();
151
- return;
152
- }
153
- // Find the last assistant voice message, then walk back to the first chunk in that group
154
- let lastIdx = -1;
155
- for (let i = messages.length - 1; i >= 0; i--) {
156
- if (messages[i].role === "assistant" && messages[i].type === "voice" && messages[i].audioUri) {
157
- lastIdx = i;
158
- break;
159
- }
160
- }
161
- if (lastIdx === -1) return;
162
-
163
- // Walk back to find the start of this chunk group
164
- let startIdx = lastIdx;
165
- while (startIdx > 0) {
166
- const prev = messages[startIdx - 1];
167
- if (prev.role === "assistant" && prev.type === "voice" && prev.audioUri) {
168
- startIdx--;
169
- } else {
170
- break;
171
- }
172
- }
173
-
174
- // Queue all chunks from start to last
175
- await stopPlayback();
176
- for (let i = startIdx; i <= lastIdx; i++) {
177
- const m = messages[i];
178
- if (m.audioUri) playAudio(m.audioUri);
179
- }
180
- }, [messages]);
181
-
182
- return (
183
- <SafeAreaView style={{ flex: 1, backgroundColor: colors.bg }} edges={["top", "bottom"]}>
184
- <KeyboardAvoidingView
185
- style={{ flex: 1 }}
186
- behavior={Platform.OS === "ios" ? "padding" : undefined}
187
- keyboardVerticalOffset={0}
188
- >
189
- {/* Header */}
190
- <View
191
- style={{
192
- flexDirection: "row",
193
- alignItems: "center",
194
- justifyContent: "space-between",
195
- paddingHorizontal: 16,
196
- paddingVertical: 12,
197
- borderBottomWidth: 1,
198
- borderBottomColor: colors.border,
199
- }}
200
- >
201
- <View style={{ flexDirection: "row", alignItems: "center", flex: 1, gap: 10 }}>
202
- <Pressable
203
- onPress={() => setShowSessions(true)}
204
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
205
- style={({ pressed }) => ({
206
- width: 36,
207
- height: 36,
208
- alignItems: "center",
209
- justifyContent: "center",
210
- borderRadius: 18,
211
- backgroundColor: pressed ? colors.bgTertiary : colors.bgTertiary + "80",
212
- })}
213
- >
214
- <Text style={{ color: colors.textSecondary, fontSize: 18 }}>☰</Text>
215
- </Pressable>
216
- <Pressable
217
- onPress={() => setShowSessions(true)}
218
- style={{ flexDirection: "row", alignItems: "center", gap: 8, flex: 1 }}
219
- hitSlop={{ top: 6, bottom: 6, left: 0, right: 6 }}
220
- >
221
- <Text
222
- style={{
223
- color: colors.text,
224
- fontSize: 22,
225
- fontWeight: "800",
226
- letterSpacing: -0.5,
227
- flexShrink: 1,
228
- }}
229
- numberOfLines={1}
230
- >
231
- {activeSessionName}
232
- </Text>
233
- <StatusDot status={status} size={8} />
234
- </Pressable>
235
- </View>
236
-
237
- <View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
238
- <Pressable
239
- onPress={cycleMode}
240
- hitSlop={{ top: 6, bottom: 6, left: 6, right: 6 }}
241
- style={({ pressed }) => ({
242
- width: 36,
243
- height: 36,
244
- alignItems: "center",
245
- justifyContent: "center",
246
- borderRadius: 18,
247
- backgroundColor: pressed ? colors.bgTertiary : colors.bgTertiary + "80",
248
- })}
249
- >
250
- <Text style={{ fontSize: 15 }}>{themeIcon}</Text>
251
- </Pressable>
252
- <Pressable
253
- onPress={() => router.push("/settings")}
254
- hitSlop={{ top: 6, bottom: 6, left: 6, right: 6 }}
255
- style={{
256
- width: 36,
257
- height: 36,
258
- alignItems: "center",
259
- justifyContent: "center",
260
- borderRadius: 18,
261
- backgroundColor: colors.bgTertiary,
262
- }}
263
- >
264
- <Text style={{ fontSize: 15 }}>⚙️</Text>
265
- </Pressable>
266
- </View>
267
- </View>
268
-
269
- {/* Message list */}
270
- <View style={{ flex: 1, position: "relative" }}>
271
- {/* Toast for other-session incoming messages */}
272
- {incomingToast && (
273
- <IncomingToast
274
- sessionName={incomingToast.sessionName}
275
- preview={incomingToast.preview}
276
- onTap={handleToastTap}
277
- onDismiss={dismissToast}
278
- />
279
- )}
280
- {messages.length === 0 ? (
281
- <View style={{ flex: 1, alignItems: "center", justifyContent: "center", gap: 16 }}>
282
- <View
283
- style={{
284
- width: 80,
285
- height: 80,
286
- borderRadius: 40,
287
- backgroundColor: colors.bgTertiary,
288
- alignItems: "center",
289
- justifyContent: "center",
290
- borderWidth: 1,
291
- borderColor: colors.border,
292
- }}
293
- >
294
- <Text style={{ fontSize: 36 }}>🛩</Text>
295
- </View>
296
- <View style={{ alignItems: "center", gap: 6 }}>
297
- <Text style={{ color: colors.text, fontSize: 20, fontWeight: "700" }}>
298
- PAILot
299
- </Text>
300
- <Text
301
- style={{
302
- color: colors.textMuted,
303
- fontSize: 14,
304
- textAlign: "center",
305
- paddingHorizontal: 40,
306
- lineHeight: 20,
307
- }}
308
- >
309
- Voice-first AI communicator.{"\n"}Tap the mic to start talking.
310
- </Text>
311
- </View>
312
- </View>
313
- ) : (
314
- <MessageList messages={messages} isTyping={isTyping} onDeleteMessage={deleteMessage} onLoadMore={loadMoreMessages} hasMore={hasMoreMessages} />
315
- )}
316
- </View>
317
-
318
- {/* Command bar */}
319
- {isTextMode ? (
320
- <TextModeCommandBar
321
- onScreenshot={handleScreenshot}
322
- onNavigate={handleNavigate}
323
- onPhoto={handlePickImage}
324
- onHelp={handleHelp}
325
- onClear={handleClear}
326
- />
327
- ) : (
328
- <CommandBar
329
- onScreenshot={handleScreenshot}
330
- onNavigate={handleNavigate}
331
- onPhoto={handlePickImage}
332
- onClear={handleClear}
333
- />
334
- )}
335
-
336
- {/* Input bar */}
337
- <InputBar
338
- onSendText={sendTextMessage}
339
- onVoiceRecorded={sendVoiceMessage}
340
- onReplay={handleReplay}
341
- isTextMode={isTextMode}
342
- onToggleMode={() => setIsTextMode((v) => !v)}
343
- audioPlaying={audioPlaying}
344
- />
345
-
346
- </KeyboardAvoidingView>
347
-
348
- {/* Image caption modal — WhatsApp-style full-screen preview */}
349
- <ImageCaptionModal
350
- visible={stagedImages.length > 0}
351
- images={stagedImages.map((img) => ({ uri: `data:${img.mimeType};base64,${img.base64}` }))}
352
- onSend={handleImageSend}
353
- onCancel={() => setStagedImages([])}
354
- />
355
-
356
- {/* Session drawer — absolute overlay outside KAV */}
357
- <SessionDrawer
358
- visible={showSessions}
359
- onClose={() => setShowSessions(false)}
360
- />
361
- </SafeAreaView>
362
- );
363
-}
app/index.tsx
deleted file mode 100644
....@@ -1,5 +0,0 @@
1
-import { Redirect } from "expo-router";
2
-
3
-export default function Index() {
4
- return <Redirect href="/chat" />;
5
-}
app/navigate.tsx
deleted file mode 100644
....@@ -1,179 +0,0 @@
1
-import React, { useEffect } from "react";
2
-import { Image, Pressable, Text, View } from "react-native";
3
-import { SafeAreaView } from "react-native-safe-area-context";
4
-import { router } from "expo-router";
5
-import * as Haptics from "expo-haptics";
6
-import { useChat } from "../contexts/ChatContext";
7
-
8
-interface NavButton {
9
- label: string;
10
- key: string;
11
- icon?: string;
12
- flex?: number;
13
-}
14
-
15
-const NAV_ROWS: NavButton[][] = [
16
- // Row 1: Vi motion
17
- [
18
- { label: "0", key: "0" },
19
- { label: "k", key: "k", icon: "↑" },
20
- { label: "G", key: "G" },
21
- { label: "dd", key: "dd" },
22
- ],
23
- // Row 2: Arrow keys
24
- [
25
- { label: "h", key: "h", icon: "←" },
26
- { label: "j", key: "j", icon: "↓" },
27
- { label: "l", key: "l", icon: "→" },
28
- { label: "Esc", key: "escape" },
29
- ],
30
- // Row 3: Action keys
31
- [
32
- { label: "Tab", key: "tab" },
33
- { label: "Enter", key: "enter", flex: 2 },
34
- { label: "^C", key: "ctrl-c" },
35
- ],
36
-];
37
-
38
-export default function NavigateScreen() {
39
- const { latestScreenshot, requestScreenshot, sendNavKey } = useChat();
40
-
41
- // Request a screenshot when entering navigation mode
42
- useEffect(() => {
43
- requestScreenshot();
44
- }, [requestScreenshot]);
45
-
46
- function handleNavPress(key: string) {
47
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
48
- sendNavKey(key);
49
- }
50
-
51
- return (
52
- <SafeAreaView style={{ flex: 1, backgroundColor: "#0A0A0F" }} edges={["top", "bottom"]}>
53
- {/* Header */}
54
- <View
55
- style={{
56
- flexDirection: "row",
57
- alignItems: "center",
58
- justifyContent: "space-between",
59
- paddingHorizontal: 16,
60
- paddingVertical: 10,
61
- borderBottomWidth: 1,
62
- borderBottomColor: "#2E2E45",
63
- }}
64
- >
65
- <Pressable
66
- onPress={() => router.back()}
67
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
68
- style={{
69
- width: 36,
70
- height: 36,
71
- alignItems: "center",
72
- justifyContent: "center",
73
- borderRadius: 18,
74
- backgroundColor: "#1E1E2E",
75
- }}
76
- >
77
- <Text style={{ color: "#E8E8F0", fontSize: 16 }}>←</Text>
78
- </Pressable>
79
- <Text style={{ color: "#E8E8F0", fontSize: 18, fontWeight: "700" }}>
80
- Navigate
81
- </Text>
82
- <Pressable
83
- onPress={() => requestScreenshot()}
84
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
85
- style={{
86
- paddingHorizontal: 12,
87
- paddingVertical: 8,
88
- borderRadius: 12,
89
- backgroundColor: "#1E1E2E",
90
- }}
91
- >
92
- <Text style={{ color: "#4A9EFF", fontSize: 14, fontWeight: "600" }}>
93
- Refresh
94
- </Text>
95
- </Pressable>
96
- </View>
97
-
98
- {/* Screenshot area */}
99
- <View style={{ flex: 1, padding: 8 }}>
100
- {latestScreenshot ? (
101
- <Image
102
- source={{ uri: `data:image/png;base64,${latestScreenshot}` }}
103
- style={{
104
- flex: 1,
105
- borderRadius: 12,
106
- backgroundColor: "#14141F",
107
- }}
108
- resizeMode="contain"
109
- />
110
- ) : (
111
- <View
112
- style={{
113
- flex: 1,
114
- alignItems: "center",
115
- justifyContent: "center",
116
- backgroundColor: "#14141F",
117
- borderRadius: 12,
118
- }}
119
- >
120
- <Text style={{ color: "#5A5A78", fontSize: 16 }}>
121
- Loading screenshot...
122
- </Text>
123
- </View>
124
- )}
125
- </View>
126
-
127
- {/* Navigation buttons */}
128
- <View
129
- style={{
130
- paddingHorizontal: 16,
131
- paddingBottom: 12,
132
- gap: 10,
133
- }}
134
- >
135
- {NAV_ROWS.map((row, rowIdx) => (
136
- <View
137
- key={rowIdx}
138
- style={{
139
- flexDirection: "row",
140
- gap: 10,
141
- }}
142
- >
143
- {row.map((btn) => (
144
- <Pressable
145
- key={btn.key}
146
- onPress={() => handleNavPress(btn.key)}
147
- style={({ pressed }) => ({
148
- flex: btn.flex ?? 1,
149
- height: 56,
150
- borderRadius: 14,
151
- alignItems: "center",
152
- justifyContent: "center",
153
- backgroundColor: pressed ? "#4A9EFF" : "#1E1E2E",
154
- borderWidth: 1.5,
155
- borderColor: pressed ? "#4A9EFF" : "#2E2E45",
156
- })}
157
- >
158
- {btn.icon ? (
159
- <View style={{ alignItems: "center" }}>
160
- <Text style={{ color: "#E8E8F0", fontSize: 20, fontWeight: "700" }}>
161
- {btn.icon}
162
- </Text>
163
- <Text style={{ color: "#5A5A78", fontSize: 10, marginTop: 1 }}>
164
- {btn.label}
165
- </Text>
166
- </View>
167
- ) : (
168
- <Text style={{ color: "#E8E8F0", fontSize: 16, fontWeight: "700" }}>
169
- {btn.label}
170
- </Text>
171
- )}
172
- </Pressable>
173
- ))}
174
- </View>
175
- ))}
176
- </View>
177
- </SafeAreaView>
178
- );
179
-}
app/settings.tsx
deleted file mode 100644
....@@ -1,365 +0,0 @@
1
-import React, { useCallback, useState } from "react";
2
-import {
3
- Alert,
4
- Keyboard,
5
- KeyboardAvoidingView,
6
- Platform,
7
- Pressable,
8
- ScrollView,
9
- Text,
10
- TextInput,
11
- TouchableWithoutFeedback,
12
- View,
13
-} from "react-native";
14
-import { SafeAreaView } from "react-native-safe-area-context";
15
-import { router } from "expo-router";
16
-import { useConnection } from "../contexts/ConnectionContext";
17
-import { useTheme } from "../contexts/ThemeContext";
18
-import { StatusDot } from "../components/ui/StatusDot";
19
-import { ServerConfig } from "../types";
20
-import { sendWol, isValidMac } from "../services/wol";
21
-import { wsClient } from "../services/websocket";
22
-
23
-export default function SettingsScreen() {
24
- const { serverConfig, status, connect, disconnect, saveServerConfig } =
25
- useConnection();
26
- const { colors } = useTheme();
27
-
28
- const [host, setHost] = useState(serverConfig?.host ?? "");
29
- const [localHost, setLocalHost] = useState(serverConfig?.localHost ?? "");
30
- const [port, setPort] = useState(
31
- serverConfig?.port ? String(serverConfig.port) : "8765"
32
- );
33
- const [macAddress, setMacAddress] = useState(serverConfig?.macAddress ?? "");
34
- const [saved, setSaved] = useState(false);
35
- const [waking, setWaking] = useState(false);
36
-
37
- const handleSave = useCallback(async () => {
38
- const trimmedHost = host.trim();
39
- const portNum = parseInt(port.trim(), 10);
40
-
41
- const trimmedLocal = localHost.trim();
42
- if ((!trimmedHost && !trimmedLocal) || isNaN(portNum) || portNum < 1 || portNum > 65535) {
43
- return;
44
- }
45
-
46
- const trimmedMac = macAddress.trim();
47
- const effectiveHost = trimmedHost || trimmedLocal;
48
- const config: ServerConfig = {
49
- host: effectiveHost,
50
- port: portNum,
51
- ...(trimmedLocal && trimmedHost ? { localHost: trimmedLocal } : {}),
52
- ...(trimmedMac ? { macAddress: trimmedMac } : {}),
53
- };
54
- await saveServerConfig(config);
55
- setSaved(true);
56
- setTimeout(() => setSaved(false), 2000);
57
- }, [host, localHost, port, macAddress, saveServerConfig]);
58
-
59
- const handleConnect = useCallback(() => {
60
- if (status === "connected" || status === "connecting" || status === "reconnecting") {
61
- disconnect();
62
- } else {
63
- connect();
64
- }
65
- }, [status, connect, disconnect]);
66
-
67
- const handleWake = useCallback(async () => {
68
- const mac = macAddress.trim() || serverConfig?.macAddress;
69
- if (!mac || !isValidMac(mac)) {
70
- Alert.alert("Invalid MAC", "Enter a valid MAC address (e.g. 6a:8a:e7:b3:8e:5c)");
71
- return;
72
- }
73
- setWaking(true);
74
- try {
75
- await sendWol(mac, host.trim() || serverConfig?.host);
76
- Alert.alert("WoL Sent", "Magic packet sent. The Mac should wake in a few seconds.");
77
- } catch (err) {
78
- Alert.alert("WoL Failed", err instanceof Error ? err.message : String(err));
79
- } finally {
80
- setWaking(false);
81
- }
82
- }, [macAddress, host, serverConfig]);
83
-
84
- const isFormValid = (host.trim().length > 0 || localHost.trim().length > 0) && parseInt(port, 10) > 0;
85
-
86
- return (
87
- <SafeAreaView style={{ flex: 1, backgroundColor: colors.bg }} edges={["top", "bottom"]}>
88
- <KeyboardAvoidingView
89
- style={{ flex: 1 }}
90
- behavior={Platform.OS === "ios" ? "padding" : "height"}
91
- >
92
- <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
93
- <ScrollView
94
- style={{ flex: 1 }}
95
- contentContainerStyle={{ paddingBottom: 32 }}
96
- keyboardShouldPersistTaps="handled"
97
- >
98
- {/* Header */}
99
- <View
100
- style={{
101
- flexDirection: "row",
102
- alignItems: "center",
103
- paddingHorizontal: 16,
104
- paddingVertical: 12,
105
- borderBottomWidth: 1,
106
- borderBottomColor: colors.border,
107
- }}
108
- >
109
- <Pressable
110
- onPress={() => router.back()}
111
- hitSlop={{ top: 6, bottom: 6, left: 6, right: 6 }}
112
- style={{
113
- width: 36,
114
- height: 36,
115
- alignItems: "center",
116
- justifyContent: "center",
117
- borderRadius: 18,
118
- backgroundColor: colors.bgTertiary,
119
- marginRight: 12,
120
- }}
121
- >
122
- <Text style={{ color: colors.text, fontSize: 16 }}>{"\u2190"}</Text>
123
- </Pressable>
124
- <Text style={{ color: colors.text, fontSize: 22, fontWeight: "800", letterSpacing: -0.5 }}>
125
- Settings
126
- </Text>
127
- </View>
128
-
129
- <View style={{ paddingHorizontal: 16, marginTop: 24 }}>
130
- {/* Connection status card */}
131
- <View
132
- style={{
133
- backgroundColor: colors.bgTertiary,
134
- borderRadius: 16,
135
- padding: 16,
136
- marginBottom: 24,
137
- }}
138
- >
139
- <Text
140
- style={{
141
- color: colors.textSecondary,
142
- fontSize: 11,
143
- fontWeight: "500",
144
- textTransform: "uppercase",
145
- letterSpacing: 1.5,
146
- marginBottom: 12,
147
- }}
148
- >
149
- Connection Status
150
- </Text>
151
- <View style={{ flexDirection: "row", alignItems: "center", gap: 12 }}>
152
- <StatusDot status={status} size={12} />
153
- <Text style={{ color: colors.text, fontSize: 16, fontWeight: "500" }}>
154
- {status === "connected"
155
- ? "Connected"
156
- : status === "connecting"
157
- ? "Connecting..."
158
- : status === "reconnecting"
159
- ? "Reconnecting..."
160
- : "Disconnected"}
161
- </Text>
162
- </View>
163
- {serverConfig && (
164
- <Text style={{ color: colors.textMuted, fontSize: 14, marginTop: 8 }}>
165
- {wsClient.currentUrl || `ws://${serverConfig.host}:${serverConfig.port}`}
166
- </Text>
167
- )}
168
- </View>
169
-
170
- {/* Server config */}
171
- <Text
172
- style={{
173
- color: colors.textSecondary,
174
- fontSize: 11,
175
- fontWeight: "500",
176
- textTransform: "uppercase",
177
- letterSpacing: 1.5,
178
- marginBottom: 12,
179
- }}
180
- >
181
- Server Configuration
182
- </Text>
183
-
184
- <View
185
- style={{
186
- backgroundColor: colors.bgTertiary,
187
- borderRadius: 16,
188
- overflow: "hidden",
189
- marginBottom: 16,
190
- }}
191
- >
192
- {/* Local Host (preferred when on same network) */}
193
- <View
194
- style={{
195
- paddingHorizontal: 16,
196
- paddingVertical: 12,
197
- borderBottomWidth: 1,
198
- borderBottomColor: colors.border,
199
- }}
200
- >
201
- <Text style={{ color: colors.textMuted, fontSize: 11, marginBottom: 4 }}>
202
- Local Address (optional)
203
- </Text>
204
- <TextInput
205
- value={localHost}
206
- onChangeText={setLocalHost}
207
- placeholder="192.168.1.100"
208
- placeholderTextColor={colors.textMuted}
209
- autoCapitalize="none"
210
- autoCorrect={false}
211
- keyboardType="url"
212
- style={{ color: colors.text, fontSize: 16, padding: 0 }}
213
- />
214
- </View>
215
-
216
- {/* Remote Host (fallback / external) */}
217
- <View
218
- style={{
219
- paddingHorizontal: 16,
220
- paddingVertical: 12,
221
- borderBottomWidth: 1,
222
- borderBottomColor: colors.border,
223
- }}
224
- >
225
- <Text style={{ color: colors.textMuted, fontSize: 11, marginBottom: 4 }}>
226
- Remote Address
227
- </Text>
228
- <TextInput
229
- value={host}
230
- onChangeText={setHost}
231
- placeholder="myhost.example.com"
232
- placeholderTextColor={colors.textMuted}
233
- autoCapitalize="none"
234
- autoCorrect={false}
235
- keyboardType="url"
236
- style={{ color: colors.text, fontSize: 16, padding: 0 }}
237
- />
238
- </View>
239
-
240
- {/* Port */}
241
- <View
242
- style={{
243
- paddingHorizontal: 16,
244
- paddingVertical: 12,
245
- borderBottomWidth: 1,
246
- borderBottomColor: colors.border,
247
- }}
248
- >
249
- <Text style={{ color: colors.textMuted, fontSize: 11, marginBottom: 4 }}>
250
- Port
251
- </Text>
252
- <TextInput
253
- value={port}
254
- onChangeText={setPort}
255
- placeholder="8765"
256
- placeholderTextColor={colors.textMuted}
257
- keyboardType="number-pad"
258
- style={{ color: colors.text, fontSize: 16, padding: 0 }}
259
- />
260
- </View>
261
-
262
- {/* MAC Address for Wake-on-LAN */}
263
- <View style={{ paddingHorizontal: 16, paddingVertical: 12 }}>
264
- <Text style={{ color: colors.textMuted, fontSize: 11, marginBottom: 4 }}>
265
- MAC Address (Wake-on-LAN)
266
- </Text>
267
- <TextInput
268
- value={macAddress}
269
- onChangeText={setMacAddress}
270
- placeholder="6a:8a:e7:b3:8e:5c"
271
- placeholderTextColor={colors.textMuted}
272
- autoCapitalize="none"
273
- autoCorrect={false}
274
- style={{ color: colors.text, fontSize: 16, padding: 0 }}
275
- />
276
- </View>
277
- </View>
278
-
279
- {/* Save button */}
280
- <Pressable
281
- onPress={handleSave}
282
- disabled={!isFormValid}
283
- style={{
284
- borderRadius: 16,
285
- paddingVertical: 16,
286
- alignItems: "center",
287
- marginBottom: 12,
288
- backgroundColor: isFormValid ? colors.accent : colors.bgTertiary,
289
- }}
290
- >
291
- <Text
292
- style={{
293
- fontSize: 16,
294
- fontWeight: "600",
295
- color: isFormValid ? "#FFF" : colors.textMuted,
296
- }}
297
- >
298
- {saved ? "Saved!" : "Save Configuration"}
299
- </Text>
300
- </Pressable>
301
-
302
- {/* Wake-on-LAN button */}
303
- <Pressable
304
- onPress={handleWake}
305
- disabled={waking || (!macAddress.trim() && !serverConfig?.macAddress)}
306
- style={{
307
- borderRadius: 16,
308
- paddingVertical: 16,
309
- alignItems: "center",
310
- marginBottom: 12,
311
- backgroundColor:
312
- macAddress.trim() || serverConfig?.macAddress
313
- ? "#FF950033"
314
- : colors.bgTertiary,
315
- }}
316
- >
317
- <Text
318
- style={{
319
- fontSize: 16,
320
- fontWeight: "600",
321
- color:
322
- macAddress.trim() || serverConfig?.macAddress
323
- ? "#FF9500"
324
- : colors.textMuted,
325
- }}
326
- >
327
- {waking ? "Sending..." : "Wake Mac (WoL)"}
328
- </Text>
329
- </Pressable>
330
-
331
- {/* Connect/Disconnect button */}
332
- <Pressable
333
- onPress={handleConnect}
334
- disabled={!serverConfig}
335
- style={{
336
- borderRadius: 16,
337
- paddingVertical: 16,
338
- alignItems: "center",
339
- backgroundColor:
340
- status === "connected"
341
- ? colors.danger + "33"
342
- : "#2ED57333",
343
- }}
344
- >
345
- <Text
346
- style={{
347
- fontSize: 16,
348
- fontWeight: "600",
349
- color: status === "connected" ? colors.danger : "#2ED573",
350
- }}
351
- >
352
- {status === "connected"
353
- ? "Disconnect"
354
- : status === "connecting" || status === "reconnecting"
355
- ? "Reconnecting..."
356
- : "Connect"}
357
- </Text>
358
- </Pressable>
359
- </View>
360
- </ScrollView>
361
- </TouchableWithoutFeedback>
362
- </KeyboardAvoidingView>
363
- </SafeAreaView>
364
- );
365
-}
assets/PAILot.ai
....@@ -0,0 +1,1509 @@
1
+%PDF-1.6 %âãÏÓ
2
+1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[22 0 R]/Order 23 0 R/RBGroups[]>>/OCGs[22 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 47668/Subtype/XML/Type/Metadata>>stream
3
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
4
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 10.0-c000 1.000000, 0000/00/00-00:00:00 ">
5
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
6
+ <rdf:Description rdf:about=""
7
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
8
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
9
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
10
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
11
+ xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
12
+ xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
13
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
14
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
15
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
16
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
17
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
18
+ xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">
19
+ <dc:format>application/pdf</dc:format>
20
+ <dc:title>
21
+ <rdf:Alt>
22
+ <rdf:li xml:lang="x-default">PAILot</rdf:li>
23
+ </rdf:Alt>
24
+ </dc:title>
25
+ <xmp:CreatorTool>Adobe Illustrator 30.2 (Macintosh)</xmp:CreatorTool>
26
+ <xmp:CreateDate>2026-03-21T16:14:39+01:00</xmp:CreateDate>
27
+ <xmp:ModifyDate>2026-03-21T16:14:39+01:00</xmp:ModifyDate>
28
+ <xmp:MetadataDate>2026-03-21T16:14:39+01:00</xmp:MetadataDate>
29
+ <xmp:Thumbnails>
30
+ <rdf:Alt>
31
+ <rdf:li rdf:parseType="Resource">
32
+ <xmpGImg:width>256</xmpGImg:width>
33
+ <xmpGImg:height>256</xmpGImg:height>
34
+ <xmpGImg:format>JPEG</xmpGImg:format>
35
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEAAAAAAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAAAAAAAAEA&#xA;AQAAAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A4aufQpUqyZAsCrpkC1lX&#xA;TKy1lXTIFgVdMgWsq6ZWWBVkyBYFXTIFgUQmQLAq6ZWWBV0yBYFEJlZYlXTIFgVdMrLAq8eQLEoh&#xA;MrLEq6ZAsCiEyBYlEJlZYFXTKyxKV67pV68bXmlzy296gqwidk9QD/VI+LbMrTZ4g8MwDHz6OXpd&#xA;UYGidmP2H5nfmDprAW+u3fw7BJ3+sKKduMwkGZ+XsfSZOeOPw2+6ndRzTHVmOi/85Jea7UqmrWNt&#xA;qMQ6unK3lP8AshzT/hM1Go9kcEv7uUoH5j9f2t8dVLq9K8s/nx5C1pkhuLhtJu3oPTvQFjJPhMpM&#xA;dP8AWK5zms9mtVh3A44/0efy5/K3IjniXocckcsayROHjcBkdSCpB3BBHXNAQQaLcuwK7FXYq7FX&#xA;Yq7FX57eYrA6d5i1TTyOJs7ye3K0pQxSslKbeGe+6TL4mGE/50QfmFKDTLSwKumQLWVdMrLWVdMg&#xA;WBV0yBayrplZYFWTIFgVdMgWBRCZAsCrplZYFXTIFgUQmVliVdMgWBV0yssCrx5AsSiEyssSrpkC&#xA;wKITIFiUQmVlgVdMrLEohMgWJYP560EW8o1O3WkMxpOo/ZkP7X+y/Xm67N1PEOA8xydpos/EOE8w&#xA;w5s24diFJ8kGQZB5S/Mfzd5SmB0i+ZbatZLGb95bv41jJ+EnxWh98wNd2Tp9UP3kd/5w2Pz/AFts&#xA;JmPJ9C/l9+e/lnzO0VhqNNI1l6KsMrVglY7fupTTc/ytQ+Fc4HtT2azaa5w/eY/LmPeP0j7HLhlB&#xA;em5zba7FXYq7FXYq+Kvz/wBCbSPzV1gBaQ35jvoT4idAZD/yND57J7L6nxdDDvjcfly+ylLz9M3x&#xA;YFXTIFrKumVlrKumQLAq6ZAtZV0yssCrJkCwKumQLAohMgWBV0yssCrpkCwKITKyxKumQLAq6ZWW&#xA;BV48gWJRCZWWJV0yBYFEJkCxKITKywKumVliUQmQLEtXllDfWU1pMKxzKVPt4Ee4O+OPIYSEh0TC&#xA;ZjIEdHjt/aS2l3NazCkkLFG+g9fpzrsUxOIkOReihISAIQj5aGwKL5MMgpNkwzD178q/z91HQnh0&#xA;jzO8l9ouyRXhq9xbDoK95Ix4faA6V+znJ9tezEM4OTB6cnd0l+o/Z397kQyVzfTFjfWd/Zw3tlMl&#xA;xaXCCSCeMhkdW3BBGeb5McoSMZCpDmHIV8grsVdir5+/5yy8qGbTdI80QJVrR2sb1hufTl+OEn2V&#xA;ww+bDO99h9bU54D/ABeoe8bH7K+SvmtM9FLAq6ZAtZV0ystZV0yBYFXTIFrKumVlgVZMgWBV0yBY&#xA;FEJkCwKumVlgVdMgWBRCZWWJV0yBYFXTKywKvHkCxKITKyxKumQLAohMgWJRCZWWBV0yssSiEyBY&#xA;lXTKyxLz38yNNEOow3yCi3ScXP8Alx0H4qRm/wCyc1wMf5v6Xcdn5LiY9zDHzcB2IUXyYZBSbJhm&#xA;FJskGYeh/lD+b+oeStRWyvXe58t3LgXFvUsYCx3mhH/El/a+eaDt3sGGshxR2zDke/yP6D0bYSp9&#xA;cWN9Z39nDe2UyXFpcIJIJ4zyV0YVBBGeUZMcoSMZCpDmHIV8grsVSjzd5bs/M3lnUdBu9odQhaLn&#xA;SvB/tRyAeKOAw+WZeg1ctNmjljzib/WPiNlfBuq6Tf6Pqt3pWoRmG9spXgnjPZkNDTxB6g9xnuWD&#xA;PHLjGSBuMhYYFSTJFrKumVlrKumQLAq6ZAtZZp+VFtoF5530/T9etVu7C+LW/B2ZeMrr+6YFSp+2&#xA;Av05pu255YaaU8R4ZR3+HX7E4wDKi+kh+TX5Zj/pRRf8jJ/+qmed/wAv63/VD8h+pzPAh3Nj8nfy&#xA;1HTQ4v8AkZN/zXg/l7Wf6ofkP1I/Lw7ni35yeRbXyv5ghl02H0dI1CPlBGCzCOSOiyICxJ8G3Pf2&#xA;zsuwO0panERM3kid/MHkf0OBqsXAduRYImbsuGVdMgWBRCZWWJV0yBYFXTKywKvHkCxKITKyxKum&#xA;QLAohMgWJRCZWWBV0yssSiEyBYlXTKyxKQ+f7IXHlySQCr2zpKPGleDfg2Z3ZeThzAd+zl6CdZK7&#xA;3lD51Id8FF8mGQUmyYZhSbJBmFFsmGYex/8AOP35svoOpR+V9Yn/ANwl/JSymkO1tcOaUqekch69&#xA;g2/ds5H2o7D8eHj4x+8iN/6Q/WPu27m2BfUueYtrsVdir57/AOcm/wAs3mVfO+lxcnjVYdajQVJQ&#xA;fDHcf7HZG9qeBzvvY/tiv8Gmee8P0x/SPixkHzqmeglqKumVlrKumQLAq6ZAtZRthdT2d3Dd27cJ&#xA;7eRZYn8HQhlP3jKcsBOJieRFMbp9vaFqsGr6LY6pB/dX0Ec6Dw9RQ3H5itM8X1OA4skoHnEkfJ2c&#xA;TYtHZQlin5neUx5m8o3dnGnO+gH1mw8fVjB+Ef661X6c2nY+u/LagSP0naXuP6ubTnx8ca6vlRQQ&#xA;aHYjqM9QLpCrpkCwKITKyxKumQLAq6ZWWBV48gWJRCZWWJV0yBYFEJkCxKITKywKumVliUQmQLEq&#xA;6ZWWJUdYtvrOjXsHeSCQD58TT8cnp58OSJ8wzwGskT5vEHztA9MFF8mGQUmyYZhSbJBmFFsmGYUm&#xA;yYZh9df84/fmOfNXlb9G38pfW9GCxTsx+KWA7RS1PU7cW9xU/azyf2o7J/K5+OA/d5Nx5HqP0j9j&#xA;bEvU85hk7FVO4t4Lm3ltriNZreZGjmicBldHFGVgeoINDkoTMSCDRCvj785PymuvJOstdWUby+W7&#xA;1ybOfdvRc1Jt5D4r+yT9oe4OetdgduR1mPhkazR5jv8A6Q/T3H4NMxTz1M35airpkCwKumQLWVdM&#xA;rLAvqD/nHfX/ANIeSH02R6z6RO0YXqfRmrLGT/si4HyzzX2r0vh6njHLIPtGx/Q5umlca7nqWcw5&#xA;DsVfM/5yeUzoXm6W5hTjYaryuYKCgWQn98n0MeXyIz0jsDXePpxE/VDY+7ofx3On1ePhlfQsITNy&#xA;XDKITKyxKumQLAq6ZWWBV48gWJRCZWWJV0yBYFEJkCxKITKywKumVliUQmQLEq6ZWWJVJhW3lB6c&#xA;G/VgjzCI8w8GfO4D1QUXyYZBSbJhmFJskGYUWyYZhSbJhmGSfln51m8nedLDWgT9VVvR1CNf27aU&#xA;gSCncrs6j+YDNb2x2eNXppY/4ucf6w5fq9xZxfc8Usc0SSxMHikUPG6mqsrCoII7EZ4nKJBo82xd&#xA;gV2KoHW9E0vXNLuNK1W3W6sLpeE0L9COoII3BB3BG4OXafUTwzGTGeGUVIfJ35q/k3q/kq7e9tQ9&#xA;75clb9zeAVaHkdo56dD2DdG9jtnqnYvb+PWR4ZenMOY7/OP6ujjzhTz5M3xaSrpkC1lXTKywL1b/&#xA;AJx41/8AR/nZtOkfjBq0DRAHp60X7yM/8CHH05y/tVpfE03GOcDfwOx/Q3aaVSrvfTmebOe7FWG/&#xA;mx5THmLyjcLEnK/sK3VmQKsSg+OMf66VFPGmbjsTXfl9QL+mWx/X8HH1OLjh5h8xJnpJdGUQmVli&#xA;VdMgWBV0yssCrx5AsSiEyssSrpkCwKITIFiUQmVlgVdMrLEohMgWJV0yssS6+mWHT7mZjRY4ncn2&#xA;VScOONzA7ynHG5Aebwp87YPUBRfJhkFJsmGYUmyQZhRbJhmFJsmGYUWyQZB9if8AOOvm1tf/AC5t&#xA;raeTne6K5sJamrGNAGgb5emwT/Y55H7V6HwNYZD6cnq+PX7d/i2B6fnNJdirsVWTwQ3EMkE8aywy&#xA;qUlicBlZWFCrKdiCMlGRibBohXhf5hf84229w8mo+TXW3larPpMzUiJ6n0ZDXh/qtt7gbZ23Zftc&#xA;YgQ1G4/nDn8R194+RaJ4u54Xquhazot61lq1nNZXS9YpkKkjxWuzD3G2dtg1OPNHixyEo+TiyBHN&#xA;QTJlrKaaDqs+k6zY6pB/fWU8c6Ad/TYNT6aUzG1OEZccoHlIEIBo2+2bO7gvLSC7t25wXEayxP4o&#xA;6hlP3HPGskDCRieYNO1BtVyCXYq+YvzV8qf4e83XCwpwsL7/AEqzp9kBz8aD/Ueu3hTPSexdb4+n&#xA;F/VHY/oPxDpNVi4J+RYqmbQuIVdMgWBV0yssCrx5AsSiEyssSrpkCwKITIFiUQmVlgVdMrLEohMg&#xA;WJV0yssSlHna9Fr5aut6PPSBPfmd/wDhQcy+zsfFmHlu5GihxZR5bvIXzrA9CFF8mGQUmyYZhSbJ&#xA;BmFFsmGYUmyYZhRbJBkHtX/OKfmA2fnLUdFdqQ6raeoi+M1q3JR/yLkk+7ON9ttLx6eOUc4S+yX7&#xA;QGwPqnPMEuxV2KuxV2KoLVtE0fWLU2mq2cN7bH/dU6K4B8RUbH3GXYNRkxS4scjE+SCAebzPXv8A&#xA;nG/ybes0mlXNxpMjdIwfrEI/2MhEn/JTOk03tbqIbZBGf2H7NvsaJaeJ5MMv/wDnGnzVCxNhqdld&#xA;IOnq+rA5+gLKv/DZuMXtfgP1wlH3Uf1NMtLLoXtP5d6VrmkeUNP0vWuH16xVoOUbc1MSsfSoaDol&#xA;B9Gcd2rmxZdRKeP6Zb/Hr9rlYokRosjzXNjsVYj+ZXkX/F2jRW8MiQX9rKJLaaQHjRvhkQkAmjDf&#xA;5gZtuyO0vyuQki4yG4+5x9Tg8SNdXnkf/OPutBRz1W2B7gJIR/DN+fanH/Ml9jg/ydLvCMj/AOcf&#xA;rkMOetoF7kW5J+71BlJ9qI/6n/sv2L/Jp/nfYi4vyCjU/vNcZh2C2wX9crZVL2nPTH/sv2J/kv8A&#xA;pfZ+1FRfkTpyj95qszHsViVf1lsql7ST6QHzX+S4/wA5FR/kjoSqOWoXRbuR6YH3cTlZ9osv82P2&#xA;p/kqHeUSn5M+V1IJub1qdRziofuiyo+0Gfuj8j+tP8lY++X2fqRA/KPyqP27r/kYv/NGQ/l3P/R+&#xA;X7U/yVi80q1b8ogkbSaReFmHSC5pv8pFAH3rmVg7ds1kj8R+pxc3ZG1wPzYJdWN3Y3T2t3E0NxGa&#xA;PG3Uf1Hvm7hkjOPFE2C6TJjlA1IUW0xLUVdMrLEsB/MrVBLdwach+G3X1JR/luPhH0L+vN72RhqJ&#xA;mertezsdAy72EPm6DtAovkwyCk2TDMKTZIMwotkwzCk2TDMKLZIMgyv8odWOlfmd5bu68Qb2O3Zu&#xA;lFuq27V/2MpzV9u4PF0WWP8AQJ/0vq/Q2B90Z4kl2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2&#xA;KuxV2KuxV2KsZ89eWYdX0t7iJANQtVLwuOrKu7Rn59vf6c2XZusOKdH6Jfi3X9o6QZYWPqH4p5Cm&#xA;dYXkytvr+CwsZryY/u4V5U7k9Ao+Z2w4sRnIRHVMIGcgA8ev7ua8u5rqY1lmYux+fYewzrcUBCIi&#xA;OQeihERAA6IR8tDYFF8mGQUmyYZhSbJBmFFsmGYUmyYZhRbJBkFXTLs2ep2l2DQ208coO+3Bw3b5&#xA;ZHNDjhKPeCGwP0OzwBLsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirwfVrdLf&#xA;WL63QUSG4ljUDwVyB+rO4wSMscSesR9zxGojw5JAdCXmnnTzAL64FlbtW0tz8TDo8nSvyXoM6Ps/&#xA;S8A4j9Rdjo8HCOI8yxVs2gc8KT5IMgovkwyCk2TDMKTZIMwotkwzCk2TDMKLZIMgpNkw2B+jGfPa&#xA;XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqpXVzDa20tzM3GGFGkkbwVRU5KEDK&#xA;QiOZYzmIgk8g+WPOnm4zT3MNq3764d3uZVOy8ySVU+O+5z07s/QUAZchyeXw4TKRnLqbYG2bwOwC&#xA;k2TDMKT5IMgovkwyCk2TDMKTZIMwotkwzCk2TDMKLZIMgusrZru9t7Va8p5UiFOtXYL3+eOSfDEy&#xA;7hbYH6I58/JdirsVdirsVdirsVWSzwQrymkWNfFyFH45KMSeQQZAc3QXEE6epBIksdSOaMGFR1FR&#xA;jKJiaIpYyB3C/IpdirsVdirsVdirsVdirsVdirTMqqWYhVUVJOwAGIFq8G/OT814r8N5f8v3PO0B&#xA;/wBOvYj8MhHSONu6g7lh17Z3PYHYhh+9zD1fwju8y63VZhL0jk8XbOxDihRbJBkFJsmGYUnyQZBR&#xA;fJhkFJsmGYUmyQZhRbJhmFJsmGYUWyQZBkn5XaYdT/Mby5Z05K2oQSSL1rHC4lcf8ChzX9s5vD0e&#xA;WX9A/aKDYH3fnhyXYq7FXYql+q6/pOlJyvbhY2IqsQ+J2+Sjf6cvwabJlPpDj59VjxD1FhOrfmpM&#xA;SyaXahF7TT7n6EU0H3nNzg7FHOZ+Tp83bJO0B82J6j5v8y3pPrahKFP7ER9JaeFE41+nNri0GGHK&#xA;I+/73X5NbmnzkfuSOZ3dizsWY9WY1J+/M2IA5OPdvePKel/ozy7Y2ZHGRYw8o7+pJ8bfcWpnEa7N&#xA;4maUvN7DSYvDxRj5JtmI5DsVeX/nP5iCQW+gwP8AFJS4vKfyg/u0PzPxfQM6X2f0lk5T02H6XUdq&#xA;Z9hAe8vJvrd0oAWZ1C/ZoxFKeG+dVwRPR1AkVw1rWUYMl/cKw6MJXB/A4Py+M/wx+QbBkl3lcvmr&#xA;zPGSY9XvUJ6lbmUfqbAdFgPOEP8AShmM0/5x+a5fPHnKMUXW72nX4p5GP3sTg/k3Tn/Jw+QZjUZP&#xA;5x+a4fmP55ReK61c0Hi1T95BOP8AJOlP+Ti2DU5P5xX/APK2PzCQgrrElR0rHCR9xQ5H+RNIf4B8&#xA;z+tmNXk71zfnJ+ZA/wClx/07Wv8A1SwDsDR/zP8AZS/WzGryd/3JFrvnnzdrcPoapqk9xb94KhIz&#xA;Q1+JIwqt9IzO03Zunwm4QAPf1+ZYyzTlzLHHzYBiFFsmGQUWyQZBSbJhmFJ8kGQUXyYZBSbJhmFJ&#xA;skGYUWyYZhSbJhmFFskGQev/APOLegNf/mFNqrLWHR7SR1fwmuP3KD6Y2k+7OT9s9VwaQY+uSQ+Q&#xA;3++mwPrTPKkuxVp3SNGd2CIoJZmNAAOpJOEAk0EEgCywLzJ+YT1a20fYDZrxhuf+Man9ZzeaTsr+&#xA;LJ8v1ug1na/8OL5/qYFcTTTStLM7SSvuzuSzE+5ObyMQBQ2Do5SMjZ3KGfLAoUXyYSmPlXS/0n5i&#xA;sbQryjMgeYf5Efxt94FMx9bm8PDKXWnL0eLxMsYvec4d7B2KqN7eQWVnNd3DcYLdGkkbwVRU5PHj&#xA;M5CI5ljOQiCTyD5r1/VrjV9XutSn/vLly3HrxUbKo/1VAGei6XAMWMQHR5TLlM5GR6pW2ZIYhRbJ&#xA;hkFJsmEhRfJBkFFsmGYUXyYZBRfJhkFJsmGQUXyQZhRbJhkFFskGQUmyYZhSfJBkFF8mGQUmyYZh&#xA;SbJBmFFsmGYUmyYZhRbJBkH1t/zjL5VOkfl+dUmTjda7Mbip2b6vFWOEH6ebj2bPKvbDW+Lq+AfT&#xA;jFfE7n9A+DYHrucmlbLLHFG0srBI0BZ3Y0AA6knCASaCJSAFnk8x81+bJ9Vka2tyY9PQ7L0MhH7T&#xA;e3gM6XQ6EYhZ+v7nku0O0TmPDHaH3sXfNkHXBRbrk0qL5IMgovkwln35SaXyub3U3XaNRbxN7t8T&#xA;/cAv35ou3M20YfF3vY+Lcz+D0zOcd87FXnP5xeYfq+nw6LA9Jbv97cgdREh+EH/WcfhnQ9g6Ximc&#xA;h5R2Hv8Ax97qe1M9REB15vHXzrQ6QKLZMMgotkwyCk2TCQovkgyCi2TDMKL5MMgovkwyCk2TDIKL&#xA;5IMwotkwyCi2SDIKTZMMwpPkgyCi+TDIKTZMMwpNkgzCi2TDMKTZMMwm/kryrd+avNWnaFbBgbyV&#xA;VmlUV9OEbyyf7FATmJ2jrY6XBLLL+EbeZ6D5sw+77CxtdPsbextIxFa2sSQwRDoscahVUfIDPDsu&#xA;SWSRlI3KRs/FsV8grAPPnmIzTHSrZ/3MR/0ph+04/Y+S9/f5ZvuzNJQ8SXM8nmu19bxHw48hz/Uw&#xA;xumbgOjUXyQZBRbrk0qL5IMgovkwl7X5E0z9H+WLNGWks6/WJfnLuK/JOIzju0s3iZ5HoNvk9d2f&#xA;i4MIHfv80/zAc1TuLiG3gkuJmCQwqXkc9AqipP3ZKETIgDmUSkALL5z8zazLrOtXWoyVAmc+mh/Z&#xA;jXZF+hRnoOk04w4xAdPveTz5TkmZd6TvmWGsKLZMMgotkwyCk2TCQovkgyCi2TDMKL5MMgovkwyC&#xA;k2TDIKL5IMwotkwyCi2SDIKTZMMwpPkgyCi+TDIKTZMMwpNkgzCi2TDMKTZMMw+o/wDnGv8ALh9F&#xA;0STzTqMXHUdXQLZIw+KOzqGB+czAN/qhfE55l7XdreNlGCB9GPn5y/4799tsQ9qzjWSWeZNWGl6R&#xA;Ncg/vj+7gH/FjdPu65k6TB4uQR6dXE12p8HEZdenveRMzMxZiSzGpJ6knOrAp4km1rdMkFUXyQZB&#xA;Rbrk0qL5IMgiNH05tS1e0sR0nlVXp2StWP0LXIajL4eOUu4N+nxeJMR7y97VVVQqiiqKADoAM4Ul&#xA;7UBvFWBfm35gNnpMekwtSe/3mp1EKH/jdtvkDm97D0vHk8Q8o/e6vtTPww4Bzl9zxp868OgCi+SD&#xA;IKLZMMgotkwyCk2TCQovkgyCi2TDMKL5MMgovkwyCk2TDIKL5IMwotkwyCi2SDIKTZMMwpPkgyCi&#xA;+TDIKTZMMwpNkgzCi2TDMPSfyP8Ayrk85a6L/UIj/h3TXBuWI2nlFGW3U/i/gvzGc77R9tDSYuCB&#xA;/fT5eQ/nfq8/c2wFvr5VVVCqAqqKKo2AA7DPJSbbW8Vee/mNqJkv4LFT8FunNx/lv4/JR+Ob/snF&#xA;UDLveZ7bzXMQ7v0sQzbOkabphCqL5IMgot1yaVF8kGQRWi61c6NqC31tHHJMisqCYMVHIUJHFlNa&#xA;bZXqNOM0OEkgeTkafOcUuIAX5sgb82/MY/49rP8A4CX/AKqZgDsPD3y+z9Tsf5Yy90ft/Wpt+b3m&#xA;Uf8AHtZf8BL/ANVckOwsPfL7P1J/lfL3R+39bEfMGuX2t6lJf3vH1XCqEQEIqqKAKCWNO/XNrpdN&#xA;HDAQjycLNnlllxSSl8yw1hRfJBkFFsmGQUWyYZBSbJhIUXyQZBRbJhmFF8mGQUXyYZBSbJhkFF8k&#xA;GYUWyYZBRbJBkFJsmGYUnyQZBRfJhkFJsmGYUmyQZhln5aflnrHnnWhbQBoNLgZTqOoEfDGn8q12&#xA;aRh9kfSds1XbHbGPRY7O8z9Me/8AY2Qjb7G0DQNK0DSLbSNKgFvY2i8IoxufEsxO5ZjuTnkeq1WT&#xA;PkOTIblJyAEwzHS7FXj/AJiujda5fTVqDMyqf8lDxX8FzrdJDhxRHk8PrcnHmkfNLsyHGabphCqL&#xA;5IMgot1yaVF8kGQUXyYSotkwyCi+TDIKL5MMgovkwyCi+SDIKLZMMgotkwyCk2TCQovkgyCi2TDM&#xA;KL5MMgovkwyCk2TDIKL5IMwotkwyCi2SDIKTZMMwpPkgyCi+TDIKTZMMw9D/ACw/JbXPOU0d9dh9&#xA;P8vA/HeMKSTAdVt1PXwLn4R7nbNB2z7Q4tIDGPry93d/W/VzboQJfVWgaBpGgaVBpWk262tjbikc&#xA;a9yerMTuzMdyTnl+q1WTPkOTIeKRckCkwzHS7FXYq8QkdpJGdvtMSx+ZNc7QChT5+TZtbhQ03TCF&#xA;UXyQZBRbrk0qL5IMgovkwlRbJhkFF8mGQUXyYZBRfJhkFF8kGQUWyYZBRbJhkFJsmEhRfJBkFFsm&#xA;GYUXyYZBRfJhkFJsmGQUXyQZhRbJhkFFskGQUmyYZhSfJBkEfoPlfX/MV8LLRbGW9nNOXpj4EB7y&#xA;OaKg92IynU6zFp48WSQiPxyHVsjEnk97/L3/AJx00vTHi1HzU6alerRk09K/VUP/ABYTQyn22X2b&#xA;OF7U9q55Lhg9Ef538Xw7vv8Ac5UMNc3s8caRoscahI0AVEUUAA2AAHbOPJJNlvbwK7FXYq7FXh2d&#xA;q+fOxVpumEKovkgyCi3XJpUXyQZBRfJhKi2TDIKL5MMgovkwyCi+TDIKL5IMgotkwyCi2TDIKTZM&#xA;JCi+SDIKLZMMwovkwyCi+TDIKTZMMgovkgzCi2TDIIuw8u6/qZA07Tbq85GgMEMkg+9QRlWXV4sf&#xA;1yjH3kBsjEnkGYaL+Qn5hamytcW0WmQNv6l3IOVP+McfqPX/AFgM1Go9ptJj5EzP9EfpNByI6eRe&#xA;l+Wv+ccPKtgyTa3cy6vMtCYR+4gr7qpLt/wf0Zzms9rc89sQGMfM/q+xyI6cDm9S03S9N0u0Sz06&#xA;1is7SP7EECLGg96KBufHOZzZp5JcUyZS7y3gAckVlSXYq7FXYq7FXYq8OztXz52KtN0whVF8kGQU&#xA;W65NKi+SDIKL5MJQ1zPBBG0s8ixRL9p3IVR8ydsthEyNAWWyETI0BZYpqf5jeW7SqxSteSD9mFfh&#xA;r/rNxH3VzaYeyc0uY4fe7HF2Xllz9PvYzffmnfOWFnZRxDs0rGQ/cOGbLH2LEfVIn3Owx9kRH1SJ&#xA;+z9aL8lW/wCZPn7WRpujS+mkdGu7rgqQQITs0jhS29NlG5+/Ku0ZaPQ4+PIPcOp9zlx7Pwx/hfSP&#xA;lb8ivK2kwxvq1xda9fgAyTXU0iw8h/JbowQD/X5fPPO9b7SZ8pPhiOKPkBf+mO/yptGnxj+EfJl8&#xA;fkrydGapoWnKetRaQA1PvwzUntDUHnkn/pj+tl4UO4Kn+EvKv/Vmsf8ApGh/5pyP57P/AD5/6Yp8&#xA;OPcGv8I+VP8Aqy2H/SND/wA04/ns/wDqk/8ATFfDj3B3+EPKf/VlsP8ApFh/5px/P5/9Un/pivhx&#xA;7g1/g/yl/wBWSw/6RYf+acP5/P8A6pP/AEx/Wvhx7g7/AAf5R/6smn/9IsP/ADTj+f1H+qT/ANMf&#xA;1r4ce4LW8leTWNW0HTifE2kB/wCNMI7Q1H+qT/0x/Wg4oHoFv+B/JX/Uv6b/ANIcH/NGH+UdT/qk&#xA;/wDTS/Wvgw7h8nf4G8k/9S/pv/SHB/zRj/KWp/1Sf+ml+tfCh3D5I220DQrY8rbTrWButY4Y0Nf9&#xA;ioymeqyy+qUj8SyEAOiOyhk7FXYq7FXYq7FXYq7FXYq7FXh2dq+fOxVpumEKovkgyCi3XJpQOpaj&#xA;Y6fbtcXs6QQr+25pU+AHUn2GXYcUshqIstuLFKZqIsvOdf8AzVdi0OiwUHT61ON/9jH/AM1fdnQ6&#xA;XsQc8p+A/W7zT9kDnkPwH62BajqWp6lN619cyXD9uZqB/qr0X6M3uLDDGKiAHcYscMYqIpC+nltt&#xA;nEuitpZZUiiUvJIwVEG5LMaADBKYAs8l4n3V+V/kKx8k+UbTSYVU3rKJtSuBSstywHM1/lX7K+wz&#xA;xHtntOWs1ByH6eUR3R/G5Sy3NUrsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdi&#xA;rw7O1fPnYq03TCFUXyQZBh3mzz7ZaQXtbQLdaiNitf3cZ/yyOp/yR+GbfQ9mSy+qXph9pdlpNBLJ&#xA;vLaP3vKdV1PUtVuTc38zTSfsg7Ko8FUbAZ1ODDDFGoCnoMWOGMVEUgvR9su4m3id6PtjxLxO9H2x&#xA;4l4mV/lTp0V3+ZHlyGUAoL+GQgioPpN6gBHzXNX23lMdHlI/mH7dkxlu+4c8Vb3Yq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq8OztXz52KtN0whXnHnTz4x56do8m26z3i/cVj&#xA;P/G33Z0PZ/Zn8eQe4fr/AFO50eh/in8v1vOzESSTuTuSc6DidxxNejjxLxO9HHiXid6OPEvE70ce&#xA;JeJmH5QxU/Mvy8fC7X/iJzU9uy/wLL/VZ45eoPs7PHnNdirsVdirsVdirsVdirsVdirsVdirsVdi&#xA;rsVdirsVdirsVdirsVdirw7O1fPnYqwHz55tY+ppGnv/AJN3Op++NSP+G+7N72ZoeWSfwH6f1O10&#xA;Ol/jl8P1vP8A0c33E7bid6OPEvE70ceJeJ3o48S8TvRx4l4nejjxLxMs/KaKn5j6AfC6X/iJzVdu&#xA;S/wPJ/VbMR9QfYeeSOydirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirw7O1&#xA;fPmPecdfOmWXoW7UvbgEIR1Rehf+AzP0Gl8SVn6Q5ekwccrPIPMDESSTuT1OdLxO64nej7Y8S8Tv&#xA;R9seJeJ3o+2PEvE70fbHiXid6PtjxLxO9H2x4l4mVflZFT8w9CPhcj/iJzWdtS/wTJ/VbcB9YfW+&#xA;eUu3dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirwq5uIre3knlNI41LMfY&#xA;Z28ImRAHV8/jEk0HlmqXU+oX0t3N9qQ/CvZVGwUfIZ0+GAxxEQ7rHERjQQvo+2WcTPid6PtjxLxO&#xA;9H2x4l4nej7Y8S8TvR9seJeJ3o+2PEvE70fbHiXiZP8AljFTz9oh8LkfqOa3tiX+C5P6rfpj+8D6&#xA;rzy93jsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVfNHnK9Ppx2KH7f7yb5&#xA;D7I+/fPR+z8e5kXitLD+JifoZtOJzeJ3oY8S8TvQx4l4nehjxLxO9DHiXid6GPEvE70MeJeJ3oY8&#xA;S8TJfy3ip560Y+FwP1HNd2vL/BZ/1W/Sn95H3vp7PNXoXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY&#xA;q7FXYq7FXYq7FXYq7FXYq+VNRka7vZZz0dvh/wBUbD8M9QxDhiA8hAcIpDejlnEyt3o48S270ceJ&#xA;bd6OPEtu9HHiW3ejjxLbvRx4lt3o48S2yL8vIqeddIPhcD9RzX9qy/wafucjSH97H3vpLPO3pXYq&#xA;7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq//2Q==</xmpGImg:image>
36
+ </rdf:li>
37
+ </rdf:Alt>
38
+ </xmp:Thumbnails>
39
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
40
+ <xmpMM:OriginalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</xmpMM:OriginalDocumentID>
41
+ <xmpMM:DocumentID>xmp.did:315ecc11-e4b0-4fcf-bed0-72cde1039292</xmpMM:DocumentID>
42
+ <xmpMM:InstanceID>uuid:bcafdf3a-792d-2e46-a4ea-c61edfb5e8d1</xmpMM:InstanceID>
43
+ <xmpMM:DerivedFrom rdf:parseType="Resource">
44
+ <stRef:instanceID>xmp.iid:4991ec66-af1b-4051-bde7-f0303643fbc8</stRef:instanceID>
45
+ <stRef:documentID>xmp.did:63c3b8d1-bb03-4762-9588-414086f0dea9</stRef:documentID>
46
+ <stRef:originalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</stRef:originalDocumentID>
47
+ <stRef:renditionClass>default</stRef:renditionClass>
48
+ </xmpMM:DerivedFrom>
49
+ <xmpMM:History>
50
+ <rdf:Seq>
51
+ <rdf:li rdf:parseType="Resource">
52
+ <stEvt:action>saved</stEvt:action>
53
+ <stEvt:instanceID>xmp.iid:41273b51-099a-4bd5-801b-1a44c629c86c</stEvt:instanceID>
54
+ <stEvt:when>2026-03-21T16:11:53+01:00</stEvt:when>
55
+ <stEvt:softwareAgent>Adobe Illustrator 30.2 (Macintosh)</stEvt:softwareAgent>
56
+ <stEvt:changed>/</stEvt:changed>
57
+ </rdf:li>
58
+ <rdf:li rdf:parseType="Resource">
59
+ <stEvt:action>saved</stEvt:action>
60
+ <stEvt:instanceID>xmp.iid:315ecc11-e4b0-4fcf-bed0-72cde1039292</stEvt:instanceID>
61
+ <stEvt:when>2026-03-21T16:14:39+01:00</stEvt:when>
62
+ <stEvt:softwareAgent>Adobe Illustrator 30.2 (Macintosh)</stEvt:softwareAgent>
63
+ <stEvt:changed>/</stEvt:changed>
64
+ </rdf:li>
65
+ </rdf:Seq>
66
+ </xmpMM:History>
67
+ <illustrator:StartupProfile>Web</illustrator:StartupProfile>
68
+ <illustrator:CreatorSubTool>AIRobin</illustrator:CreatorSubTool>
69
+ <illustrator:IsFileSavedViaInstantSave>False</illustrator:IsFileSavedViaInstantSave>
70
+ <illustrator:Type>Document</illustrator:Type>
71
+ <xmpTPg:NPages>1</xmpTPg:NPages>
72
+ <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
73
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
74
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
75
+ <stDim:w>519.242588</stDim:w>
76
+ <stDim:h>519.260474</stDim:h>
77
+ <stDim:unit>Pixels</stDim:unit>
78
+ </xmpTPg:MaxPageSize>
79
+ <xmpTPg:PlateNames>
80
+ <rdf:Seq>
81
+ <rdf:li>Cyan</rdf:li>
82
+ <rdf:li>Magenta</rdf:li>
83
+ </rdf:Seq>
84
+ </xmpTPg:PlateNames>
85
+ <xmpTPg:SwatchGroups>
86
+ <rdf:Seq>
87
+ <rdf:li rdf:parseType="Resource">
88
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
89
+ <xmpG:groupType>0</xmpG:groupType>
90
+ <xmpG:Colorants>
91
+ <rdf:Seq>
92
+ <rdf:li rdf:parseType="Resource">
93
+ <xmpG:swatchName>White</xmpG:swatchName>
94
+ <xmpG:mode>RGB</xmpG:mode>
95
+ <xmpG:type>PROCESS</xmpG:type>
96
+ <xmpG:red>255</xmpG:red>
97
+ <xmpG:green>255</xmpG:green>
98
+ <xmpG:blue>255</xmpG:blue>
99
+ </rdf:li>
100
+ <rdf:li rdf:parseType="Resource">
101
+ <xmpG:swatchName>Black</xmpG:swatchName>
102
+ <xmpG:mode>RGB</xmpG:mode>
103
+ <xmpG:type>PROCESS</xmpG:type>
104
+ <xmpG:red>0</xmpG:red>
105
+ <xmpG:green>0</xmpG:green>
106
+ <xmpG:blue>0</xmpG:blue>
107
+ </rdf:li>
108
+ <rdf:li rdf:parseType="Resource">
109
+ <xmpG:swatchName>RGB Red</xmpG:swatchName>
110
+ <xmpG:mode>RGB</xmpG:mode>
111
+ <xmpG:type>PROCESS</xmpG:type>
112
+ <xmpG:red>255</xmpG:red>
113
+ <xmpG:green>0</xmpG:green>
114
+ <xmpG:blue>0</xmpG:blue>
115
+ </rdf:li>
116
+ <rdf:li rdf:parseType="Resource">
117
+ <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
118
+ <xmpG:mode>RGB</xmpG:mode>
119
+ <xmpG:type>PROCESS</xmpG:type>
120
+ <xmpG:red>255</xmpG:red>
121
+ <xmpG:green>255</xmpG:green>
122
+ <xmpG:blue>0</xmpG:blue>
123
+ </rdf:li>
124
+ <rdf:li rdf:parseType="Resource">
125
+ <xmpG:swatchName>RGB Green</xmpG:swatchName>
126
+ <xmpG:mode>RGB</xmpG:mode>
127
+ <xmpG:type>PROCESS</xmpG:type>
128
+ <xmpG:red>0</xmpG:red>
129
+ <xmpG:green>255</xmpG:green>
130
+ <xmpG:blue>0</xmpG:blue>
131
+ </rdf:li>
132
+ <rdf:li rdf:parseType="Resource">
133
+ <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
134
+ <xmpG:mode>RGB</xmpG:mode>
135
+ <xmpG:type>PROCESS</xmpG:type>
136
+ <xmpG:red>0</xmpG:red>
137
+ <xmpG:green>255</xmpG:green>
138
+ <xmpG:blue>255</xmpG:blue>
139
+ </rdf:li>
140
+ <rdf:li rdf:parseType="Resource">
141
+ <xmpG:swatchName>RGB Blue</xmpG:swatchName>
142
+ <xmpG:mode>RGB</xmpG:mode>
143
+ <xmpG:type>PROCESS</xmpG:type>
144
+ <xmpG:red>0</xmpG:red>
145
+ <xmpG:green>0</xmpG:green>
146
+ <xmpG:blue>255</xmpG:blue>
147
+ </rdf:li>
148
+ <rdf:li rdf:parseType="Resource">
149
+ <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
150
+ <xmpG:mode>RGB</xmpG:mode>
151
+ <xmpG:type>PROCESS</xmpG:type>
152
+ <xmpG:red>255</xmpG:red>
153
+ <xmpG:green>0</xmpG:green>
154
+ <xmpG:blue>255</xmpG:blue>
155
+ </rdf:li>
156
+ <rdf:li rdf:parseType="Resource">
157
+ <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
158
+ <xmpG:mode>RGB</xmpG:mode>
159
+ <xmpG:type>PROCESS</xmpG:type>
160
+ <xmpG:red>193</xmpG:red>
161
+ <xmpG:green>39</xmpG:green>
162
+ <xmpG:blue>45</xmpG:blue>
163
+ </rdf:li>
164
+ <rdf:li rdf:parseType="Resource">
165
+ <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
166
+ <xmpG:mode>RGB</xmpG:mode>
167
+ <xmpG:type>PROCESS</xmpG:type>
168
+ <xmpG:red>237</xmpG:red>
169
+ <xmpG:green>28</xmpG:green>
170
+ <xmpG:blue>36</xmpG:blue>
171
+ </rdf:li>
172
+ <rdf:li rdf:parseType="Resource">
173
+ <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
174
+ <xmpG:mode>RGB</xmpG:mode>
175
+ <xmpG:type>PROCESS</xmpG:type>
176
+ <xmpG:red>241</xmpG:red>
177
+ <xmpG:green>90</xmpG:green>
178
+ <xmpG:blue>36</xmpG:blue>
179
+ </rdf:li>
180
+ <rdf:li rdf:parseType="Resource">
181
+ <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
182
+ <xmpG:mode>RGB</xmpG:mode>
183
+ <xmpG:type>PROCESS</xmpG:type>
184
+ <xmpG:red>247</xmpG:red>
185
+ <xmpG:green>147</xmpG:green>
186
+ <xmpG:blue>30</xmpG:blue>
187
+ </rdf:li>
188
+ <rdf:li rdf:parseType="Resource">
189
+ <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
190
+ <xmpG:mode>RGB</xmpG:mode>
191
+ <xmpG:type>PROCESS</xmpG:type>
192
+ <xmpG:red>251</xmpG:red>
193
+ <xmpG:green>176</xmpG:green>
194
+ <xmpG:blue>59</xmpG:blue>
195
+ </rdf:li>
196
+ <rdf:li rdf:parseType="Resource">
197
+ <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
198
+ <xmpG:mode>RGB</xmpG:mode>
199
+ <xmpG:type>PROCESS</xmpG:type>
200
+ <xmpG:red>252</xmpG:red>
201
+ <xmpG:green>238</xmpG:green>
202
+ <xmpG:blue>33</xmpG:blue>
203
+ </rdf:li>
204
+ <rdf:li rdf:parseType="Resource">
205
+ <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
206
+ <xmpG:mode>RGB</xmpG:mode>
207
+ <xmpG:type>PROCESS</xmpG:type>
208
+ <xmpG:red>217</xmpG:red>
209
+ <xmpG:green>224</xmpG:green>
210
+ <xmpG:blue>33</xmpG:blue>
211
+ </rdf:li>
212
+ <rdf:li rdf:parseType="Resource">
213
+ <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
214
+ <xmpG:mode>RGB</xmpG:mode>
215
+ <xmpG:type>PROCESS</xmpG:type>
216
+ <xmpG:red>140</xmpG:red>
217
+ <xmpG:green>198</xmpG:green>
218
+ <xmpG:blue>63</xmpG:blue>
219
+ </rdf:li>
220
+ <rdf:li rdf:parseType="Resource">
221
+ <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
222
+ <xmpG:mode>RGB</xmpG:mode>
223
+ <xmpG:type>PROCESS</xmpG:type>
224
+ <xmpG:red>57</xmpG:red>
225
+ <xmpG:green>181</xmpG:green>
226
+ <xmpG:blue>74</xmpG:blue>
227
+ </rdf:li>
228
+ <rdf:li rdf:parseType="Resource">
229
+ <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
230
+ <xmpG:mode>RGB</xmpG:mode>
231
+ <xmpG:type>PROCESS</xmpG:type>
232
+ <xmpG:red>0</xmpG:red>
233
+ <xmpG:green>146</xmpG:green>
234
+ <xmpG:blue>69</xmpG:blue>
235
+ </rdf:li>
236
+ <rdf:li rdf:parseType="Resource">
237
+ <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
238
+ <xmpG:mode>RGB</xmpG:mode>
239
+ <xmpG:type>PROCESS</xmpG:type>
240
+ <xmpG:red>0</xmpG:red>
241
+ <xmpG:green>104</xmpG:green>
242
+ <xmpG:blue>55</xmpG:blue>
243
+ </rdf:li>
244
+ <rdf:li rdf:parseType="Resource">
245
+ <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
246
+ <xmpG:mode>RGB</xmpG:mode>
247
+ <xmpG:type>PROCESS</xmpG:type>
248
+ <xmpG:red>34</xmpG:red>
249
+ <xmpG:green>181</xmpG:green>
250
+ <xmpG:blue>115</xmpG:blue>
251
+ </rdf:li>
252
+ <rdf:li rdf:parseType="Resource">
253
+ <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
254
+ <xmpG:mode>RGB</xmpG:mode>
255
+ <xmpG:type>PROCESS</xmpG:type>
256
+ <xmpG:red>0</xmpG:red>
257
+ <xmpG:green>169</xmpG:green>
258
+ <xmpG:blue>157</xmpG:blue>
259
+ </rdf:li>
260
+ <rdf:li rdf:parseType="Resource">
261
+ <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
262
+ <xmpG:mode>RGB</xmpG:mode>
263
+ <xmpG:type>PROCESS</xmpG:type>
264
+ <xmpG:red>41</xmpG:red>
265
+ <xmpG:green>171</xmpG:green>
266
+ <xmpG:blue>226</xmpG:blue>
267
+ </rdf:li>
268
+ <rdf:li rdf:parseType="Resource">
269
+ <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
270
+ <xmpG:mode>RGB</xmpG:mode>
271
+ <xmpG:type>PROCESS</xmpG:type>
272
+ <xmpG:red>0</xmpG:red>
273
+ <xmpG:green>113</xmpG:green>
274
+ <xmpG:blue>188</xmpG:blue>
275
+ </rdf:li>
276
+ <rdf:li rdf:parseType="Resource">
277
+ <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
278
+ <xmpG:mode>RGB</xmpG:mode>
279
+ <xmpG:type>PROCESS</xmpG:type>
280
+ <xmpG:red>46</xmpG:red>
281
+ <xmpG:green>49</xmpG:green>
282
+ <xmpG:blue>146</xmpG:blue>
283
+ </rdf:li>
284
+ <rdf:li rdf:parseType="Resource">
285
+ <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
286
+ <xmpG:mode>RGB</xmpG:mode>
287
+ <xmpG:type>PROCESS</xmpG:type>
288
+ <xmpG:red>27</xmpG:red>
289
+ <xmpG:green>20</xmpG:green>
290
+ <xmpG:blue>100</xmpG:blue>
291
+ </rdf:li>
292
+ <rdf:li rdf:parseType="Resource">
293
+ <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
294
+ <xmpG:mode>RGB</xmpG:mode>
295
+ <xmpG:type>PROCESS</xmpG:type>
296
+ <xmpG:red>102</xmpG:red>
297
+ <xmpG:green>45</xmpG:green>
298
+ <xmpG:blue>145</xmpG:blue>
299
+ </rdf:li>
300
+ <rdf:li rdf:parseType="Resource">
301
+ <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
302
+ <xmpG:mode>RGB</xmpG:mode>
303
+ <xmpG:type>PROCESS</xmpG:type>
304
+ <xmpG:red>147</xmpG:red>
305
+ <xmpG:green>39</xmpG:green>
306
+ <xmpG:blue>143</xmpG:blue>
307
+ </rdf:li>
308
+ <rdf:li rdf:parseType="Resource">
309
+ <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
310
+ <xmpG:mode>RGB</xmpG:mode>
311
+ <xmpG:type>PROCESS</xmpG:type>
312
+ <xmpG:red>158</xmpG:red>
313
+ <xmpG:green>0</xmpG:green>
314
+ <xmpG:blue>93</xmpG:blue>
315
+ </rdf:li>
316
+ <rdf:li rdf:parseType="Resource">
317
+ <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
318
+ <xmpG:mode>RGB</xmpG:mode>
319
+ <xmpG:type>PROCESS</xmpG:type>
320
+ <xmpG:red>212</xmpG:red>
321
+ <xmpG:green>20</xmpG:green>
322
+ <xmpG:blue>90</xmpG:blue>
323
+ </rdf:li>
324
+ <rdf:li rdf:parseType="Resource">
325
+ <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
326
+ <xmpG:mode>RGB</xmpG:mode>
327
+ <xmpG:type>PROCESS</xmpG:type>
328
+ <xmpG:red>237</xmpG:red>
329
+ <xmpG:green>30</xmpG:green>
330
+ <xmpG:blue>121</xmpG:blue>
331
+ </rdf:li>
332
+ <rdf:li rdf:parseType="Resource">
333
+ <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
334
+ <xmpG:mode>RGB</xmpG:mode>
335
+ <xmpG:type>PROCESS</xmpG:type>
336
+ <xmpG:red>199</xmpG:red>
337
+ <xmpG:green>178</xmpG:green>
338
+ <xmpG:blue>153</xmpG:blue>
339
+ </rdf:li>
340
+ <rdf:li rdf:parseType="Resource">
341
+ <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
342
+ <xmpG:mode>RGB</xmpG:mode>
343
+ <xmpG:type>PROCESS</xmpG:type>
344
+ <xmpG:red>153</xmpG:red>
345
+ <xmpG:green>134</xmpG:green>
346
+ <xmpG:blue>117</xmpG:blue>
347
+ </rdf:li>
348
+ <rdf:li rdf:parseType="Resource">
349
+ <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
350
+ <xmpG:mode>RGB</xmpG:mode>
351
+ <xmpG:type>PROCESS</xmpG:type>
352
+ <xmpG:red>115</xmpG:red>
353
+ <xmpG:green>99</xmpG:green>
354
+ <xmpG:blue>87</xmpG:blue>
355
+ </rdf:li>
356
+ <rdf:li rdf:parseType="Resource">
357
+ <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
358
+ <xmpG:mode>RGB</xmpG:mode>
359
+ <xmpG:type>PROCESS</xmpG:type>
360
+ <xmpG:red>83</xmpG:red>
361
+ <xmpG:green>71</xmpG:green>
362
+ <xmpG:blue>65</xmpG:blue>
363
+ </rdf:li>
364
+ <rdf:li rdf:parseType="Resource">
365
+ <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
366
+ <xmpG:mode>RGB</xmpG:mode>
367
+ <xmpG:type>PROCESS</xmpG:type>
368
+ <xmpG:red>198</xmpG:red>
369
+ <xmpG:green>156</xmpG:green>
370
+ <xmpG:blue>109</xmpG:blue>
371
+ </rdf:li>
372
+ <rdf:li rdf:parseType="Resource">
373
+ <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
374
+ <xmpG:mode>RGB</xmpG:mode>
375
+ <xmpG:type>PROCESS</xmpG:type>
376
+ <xmpG:red>166</xmpG:red>
377
+ <xmpG:green>124</xmpG:green>
378
+ <xmpG:blue>82</xmpG:blue>
379
+ </rdf:li>
380
+ <rdf:li rdf:parseType="Resource">
381
+ <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
382
+ <xmpG:mode>RGB</xmpG:mode>
383
+ <xmpG:type>PROCESS</xmpG:type>
384
+ <xmpG:red>140</xmpG:red>
385
+ <xmpG:green>98</xmpG:green>
386
+ <xmpG:blue>57</xmpG:blue>
387
+ </rdf:li>
388
+ <rdf:li rdf:parseType="Resource">
389
+ <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
390
+ <xmpG:mode>RGB</xmpG:mode>
391
+ <xmpG:type>PROCESS</xmpG:type>
392
+ <xmpG:red>117</xmpG:red>
393
+ <xmpG:green>76</xmpG:green>
394
+ <xmpG:blue>36</xmpG:blue>
395
+ </rdf:li>
396
+ <rdf:li rdf:parseType="Resource">
397
+ <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
398
+ <xmpG:mode>RGB</xmpG:mode>
399
+ <xmpG:type>PROCESS</xmpG:type>
400
+ <xmpG:red>96</xmpG:red>
401
+ <xmpG:green>56</xmpG:green>
402
+ <xmpG:blue>19</xmpG:blue>
403
+ </rdf:li>
404
+ <rdf:li rdf:parseType="Resource">
405
+ <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
406
+ <xmpG:mode>RGB</xmpG:mode>
407
+ <xmpG:type>PROCESS</xmpG:type>
408
+ <xmpG:red>66</xmpG:red>
409
+ <xmpG:green>33</xmpG:green>
410
+ <xmpG:blue>11</xmpG:blue>
411
+ </rdf:li>
412
+ </rdf:Seq>
413
+ </xmpG:Colorants>
414
+ </rdf:li>
415
+ <rdf:li rdf:parseType="Resource">
416
+ <xmpG:groupName>Grays</xmpG:groupName>
417
+ <xmpG:groupType>1</xmpG:groupType>
418
+ <xmpG:Colorants>
419
+ <rdf:Seq>
420
+ <rdf:li rdf:parseType="Resource">
421
+ <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
422
+ <xmpG:mode>RGB</xmpG:mode>
423
+ <xmpG:type>PROCESS</xmpG:type>
424
+ <xmpG:red>0</xmpG:red>
425
+ <xmpG:green>0</xmpG:green>
426
+ <xmpG:blue>0</xmpG:blue>
427
+ </rdf:li>
428
+ <rdf:li rdf:parseType="Resource">
429
+ <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
430
+ <xmpG:mode>RGB</xmpG:mode>
431
+ <xmpG:type>PROCESS</xmpG:type>
432
+ <xmpG:red>26</xmpG:red>
433
+ <xmpG:green>26</xmpG:green>
434
+ <xmpG:blue>26</xmpG:blue>
435
+ </rdf:li>
436
+ <rdf:li rdf:parseType="Resource">
437
+ <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
438
+ <xmpG:mode>RGB</xmpG:mode>
439
+ <xmpG:type>PROCESS</xmpG:type>
440
+ <xmpG:red>51</xmpG:red>
441
+ <xmpG:green>51</xmpG:green>
442
+ <xmpG:blue>51</xmpG:blue>
443
+ </rdf:li>
444
+ <rdf:li rdf:parseType="Resource">
445
+ <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
446
+ <xmpG:mode>RGB</xmpG:mode>
447
+ <xmpG:type>PROCESS</xmpG:type>
448
+ <xmpG:red>77</xmpG:red>
449
+ <xmpG:green>77</xmpG:green>
450
+ <xmpG:blue>77</xmpG:blue>
451
+ </rdf:li>
452
+ <rdf:li rdf:parseType="Resource">
453
+ <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
454
+ <xmpG:mode>RGB</xmpG:mode>
455
+ <xmpG:type>PROCESS</xmpG:type>
456
+ <xmpG:red>102</xmpG:red>
457
+ <xmpG:green>102</xmpG:green>
458
+ <xmpG:blue>102</xmpG:blue>
459
+ </rdf:li>
460
+ <rdf:li rdf:parseType="Resource">
461
+ <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
462
+ <xmpG:mode>RGB</xmpG:mode>
463
+ <xmpG:type>PROCESS</xmpG:type>
464
+ <xmpG:red>128</xmpG:red>
465
+ <xmpG:green>128</xmpG:green>
466
+ <xmpG:blue>128</xmpG:blue>
467
+ </rdf:li>
468
+ <rdf:li rdf:parseType="Resource">
469
+ <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
470
+ <xmpG:mode>RGB</xmpG:mode>
471
+ <xmpG:type>PROCESS</xmpG:type>
472
+ <xmpG:red>153</xmpG:red>
473
+ <xmpG:green>153</xmpG:green>
474
+ <xmpG:blue>153</xmpG:blue>
475
+ </rdf:li>
476
+ <rdf:li rdf:parseType="Resource">
477
+ <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
478
+ <xmpG:mode>RGB</xmpG:mode>
479
+ <xmpG:type>PROCESS</xmpG:type>
480
+ <xmpG:red>179</xmpG:red>
481
+ <xmpG:green>179</xmpG:green>
482
+ <xmpG:blue>179</xmpG:blue>
483
+ </rdf:li>
484
+ <rdf:li rdf:parseType="Resource">
485
+ <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
486
+ <xmpG:mode>RGB</xmpG:mode>
487
+ <xmpG:type>PROCESS</xmpG:type>
488
+ <xmpG:red>204</xmpG:red>
489
+ <xmpG:green>204</xmpG:green>
490
+ <xmpG:blue>204</xmpG:blue>
491
+ </rdf:li>
492
+ <rdf:li rdf:parseType="Resource">
493
+ <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
494
+ <xmpG:mode>RGB</xmpG:mode>
495
+ <xmpG:type>PROCESS</xmpG:type>
496
+ <xmpG:red>230</xmpG:red>
497
+ <xmpG:green>230</xmpG:green>
498
+ <xmpG:blue>230</xmpG:blue>
499
+ </rdf:li>
500
+ <rdf:li rdf:parseType="Resource">
501
+ <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
502
+ <xmpG:mode>RGB</xmpG:mode>
503
+ <xmpG:type>PROCESS</xmpG:type>
504
+ <xmpG:red>242</xmpG:red>
505
+ <xmpG:green>242</xmpG:green>
506
+ <xmpG:blue>242</xmpG:blue>
507
+ </rdf:li>
508
+ </rdf:Seq>
509
+ </xmpG:Colorants>
510
+ </rdf:li>
511
+ <rdf:li rdf:parseType="Resource">
512
+ <xmpG:groupName>Web Color Group</xmpG:groupName>
513
+ <xmpG:groupType>1</xmpG:groupType>
514
+ <xmpG:Colorants>
515
+ <rdf:Seq>
516
+ <rdf:li rdf:parseType="Resource">
517
+ <xmpG:swatchName>R=63 G=169 B=245</xmpG:swatchName>
518
+ <xmpG:mode>RGB</xmpG:mode>
519
+ <xmpG:type>PROCESS</xmpG:type>
520
+ <xmpG:red>63</xmpG:red>
521
+ <xmpG:green>169</xmpG:green>
522
+ <xmpG:blue>245</xmpG:blue>
523
+ </rdf:li>
524
+ <rdf:li rdf:parseType="Resource">
525
+ <xmpG:swatchName>R=122 G=201 B=67</xmpG:swatchName>
526
+ <xmpG:mode>RGB</xmpG:mode>
527
+ <xmpG:type>PROCESS</xmpG:type>
528
+ <xmpG:red>122</xmpG:red>
529
+ <xmpG:green>201</xmpG:green>
530
+ <xmpG:blue>67</xmpG:blue>
531
+ </rdf:li>
532
+ <rdf:li rdf:parseType="Resource">
533
+ <xmpG:swatchName>R=255 G=147 B=30</xmpG:swatchName>
534
+ <xmpG:mode>RGB</xmpG:mode>
535
+ <xmpG:type>PROCESS</xmpG:type>
536
+ <xmpG:red>255</xmpG:red>
537
+ <xmpG:green>147</xmpG:green>
538
+ <xmpG:blue>30</xmpG:blue>
539
+ </rdf:li>
540
+ <rdf:li rdf:parseType="Resource">
541
+ <xmpG:swatchName>R=255 G=29 B=37</xmpG:swatchName>
542
+ <xmpG:mode>RGB</xmpG:mode>
543
+ <xmpG:type>PROCESS</xmpG:type>
544
+ <xmpG:red>255</xmpG:red>
545
+ <xmpG:green>29</xmpG:green>
546
+ <xmpG:blue>37</xmpG:blue>
547
+ </rdf:li>
548
+ <rdf:li rdf:parseType="Resource">
549
+ <xmpG:swatchName>R=255 G=123 B=172</xmpG:swatchName>
550
+ <xmpG:mode>RGB</xmpG:mode>
551
+ <xmpG:type>PROCESS</xmpG:type>
552
+ <xmpG:red>255</xmpG:red>
553
+ <xmpG:green>123</xmpG:green>
554
+ <xmpG:blue>172</xmpG:blue>
555
+ </rdf:li>
556
+ <rdf:li rdf:parseType="Resource">
557
+ <xmpG:swatchName>R=189 G=204 B=212</xmpG:swatchName>
558
+ <xmpG:mode>RGB</xmpG:mode>
559
+ <xmpG:type>PROCESS</xmpG:type>
560
+ <xmpG:red>189</xmpG:red>
561
+ <xmpG:green>204</xmpG:green>
562
+ <xmpG:blue>212</xmpG:blue>
563
+ </rdf:li>
564
+ </rdf:Seq>
565
+ </xmpG:Colorants>
566
+ </rdf:li>
567
+ </rdf:Seq>
568
+ </xmpTPg:SwatchGroups>
569
+ <pdf:Producer>Adobe PDF library 18.00</pdf:Producer>
570
+ <pdfx:CreatorVersion>21.0.0</pdfx:CreatorVersion>
571
+ </rdf:Description>
572
+ </rdf:RDF>
573
+</x:xmpmeta>
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+
582
+
583
+
584
+
585
+
586
+
587
+
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+<?xpacket end="w"?> endstream endobj 3 0 obj <</Count 1/Kids[5 0 R]/Type/Pages>> endobj 5 0 obj <</ArtBox[0.0 0.0 519.243 519.26]/BleedBox[0.0 0.0 519.243 519.26]/Contents 24 0 R/CropBox[0.0 0.0 519.243 519.26]/LastModified(D:20260321161439+01'00')/MediaBox[0.0 0.0 519.243 519.26]/Parent 3 0 R/Resources<</ColorSpace<</CS0 25 0 R>>/ExtGState<</GS0 26 0 R>>/Properties<</MC0 22 0 R>>/Shading<</Sh0 27 0 R>>>>/Thumb 28 0 R/TrimBox[0.0 0.0 519.243 519.26]/Type/Page/PieceInfo<</Illustrator 8 0 R>>>> endobj 24 0 obj <</Filter/FlateDecode/Length 5871>>stream
596
+HK”WÍι ¼ÏSô ¤-JÔßu § Xì!{÷!>ôöý¬êµìK`ß°ºY,Q©þòϯǗ|MÇ/ýz¼þûJG•yævü?ËÙK;.û­¥ŸšÊQç9ä(­ÚÆ!EÏÑÔì|–\o¯¹^’úYäÐ*gJٝ§æ˜rJ3—rŽî@Iél݀q¦&ÈYfb.%åS`eXãc~{m€¹g=çç}-F{”šN3÷sdq÷'p½1 O1ý­ZÜaa†Ù嬖&9DaCŒÂ6†“¶SÌu̳tÏRµu·­iž–Vcx×°äµi ]Î>-‹SÏ¢#V1-EULTU.cEŒÃ„Ï$±Åb²J©ç(åÞòRŒòmù*Vûz}ýëøÕȗ¿ÿ–ŽÿIIÅõHöï/O@%YºÚ>ßþxýòûñå·ïéøóûñ·ß__¿SQ=sª!±e«9_ÕL«™ÇºêÚþŸ<•fU§¾éÂêÐK ǚmk”[ƒjِ‹w¯so[`ç;՛bA¼âúÙk?²-dNó±$v“•§]19–œžË‘ǰcÛµ!+ >©Ó³Í S)VÄύ kNj2†ËiqòÈgî¦Õ=ҙµǎ\¯<­J>âK±Ó5[PvßËü(þ¸ŸS"r2‘^ÃÇ Ñƒ‰t³{ƒ©… à v~";Ý*Å£Zk¶†ÃÍ:ã?4™lÇ!ÛߥmǞҏ0­´ agÚÞÙ6ÛX5IÉ!7àë6 ys4Ûº©SËÛþöÚôJõ2y e~Þ Û
597
+(¢fÚQºíý·×Ž\èÉâ -gìG¥­7»Ý­óº]쐸ݢ\ÌNƒm}E®— ‚.žày&Ë^:²u“fí1bÏ4Æç·ÏñãŽq’­òWµöå­¸ûoñß®ÉÞP¼Z^Œg«ã° ÍÒ$bíÂB:q;äqN}›VÍOÀý‡IÈ¢žÈ[\É^¾ã¨-Lm©¼&“™íˆg;KÑmžy»LÉ£îÈõ@†æ)èÁ^ŽÑ“SáÒe°k·èëm‚õ‰8Gcd7Z‡ÚImvRÕÚQ²ÊSë}>yýOÜøÒ¬",±îYmº«íT=º©ò6åKžj
598
+†ã¹ˆ¼0ÇØìºS,(¤×‡dŒÛ¾mL°IéݤÔG´¼‘äÆX`[½ºýp›-Ñ vä‡UÿêS¢Ç|8ר7(Ƥ é! .ñŠ~›
599
+ƒ–FЁŒÝgç\‚’"OR Ög”‹´è‚cÖ°S ¿ÚtØÙx"©Ÿ'ç3*9ü`¸GŸÔÑ+¤'öÿè"nke7gʃ+»ÏιF%Gâv, £¾“0Ôê-w›CXšzt³ßKYÈØ\vÆ5&(¼ûûûíNFñ;R1ÊrcŒ‚M» †É°ÐàÍkõ(^˜ÁˆT,!É0è "b÷ \GªFŸf÷…ÝPŸO*’ÎÅÇ)ûƒr J¿m6Є¥ íw(ux»7»ó±()àzýÌcg\c’¢B×°-ƒŠ6±~—;ce½ƒÃoa³ñ<èhåá²S®AI¡@z­”¡äÔð¸çf©|*ô_(P™eþÉ·Æ# ±§L¹¡*pÖÌNx£u¬"®Fã+9µ‡OnýÁ¹F%‡TrPFªüŽ3l¾MRFS¨¨{·*ë‰\¯}vÎGPR„Yí¬ý6뽎1ã¢Ùñ6²Y«Ò €¥z; •á'üûM
600
+Z¡„z‡0V¦BŠ€„Ýcg\c‚‚5¨³Q„
601
+‘Üße§q±®6õA¡5“bE c÷Ù9— ¤èX‰ê-#'ä+îÖfËí# LU¥ïd¬dÖí³s®QÉÁŒ–‰‰Šï¸@¾§˜Ð+³ u§]!ã‰\ (…>ø€š3(Ÿ1IQ°’¢·
602
+–V‰ž‡o€°*ZcÌt«X¨è9?|zŸä<ö˜¤`¿øAE%iF.*~f.”éÎõ¦X¨¨œ;·Omu¥\c’B ;k¥ŠR©"vQßå—¹ Y9Ur¬dì>;ç2±‰2oÂŒÅØ3;±aH›°3–&µ‘cE ƒ³ëv
603
+½)× NQl*C˜(f™!7©W¦Ùƒ“J¢šMUib®×Ï<vÆ5&(:g¬PC¤/½7ù{f×I»‘` a÷èRŒŸˆ$àIµPCåèJ­¼&¤ ‚Âöž$“bE b÷Ù(ט¤¸’REv½} m¸í…í¶Ÿ`³ãÊdf»7t b÷Øט¤ˆëŸ½QU¤Nޏ:›³ÏìèÙÞT؂¢x"Б¤->ÎÙœkTrÄÀs‘l—ŸÈ5ⶆՎ
604
+»fpŒÜȱ"×ëg>;ç:é!“:´`ý#Á§tØÝϗÛÎÎO‰'¥+}òÎFÎvìQoys¸a“µïÙØ[±‰ÎŠoŠ1°m:°µOäzÁ%ÃÅÛwPŽ…ò”‚ Ê’dÏÈÚðíÒ‹ÕŠ¯Åž SyKx"×ë§>}>8רà¨LæFµ‘CðEYYúÑ}ÍÖIvò'wÁÜ>•ùys.QÁQÞ(£PGac‹ÍΌ‚m6ª¥ÔNŠ€ŠÝcg\c‚"Z¾#*TÁŠ+.ib#ã[ÏíÊçr'tE #ÍüðÙ(טFaMd*tf܂¡Oæ½gp_óàg—b¥öŸ+r½~æ3Y ™Ÿ5*8zaÔÚ©£MrðÖΓ’s qÛsé¤XÈøø Ño”kLPT¶¼Œæ7Ã{%Ôʪω7ÇÁÝmC ãŸñ \ƒ‚¢$ì¼ô[Fn(8á¤Î…&G9«Oê­bE bsÙט HƒE©"хßsIm6àÁç\ȁŠÄq'¼ç½)¡b ŠÁ=L¸„:ÂmÃußû/ßàÃMaļNJ\àHåáóçMñ„÷ G8SŸTr%ΣÊÇåÎÆ@Åî±3®1A.ŽˆRu¦ñi?açÏÁïÝîw.V*~ðá)¹9טàÈÑ"Œ£ß*â¾êŒÄ'ÛÜO>ÆUá @…ÔüôØטNá+àJ
605
+NI;þø› ÇןÛ7øÄx^<"5Â%"zÇ cvjèz#È@ÚÛ¸m!NJ@F—þðùs‰
606
+ŽÚðdÔI‹Ž@»N$c(þ*—6ôÎÆŠ@ÇîCª›r
607
+Š¢|# enÛ`2ᙕ"ӝЁˆ§ÇηFƒdlÒÿ¯’+Ùavï(&‚~$µÙ9ù0ُ(€.JՇ9ÕÊ¡¢ÆUéA¸lèz&îFŒX)œÖ~Q#3p!]÷˜C3gu>ï<fÁCm2×hd\k₱ŽÕœv¥‰í¦FfžŸ?cFß4sVhô›YUéƒë<ݸ3×¹ï³aRâJf`£ó€DLé ͔u`‚:kÆd*¬öÊÓØWè³u¢/*×󥙲BÃXgz¹èÃ,h(O{_;oâ¸P#3ðqƜš9+4¤p,³ê‡p±Ñ°¶Y錨€1”vae7â1JŠ8÷œ¸Xiüeûo1ƒ5môč¸ÁÕàÊ·™ÑÚsM3g…F»£Â}´NfÍèÄ,Ímõ1 1^°_1¯&|å¬ÐˆVõò††÷Ú _ðe+%E¯-âK1å„Dì¯Ú+]°êÕv¯¡ñÚ*0/¾ZoJd6Îe ͜Ô5êÜ_Ø`OåÓ`¬§”ã‹E¹®fnbæÔN…D< x«GD”«PL)¡0x
608
+¤ÎÒŒ­4ù¯é¸ÌÀFçXßßÐÌY¡”SQyÔʚ½ÊßqVF4¥Bfà¢r°o |h~rBÁ.¬`á!™L£ÂÚÐ]ÆÁ½Z4†‘x8#ŒG÷UL9!ÁS!<cvc"çOyK’¿=~gàA¤}B\ñÞ#!â/¶–ÖQÀ'ÃQÙZÕò–0k0gÉø:ڙ KTÄ\<´¡™³B£óÆ7¶Ÿ…eÖ]1QnlÍåÄ °J"à¢õ{¸û¦˜sB¢
609
+©tåÄVD©ð¤K©¼åKÙï \|ÅlŠ9#”ó­#<h£&†¡ìá´CPE‰ÃDf`BYGߘvm’)§K“a¹š ¯;]ÊÞv_WïdoùRîíy Á#b¾4SVhD³®>¢WAL¿èC É~L%l$.ΈÁÝŠ9'$«»° ¶y½ÜdVHåV“µ¸ó±$#\d6¾bvɜEÉ´Fv£+Æx®ðäØÇH2_1‡fÎ
610
+ ¹Øµ[ø¶5²êÞÄü@1yñ+‘ØîÐ7¦]2%u EďÎlÒoؘLaÛ¾.ž‰å&^•lBö|;óüüòQ,ÿ9sB¢°€NFùÍjtu”À
611
+ÜÑOÞìÄw6Úu1#éZ6͜5¾¨´QnZ_WÊĝ’ëþž¸rìE)‘Ø(}ì1‡fJ
612
+ ¥-5ºÐÈ*˜P­¸'K^‰ÄÀ…†/AV W¡ùIê2gׅ1™ŒÏçÄPâý7B"1k[È©˜rBbT äj] ¦­˜!…¸,ܯÀJÌÀƐºÅ +»fÊ
613
+Æùñ½ M°Œ×:s2{i#ÀcÉ |œ1§fÎ
614
+ ã;ê’Xœ3ÁX¬1fiM\1¶qß¡‘øøŠ95SVhH3Føžrgæ»s¬÷®ãñbj$æùù3æÔLY§F¿9S“ië°8£ÁÌØ…©Ñ…x—ÌóóWˆí‚)%+à@-_L{àz`.ÕWãÃ<ÿ§Æ'+4J§oºø` ‚ÿþlð!´¿¾Ýe<͵nÇ^qÿ‘±—Þ¡ŽS"1ÏÏ_!_Šm“søpҟÄÀ ®Cã˜Ç­ùeè¸uâ‰y~þŒ95?I!Q(á}Ç?2… $J½Ü^LÄ<dî=¦Ù?Y¡¡…YFøPS2cÅ(k^õ³Ý½%ĕ™3æK3eu ¿?¨Ñàc֌›^½q<8Z¯µŽÙ ÔV¨‘™ççϘ»mš9+4úMg•6úà„ô˜âÉÎ+ –°‘Øè±”3Ê®ùI
615
+‰]ÔÆ \ûËÿ  íÀÂÉB“w0pQY$ߘSó“ó)aÃXy‹whŽyúʍ(ç»Üa#3°a¼«"ÆhëÕLY¡Á‹º\…6DhÃOUo¿œ¾2nÀÆ¿ÑP̆1.ٓä–—0IG­n³­dÊJ;Z|W£Pƒ›kg`cð}cXÍC3g…FTwÙÂG /Ž#K…F ª¡‘øh¥î1§fÊ
616
+Â–«Ú(<ÓÅ×Ó1/ÃâÝÞÄCãÕµ3°qÆvÚ¯æ')$Øí ʦx)Mµ©öF,³Ä8rõ-BßPL)]¡ÎÞ)íÆŠÔYf*Ÿ½‰{à\+52ó€ée94sVhtLCÂGgÿok“OL‰U…'T#n!‘Ø8CNŔ^Ò3—
617
+.*«ŸuŒÄ+°.\¸ Œçdg`£rÖ#æK3e…F”¶V“`ÿo:±Æ„ú[Âq •Uxg`ãŒ1v¡™’BBx­„ ‘`Üyù½y¿˜·¬Ž+Ž€fcg0£¤×´¤¹g…ÆÅ•¡’—Ù ã\ØjPÊ/Ë´ù…èm”i(d.oÂ7f\›dÊ ‰h<M:]4ÖeóO[|É©wü¯ÔÈ l44g¯fÊ
618
+ 6©zÇd>ôÆ®‘^‰Àƒ™3æKó“Êה²óš #æS¸Dºš¨‰ù¸T6^;Â5ˆ•{ÓÌI]Ã~ùBSWû½X1µûüߺŽ 0{9íJ‰Ì<`xÞ®Ah¦¤ÜÁÚ*môNÞÂ:fÇ£Ph<‰Z/Jd.XAÑyw„`N …Ê׫²íšLå7u…Ô˜M¿ê&.<5Zb™‰3æ”L9!a1߅&L¹¦å]¬ë’´_ بx8#NŔ
619
+“=?tú{³sÖuØ'æ³O×ìNÌ.N©±3¾ߘMsÏ
620
++&OÂÇ\e¿·nq8ŽUe÷¸3ð1Ø©¼1q˜©™³B£ñB^ñ“añ“ciډ¡Y/#™Æ…Š˜/͔…3è] |VL¹c<Zⱎ[ü>2Þtä˜S3g…†:áCÙÕË@ŒðøÊÀØâJ’>2gŒråB3gu ‰:"ÛCf¡ Ɨrâ¸óa*½P"3Ïϟ1‡fJ
621
+‰x¾I í³¬wæÄ YÏP™ ËÉbéÙ¸8B¾SNHT^Òh¢òhÈjN®…!QZàF‰ÌÀÅSytB3%…„Õø@iƒ—ƒ`2ã=(ÞÙ;“%Ö430¡<ócºI攐ØÀeÝ&ížÏ=~Sæ´:
622
+ŠkWìÄ"ÎfDdÁ#%$.6þLŒÎ¬Þ5:Žoå'Žé`àãŒ95sVh´˜q½é£ñU%~ 8Ž#àuxâÊ&_Ðü |´ÈØ/͔þtcô¯=QÌ©Åf"Œs(!‘Ø8B
623
+ß/¡˜sBBٖ‰ÄªûÌà:q W`¥Æ»92_1wÙ4sV׸~×l-×|êyt›÷ádÂkÁqÇ߃Á™y~þ¹V¯óQD6÷Ujü¿Êü½†\Y_w l ·~¿™.}‹é«5Mš)+4jcÄuÓG]mIûÝÕ®G ûý
624
+ýÀމz«a¤Ja¸ˆûC¶çþÈPuҞ؝Ù㐢$Š’½ìuTܑ2Ö8‹&bf$ߊõÍ&P]4g¯¢Ñ.QÑ|¦·„fCQ5d,äԇæcf$Ž;›ÍÙ«hX«L #£]ÊBðݖ±÷ .µ»Èí80oÛW6«æâT$rîcï«Lè?á/ŒmYpÊ}dr-90ÆÑæNsò*1öŒf×㈔Ã8èêÈ$8ԁEcf$ŽPÂbsԜ½Š†æ/Õ†Óő$£®¯'® ]XfF¢8šÔ´(N.EA.qÌèœØLƒiا 'Ù÷ K_‰bµÉ­›ñìU4JŸÄ$DHƒi˜4,ßpÎy`‘˜™7Ñ ·ØÝÒªys*£²$×ÃHtcG­Ü·2Ž4°ȟ„q´IäÍÙ«h„ᵇá‹f£Yø¸B§éö!!H÷u3(q†“;±'ÑX{¤››kcïV<PWX ]yúû£Þä‘d‡ #E oº³#/n<WXtþ¥m=0o"¡ÅB%‚[ñäô²ý4Ûçvþþl͟붇Š›VÆ «v·ü?3Ñáð¾põ—.:WË{ä}ûöbÎϯÖ\_Íã‹yڞ jC¡æ~Ú‹èˆÏ^ú;Žùà .>XN¥-H¹Ø:Ê¥µCÚ#Ì¢å˨ã?0E€è˜'Æâø(–÷.µ ”qè‚ ºEœuò11HÔç<‰+°ƒ
625
+ÙÔâu(„ŽRqùÿ‰‰T¹Žµ²°wü÷Wó{~€×ËÕPû3×ËÇäg“Œ÷žÇèG
626
+†ÃÞøÓû¶£ü «ß‘HÂ<R@Ë̎vÕawîTPTwò§P¹²ð[æ GjRáhډ²£zà`fÉËö›¾É‡w&•C 8y¶íž·ó-ƒKÔ½YI¸ùä>”¿aø…Ý㏃Ç?ÿÿÿÿø endstream endobj 28 0 obj <</BitsPerComponent 8/ColorSpace 29 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 64/Length 880/Width 64>>stream
627
+85#1J4-mc,$uDF\-WqA:`(d1NN)Zr>Z`g_3,7ML[4;Ekg,L&ct+bUDHM/Bc<^>M)U
628
+`%.b0muH*;LgM9PJ_1]cMjk`M@.!0""MVc:<P5!^aoL=\\bJZs_S\-R8d6fa^<e$U
629
+(M*#i"5Z&cHh=/R0A*K;gZ.aiJQdn3#6$(V`/&u/PepGoi-p[So=q^2@g9LrPQS:=
630
+@pj'i8/2645A1*WodB[S5d^<\5Q3@dh\c.;I-H/RIm%2(6&qOf:br+%j7?CQr6DRb
631
+JCFPV"%N-ZnY>f.l0euCkRU$kqBN`HU#VaY)![_CFCjAYqB&uI9`OI[a2u^e2Z4qQ
632
+Jc=?g?h!"qd-a+<"'>?"!Z^5*CS^t:4h>l#ii."`X+s3o5M#ZaFo2b3c[Qc2idc@S
633
+kO=P-=8`:$OnQ2^r\9,QKAG/Z#/8so"8sl(p<[IA&cLB:i-/RaBsKeu?g>NJp_\s,
634
+b"k+l^0.7gPR6U5oBh-"82r7B+$6-JY5!7J6&/s:dkc)oOpM+q*I:fe%-Te102aqc
635
+aakhermj1--V<-jc\\P\q2YH5rlI/.!u0UdNu3E'I'3n[S:73C2[6!2E7UZ?aV_dl
636
+T(W*nn6,K]2?l-h^@eZ%0CXVZJ*VTSX5D%`+7G6hY'SP]-bXFOop<sFeT5]`DWrfa
637
+KBDeJTJm;CfNImi5U$E8oIj^D/,^FbY5[k7psf0/Ne*>leZDfGlOi)d"oUD`UOS@Y
638
+iq(0@ebUfQc/=fboHbKoD/@*;r?H`IP#'##oisBO/3[1H;.ol,<<)Lm?93E75Lq_+
639
+YMXHYBCW71][+M`ofUjOkO?[>U2(6g/b:PXKs1+8Hm\j![5J]5doUGS1\#e3H_6/p
640
+#64c(rr<$!s8N0$#6GjY~> endstream endobj 8 0 obj <</LastModified(D:20260321161439+01'00')/Private 9 0 R>> endobj 9 0 obj <</AIMetaData 10 0 R/AIPrivateData1 11 0 R/AIPrivateData2 12 0 R/AIPrivateData3 13 0 R/ContainerVersion 12/CreatorVersion 30/NumBlock 3/RoundtripStreamType 2/RoundtripVersion 24>> endobj 10 0 obj <</Length 1557>>stream
641
+%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 30.2.1 %%For: (Nott, Matthias) () %%Title: (PAILot.svg) %%CreationDate: 21.03.2026 16:14 %%Canvassize: 16383 %%BoundingBox: 707 -846 1227 -326 %%HiResBoundingBox: 707.074770252821 -845.881486652068 1226.31735818324 -326.621012464111 %%DocumentProcessColors: Cyan Magenta %AI5_FileFormat 14.0 %AI12_BuildNumber: 1 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 707.074770252821 -845.881486652068 1226.31735818324 -326.621012464111 %AI3_TemplateBox: 960.5 -540.5 960.5 -540.5 %AI3_TileBox: 687.196064218028 -966.251249558089 1246.19606421803 -183.25124955809 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:24 4 %AI10_OpenToVie: 506.06067895579 -419.011484846167 2.1615429790394 0 8266.08092564465 8355.687044383 2548 1384 18 0 0 6 50 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: 506.06067895579 -419.011484846167 2.1615429790394 2548 1384 18 0 0 6 50 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %AI17_Begin_Content_if_version_gt:24 4 %AI17_Alternate_Content %AI17_End_Versioned_Content %%PageOrigin:560 -840 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 11 0 obj <</Length 65536>>stream
642
+%AI24_ZStandard_Data(µ/ýXƒªpÁ8.àˆhÓÀüçy\¬á¯Ê<å`ÿU^–LB’ÝdO1NSñ#c|„ãk60ˆPáBÌLNO“(Sšžª®¶º-H•.½ÍÝíý=‹V­1ròró³aĉ[cksw›FZµù9zú:{»»ñr¹òåËíïóõ÷÷ùûýÿÍ#õêׯaÓE<ÙÇ?•uì°4((‡iÔp»yóÆcŽ9¤Œ2˔e–±sO=º‡O?Ì1礣Ž:ë:t¢D©h#nT=2È„J
643
+-´¦L™4iÚT–S§ö7¥”RQ+Ù©Ò 8P‚ˆ!ew"ˆƒbB‚Á(€„áÁP,Ž¹Â€ÁB@(($$@@&4â±¨q( $<ðP0ŒEG‚‘€PD°@ ¡€8ˆ„
644
+
645
+E„…
646
+ ÇÃ"óp ÄÆŽÆcá ƃˆ(@ ŒÆ†DB„GBуB   q(DÅ#b
647
+ˆ‹‡#ñ`BÄ¢ñÀ„ Ph@("`¨ ŽФY€( ˆµ€Â"‘(@<0ŽȂG…XqP4`áh<"(   4 `8 P¡á8€±x¨ñ Á(ŒÅƒ±p<`4h PᡀðЀh8,,”ˆC1aB90ÔÂB@b–j@†âñH@,Ôó=î|ÿ3OÁvX8hhuˆñ20 ÇŠ‡Äƒ…–@±0À:(J‚w`Šâ‘`8ÓÐg‹°¢ž‡¸."é©jíœì¦#˪¼øæ–0£#†è§}?ê_‚H󱺺ÞYò§ ïÝ÷fcKØaP, Ðh€¡ °@ƒ³PQdx<4DÐÁ¢áÁP< ÔÀX<(NC_„C1A ðGˆF„‚‡âÁ‘hàëá0 ¡ph$ð
648
+ˆDŠGEf¡0ÂñX0
649
+àP@T`ÀLÂÃaŒ†ƒŠEŠO?H²â!ïæ»¯x‹ ó3@Í•ÿ’v†X4°‰é2@61~Å#Aa‚¢†t`"àHL Ðp,H£±X<(p@! çŠ! ŒÅ㡀 xHLpÐÐÌBA‰ˆ4¤³Pap(˜PAˆE…Ó€çÀòHLp4–b±ցY(‰CñHa$&@C„£Ñ@Š ǃC1¡B„FZX(w§¬xvȉbúùf_&Œxˆ³á2»ž{²ê CÇEëÖ¶$BÁÀb …1 x«3@Úa`@ã<0Œ
650
+³°PғaP4`‘ˆ€‘@ Ea4LҒC„AñH$Fc±à!‚ˆäÑ@Ày aP@< ,,”
651
+‰…„Ç#‘€Ç£¡€„ÁÑX åL,FcáP Á˜……b‰"²€ŽÆ#áxDT€€p€ ŽÆ#¡p ……‚X’ 4 °(¯=]gs­r'õ:õm÷£Šõ+;ýt.M«RY ûoáÚaIK,em­­¹=©’^ž./·{9Åýà•+˜e¹ôT!¥¬æ¶))ö?(¥_}K©\I¥LsêÔ!Ü¥+®S§P¥;\f‡(dò‘£ek©¥”2ʰâThj%…ÒI¨Ò.]½//×%*fžö¹I–_ ¬3<Åu|„Éò3Ss“³³x~š<*jò«Ñ£H“í-n®î.o¯ï¯I«vm1>FNV^fnö£®±³µ×ÏÒâþn<¹ÂÏ×ó蓙3)e'K—p‹§O&•V2u
652
+U*U«XµrõÊ$[·p¯6ë,´ÒR¸¥Q#G’å>ŐË]Ê
653
+%Tì0uUYn£Ž*j)»‚ S—Ûׯòæ ¤Jƒ¥VZÈ,³~ùêÅk×.]¸n-¥TI
654
+©£^½rÕªÕ*U¨N­¤J'}òԉõ’¥…Bè ƒ5ê²^=úóÿ^°›[Ͳ–…z9÷Ö¨Q×V™òäÑÌU5ݹƒ†11-—J§4èšx—
655
+òûûf>ÞK=,x¸l™]²tìcƎù67·ç¶-j›iiÇ<zcaddÅMÃU:gÞ»ðj¢ZV:滬&Þkä²à±`a( :0T:%âtŸŸû®õ[bH¦·b.®s'†`Ú¾5º·§{b%â4,§a1»C9dµ‘÷ðÓ¼CÙ;ÕüÖÒ,1ä”ÿó›“+ÇiX@´\@iÄh‘¢DˆZGtÐ9ǜ?~úðÙ£'ž;v–Q&dŽ1捛6lÖ¨IƒæŒ™²^}zôçÍÿû÷óïëçãßÛ/Wžùqãïîíìëêéèçæ«U§F}Úô·wéæÞÖÎÆ¾¶^¬81âÆŸ›™—•“‘×ªM‹ö¬Ù_ß^Þ]Ý\Ü[Û²TiR¤G¾º¶²®ª¦¢žš®T™åI“Ÿžœ›š™˜—– &DxÐà£cid\TLD<4\§.ºsæþüúøöôòðîì–)K†ì˜±7·6¶5µ4´3³ÒÀŠÊYš››1dÊìðòöúþΡ[gˆ¨ÈèhŤ''jläRJsYÍrK•cŽI+ʔn>N{Ö×qmU1n©0¡ÁGwô5.bÈ3³qºíxßÔѕóϼÝm1 o­5“²LI]u)§}}¹ä¢9œwú¸hُlùïönëXÖwù¤VaG©œ¦.ÿ¹-·¸Èý§l?ÿÉ?%µj•­¬”’Z–»ø›ô%eÑõÃÂo’*‡ºÜæ¨bú§ik)tŒ©¥Ò1ï]Ðt´’Λg´ôŽeyòtv7Ä%ñ1®Km•*EjÊ««âaáã{vËJ¨˜/+•c¾9˱Jè¼wÙ=څÓVªïÂú½š¨÷N¡W´²À¡˜0¡‚í&ÿ‰!h‰±}/2»¾çÚ¦³â¿ºùvÂË–’œ’ìã:3?úvbbÈ>+òúæ~j;ß&Ì®ÖjŠþÿׯ‰!i¸ïxêú͎žšüobȧe&k¿±ê÷YbHÛ¥ýkÚ¦j§&³¦9¶Yöçv#ó'V0¥dWRוÃT[>—>ÊÚÿ;L]ö/æ ¤®”²Î‰¿Ó4%%tÒI™š/ÑiìUŘÒ×·šåL©¢Ô:çìÑ[å[_W4ß^®ÍRá]]U\%%Jô΋ê¬Uû÷”Å:a[+FÍk¼|yõ¨I8B¾¥Á"õ©4(¦‰·)YrëÅdŒ¯Isʼ«ýý:þÞêê¸úÕ§"†”,›™°"Œ‚<sbE;×O¾ä4Ì´ÄÊÚns_ç1'V¬,pXHˆàX@€Ÿü÷z’Ž|¦'o¶ˆ‰!ת‹—êm¬Ùù«xÏŽ—™¦Ÿ®·®øŸé¾ê¿éiIöbb'†¼­~ã覆{bÈ%¾ž¡!¢õ¢»¢ûj›®e‚îo—â¾Öډ!Ë}§›è¾iÍo¶ÙŠú—¢lœËúÆÙ|¬ËÉù&¿=ÉFÚZs„»â@*Å(óÞ§*èxâ:ê(tÐ9ÇSü8+šBÆÙl9cå´)e•òE³¬rÌ{ÞJ)¡cÞ»óÞk«¨’
656
+:ż—æ-K¥cÞ[•Ö[
657
+•Ôåæòö(]ÑS>E^©ÉɝžžŸŸ%™®<=MMÕV”V]]^^ß6‹6ˆ!˜ˆ!ц…R¡a¡(Œ0ˆ5,”WE\ýuô„‘uÎô|Ì·D‘dÖÄÑä² 1„Q€00ŠS, Bâ P<ÐËÿ§šÎlx­íkÖËØŽ–öxžRÛ×óóâþîޛ™©Ý§ž6ãáñ¢ffڛ;Zþ¯5^>jÔUºw·—Mw;QDÚï/iEò´Q“ÄEÜg>¾´D۞ÏúñììМý=m{/ÑF6ÑïVôGþ½ScÆ}¾ÿ\¶×N‡L2hÅ;—*{h>{´˜w+Þ¼Z’YUÿÚ³PyoN4//mmÍ2ëóCÄ,ƨUV]Ò®S~þ+'5*£õ¶†•½hI PRƍ0•rs 7ûêUÌïO„ŽP–¼\¤ö¬4ý„«Ê̮غ4°bÅJ)gi™¹^¸èrc9üüÜÊÊx©Õ«—SS“<¥©ÃZøRaD­±¹*:z&†øãÿ¯·¡³á"2¦cšÝÚëµßºë­3«ò©¢'—‡Ÿ ç½ý3k36Zúõî¾{ö)çñ&†ðîßs/¯òeâý—~ߏ뮽‰Ûüiömix®­wŒ­ÈŽ®èÍ¥¨Fý—ˆ¥¤º¹jî”ëìE­ÚÚߕÛçï÷ÿ£Wo™;yöB/ÿæ &nw»gwg·oÞ)vç›ÝåÝ%¿îª='xÁã›}Åù}kš¦LXN&zRJ§ræÐ:]bv±»ÓT)BdHtÎùÓgO&6£ýÿ~"/ïí«íâÄ'y1x«|Z%™çRÊRU|„L–V…Em*˜™¸ˆ;v’ˆ0r†~g‹½zö¨hͯÖü|—©߯ÿÖ¸‡ýÚjïlț{§¸¶Üêÿ¿üœÙŒªfÆn؜íœ5r”ˆÝý˜‰!¸–\'šÈÝ]rŒ0²œœ¿%·Hˆñ%† ÷ñ9ç%owbÈÿªqo?ßjŸ-³¥î)þ2§­ßb'VX«œ‚J*ºåQ*ºŸÊº-\0¥ÎAÇ%Lš8å«£R®M…µàZ%M¹JÏïÏ.ë{m2‹O§r‰Çe5ÑV—¾ÒÉÉx–k£ʲ©Êœ—òÅ»ðjAeŠé´bÜ ªŽ!¨ÔQÕ©’2efh£ A(ˆ„™hÎîvnF†TBšHDAã(ˆ‚Œ1†BÀƘ!¢R_‚,W—d'£x“Q㮎‹´/ëÙEý¹€[ùE•È73â7ç´Ã}ù¹¾t¾7 Άט”_nÿ{:¥B°\2-Œ{¡8Ë&¡‘ʘ…†Æ²™[7¯æP@¶.ÎWr—W6œ××JoõöÖԜÌéma]z+¸àä!¶,·IT÷´µŠ•>xZ¥ÐЖs¡ë–$›io&À`Áa«U~.¬Se9 ²4ÛâI† ¸!M-B§Öà”/Ág‰h`5ÙaK~–ß§¯€Ójù?Àëv·üÎÛ¢|âý#ԟ„ԍÎO!³Wví¢¦M†¶R)jª?P7Pi‘ìY©EW§ÌgA} 2oœ¨ñ5l±ì5‘MyÚMÙ«»Fx¥ˆ%+Èg¾º“‚ÓLÈó_Y0Ljµ}nèh€2'±Ù1'Ða†]ýσ¾L‹«ÿâ7|ƒÏ|.žº*<é?)ލ`„Ä@+jdIzMñ˜ªáp¦%;V¶Ä¤I}ސCAAØ*tö3enRÞ*ÐÄ»½òUÙ´ÉÅVi~lX0§Ýïá雔¨•R\ƒ¥&. ‹0ŒT–€D!íz-9˜¤¼Á_ïù$û<-÷aU]вNEiá ë“3b´²•I4g̦ßV«ÂŃü<«x]¦²±é±Ê/ú}K98[×-yΉ3˜'2_ÿ%>D«!ÒôÉÖ¦¾ÔÕº´ªöV𽺲i„õ eR†u+ÉQö ÉƒS¤®¡ úŠËÞ-"'ºä)@}0íP·ËãÙ£Gˆ­ÌI'WRæQTgü’šÝ†`¥úùy~-ad‘PÑÎÑÂ3A© [ÚZ!u
658
+,HKª/OR¶q’^iJÕ"Ëz\Ósd·ù0>wÍÛH5 8>»[Ô&>c¤¦O:ï K®gÓyYÌÙ2Õ·Üw—+.'^¤}!C ‘éJb<¶Ã2Ûo¬ÄN†åä|k7JÒ“ª!yæ¥qŽ_†zœ!ël£xŠÈ„‰….ʄ[ÄÖ&!‹1©Mychj…óôk‚-–,u ÕvßÈZ²Í¡Üâ3΁fñå2®°2Nӆi2®Jܵr‹2Áæ—Zd"Ɉi)Xö V˜Éb±še¿O’pÕZvN9 åÖS =ÏÈmêüãŽe²™}cijKxˆ6§ÖÎ[9<YfŸÇaÒ&Šfç¢÷¼Â±¸!ë
659
+VŒ=ÜR¸±Lš±EL%Ê3ÑŽ‡í§™´ت™…  ž¡YžÈÏæm¤tõ`³2A–KÔÊÔÝ[7ü($^U°Ô²±gºÍ4žZ÷p±¦BRá¿¶¶¬¤Åoóù§èò÷‚æ`) $³ ×  1߄¯=jÔ„cÄj“! Z͙O-ùl²‘V„L«æöܴے>³(àøošüGè ÀbÕ¿cX ¢¾ ÓÅ`éot›²Á_¿S¸”Å_|zҎ<u|’n/'Ë6Ç š’˜Ø™ú3q7ŒúO˼ë˜X)9µžôGˆ…Õ…ŒO_%”'脛ñ ³gŽûp°PTãâÝPp©FØT-ê[œé–ßÈêä+¢åJ•xg¥$’†3Sš`¼*y°‡þNxwá×àžaÁp½Lùer¤>D-¶ *%Õθ8@ „†Ö’é¢7B²J @J¡¬G©®a¥Ù¯Ò3MkW½JÛUëقn­ÁŠ]Õy¶C½9ªŠ,œƒàH'%Ö¹ïîí’Tˆ7’ˆê¨+!†ï`ÕÛ_ù/ŒÕb~ZÊÄ5º¸Ð4CæyÒ'
660
+›yŠÌˆJ’Ç/ʍkŠ3'ä×'ÄÛPtsgÙ!› «bQ¿ˆÀ >r$0
661
+ŠúÃL@{ù¹šÎH~d!ː¬.ùiG:Ž ?ޅ•îüçÞ¼8ˆÊD ¢hNj̧qÂÜÍ@2í¤<EÊÀT„åNªa4€bÍx’;»Š{vê"¨P"±^öȵ­Ò9Ÿ<­€f}tHyãå;g°°¢,?Õ@:©yVk~ÅFîÅpµD¾p™`58FɀÐ;WÝÁPdÿ
662
+âî×R£ŸÒÝ(›7Y¤´¥‹˜aô_j¢ºdæÉm L±ÙzƒðÔRy³‡!pÝPþS-r£üE$¸X=žræН_ˆ¥™Ã‚ת`¿¶¤l°?qwþ¢t2 º}¤W²ÑÞ7³² ?±¡]~ÿ–&¿õÛZd­êB›ÛÏÎôÎØ!ˆÐ ‚D&0v'ŸšºR~¤tÌÊCe³äõýðI%ÞÙ6Ձ#·Ö+­ªý‹ _[öîežVj¦3dž¶;fäÜn6Ïí¦ÑTÿœø¡4o\˪D£¤Q3S(U0Î;jô|ªÑÞZ¡;?XUp£¶‚5¯?ÔCbØ;öÓÌLÓtRŸ ‚\w{¬!ãÌè3BÁꔇÌN>·°÷iéqŠÙcƒØ°cOù1Ώl0z`Géùùx¨>Î}5¾Òì
663
+ð%— huØ«n Cߕ²5=§‘ºìP\‘×\"¥– 1ä\åŠÓœ«.ò>çz?§¥8'2ÞíÂۂåUrxßQûW1ÕÈ[[Ù¦9õjm6‰A­ÃU¹öñEzªi¬J±‚ÛóT\ÛO>6§Ú@ÍÍsêÚú7'¢”DJ´“qІ”®CZ°¡\TÿL„3\%DéTQ-æù¢ŒjðC)âì¨Î‚ KAÝ<¤[â!¹ FþÜ\ɹ˜‰T)bùó Ì+âþô“iº\uíã6K­LL¥'îTåÔfꝖնD \ϐÐ«v›+º­Ç®E·E ÎzÚZ^¢ñÛ'¸ÕtOZ9œèòkÐçdžˆ&òbó †Èc[iC¢Ù³­çB×àÄÉDÅ,×Úqpe̊âõdO†mOŽÑ=édÄøïnëÄ&…²‚ÿYʂ Ä f@”¬Jîÿ·^HØën,Rj¥£óoËßß&êo׌‡üg&ýÈþÂþ!-2 À)̪)Úzi sÉIRR,X•´ËJDn²5\‹54¥{Vé miI® ùօeГ“À˜(R¢¿ž„ŽÞ£ŒN˜£5z4gØ4 &QC г©•þ˜CzÌä(A¢eÍX¸tŒtLÜ"a[ˆJì³֎¢°]RPÖ>ëý‘²Û0àpù´à¬/¯#häÝb`_ÞÀ&ÌP¡¸jéÆz ó‹WۚT,<&pék¿þ£kÌ7SQuLy pLùju¼3T-O¿e¢#î¹ÃíÒ™wŹä•_ï°Ø²—Zÿð} #pP=ßG÷ö!yžG,nâТ›g¼ýäIY €zwƒä{®ÿ¶ݞÃ!lO)m»¸ÝÛ ö¥Û=‡•‡¡êâ’#ß7dWCkÜ×îßÉå£xyD0A’}épü/o¥›à«‘Âý™©ÄMRh¶«„A¤ è‘ ̂Ì̀ Qñ8E3zw°4 vED¤ÃÀ2iÖ.«Ks:…GmÎFëcuÀ4ÍÀ#­?ù¶:›³bMÎ ƒWSŒƒ¿µ)‘»úiêÖ6¿ø~ Ó±ô¶˜ùo-êã)-à¿Ìf¶âÙ8è‹¹,W¢Ûö€°ÝôQ7àôBYÔ/Y>:Yš×ãg*8Ý)>¿‘¥}²$bËe„Ó6¾=®FMMkü*Z˜éÆÚø ±ÆèGQÌà‚z cjÐè§f_Ô –8D—ëÿ@ñ/Eÿ“:Æ×Q×ÝÌ-ÑB|¨ uG£(Uӈ¸Æ|¢}ëD·©š!m–-Þ`q^ÍÌ5ËѓxÒjd)ÑË(ŠS5«&ýíjï~{sâù[)˜}9ɘç*tæ9È®2Ɂ†EH¦NmXšZ~N¹+åÍ«¨i1eë'Ýþ„À‡»Àq,$Jo;•?GÕoŒ×xB³ƒ®”Ø1l8…]‡tTjŸJìƒ Ž…ÙÅÆ;[Ñy²WÚù7ԟb:h£ŒEÈI$Éöå½ܕ›õMð<'Ɨ"½¨;²JÐweN®ÆDcÛ·3ýÂî¨Í¤Y<¥î _Üuø3Ü-«¤RE҉e˜†¹Œ*5¯Tj7`¹’+ûs N©;怊äàÍL•Ù»ø‰B€ð=öR­Ê'N/m?[ÈÕ@Ö*XnçŸÔ¢'–õK7GØÐٔ!¸è&Ǽ†ôV’<o 'Ðàôõ±›Ú„X<ŠÏk0MŽfKˆ"|~½©0@jûÐW{¤©Q6<ݐ\ñ!Çü@VFì “¸Å1
664
+*"LêNõD°‘Nîõè”ðýUY]Ž4!;(¤7€LáÁTتB¹+äŸÐ ç_ZÄÁpHi¥OZæÖd)ϺĆ2áž]= ˆÏŠó³v´úD ÑR\×dGº‚¢-­G' ^iâ˜Pd Å·RìÖkaó·ßHiuF2*Ñ$=à D$d5yË2HyCÄó^ª9ufž€Vˆ™£ÉŠ¿™è$¸ü††ßƒúG© ý;ˆ<zý8±¥(𥤨ŸQ¦öûÃÛ,¾)ñâϞN^(ã(‘6ˆ,‘Gñ‘[Qa1^‚Q÷ —Œ5é3ÜüjgŠº=æ®úæ5.¬´pœ’° /ډ)ÿƒ¼¾Å B‰¥/aTÿ3²ôµš¦¯SÅÔ4yó§j‹Ýx5 òD!«8Ùr].7I„ö æ~D1Ê}щsÒøã%Àl¦æÅOÈÆQŽ ¦GÊ)y·«vq_® <¬îk9üðâ\ԄÐbV'Hɞøãµˆe°*dG†uT‹GtÓø…ý&¡yP‹h6ÖíלdBª#¥‰Æ‚ûeBäÚMã#Õ]Ç™TþA„(Ü»–† Ÿ@)õAmtð Õ?ၗ®7à ñòÇ]‘Ý|Ÿ;ñǙ?ì7}P\åß=Æ:5' ,×sóô~Gæì@MõÈ pR´'çÆc‡èÆÄþ™¹5zñ•Í:‚¾ÙX0†È¡âES˜ˆ±ˆ î…þب|!֔³YކXû\6×½çÓ°)j¨Ü°E;X9”ÈYܚ/ ‚¶Wkp1vÕ~뉙!¶˜‹Ä2BzT6)ll¤<ÇÔ
665
+FñZ÷”¸õ&QV…MÈv„ €:Óg÷IT!‡s,4òC"ŠdÞ¯f<=’™ý‚VЦ©H.º.çî»!‘ƒuy]]Ó³ºfˆ$D2½<Ó;Օgeñë%‹‘Šs¹ÃZÝ¿†z±¡M{eó¼NÓAÉÌ.ɵ:l|,Õ¼¬Q¢i8}Vví¦ì”+¯éå2­Å•æx­U–Y¡¶[HúÓÊfQR‰Øö/ÎY}su燶ûŸÌVh¹KPJ½Kã'xL ¶¯‰?%l²EÌ
666
+ö“TrDF8_%LwËÎüÌ
667
+{H‹ÑÓUR“哬Rz
668
+Mè§·+K¢ÂwzÔᄒùE\I¥ª ˜•ÔFm†Yh£µ½hc5œ÷èηÿ¼\ØÒ¾òшç£íC‡lnÙ ØxÛÓ <@ò>Bi–µoÁ CN ‰®¡2ÏÀä_J-Ùèav(›ö©¯~ÊFǺ<Ò~gwWÅÿ­÷=ì}cG¶ºÆÖb ì¼L{¬þuÎÙYÎ?,ÁW«}Sôb*Ž+ÂqJ•Ê9íäðÁUÇ\”`è  íðuóGúŸ}ï}k
669
+/úD<@™Œ52cMÓI¤P{ò<MžvƒÍz}U¯<™zƒ6ÑôâKïk”I°{ìçU9Sÿ§o¨Î.þÉy£Élö˜3ß:aˆ¸ô(’9\2a–?^–üuòãõôÂç Šëw‹wÏÂb®ÜI™`Y7xx€…a$ý8½gˆþ+·K­`‘^"ýWŠEœ¤¿öî5yk¿+£ß›òû|×»{a÷ï&Ô»Á÷=â½â™œdžšdx­¿<K…]1H[g.è"á¸/—âÿÊ[ÀVŠÔ|ÎêH:,ìÀ…¦Ö©Ô‚ûtD ü¼ždYôÁ6 ­tå†Oáÿx¿ª/sŒ…9Ƽ¿êP¤Ù_éÌýµ$˜üa3á_‡¶!e˜¿Ó*ùüº§õùú‹þw‹y.ú_oË_Œ9}j֒œ£¹HÐÕ}ÈTm¦ó÷#Hµ´æ,záì=^|ÎÏÒ³Q;¯â/ЬD÷+ú<† ìéÀðåz XÊxÂñƒpäLf¸y¯Ÿß¸Ç»1t˜t“J48ÝÅS®T‡<ʤh5ùÌAö„8“Z—IðÃaIvVˆ£q7•›]W.ÎKА×4ÄU—ÄÃ=‡×e.ȃ8½Z|õùG~8™ö-gø¶ ïURø=—;AÜÿԅÁÈï[eþ÷Â:z±ô…ۙêúqŠ‹ü…s7§Ü-8ÁùN Rø9|bïy læíà`üÙ鯘/8Øoqdå@açÝ4G˦†3;Ƨá¼t“l˜‹Í‹¯æ"I·9Bò|XUµq†`öSC¹€Øöí:¿ÚwðJú—6‘ýéZæ?ÊaŸfö¿( $ºH²ø¶²[;0àØv-ˆƒâ–&/åμKàouŒ¯á ža¢Y QƒæUçÙ³|Ìft)iăEÌ#fÌ ôÁÛç—¢ ¨µsž#IQ£s¦#–Ý–å¼Þ`;;çßvÙq»A°™¢ÿ¢žköb7ÙØ½w²¡ Ln¶%\¼º«ÌDe1—Ýeýï~ux»[ò®€å_·Ò ،£@kã¨F˜„ŰBtoª¥¿J\ø\ÐæT¼,?ô»5®A¦&wM°ð}ð.öæùņÿ#ïËÒQS”ªF
670
+=‘²*”€L Bnß³zˆT­6?žÖÒÊðI¶õC_ì«è3þ{˜‹1:
671
+¤¡}ÎÜ¢uw+‡ÕïÛZ °ÚšÎ¹¿°:öHÅìrÇÄ—Çáx w[ÿvív@ډp‰´Kr:V ‚7ü½™á÷ì
672
++ò€Àº”ý¶›vïëèàèÆ)]ªÌ©¯[Šˆ®-Ñu>tÓ8M º[í‰°ç =ló¬°e!°E¯0‰zí¤[ò”méòr…‘Uê«e6dàµ5ò2+‡²g
673
+893~÷~ΗbR#)êIfŸÛ`æ!‹ÅËÈ(³þ·:™ÏZ¢)kõ¬uWË#悭„ÕJEÕzCµÊšZŸH-Q«ÒV7 1…ÈÄyZ-9­×ÇĈi¾"«»¤Õlb£e˜`L´d_²„u¥UDa|ÕÑ×õ‚°jc”Õ¨ºngÓ¹o%‘®;z_~v÷­|¬ÕÈak.ö¹-¼·%ÂÛ ·!ücLšw¢pߐX»°Ý·ý£ß¸ïH´ ²e‹•߯üËs\èßTÌ|;ëÚ[v‘9ÏòvÖÛ£2˜Zú’vºwHPžÔm±ou%ß:µ'Ð
674
+F[%X{G~]Gp‚ND_»:;•–Ã8Î:#³6oÖM<kù¤ùeͯ¬uïèþæ3ë=aQõ¬åGª¥IÅÆ™–ôÑØÐ2
675
+‡ÇÚõkáZ­ÑÕŵ=ÉRĨԚ¨‡uË£°4 –™1õ¯¤YÖ`^ÙEñ ºÒ‚+s·r©ÀڗVzÏʦîJ-‰âWí*µo±OQ•¾T™ÖØ<DiTökjŃÐÕu–7ìr&ëm¥˜çnÍótª°L©ÓsïH"èà3°¨˜ï“ËrѵDµº(¸"öè6 jÇîm¬·;žu»?!îÁæÀáý‡÷/±¬î:«cw׸dÊß ­µ­~ìt´ô´/:£i\ÐÝ®bž®â2耦ܤ[>›®îIµ0ˆ-ýø1È{LAä³¾ ´ŽˆñI(>ۚPµM¸|À§ô{FÈ÷€f1áܒ¢VNJ0«r"`ÎLz2fZU‡Ù‚ø`ÅågT•çñàj]š°¥-¯P]^Ó7{f}Ï-§;­Eõ󨝣¥½ V)¯*“:Liï-SͰ¬ˆ©Ñb”Kò
676
+ˆL÷zÝ3ìèRT¢Õ= AÎ.ox¥Ö—Ümí3ô@zŒ×øaÝK‡æ5WzŽ>e£ÀÂi‹$R؎Òõ jBí†B¥Žü…űÚ3ú:Ó ӇrçWk×/ˆŒ{Õ #¤"Ÿ`üQ`|†Ì}tÛ’â$A'ôƒò­çÝMÌ#aa]L]up0o•iA9¦kKOg
677
+?ôå¸OºñsF·ÿÁ¯W–u=Ñ4ËåEU­ä´ÄäU“Ã ŠýÊYEF1¥oˆÉõü9°tc?&…$Ã÷f~(üér†j}@6¤ÿÎF"³ÿÉiT‘YN[f„ɸ–™©¦wÊZ ´0Ñ,#ªÃ€‡úˍˏôŸî¥vpÒÙä?èÐPƽéäZõ] Yüe+2ç:ôÂrbÉß#‘³ÒÖ°l,à}ÑWÕw½L¯òšGÄÕ-»’“oQd®Îé}®ü¼U[©i+ÛìnX«µ—n´ºeîә•9YŽ•V±2¼aÕå¶ÀJÅW9òª¦®:ªŸ[õµV•Ï*éÆ*¼Wµ†UŠÅUy­ª‰V•Žÿ¨ vÏ[H8¢U\™=GsöTË Zâ(ôP%#†ÉD­.ˆF/¡ì¹°Ži…´m§1ƒ ©4ˆûµ§•Àú5cYT:r#šBLb\ÆÉ·‡(|‹²¶Øf
678
+c)Y«+YêIv¿È
679
+ÊÿEëP½[}ÔÚ=Pt¯<%‘KíúÀ3»Æ-·`lܖvFò,Þi¡Ï— ”e€âIFÿ*A¾÷äºãª<eÝ J<Àÿ´Ÿlù$Ðòæ)0ÂND󋪳hƒÞŒËdg|Ã÷¤UdU]7]FžM$jÉڒCÞ4˜áëÜí‰ÂSFkÖ«ìÓ?jfpU ‚ ÌÞ¶ˆÏZ™i”ðU¡bAQóg"þH:7‰§õÑ?+„/¿€„)¹aSñù͸¸Ó¬6‰ÅcÓþÒ×Ԙ‰Õ Ÿù¸XsŽ•âRíÔu¿Ñ¨Wò‹§¥žÁjqhºÕ ¿Ãådlš2¥;yûå&±AºÇ—cŒrV…úŠÖ¶>Ñ|ebe(ó¡Ý¢¸P¸¼ß½'H°Ð‚ÂF´Ó±ÀôÍ rX…®ýoAf֚ԜÔ|ÃÐÇÁÐo“²ŠI+\Å¿5v¦Âq«êöÓå
680
+ó¯9Ae0NŒ1ïQò’ÀV„šVæàÛë$,—‹w;Ùƒt¸i¤I„@…ê> Ÿ(Ê Ž.?âá
681
+S~Ó.TÙB·*Ê¿¢sAÒ
682
+5#.3Qðܯö2±‰ø¡Aì· ¯i¸ŒïO?¯âú·Ù55‚é¢t.Az6~¿à½ÄåÊâ=óXµ>€]$όFō²^ ™Ãv¿ß5Mâ@÷]hKð+`:EHçÍ3ÌЄC5a¥OZ>Éã®·|'ZÚkrƒZ¹¦ýWdÐ}ž/¬I×n%µ9ä<̚OQ´<œ¢åÁ‡˜¬s," àm åچ0¢k
683
+NܝS޳5EZFE±
684
+ˋó®Ù™3} ¹Z#?…¸¸Ǧd2Ir…¥JÓ}l¾GÈ<\¸có:BÌáôé§<€Á}Sz¨” VJñ4i!(7ˆµÏħ êgà¤bdˬqÆ@ˆ1©¾ØÔb{5µ¾®‰Â’çô'Gn_ç+ˆ”§@§cµŠÑ·ÞU]V49`V]5X̼5¼wézò*6>Ç—æÎàF“³è#ºÍª­¤'NA…V\ŒÜ#v^³*úÂ9d2L@›-ŸG˜—úÊ å{< K¤Æ´=‹Øo–Û:N˜… -{ŽÈáúkôO¥QÎ-iýÁ"ö%"J¢^rDï‚(ÿ‡të!Ž;DbÌ¡ª¹Dö†`۞Cå(Up©_šJ†Sj|Šó‹HˆªnT;UVV)¾Š·¥©wAá?Nì·3Ã%í2%žÕêг6ùÉ—t-ˆ X"c¥•þ™Rª()yo
685
+I‘øJb’P&m¯$꬟C˜4êI» ‡0œi»(qU¥¥(ºYž ‡š“6¬ÄêBµ Ñjèb‡±/Œº…#1՚¤ýTûÄö¯íØí2¸¯€U܌è<‘r Ø8 x¸& ¹-uyœÕ\]î™fôÎou*‹7˜kò†„¢
686
+ŸD|ÎJ±ERÄf¸|\¿Â{ rîv ™&”…'öÛ3I\ûy&֓‘´ëžùôˆöéÿê=Pç‚zê“Pׅ:bC=%*¬ E-F»g´‘:j]‚´¤¥Ò¤%§ÒâÊwðK ½ò=iʁÓåh|Ãy:‚ïùFãì‚)%:õmËdeé^ ڒ½ †LÆ1Zͨӿ,<ð¹óx÷ÆäÎÜ8 9W,>›È#ÐNÝ団›GšéŒ¹C뎶tÜò=ȩȿ]1€;:ß *þuÈ贈æÕ)ï*ꠄ,X]t/YqË}áj’~áAzž•#^ *;õ˜m¢=sâãò"Z‹éòfArmm¤{L!K}ˆZÏ.I”œ‰8πí“$à]4Eúèh"3ó‡)ÆeTa\ÍYj§¿Zn†(CüAº} ½4)ñ0”©ÉOä_œ™ò±" Ә²»þ±¸Ýœ,¨ª¿·åVã‹×>ÛS.ØÕ¯5%{«À¾Lö
687
+´c=?ùNƒÚpÈÈ(\Ç¿¬…´z÷ï‘H¥¯HÖϲȑûâ*H“Ç´Ã ˜…)©-+´¾¥ûßÊp`ÆÑØ\¹³é@Oª´4,þÑ¿ˆ¿dBÖèž
688
+Лà ¶uo哷”R`ñ9i‡K¯’Ma— zJÕٞÆ qì
689
+­s
690
+Îãî1µ\×rFÓ´xO8„ëýÆE^”KJ×ôNÖ6Ã×éÙSÝà V¡¸„e6ÌFŒhª@¾ ¥ê0‰«dF܁´3¨gðÔSZqUbΌN-Pó5I±~y‚Q¦¦-¬œZ³‰¯G€ÕšZÚiÆ÷øÙ%êþƒtÂýSéÓÛ̆…ö²kõѹgø
691
+(ÿ)½þÁz«œ­Úз¾«Â Å‘ä hn,±’ùšP/0>3Êxãò8ý!&Ѩ„ RŸñž­¤lJò_£>µ¹i¢þˆ¼:S‘òœëÎ!ö:DuÙ×D`pïÚMÆ8鮼ØRÍxÅÇϞ¼°/|­*¥aÜ¿N®XšÊt]…€§Ž½Aÿè§ýEâ>@äÿ¥0Þì†÷g˜öŸÞ÷,bj†ü ð^©tÔ>°7ʧéXLR¦$e*zCšÈ&·y<U 3 ã 5aBS*©ª¤qÎá„?&¤X,³ZwíóYØÌԄἋ[±øœ1œ™N:‚¡¾æ6KE;(šx¾DU˜gÚ ƒþˆ¢¾Kj$¦÷ú°šŒ¦– ÓÊ+÷
692
+³LUõtéC3,CÆ%2þ=U/M35ž˜ØSëÁé:ïŸùD)ÐØ91x¬Î-œé+’(z^5öΩ
693
+«¼ÒÕ^Øޔ_¹H*ÒÖTw5œKk„69E=6v+Ÿ³’©†n­#Þ&!}(Å(îCֆµš÷[hi¢î¢‘Ši(6Q’¯©=Z÷U¿U.#¥ÜÍE´4H­t&êAó×È"¬K+™Rå$Ä·¹6ž+$w½Õ×#_†uÄPËöôDå¬<ýª¶†º]“&TTì£!¢xˆ^¯tf¬M}¡uРw‹ïK6<øCJ$Š}VJYg¦3ÉAF \É|jHµ"¤™{\1’ìW\(v¸¦šÖdÎ;{0yPú>YR!S1ÒÂSZ.¥|&Æ«åüv¡ž¤å•¦ÝGk å"¨A#ºi(êáÒ#óIyòÎ;X…hæ$s¨-Tw0wQáËh¡­ñ',]$¦ÂÔø‚¸ù3T-½¢”)èªg²à£B¤ep>w}ñ‰¤ª$&™è´ßLÍÉG˜¨/3!ëMÈue\W1¶Ç®2ÌØÆ´šÏ\È×5«Ê(èyQ%”ýmŸ¾:õD$®N<Om.< Ib¨fç|£‡²h»bœ—^8ùGíö;}ù>òG`šñ;:Ĭcp¼—ø³ áfEfåB.òɔ¶XJg(ê÷cR¡¶o¤!HߜTÕÔ[òëóCaD¦]LEˆ84ÖiàMQ#hÝ4Šy—Öp/±_¯…sg]쏋 ²š5ÉB|š.xF♏ŒøÂ dY¿Èœk„á£"†„,–üº%£8$4|'FJ—qÜ»„ ÿ"0Eš
694
+þžNÇҗqB éφ"ŸÈ
695
+Äy:ä7¤B±>‰eþÐ.“’¡ç‘|ŽîÀ#TûT“@€x*As”+äQ]_1ŸŠ¹;øWÉõ§%2#áЖ‹î+jÌÈÆò¾Ü*9 z­<NÊÛÂÙàÙéu:Äv0Ӗý2&;¸L´M*ö+¾ ²ƒrƒìɆ«ðà,Ê 1‚ƒŒS5ñp\¸žÏ¦aãú‰ˆÀëeã_Áí®Ï‹3¡V3áï%â觛ÐoL²Ï%XDžg&ȟsÎë­P’.”y´†¬¼*#ä{!š—TÁÁ…G‰ê(E4÷ïà PÕ ’lóèD˜§!í)|0b4÷õ'M¢³R°g*ê{RDï¶nç!BŸ¸…Ï.qñçªÀÙIŒd3Çóp™MgétXîÉ© 4Oï
696
+§¥÷ãaj²I ‡Öú‘3¸&IÏ҂ÔX‰ö¦•ìÚÄ/ՏÈa<ɪ—…z륨öÚ[„h›~†«yØWt¡jë'‹°ï•Øú¹ òyn¡-ùŸO¡>M¢—ÛÁß"ZA¸„nDƒ*4+1yÅcš‡)š¾âË-²Ë—9ÃX4¥Æ“ ŽhYû
697
+E$ׅ|îàŽ—åE«ðá1"!¸²Â_upŠ1äA†l±<ø
698
++£(:á5?¨*Žò‘†ùÁ,}Èé“ ÄƒÅU?œ¢vd«¸âÁ<ÔkV¡ØyO1ÄM*7hē=aT2îë2´^‚Ð\á^‚6‚à· ަȖi™Þ®Æ/Ø
699
+äÊ~ʗM:kÔ¢}céYÑ µ¢¹”5!)§W„ÕNJûÔ•Lt*7P÷ň¸³°¿‘adRƍ´•¡NQû¨èž·Hà7©ÐŸå
700
+þ'xyñA>_”4DÌô*©ðØX/SȝÜƒV¼ßzøGˆ}5h“NîÝ^§ÓhºOßá[?SåQ‚p´rÊÝ å<"–rzCêÃÖßW¹ÈŒ›ñIæafdsãËDÎØ˜Ð©£Œ_†ÍŠª‡™½$ 4£YhǪõv<Øì#ðuƒŒ <‰©ÑÔ%¹çBÂh%;ÔœlZhÕ/ÐDIè˜}uh*³Þ~[߃°¦HºÄ(\¢¦ìP'‰VŸÐ×Gpì ®2úŠxð÷¢Vè;ÐÇF‘§â#§FzÂä#à(އžù»zª=†ÕOBB=Ë"êÉ;7X¸½4fꥪ¡¼øÁ:VúšzÚ %ì_‘l/‹
701
+ü‹>/…úú¡0?à\ˆ <¨®:t×"v`ι閖'Æ¢1:¡‚¬" ñ”ù9+DÐÁoþ@ہëÔh¿ƒ
702
+¿Y¸<öŒ‘ðÚ¥SRyµé;’°é5Úv@o´½œ ¦ìsŒÎµæHîP1ª|Kkg7DêS E¤Õ^¦†¶F¹'×C‘‚ò ÞAÙ,±ÌZÃg}‘êP!!Éï …“"B"Ôè|9I`wЩ)ôÖ(®~„*ˆç?T/§
703
+ã]\TÛ¡lVäàAwŽ…{3“é穵ƒ?\Ô}Î*hh¤ü<¯ÿÀ•îƒú§jD<Òj´è;Ã@ßÁTE0µV?I¤'RÃÔ¸0ÁÞ?8½ þnô/̶ÛE ]i¢A'—&³ OÕBmD‰ÐºŸºß¨„
704
+8˜gETŠ#XEuµ†Y×ÎWäЭsÚh<X˜: î4ó‘é7”ІÕÑgæmPøx°O÷À&Íæ‹r}P¤)'Gbáœªˆ<X?—œ·¨¡ÈƒM9‚›@á¨hJdsÙ(<Š°¥Á?(™`²ÂÐHÔ=ór ó×='šޝƒÅnš×8¿«ƒÉDÔÜÃ
705
+  á> ¬Sóµ&x@1ÃzÀÛù:6"Âô€©Ì;Ÿ äTÏSï°Ü¨9¨¦Ê¢ŸVmB$â@j6©’,~¼ã½#“°ÙÈÅøCÀفÄ"L‰+°*D$þ¨$ÈìåÐz+Ô+L&½b£)GëðF_æ5a}9HvÀsoñ„âˆ+!½E ½t° ¡ûÕSø¨Œ­†á²yHlšpå >àXΧ”é\”žO :à¶¡/=…š“âßËvQH£þð«~„ΡèÀÁpp¼7€A*D 
706
+ J0ƒ”%Àd € Ø@˜à3a2p3žàL7ƒ÷Ì¡"Fðt7xr@C}¯aM†§¡ƒj¼ß!¡&,q؟ÐÈWùÄ4„IâHäE—@wD&ò
707
+Î4-嵺£"„[@=¨OåÜT¨˜À(@= rå`&ñ„DÒAKRš)%™¢C)¦O :0¿W…Ã'¤×ÁX"Ûäàò0uÐ)Þu‡…H¬¡|°Ÿ¥!­(Øfù|¬ŠxP½Ãø`´‘ ÇjM0T>æ•DBùÀ½©ä%Ã7(Œ,çÄ<b*<ø„Á=øL*L¤:Å
708
+Ōð`n(9xÅö dd¡rð?\^BbxÐq^µ]^úC í sŽ8X¥;Y"æ¶%ð@.l˜š¹.j„¸Ö…àà´¯dfANUÎòƒ”4S ;¨yí ?èG¥¼²ÛÃДoÊå›`ó€Q¤Psþ]ä%j؄ÊÁ”HØ”Œ9ù /†¦Ás0tsäÅ/„Kh¬ˆÜe18y 9X åãN ó@Vaæ@îÚÂ=!—rúÉ«*á&åàe×䝠póàs@£rÈgHÂÐX ăÑloˆâA ъSˆhÁr0%tóŠpÒ 2ãñYpñÀU>Ĉ)~Ä R<xԁ=8·O´„AŒà ä íAkF<Yªx0óõ୉ù!;ì<xÜá=_†/Ã?
709
+ Ճ¶œñµDØ$8(qŠÂ#6¢ßã0Ù贂RªeQZ ó@Ѐ ‚ Á \‚Œ  " °à/XÀ‚7ˆA\ð‚Ì`)hÀ b €€ p
710
+P€ Zp‚ ÁA|À8ˆØà`*#+‰0?¸›=ˆGj‡jT°¡JùTNu¡ÇQ÷‹°ä$-Ýï/vTú…$FèQU%87åÖÁcUŽÍ* …8Ÿ'Î1ÁsÊ7È9õi"…r!SÒ瀗É‹¢3ŸÚá£<ô–òs Ek…a<7IE©ˆn yw«"Oì sÚ<tVÐ&™ÇtI,dúхfjìÖNä³À0…_x
711
+õ)Ñkâzý`©yͅ*ã?að@d‚d3¤ž ›eEªè'x­9çÁr£‹ÒíøCEç:;¥ðú-TgØ_áÑc!…s¼!é 9¯+:Æíê¯Zxþ„¿Hš”†&F¯¢Ãlᙌ^>ƒŒ‚æY‹æ,Qyö¶‚>®õ¸+tAAÖG#Ý¥צiÕA—èÊ´™© /6¡zÅﯫ΂Ä
712
+ÂZƒ\3³xí˟da«;LBÙS-Ùa2ÚØ¢ “ Ui2i2á`˜ÐÆþ¤(D48wM„
713
+§HǐOšDšòœ•Ì÷²ˆ Nè„CKênî(Ê.#ü)J†h´kh2‹ùˆ¯EDJC.‰†<1—áCq"æÜH áJnÈPùBAø]ä ³Ñ¥ääK;úH80ÈËf…ÎZòI3¡ØùŠŠ‰’‹ÏPqEƒD"J:zCO%‡âœäµzäH:¦¡Ü'^ˆ%²$SÄU>¥G±Ìè$ #s¾RO™
714
+ÄPnDڌL¼ôæ` 7lZ0ÕLˆP0Üð|4j‹ÍD s¼9Ïñ¶@ã UÆóÚÁ:#³JMÆaóžþ˜®©
715
+Äֆ~Øj̃¡I';é QڏWD<ý†1bS…ñ —yð>A¤8㐕Œ
716
+ªc¼ *„Z[f!"N(H¡&ŽYŠÂع’“b†þ'ސ¢jwñv 9¢
717
+é2¾F„ô8ŠŒB‡¢Le!ä ã’r*£mN{¤¸@Cª’4©"äò’*j"Êc !íC2…-æ€õ`Ð9| ¢RˆiØØ žõŸz<Ú˜ËÄ4ky¸šƒ*>Ê4E†;JŠæëM(V¹HB±Ì™&¿HÓÿ~‘(Ô'¼{Æ#Ž›B§ŽZ*
718
+3ÓòO¥ù/s°Íü~˜>sЅÏô/Dˆ"‚BmR•:qž9ØÄF³ÏcãiHuPÕù*tGÿJËg´®¨Šø&VµXNÎÃ{`”—7ž9…ö­.ñj;E(é§nêj­¢.šÍD]²Eƒê›5<¨ôs”6ßÔ^AŸî˜¨ù®/¬zpÏø YÌa색!=bÊWOyáæ}ð UùÀ#­ª@s¤ªtù HEfµª·üU©·Ú˜|Þêkñ  šW¥FD< ª>Lä ——nàp<6)º‘ƒ)#>¯ù®([ù^¢Êwi!µKCa†3±¼á
719
+æLÃOlB¦=ŒÈÇù“5H„ò 33»q§J¢bafå|ª#‚#
720
+µ,Œª3­…±,¦ÕùÈÔZÆñ€ôyzªcš0Œ c)ЬWƒÂЁÔTõK¡v˜P ¤®&„¬ÛĞù8Œd>Qý ­ð™P’ÅZŽ”Ð§‰‡š‰e âù±¢âú!ûéψ„—ˆÃ¤»„Ï–y'Œ"L-PQµNôJeç‡L­ª"Öï ú`2Uåo‰S7*}SðÌå"
721
+6•ê/š q•<ÏAq%ȋ@s0B´’µZ©òBõ|àØˆ+t ¯Z†3¾
722
+ò ҋŒÀ «VUTB:McsšñAm'†çUщA|0§‹ÆÁ˜ >x‘ËdpÆ+rˆö*NÑùB>/˜ìàiNí‚Å2ÒTE0BèÍ¥¸ÝîƒÍëÕÇhÁWМ<>Y:¸Lx8¼Ú¸-‹èɪÕA;31$!¡èÀâV떡Ðr)TBÑt*›é„®›Ž)f•Q$®ƒ
723
+¢ qé¿% nXþ Þõñ×BüƒÎE?ËBg>Š.lá̇¥àЂ„[ËõÆ|ˆÁCg~PÆÔº1öƒÎ³a¨)úÇQÒ¡/‚B¸Ø‰Dg‚¡(êRS´,[J˖B*YÒç¦Pfk-‹˜ýüh¤¤WH¡ÂfÏa™½\¤þv éש™‘Õ46=…V&qè´Lt Ž˜Ö´‘NÆDÉîhfdqµ˜!.l+S 7cxHsS]zD´æ†ytN<õOM.5±ñ½„'¬¤Çj¯£‚¢]9Œh#c«'S,)†Q5‰LhÖ8õ¤8øEB¯–‚ÄÖ"éï´3k»á?pùó(©'쇗Ìl}:=óLO[)†¾Î4V ³TÌÅBsČK“°®æ1qH*š5åãæ¯|øeÜú¬sÕ+Ä[ aÕÐ%ÒÓj’ùéQ ™ uÀr=HDü‘j 1H”DY
724
+k©ƒëGIdátà—Ä$8V#’a 8 ;¸hdH ÷;*†ÒÁЧ(†.”NmuË77Be.TUW6 qً¦‰ŠzgN©FN5×IC¨š0Ã7‡_õ
725
+eÉ@ j ÀpÀ \P‚Ä A RЀè^@°@!˜A
726
+Hà€¹A &” 0x@Ђ4`&(Pp‚”$OÔZB
727
+f@‚p%`A
728
+4‚`àµÁ 00¼  R¼@  ^ÀÌÀ8ÀA/ .Òv# 
729
+ô{ab‹ÇN5†Ç"Š8uZ˜²ÈCK*ê Ó3´ F %Yêc¨ !‹0²`¿‚÷‘JBp£ƒÐƒúLòü¡³wXŒjhk çjÑ$(°jJ EÄ¥™036P¤BðÒ0 •*?¸¦á cÚ $¡
730
+tŽ“CÑN F0’†(
731
++
732
+¬ñP±Ù7%BoŒƒcä}†Þ¡‡ˆ‘Ãiȓ e3ÂAºP3D: 4§^òêbI
733
+Ar
734
+BB «‰:HEpUXµL`
735
+Ö©ÂUúÙ)/Ò)šÐ¤'±„ÊÜ.GÐKŸPÓ©»äÁµ2bÜË«4­©ËÄ*ÈR¹ÜÝýíî×6„LÈ=Qq?&ZÔÓXÁ,éª/‡Ž Ϩüy²öŠÄDÙ­*úkõþƁ¸("ÒH#˜p¢fF±L/¡"s ?šp‹§%^¨Ø—ihE›Bñ„qJÙ0BÓ´Q®ÿ,HÍLàˆ”ò_‰z>âïmJXPˆRÃ~ EŽM°i(!§
736
+Sôtª©£¯†¡u0SóÃi¨ƒòƒFðvøyJ֓Ìž§
737
+ù"e*)ŸÁ?£Í7R!‹º‡ÉƏOÅpÆøÁK`K$¶y@Òñ>…kl=qèLöñWœàYÑ«rN÷þˆHbÅÜ=¨ìa ‘Q§ß\¾þ# ‡· £5ÇÌeWÇæMÜjcßS»Oƒ]¹óYD(GFPÝL¸!z±R¢'1Ö0aIªF(TX“p[/u¡#˜4Fø*!?/¯„!îƒèŒ¨Ú¹½AÚSXÂÐÌÍ461Ý„=#PÕ†ÖnV…‚Ô¦!9‘$îï$aÉ KÞÙVy8C«eôN„+gù0ñ†åõX²ºŽSäI o^ñ„"\=”°Â%$Òâ–5RV\>.D¦|Ihx™ÛáØå† e’„…ª¸"QÈ©aˆ eŠØ+åÇIÉ ?1Çq ‰öhŽ•°Hó4—`çièÈ::aÆUɐ,z}º†”Ã7‚a‘6!œÎļ
738
+W\%gE´æD“PÖ×ú³h°ÌÆäsPü+ RE§Q 3x-ñ¼D8Žõ—Èmk¬]ò˜ù&$Œ\¸33¶í'ñKÍG3Lð62hôÄÓu¼öF¸ªÇ<ê "$Óps
739
+j p‹rˆô©3çJÂÇRLë@Á`?¥ÃkYùQhF0aNJš84‡„"dLq\ ß!Æ¢!…Šn^ õÑÅÞB08‚òðð fÓC‡ ‡ˆ ђ3ÄÁõe!Â"|c°³Á†J¡-ÁBÏA¤Rá,.œí+œ!$D„³‰„’° œÚ:Ÿ0Ý´1 ÓétZ­Cteˆ¶k;ô„¶Âږ­ƒ!º¡ 5« lÙ
740
+lÙhJ –¨5Vh)AíCÁ•Zp‹
741
+¦£LË,P$̄MÌÇ!&Äx8AæàÏáCµ7$]5L%|J¨¶UjD…ªÏ
742
+ï¸4k9È%Ú@zU(Ðé$=Ðëf„zãøà:˜þ´
743
+t#¨`uÂЏLœ¢¢C‹U«„ÌðÓð2ƒÂÏ×C¨áÎt—˜"ÅNäI¤+qhf$E0ÔNœ¤‚‹D.{NaŸWØK{Ø?QöQØÇ­¢¡¢
744
+'zM8íáÔE„“ÐT$™äàZ†RN˜¾Ò邴Ú
745
+Ô!¡—J'N‚ ƒ d‚ Ñã3o…š­]‡á¤1œÃÓI`-{—ï°^‚YÁ¤Q0Åw0 pиD·¡Óۙ9>_JÜ[ž;éSó&ˆT«­£8Óy‚\1ÔqÄ´X%õv‰iêËpËAŒÒÂ1‡a˜º{®ZÐڍ͚W§Ä˜ÝEŬ’iˆ"qŒ © ±W¨üµä**y?M«XDwBÓoĎP4]t}„RúØ™\Âú¿sÕu»¬—oò_ªŠLTUR«Í_%Añâl¯aÔÉgM •h‘?³õ&§ÑïD&Çӝâ
746
+ÞLÍë8óT²¨ƒÚDœ$>o‡Â‚/F•,qiŸ>z+zŒ$ô=¼ˆeFTäzž+:Ç»Š;quäÞÁNÛ*ëNYYª±4R‡¥ß,}ƒ®:ªW*EWjÑKUaê×øL´°³ ¥µJgŠ:-¬)"ö¬  ÿ*‘¨?>ú
747
+R?¿„UÿoÕ¿^>.„< ¡ÏÿUÑâ±ÜyWï>¸=|×y~¾'6DBxõA7Ë[’¼D– wÎU˜j—©—TSRE­dÉ8žºƒä[Bª(LxÐ}A$ê“t¡DÈô@ãÇ"¹‘"©c“Ф`QxTôX¥¨Î)SÈD/–Ïc¦A¦ð·DÂA·}¿U,(Až;~°5¡ä€ÖY™ –›œ`9 ’/ˆXC¬  $-SF²{(£Ë¢îyloJâ¬@[(öcؗ†È¨¯_1ž‘’z†dÂKÉAˆgB”èÍÔ'Äš†¸ZáB< ÕP=¡z`Ïz@¯ã'U>² —úÃÔI%ÌÂ
748
+¾!ár9؈v9(öβ·øÎë÷PøåG¿Ã€9M/ î"Ô ™µŠ!(3SwQݱ WqBU½UªaÈdÒT â4ªÑâ4ŠÓWI L£H™ž5
749
+QäAeH¦Q2â
750
+$rL ­¼ƒÖR´“$T¡–7T¡²]Eqà"L>© ídH3‡0ÀÁ«¨ô9Y¨™úÞxBŽ_v!„Æ${ÓŽgžǛǥÂâwz0•°ÈèØÐ‹Óž1U Ë8&vP®ÊØõT$È'TõGbš6SUGƒZJ"¯«&—Ò" xô;¨WÅc”-TŽW#̓/ãPiª_¼‹²Æ3ʟW¡U®n1@¦lZPÂ¶ÚIÕÍèQ©ùÐ&LPy‚éºOu†oq™¨B ö´{^ K=FÑÌÈ™•Ä´À•2Áâè¾K¢HŒ»_{óéBb3â‰cô‰”›ÇfáuæÍd6:y óEQ„ØÏ™‡I*HŒSÎ,³³‰ÄèRÂäKÅè˨‚ ¿È¡¢úf‘eabº¹óƒ]$ø°Ãë@äµW$BÂB<o‰Hè%‹N螫Ò?<³ •0ï£Vr: #,Bs„Ÿ¶Â‚”(‰<b„Š2¦’JBá):LQç˨¦<™: å"òÒbšžÄȪFÂÜè3ˆo(do5œŠ\]d+ª’;HRRQř!ik³‹¤D¨fZñ‰)ù¦¤D&.%2¤¥äÞwJQM3¦-ù€Â‡q’yV#7]eü•hla‘ÎÂ"­G±^©¾"=脯H[BT%+: žF䔃sæ
751
+by‡äb÷eV„pŠßœÂ¨œ¾Zˆ´ãŠáTÌH+¦bF¢ÂR§Š Ç|eÎ4Â8˜6bæDSBü`*RRXG'·ú€®ÑŒR‘ ùMÔ †}ÐjEµAV͂œŒŒq4Îó ·d8ÈšÍú mc¡™¡©ÒˆE®º,
752
+UR,<[xÍP¤öV‚õhO§¯"Ý­ÖöŒ…=#÷³E:Q(^Ï¢B/_5{£Ø“Tp}aÇ:$2¶ö˜Æçú>2zlEcj#Æ¡Š
753
+6Ä64+©ÚДG<14ŸK’UÜ¥½!bˆQ\ð‚Ì 3xZ@ƒŒ@ X€Nà‚Ä`8ÀÁäÝ,ˆÐXY!åØ( Ã[¥)šAá™û€Ú˜@2¸¨"A>T¡Œ–©„µÌ dIYXːô¹:3¾·{
754
+lÍù@žˆà¯Ê
755
+ì<LÒrå‰Ç„ƸšÏË®¦Á©Õ4„¼ZM‰6”oÂV­þš=„&s")j»uª=Û¤‰²+DQõ,|PòH™¼óD>UCë’9„¬Ru³‰Lù3=”ÈEψT½l¡–ç`RóÞó™µ:ž =h‹ ?*¨ð„]z‡ø€h ›5…Œ©áVÃ"–U͏x…h£²âAQ§‚å`b­
756
+‰j\
757
+²+T*RG¤FŽ‘ƒ¢­î‹.3Uʔ#ŒÄȁ4RãJŒ¥/NHÃT=õ@¼†"’NMŠò0EÁ< kçU„Š·£o£^%Œ¥Á0c–T¡¢ÇRuT¼̓J 9&45cƒaQž+FNó8/RÄik¢V¢`ÏƃS;~ç„.µâÌ#JšäLLÈ7ÃpÎ9r@Bޔ”áRÁÎX4"¤˜“ššƒùH1ӎbDbêP3+IÃY‡¨7v¦ՈéAJ<›¹HÝ Rb1¹1$Q"†dBÄïÍ"¤$fQ–®†PaÈAñ—™ØÙ˜3#D4O&Œ¤ Œ‘bf§ $Ãä`Úu.™š “ƒ:m¡x ÄëˆÜÙð4êL#PgÆy•Šf šG>§bCD‰f¢>õ$Ì.Qªj¸§¯#¡>[]‚˜rKƒÖ»Uþ†q0È'ž×V!
758
+r touµ µ ÿBÑ·<¤. =`É4jÄr§óV„…iӃs!BaHÔ
759
+æà¥ Š´=X¸Ö=́‚ä€Ï­ª k0ÍÁÐÊSªª0;pÉJ åGÕ&Å&ÑõT9/¦sx3îEHܕy7Î*wB©Æá«Ydœ ³³ ќ¦„¦'–æ4ö`$åñ‰(¬3áB¡æ`ôøL(š>>-b¹M …¢­<D‘©U [õ9¨š„}Ъø—t¨aÃ砍¶j¶jŸƒK\Xî2”¡V˜>Ĕ,bziE`MŠŠHlÍBëMñR-LMˆe«|“
760
+Ͷ0”n;n%â—T\Ò]â’&¼ñ[wÆÑ=.)zàŽI!|@aGE±ºÄ±ÞϯP!‡Òph*(õÄÈþ/ŸÅÒ¾öŠ^oÔ`LØ*Ü¡’팵Œ#¬F‘ŠT«ˆHr†)HHG2%"³˜Ž·y£ÄÒÑewàŒÈ£< *¯îgG¯IA¶¹+[-ìU‹'¡Ö‘†èEOMfb*õú­˜—ƒ^ ^fÆ"K”ñ`‰<ìá~‹,!&4 O²½-Äf$…˜@{$}¢­oÄ¢VehgI>q–8âT¡zk
761
+§…y„4›ÊöËBC¯(©Ü+
762
+ݹú+$eT.–
763
+-ÿKå;ck°6#¹‡T²"qëDáŽÌš*/ÃÈ¥<òI©XšLo}k¤5œ…ŒêŸ^—سQ^ÁǨý<úužGqO´¯W‚¤"1qV –f¿Z|Åù±ªÍR
764
+rÏ¬QjÚgúÕ:© l£Œúã2sw³ˆÖѽ™„,‚-Ù5qæ ­«ªú_IÑbÕKÍ3%í…Ve§Jfþ~.~Ikãè7¢ J‘¸H$LS¾&F1!~­ñ&ë i>:4nëtæšÓK%xœV‰9')sgN՘bë‘*Ǟéǐ÷ìEQ2™jyRݨ6꽢ݏk4ÅCíŠ_ýüÓ)/È/>âŋF‰)¢š ‡ùFPÑS¬¢óQH[+NÍ%k·ß™Ž?t‰Ik)Ž¢‰k1=’‘M{LÈ*6Q=ÅÝ`t⓮ê„G3í¤#¥NŸT”SÉȬ2ҋÅÊÌDÊêŒãu&HÆã¡×©éØ2Ë´å éÈd$»%A ºí‹SãÕ;9)öq.8#NÍ0XÅ™q¡Õá‡DZÂ
765
+5UQSš Çtq:ZQÕ·$Ž`‰¨:M¿ØÁÐhfJpL£l6–QڏŒ4âeô¯>¹r²i²h2ÍXѕJJ,£œ\~k†«ŒR¤KÜ âŒFÂ!®lîÁM‘H!֍d«œF‹ E¬Æn8$ì&]÷Ƀ4¾=: ‘1œ-IçהÞ'#EÙgï¼yßHý}}¼…¶n¨ Óizï0û6Nï;²Þwµ×û֍áÿÉY!Fê}<>Œg¢Þ}{öá}†>v´D['J¿_Í5o› +3í‹h¤M{¢1˜ÆIkf$dhÜ"‰RfHý1Yyæ#]¬ç%&„µ˜—KÅÆÒI=‰ÖºhTi?ÎYõ~xМvHRË~{¤k†äªi¥„£‘ D Î~ÍÝFcæUà ÉE•i);)UpfaŒ ýÈ]`™>kA¶>ER‰ôRc_kôó¯æjhj‚¯‘Õ˜Ÿ:+Òè}kÞ yuRÉQ©n$ʌÔӐ*8Ó Ö2SÝ: …B.Oj$Ï%NöÌãÄbƒGË|‚JHÊÜD
766
+q”„’“)I$g…’£·‘Sd¬¨„¯’ϐ—Gˆ„ ËV0lX.M…òB­‘™üæ²x8IT#¯ÂÝL(cIL…sUêrò»Y4³:$yRü‘æ–̃ ÎI¶ªVôÒ$”°„ј
767
+¥dÈ1IDq^R($Crd¨8S>™ÓÝä´¤Y…àd"âÉüÉ_½¸ÒÆ‘D D³ÌMݤ™*×$C¢ÅVf¢•jd"™Ò–U}©¨âƒgn°ÊÛFÚYMV#Ãe<±èOgfDá²áDk<½‡dž6~Y¿Ž¨úÖ%¸ZïÄNp‹BR%ÊčåGpU.'FÆFµœêUb¼é)»B ôÞÍÓ¾´Ñ3Zôäyåsp{k"'©ùB+Y”c¹'oÃÐ(kËÕÕ©æ%.9ÕO´sÅJ=b±¿
768
+2#¹ÅçÜAfu¡O1j㙿*³ŒêQ„‘;?ˆ¬f‹ìá0YA{-™Gm˜Y§ÄB™éÙ¯Ó+ÊReŸâ&—] “‘¨<ÍHo S3½‚³yJUj»OpòW\R¨©Ôß É"·±âã‹à^sù Mè'c‰Ìœ£¦„&bŽøÕcºZH_)SiBÔÄeTÙ±M /ø@Z‹®ÐHSUp¤Ä¡jnÔL8m"D—‰|±ÒKâCv.“6¢gg”b,¾h‹VŸÒH±Ï#o,"$¦OÃÇÁÇ®œ*"y˜hU,ÚNw¦˜6aƒ-ŸÝiXc°8¡FK¹Æ!¢ÎŒ¶ŒP=)Ú8‚Ç’ñHñÌ[S²⒵UM2ȹHf!Èú(5sSI¨Ñãi>U 1–¢qŽç5zNäVKäbšÖç#”©zqdåҕ[óÓ¸hö§(b(ð#e![YýØÏ¡j.‘pÜ媳‚ ‡8'쉩ìԌgÓ²4!h^ AE¥ÛZP‚T©êÜeæòª¾U1úñNyLË«ªXSWMZ-©—*D,I(QX]„!‚‰ÊQDwªöÚÃv?ì¯é¡ÚÞíËöŸ¯BXö”,""b$‡:à ª`F'¹¢ÌI°„É̄†QK-PIˆf¨…ŠP*Bí µ–Í.¡4 ]h‹´Ð…ôÂ2L~"‚éÉ f̓2aD.±p $ühj¡DBÉe„:lèÔ¬‹ ¥/ Ri YOÍäbŠ>̟J…yžÎxB”Ó¡©0¢ƒm!ÒЁDý'ˆ4.+â†'„KbB¸á°ŒPøÌ÷à™)Oá"1ADDDø.ˆˆH )
769
+•S°ÔÜábFwƒ…á D‡…Ì?˜¦YAÁܪÁ$— å¬2
770
+5‡ªŠ†
771
+Õ †*Søha(‚/§˜â˜:ÛFBy“ßß>¥x½J/
772
+Š(û¤ŠÇ´«bDA#± YÖ ‡¬„³0楙WĊo,ã;»6EžNUL'=ºÊ¦ÓUøGg«¾>>EQ(ñ,î$ò™Xaj9´ùÇ>q#&S=4Wc×6TªMDueu2…«4¢ Ôç51´zóQU„?IØ"Ež ÏVwv„¤?;¨/E3áéæÂí<»Óø²âzRΪûkí'ª`9N–"Årå*H&«°{£V3ÒcT!ÿb†bœ¡ÅŠÓ™S>SþgjJhl\„b÷ŒÔÃOŠ•‡C†ˆ yb$]Ф¯ Åê#!zD¦˜‰¡MSiÊSþü5þÃÿ#C~tªâL)*Œ©æÅÃlã´1F3V^á¡"/„BÉç$CÊ!jh1úü÷ýé_A1D¨Òmj•ºjõ¥ï@-:u˜º›!OÛnL»*´$¶¼’N*ÐÐЌLI .Æ¡DB $›H|8(ˆt¸Ku„•HL#*™(BQ? ¬!]Õ8÷gŸz› 1ÂÅ£ 1Xèô½Á?Xÿ’˜‹åõ<âæy›NªÒp15Dާ‚ºI‹æE=ˆ¢ö(›“Þõ¹aìⶊ¦ ÒH;C‹šLª˜‘J)ÎH¶u¶˜šNZ¿Â% ¼Ðü[c!¤’šŒ(Ž }ªÇD&C‹ý¤â½¼ZS­05U¿\uZèPHq0R‡¹æ¡=ç„×bêIól2Ã,вÖ]£9(È4Úa4úJBP‰US Q¬%DQ”;L4dTTåÎM£¹i• ã0v„qWH„1-$µ—£º
773
+ |E‘´vŠ¢¨ "Æ0vÿ£Ø›Ö'Þ :É1Š™. R”$¥(š
774
+^t#ž™Kf›2ñV7…r|K·‰y±Øt)îŒ^C]ÑxbiÄD"mH¥p!úUËD_fU+‹ÌLÖ8)NÌ]Ç`ȋt4dž3è.èh<dÔrÕ$_8qùC£TÈçÄHæ*ºÊÂM?S»Ô o5K"1ŠA´yÛɑ ñÞ >㚍†¾ò!äØ]C´ð›é¬•pk•4Í˜$ˆ¶ àÐc[¬‚œ‚|ÄAîq;Èåã
775
+rOÑÔÏJ$¡JXS¤¦‚AJjae„N±‰U„úzÚz2ôë'ôžiƒ¦ÞVê&3ÂU&vŸ~œX6âñÚÞmÿéA“3ªò÷YáÞw›ÈÅÕb¥½äš1Ņ|ND\S(È‘OO©O§œÚ²©-I}wõ‹;ëÍ8”ŒÆ²‡’ýŸÉ¥j×ð†©R†MYD„B¡@¡C qBLJYV„Ò¥HÊʅބÊÄ<KJÂcB)¢¤B¬VˆaÍCHEX¨p²‚fp‰2B DI˜!&„ÌÉ¡„rü{°1¨4Oˆæ…™¦§B43#pp‡C¢Qùøâ€Ԛ8¤
776
+Â`(DSQ"4H J}©B½ªª1¨W
777
+P¿p¤– ŠÈ!8ýwég‹5\ú*Xj‰7[-ZÒo‰—§³£¤/%ç-¼ÑÇê£Wô^ál}•mæÇÊ ¢¯¾;ëϺ‚ˆÉ}®Áåû¹-Tþ|9mDq`k7"z~lю!̣󛘴ÒËψ–úæã…18ûÒ( ÷¸¯ùC#„"úŽjA$Îü*=ºTOè|z‰Å|n–2BSQ—¸†¿3Ã%~Z À¢ÕÖ¢Õ¨òU6 qtçôñl³¹¥ös§Î˜|iVgñmOƒ ù3<·J½Ÿ×øúf¢tüÛ9Ó/›dҊ¼QfuI=þ?#•³ð¹Œ‹+z¾1CÖ,~äþ«âÓzÝ­„êvt: ‰¿‰—o—¯jIXNbë‡ÿYLË5? &`õ²áûSцï¼*Ä¢Nhá»Ü[ƙÃ8š„B¡;šÐ'¼|mf¾ÆH_Ÿ9šEK ð»À¸o*¿@¾ۗÕ÷¿3K¹N¢ý^üûÿó‘m¡hß7ˆ»Þ\ž%•|¿»û¨mªª,mïÏÜ軁ʴ$½ÏÓþY4d…<yÏEã’f«ùÒ Àû×[Z¾SY‰l÷O)Û½Ô#þ⟶T½ú‰KºÇ´µ¹×® ¶ßíGD |)RâÞí¹·4pLo•­¾Ûktˆ4ÛØpÛÓBð!ⲛ[r¢lßzÕE¹‚Ù†™k_Fíƒñ¢- ¤öøUº±Hj_•>ôàp\-=Ӄ6PbBó*&ÚCvÆá%Gâ³ï-µs6ˆrqÙ+U}·ÂcirJöh0[6Ž}´>ò–qLû ûaÆ¢/ŸÐI3öà
778
+ïó/ãíS
779
+Øo¯
780
+‘S’‹³çëñ“]#¼þ6v¹á€ÍÚs½ùڑi/VeÚ[ïGÛ¼*ü±ZoR=@·„³È¬¿äÓ§˜Ú&Ó°¾¢š`Ö[•·ûCºz{oì·]}ÁöJ2›D>VOÙ 1
781
+U¯D(1N|þ©§Ö!êÅ0¼ø#¡TÂR¯ÇôݗQG³õ12æXªp“N`ïʦ£ÛðéåLÈêV.*Ã͜Þïú6 M¼'5ýU՗÷Q˜¾,!Ôm"_˜~~â¬à&=a[üÑ:C³»pœô5X_B_+ýªsòªsçCYzVzIn¦‰€ 8EÝþo¥Ç¯É ¾¥„XémæFÎ&ý!̓[‘Üœ¤°I¯ºKB¬ÙÅׅ”Q÷04P1(4˜‘å6é}ØÓã*çZc¡Ÿ4n‰×ˆôã¢vò+\Uöa´f‰ô5ÀCI¤vïÄ—+tïG¤WëpÞX‰ôF¨ß_6a:|¨ ‰ôµûv‘7CX`hWˆô”×Û§”¥È¾×׎D~h9¤:ÙÌ VÀíú“-Z‡3ç`BL1ágÙl<Œcô†ú²ÖZÇDÉQôS›€¼\€ã=Ësà„Q4cV }>}2¿A/څ­FwpD ¿0ºÖ‚,Aûy ¹P0ÂuÎA÷TÂéyèĞø-ƒç‘Ý÷—¦eçsi›²2îàn–`s Ò^Ǹã¼ÇË÷ÚËlޘƒw|óAÐ¥õô¥_„µù(ih•5¯çÌx]úvN‡ï®h^¡¿ÉěbYšÖ™y€ÛGXnãȒXÈüácð€÷!äaB@s±ÔksÈù‹F½8àLê‘öY—qhsW VÛòºs+æÅ¼*þ!ˇ ;w+Ÿú Âk:_ÇBGås¬_º¥Í åùûÃplP>.ïÀ«‘P^(/‚@9:¸ÉsW#íps·œ¥Üû& Oc.y©Í˜Æqam—ä%üdñon+G¾\Y'䆪2‘/$ZJòÄÉeÜfYk’‡vCǔö÷ø&QÂ2€Ç%w<„ ¡Ëï2.Ço}—@Z|‡]—ª„DE%Ù¡(-ÓxMÈhóþ¸üà±HïG0– ‰ÛŒ`üxzâŽ$O$©Ø¥Ó¬ê‹¸×cõŠ'+O œ*2Åç¶T'~˜n[„qB”ø9¿-³
782
+”xÏ1*¸ëEòzt‡'£1&±ó·–íÚj¾S(MOQ±M¡áñ ˜öá¾V]F¿ð±Æ ܳlîNÄ
783
+ªq‡ý¡² F7áÍÖËæv^?t¦ïÑÔ:‚V30Ø|ƒ#Šw!Nƒªà“ÅBÃtÝX#ñ¤n>·0æ”m\ÄÀo´Úÿ‹þ
784
+ü|±‡ò£ö>Vx¥]ˆ\ßB´ûï}°ÖSX]JÌèïQƒ£’Þ/Ã"b<<S±’ßG7¤ÉÞä¾7KÕ<ˆ’û§ï~¸zÙ ,”ïáW?
785
+ 3ø‘Í3
786
+➯Þޟl–PÛÆ®÷ ”¬EF› ”Þ(ˆ~^eK=/wF:sÞ!b­ó彿)Å7¡R§³"šSŠB¿•ñ¾ ÜØG6é«Á»¨ ¸šØ»wóƒw µé—°Ü}vjû×Í2œv¿TÆÀèáևóuÇ(Ar_é×ÝSßGq'ãÒx¯îîàÏé^.Ž+êæ@]EwðAI=÷!ÅVQ ÂÉIs¯y듎6wÉj宽Âí³‰Ü…Ë!½$»ê‚‰VêqÇÂEvžqüràð!”x?Ü–Ws…Ükw 9!$Sýí´‹Å'oo× L‰ýIªW¨ÝΛÚ8Z5Eɾ:¹ýÙgŒù‰qÛ!énT:m—‚)áÞ§2m?Vk"{ëÞ³ÔLjÊ\QJLl÷I!ă«Ÿvº;\»Ü‰ú†\íļ}³§j³ûTjo»vÜ Ô„Qå´×õ˜U„ŽÒžE;JF²{µzÑÞÌ""©p;§ ];÷ær8Ðr‘gG+ElÀ¯‹ΞJ±Á³
787
+ȱ.TñÌ>åñçe×b\’:*;|gFŠÒtF,ìb×€Ø×”ׄì dCóz«%÷^:ŽÝÞtf#àã(HÝÌe{&všPØSf®xØÇÔ~+šõE³ÂöûPuý43ؕLM£"IÑ °c8¿µ#UÒgúuN­õ5FܪÑñõ´ï©iZdÌãr´>au×èE¸¸Cô]§¤,Çõ —b¬šÈÏb¢òøÑ\W©²˜÷‹W‘ÄõS äj—[Þ­?$Cø}O)dë–Ñò¢k×Ü¿ü¡/¨—µZwQû^×ôË:ÎÚfnb’mØ3g…, ðRO Ž\‹ŠiXœ2d'zœ‡¾æ«'VRNKÈðŠÿ÷Ó\]¾-K`OZ§V'ž¾>D\­Þlx2r±*au2ݑ XVݨÈÁBo‰  ¨º“oñp¸í¦àùÔÛÙ£3–¨®ÐmpêKìxÚ(s@{©KyÌ-˜Ôýzk«Œ´£înFY<ê@°òqŒiÈ¢¾Ÿ’´"@«¡n0¨‹Ca´ÐP' †*êBîŒÈY…”úô®Ÿ6Rñ²qŽAÆñt’ñ J.§nÐé(•´Ô§ßôs®q»oÍ kz-8ì?ŒïÍtg/“J‰\>#´'݅ÌG“ÙN—>±Ù*²S±ôÚ»„¯ N¨t0VÅïC|ÒíýÊÚvÐ54kIc¯D¥ÚæDµ¤®Z6ÊMb>…t•ÉVBü¯°¬ìћ½‡Ü·G¿!Ð jï‘£ïœ ™F7§tƒÑÃ*´t"ȐP&ª±E‰Ži2Ê_ÛïIë—æ¹ÐÉù}”бOšôK6˜Ú“~œ› K`J0l.–
788
+t5ÿš èÉäÈ÷¨Kz7?2É *ÁŸ‡9e¸QÌj
789
+#ßçfÀ+Ñ皜ãð1ÿ÷œÓjо’ìy³ž7/@‡ Öó¼'á:•ô›e0ž²‡uœ¤Nï<â×›l$;ÇײË<ÉÎkØ7eÂË$éB“¬ÐBà/­Öç\ר {ZÎ1¸›íB¹ô’©ò·Œó&dbž6a¬²08?ÇPo€.ôæ—OÜ[{ó–[r¿ö[æ‘ÊçpÐLH¹ºãÚm؍8|Àæõ—.ÈOaüWs»oj‰Öi^ÂE=™ÈQÑ<gµØà©·ÖóÌë·qyÃð LsNç>3_Ù·`'ú»Q™CÌ ;6™ ѐyÕ©l˜Y³á`Ì Ô
790
+²zø§ïh²u0å’Ia.þò%0D±êå Rvy~˜„Úx?áqy.ÿ¥yÑ-«­-ÖP(ûœJŸ:JËÅè÷E©Cd9k›%Czԍö+Oùˆx©%¿H8©‹e9ˆ™ÂåÓþüx@Ǩ|úbkÊ)å§ä5Œ”_¬å<©rmE@ÈÚÌ?9žß>[Äãƒûɵ&¢kòA[ƒ¢"5þ³ø`¯ä’
791
+']Ey¿;É;£Båkù£ÊHn΋<:‘2'¹ÌÈQ9tR@`R¥~PŠ|•ì[5'“й™|ƒÁ"6[!÷1$¹Ä
792
+no r¥¥º”
793
+å9/F@nõ4E~üãb­àãJ|ÿä<u€Tμã”U)/îMuü?[!Ð师²ˆ(T›p\²Á>¬¨¹ñùÔÚ¾GóT…m[Ú”§q};u¨g¼÷ܑEãá¶…„Leœªzdx*㍝C>eŒ_rˆ_×}1L+Ý»%Š5/.ùY˜ $¹ëй®µ)/¹; (ŠˆÈ.Ã[œ±CR2Í·øaèöhòÑY¼u\A+t>‹_²O"FRÎgñŠ×J¢:^¸øyd y83\|dîºgµß"*˜¹1™¶ Ù=áâgóéôâ«L7zñ0W ßlîUÔqñ@¨/Åj59qqñZ¥“^8&Åʼnƒ†E1â\~ãâÞH êãÁ¯ù*.î
794
+¤c¥lãâ$¶0™m҉‹3µKu] ·ÜäqñéNxŠOqõËqñ´mÌYj$w!%.N‘•ü” .>ÅDzGxâ¢Å{¶M\‚Ùê+.²ÖÛõ¿Qy·é“âÅÍ*Øy¸ÖDýŠóüT;Ü*Û*.;ŒÂ¢).Æ©—öjØæCñJI xýíy9T©Ðò˜¸"èÒÊÈy“פ¢~ÈU÷W4Qù¹›Œë¤»ñÈ_ùGfˆ÷Ac NdÄM×JqúRsAqâ„;ôûðH)<<¸2!Õc€œ÷ĈŸÄ ñÁáëw\þ¬IJËòàrØÄ‡-ÜßûϾd^ÄðX¬H×nWžÚڅ P‹I7€’z( çDöœsp*œÁEâ•
795
+߁pK6(G›]€]<VÂÙ~æÕ µ?fŒp¥Å'VÀAxJ۔7˜eõàð`=‹tPšâà\»pÉ#½¡ÁÿÒ_a|üœè©OêŽVp«ânJlV3'x‰¡ ½¥aBœ¶sê¥x ]OÀ@þ¸Dáå•̪ ?¿%©Ël„8 ÇN¿1;&Äëv÷¿5‹hH/ p¸Z~Rê$€K-MÎÞÛþ›ÿÏSòœtË¿‹?é.T„ñÅô7ÈëY 5mð7Ձ3º¬–Çë·ÇÓº¡?›—-Îù œ¶à <ôwñÛ†Þ‹ßñª¦Jyßm‹¤êÆÀ"gJeö-\8|Õw*ÎvQõmÅÆØ)„rϋ×+*~¥\Y©6jrs/6 pTÑ90ß #ÆÆsƒù¾dœ|gÀb›
796
+*^f>êùñ=UT6ŸªÞÖ­<Žó,|¯:´a¾w²á‘2åÞMÔp«n„6'ì+íɶ1ÒÞ2?Ÿû´Ñ҅Õf(í}^¦yÊio8|ú-3í}
797
+LÉТòÒÞ6ê$GJmÚ»-,›÷iáãæioNò÷1Ë´7Ps ·ìEÓí~Ú{³JÓÊûí—ÓÞú˜ç¬“öŽXµD^^^îýZ¤„ö•%÷f %’a±U¹÷#^ñI Ç½K)pÁ<ù•ÜÛÕ «…y§Ü¢Wro¯S“?µ%©Ü»Ç4¶V'‘{³z1ã¬`E‚{¶FÉ!’ÅjÐI¯ç¾¼w@$hà¦Nǽ=(7œþ0zo‡/ýÂøzï +V?è½ü‹ËìÀ¥0NH¨÷kg»ÀP*zoó­Ã_ï=8Ôf˜ÕšôåIõÞÿ7ÄôÅ.Izï,U÷՟Wžê'n¸ÞÛyŒ%;Qòš„ Ÿ)R¥ÁwD ŽŒêÁ÷÷°­˜â»m¼Á÷1ìuƒÎêûàÛîPŠ ˆ_"±ßƒÖeºlSDïÝíÑo:Œq%ñ¸zo+û¸nô‡êyïd¹ÕÑpoj%^;ÿþ¿÷®ïR¶òÞÚeÊ{7f.#°½XvÄ ÷>¹)‚tàÞn‰Çyo=†Z¤¡)´/È^ÇP5L—5 ùå½=
798
+:è
799
+É -@yïÐ$ۀúu,'yÞÛòΧê0ï}Ò?kT{Õ/ܻ߲'3êIé ÷Þè/¸w¢Ë³9 |
800
+îÍ;¯ˆ,Ú!Á½iQ;w°ñHïô8¢^ëw€Ò{?ÄÕàÛ~Y»÷÷…Á7ד’Å·Æ[9dIðñ®c)øÖâ€H֏Þ;Kk4Ç~·Ö{ÿß³•ùNŒ{÷‹'ɸ9cƒT¬O4—še‰¬×›¬¢. !O¼q³e傴SqïúBW]å}ô÷;Ä®˜·ˆøþÃlß"£¼“Ðìx IºU ”õã- L€¹ä:2^-ÞÎhO†= ï/ռƂõ‰s‚÷ǼÛí.ì»Mzÿ»…“ZUYÞ}ï6ðËQOP’î&5ü³«Ý°Íàná3jÛ.ï%Sê®ÝªCõmåìž={hªBœ®Ø/ÓÉ¢r áœ%*eÃ]06<ëNÐ·Óøêƒª»3ÙþÅï!Ô}ã°O[
801
+_ºë7Èrš±…Wþ‰£»Ž‰ÎŽnÕÆq{%°
802
+ÝÜ=–”‘su˜LêÆO¶]Pɹ[dŠâ&I_½›ÓÜ&[4o9Ì n'Þ ²Á§Ô•´üGk2ϱ ´“[ |Hw­<úõRI¹£(g³sÉ yܬZoC9¢»g܁Ú.à ;TܵÑÔ+MíR+;…¸ç:A!Ò J wܯ‹=ˆ·Ë5»•ç¹x¸qðE˜Ò°.÷·QëZJ½}[³ÂÛÛfÆ?Ðõ’#U!oRÁŽ®Ô™HüŽrÇ|Ùnã’n÷ŒmY‡HR&¹ý:¡sØd.wPH¸}9ªaT¨ Q±Ü¶àˆ9eŒÁ¶ ZSìiDû­Ð°ˆ϶\—:€ñÔJjÙ¶À–W—m²óuÇ5— nÛ­y&Й<®]Øææ=
803
+ÛBÄB/&íÃÅs×6rã"9×®wF¯Ñü,jíÍRl­*Î÷È@(¬j«0րo\=µ—wd®ŽHvOïFí×û0Z&ƞö!Ç ©­ÊÝÔ.x¬Ô(P·ž=†Šj‡»Òö» šé Ìîy ®39
804
+Bß²¤óPµíu֘epxù\( Úp‡z=hSYÀÍ þlÇlDôV‘ˆ®I¢b4Ä(±³i2 Qàó~œÝÕ]·ü(òÒÉ “ǔ>_A&?5šý@&ÌUÿæ³™]ÃiҌí€OÑP¸ÿ3s¢-û9m­¼ÉŒV¶% Žó=ÿܐ” P„žjËMØdŸys#-+I6zÊ jKq$²“´Â”…«Õsʲ)¨\'mpû²ŠkU6l0(«©‹B7vÔlb8ñ{H)c—‚ËÅnÙQ£Ç`æSŠs¬¹‹µ ÝôxÈv°€Øz§¦`ڞN²d¶¶lšSP—“B [œìc(1oIØ\îa¶¬uè vms[ɉ03Á.àiËe ¶pªÀ&3Îíj9p^;4­!À__+şªƒû÷5]+ngÂt¼ž©ó58Yí½¸VÊ´1„u¯ƒºÉ÷AŸ Q¯;[ôhËkқm_Þ9Iâ<ì[xýZIÞDRl6rתR[4|_>
805
+»žh¯ÉH(4]W¢õ”³tKL纃ðû{RVQ®çA$¾36ÓñâÚP8+Wó¡^p&U†Z5m:ykìWNÝË!H°„Óµ“Ê¢­Éîâœ?,ú¹ðµ>0ýóÙ`ÛjÍ7¶²Ÿ_KÓÚ>¸ñÿL|«?£ƒŸDi;ë wÕxdgÍÍ~úÈÕ +fÖkPÄÖ†Êzèu~š-Ìõ˜Ÿ5$,1Ör
806
+Ÿ\fBQâë¿1žŸ ”Rï&d¨x©åW îžÿX >Â7¯Î3EäeŽ@uõáï3!5\]{Û¸Û¶úԐö€ˆ3ÞguʕҭX­ ŒhO\»êáYV­H~yͪ]¼¯’4¤©ª“³{hgôÅPµ³DåŠùéä$·B@:ª‡J®X¨¦[º“OÝÕF"L ̚S—Ëm6ž¨©¡;˜PH…Z¦&—ü2ÚÏÅKÍÎÒà†I½Eڟ¶”BpÔ¾M÷xÂ/L=j£äõ‡Å¦2yF­g·‚¬[õúÚZ;¶¶±K€¨Bx€Wq“ýC„Ƨ³¥™ú9¨ÕÁi Ô5&Së+üé¤jêCŒ—ùô7¿Ì§“u[ßņâim9xW­VBÅRçIôeÀ!ßuºÑ»Ÿú©6Î鈢ŽJãpÜHv`fç*²4d¥…Ú! #ÿ³é¾±Ž´¬éJ|?¾©Ë£éF¯HŒûçbÒL£è¥áw^¶+B¦ö”Idñ<:L/•bÊIaZ¿tíåk2»i]š‘ò˜–ké ªòHKrh<ސŒXú)ÁŸÂM“³Ò“¶ö2lB¥gç'ù¸‰ÍQz9ß ¦5…¥Ozr?t†ªW6MMZ—\v²Ijª™ÝÊ ÝeSHhIð Þ<럿FB’>æTfˆ§ÂèFº$ð}V2M²Dšm
807
+@ß²9„ô{è¿£´!<£Š9Ø/†n8[NJ¿P`Gµ¥…ˆŠ£Ï÷ŸøÚ鏄> ¬õ!3D¶ŸÑ»1º€c4 šAq«큔r÷6€iÑ>ÎïÏ&WÖ*úՏl6׏,췊(RDåC‚åéËDÃN…3aH4¢ŠË#Ñ(y mˆèWG²ðʄ™,÷ªþ¡I<Ñ۟±üWåÑß¡™E’“~;Íú–eú‘â£'n‡³ -W¢eñ÷)JÕÓ‚xâ ou=¼"ç:FºBB`áBBû÷=·I–Ý sì(:šuA÷òp:‘ àÐî°o,n Qyjýå¸òH½„ )Ÿ¥gQ@·`©ÜÄ8]«ÖŽàjÂ?h€‡®@TÞÏ=½ŸIÕgZÃØæg“Èx¿è>óÇHä rµÊõýƒ‚ @æóƒævÛˑ Ÿ}O™‘qÏ8‚¼K˜pþQØùœy=C”D ßBo6=¿×Âc†çÕïCš‘Ãʳüpȁ²xÖ{%~§ŠôžoeЦóŸ*áùç,ያ¶„g³®ë¦uu8žókØ$ŠÖ*ð¬Tú+1jzçxÁ$ ª`‘Þ¹YG¬Ö;·~5zçÊЀ4Á*\¤­w.Pï qgú{BŽ0î\:HèKEÜÙ`–}û˜´wÆP¼{×M$µ¸sÃå!î°qgÑ€i8¥>îl—@ñ•3hç›{Í?ëR í܂Òáð^*¢hçÓ\ž;èr¬TÑ΋$=î ¶‘!öÎ 1˜Föξ*Û_Ý«r²³w–&L:gá'ȃ½{gô„„gM'¢­ðd!iN
808
+á¹b¨‘QL-á¹ÃqêZ1×;h§ù b¼¿‚;#¥õ¥\Ö`Ü!–ëW£¹ÞÎfµI×·óôåø¤®¢L¨l½çÍ,Í|x»6ƒTCzZÈ«›¯Už‘T»¾$¡S)éL°]TóøÁÄìlWLì1·ÍHÝjUx%ô@!{‰Ÿ§Î7U€ËêÒ¹¯îÊäµ#~Î`jk•V›sóòÝèrß´œ‰å˕ãW¥…èY>Gr¾àn݁±Ì¿qþӚØQ82\âH)y8Œ\™…Ëô(¹Z¡{ÖÎÈ«)aƸʽî˜@|oNñdòs”Qí_¾Ý<OЬÿ‘›É¥~ßÙ¢ð0㹂@™£ãÓõ;ió@/ÖÒfªíÀÎ$rN6/Ìû¤|ïù! ¾ë]~›l/؍¿,³ö$õl¯ôïa›£‡›?ŸœH-ÂQ¯ºÉP#•öySÒêTñ›¼)JÁ9zÇbÝpîÝzcˆd
809
+„oÌíqÞ(¼sïÉÉÓ,r0çÁ*2Ówuè æöb–:¦³O8˜Æªó`ü,ˆªÎ½Îõ÷ugç3½¨àÎ/¾°æi>ðÎV¤‚é¨xª ÐFñdÜ çHyîë²F¬\çÉ ßjÓ³v¹Ûë‰r!npÏ÷\”óg<V|
810
+´•&ŸÖÄ Ñ•ô‰²íSht[’ŸºÝ¾Ë’wìg=×shý¹Àj§R
811
+*‡Ÿí…ìNçùGÅÈYàK²è3¡f€Ð ßAQØD´¢v‹;qCÒ ¹/Dâ<(þ:k#
812
+»*âÿ£…†]]åa(ö,SÝ%Du¹¾³×9TQÙ{èCÂY !*Ñe?¯ÝÖn‰F+ßí%4§MõCÀ)‹¦måxQ Ò iéé¢e>ów£ÁŒJš¨òEU"SjZnôÄèó¤€Í»D”ÊQ΃ƵÿdÛ{t™nÍúG…Y† „4Î0$G¤}¦‘Ž®ÏðF’Æ%dIMƬ2T“v–Ó?©íÚŒ¥‹ÆÒê'Eqé=)ýùⅨtË®±…rf3'¥”ß–¶bK]ìŒÛêÒ íÔÍÞH~i¦ŠÖazÜ JÈ´Äán¥zÉLEzՉ¦hÛjŠ‹KfhÓç{}5CP¸H;hœîqR>§XvŠš"Å?ëÖÌÆæ½gmÉ{SW…(ûé˜j…ðç5¨/¤ÿ[C¿XÀ.|¨ðי¢
813
+¥²³^F}¿Ý;êâS ?¾¤ {‹­2vX©#ƒÆ•‰äIµUžÐ)F4ÕÆMö85ÃuÆ^O͊ÕP¸ÀÞFd0ëXªLJŸjÝùCU+¾e˜ŠUéÑU%jíÃjh? ŒY}Bˆ ©V½²‡·z}I¨ÔºŽÆ"÷Ö¸«b|õ‘vµA¤¡ѯC6¢Ï‡^-’¤ Ưrü#Xs°G5¬ôßbP«ùdÕám"bֆ$ßøL®¦Î™qS¡1­7wPEÕ:žÕ½VD>Õ#gkõa£n=¿rE¸‡8$ ®ƒɸž¾à¾?¹ªÆ¹*ыEk‡æ2×Õü½]=uE1xíc$•×ñÛæéÜâséU,‡÷'Ï&P F¾â’ÍÏ/JºVl_TIû•©D´ý¿
814
+_M¦ØãOÐ"Ø|@ÁÑó+da×ûTkž¥»‘­a B¨ù°[+W>bñA¶@±1Èbãôê{1¶qmýu¬O¿öËP-qîïwÈêmò\„dÃÎd¯ÅÜEÙ1#¿ÊÎ0Ñ{¶ñ´l%Dõ²^ì]KÙæ
815
+|fí>°YÈ ²pöæ˜ÎúzÃ5òìG&t´AÖ}öž´¨Ùµ¡ ³´Wњ'^±Ñþ1{Ø) $-?Jn¿¥Í®MKìšÈý´Có©•š’ÓQ­„¯Õ6mí–J¬-¸øœYkãÆKŸ®…ÂHákA¨ª°½Cöñ[¥ÓQ/ÛO¶]뀯ÁøŸËØ,nÙVƒÝVÂÅmˆ[åɰ™ÛîêV¿“¡
816
+Ì@§Ê—ò¼µGÞ۝Ý9M×ܬ«nª‚Cú›Â}±¯BÇm|;cL\ö6ãÞe{{ üQuÜùÓ\Ç(CîÓÝegrÇù;0Tî¯ërƘ6s 7KgFQ Ï%ðôÆt1ç'€Ò½â/„$m“îy•Dât˰ˆ¤ddäêû­«%°Jæçd·EÖv´ëZ)3Oۍwk£ fëE'ÞµCøiŒœ‡¦Á Þҍx‰5^º/ÞòÈ+‰+÷‰¹?f^ZóšrÀßçÏ”¼èùåq#‡z Îÿ8¨·Áå‹" !@PÖ[J`Aì…þl/ëÞ%› VwÜÖL•›røVB,ËóÍ;‹;Dë,óm´JgUÙãccµ+¯úÊ S–ýNSv‚zßWñ[”6T¾8l§ÞܽG^ý–ädÞﯰíùûHœ9ø×}Y]”ÿ>=ŠÀwÛ(òML£¢à÷†{ðÖÆ[nÀIË#ÛÊc·Àö¿ôÁM‘¹Ì·x8nAEœqiežšš!å>ð€VÏöÇI¢•ùÀVqr)axâe+ä|j¥¹>ð†ÒtÁé¸IjYýVñ²Ú™> ^ŒâóƽC ےZà§dxI4¿# ¸£/Àò>I p绌a½ó¾ê~Û²`ÍQ,ôWÜÀñ“—܌Πÿ:÷F$P.KÈváqÜöÕ¸(Aã"·ŒrõþågœˆÃì« üöúTÅ î—zL¤þH±Nøß쪛S/Ÿ.0ŠLu—C)³œ›¦´©Ç <Oó£5^7`ÕÙ㳓ˆß€÷?l%W½³)Û"Šúð1}ÓAÈ5`™š`2ã@Gà¢Ôq7ϟ£Otâxý˜ÒЄVÁhÀËŠ/n–AGgŽøwY- ˆWÍt6†1™†"àšW˜ÚÒ'bm™¶vƒ3PÍòSH
817
+ŸQâ.\]>xŒ€'§sé­Á=é<-L–*Ñtì–öƒï  p`Òz!©tK¬EÀ·“xA`›‰³-Ý;!°Æ8¾È€k†P „Ö2`–V›>† {|ô0¥¶()ÞH…\¬,B!S•ì(2fLgÀF‚œõ/üdÀ›?!"0쬛Y-­’w0oËÓ~Å£²ÿ® ÃK_#]Ÿr™ ”?¥áÍ¿‡ž¸ð˜
818
++9Å:˜ìÅÆÈFßuAÎ?0ÑÀ%Š:·…ýÃ©i+6% Ì6{.ëZ40ˆŽ2mÔÕÀpâŸX 8v¨¾Ÿ­¿Äàoq¡^0Yü/WÊ% =0שdŸÅíôc!ø2ȹúp’|`/×@ž5iåû€ ¸¤×÷IX^áìƒÔ}ñÑ"0ùÝ<,{õå©76†­›ëQ¡ƒDÄÅ¢"~àÊÕ·Øú¸þç­|ª¦‡2KÚ_/üÀ¥ÕᓛTCÿ f\×à¼S#LE¶•—­mfbsÀÞQ@ûÀïA¸ Gð¸3ѯ#X'ÔÜeBÀôívÁË3ƒ–:‚¡’”‰’`ø1k2’×JpƒòÝ GdÝT‚­KŠþhÝф 8<¶Êï<§w­ú ›+ôyǟœÒžM$!üÊ(ÁY8•ˆ”
819
+&˜Ã-°3¡S¢ß&8YÌXÁ§×äGP‹ )±®ó먌r6c¶'¸†ùF¶öëTðë³nâÉ
820
+Œž`Bú(€ì'ø  lÜ!dé ÞJ‰È‚x‚!3Oðƒé’ß_֒Op­³ï!N0ÈÞ &„ù·ìJM¢3QÁÁûjض`pu,4=ïކ›DJªcÁ
821
+ž¡÷ƒï²ÆZðS¡Y²I$Qcÿ±ÄùøC_´àžZpõö3Òëô­,»P\6°`ä‚.@•gbÁåØ ‡Ã08§o¨ËúÔ¤ž0Ø6=ûŽþŸŽr„ìqVÖ4îU5xFE€_¨þj0ì»ènÁnߣ] M žÉü3£„/
822
+6ۃr·9Ôàÿ‰ñ¼×"`>8C˚!–!¼8pŽçÖbŸ¸ž§Æ.Baš¸ †*¬ä‰Br›…?siÌÇ ¿‡]ٙó;º aåÉÀ–‡Æ°>úùü*Æ0%kHì YqÁÙFn)aYH”©‰¶„Œá¨¶iÛ4†[ŠÑ ` çZÒJѪè)—ÛESYy*Èöþ¶$º.è ·¨½¤šÒœaˆ(üÙÝ@‚x¦Ê?»çՃîbÓª:Ã'™‡Åg{”o„¤'sV&7fgØmPX3,ª9XÃò*Çß°€ÑaD'n,ͧ>¼œR<Â-{ìÃãÕ¿2±è÷bN.ËM‹øymxÈTóô¥“xû™\&–”/~̉ƒy¾ÉÙPP¼Ëb Jñ½V(ÿÊÜA4fØé¸þ±C|Ú]ìŠTřÞâ¾Ú2¼x(Ô~1ÄÓñ·ó¦C!ùdÌZ›JáŒÃÆ I¬¾4ï¼NpÐCýÜR*ØmüL½îŽgyÛàҋa°`0:ËA‘ã¹T܋ŽñtÂÚ1©ÐÆÇce!Dû9¨>î|·ýãG0à ./)ìºx•Ð?Cní'/îPˆ<Q‘{´ÐŒ\üüŽœn6ó™FD2ßQ¹šd·Š®æð%ë SëLö¦
823
+2†“4ŠôŽfœ ¹³&b³q(¥f”E1M|¥,
824
+ó”G[­U +¶jf*ÏB+‰_åÑ,š+
825
+25,a¹!k˲Å;SËKz¬¡ç–}½ïÜ2äŠÜ áår6ø{¾«îr•ĽLæo'ÌÈ÷/„‰U?äsyIæRtìl™WÛ¶À4"½Ò–™ª_‚JNpÒ2óB|A荹ÍÜÒ8Փƒ@¬Í|´ˆMüÈE›çeŒtÖ§©U4•Ö¹ºó‚²™Ymx 2Âôe̬K< ‰=‘埙O¹Íóc傞[³f
826
+ÃZðÒD€
827
+å½cÒ:G޳×5Ï=/±²Æ‘ÖìŸÎ%;.c͘ €Õ+¬Yã,ƒuÀ¬™da‰¼OÊGï 5_^Ô*°3Å¿b‚V´æìš$”ø±ZsY0Ôw¦kÍRÙ®ÖY3pTUÃ'þ{5ÔALLw4#gÏ܏fTÕ³(÷á·5&ÀƒÄÄ­N¹5šoO3b̵ååó¤?Íõ¿/Ö§R¬ê Ñ¬¿Šv´’ÈS8¶G­‡ŸA~…vEÀæòeâÃÓÌfl–• ؘ=‡sÓä‡Àœ]½¥Y»sd3kœÊ…L[Ô ‹fvOò¿NÍâóh¨~F£Y=¸òý©TÍS?iJÝÍj°>ù<ó!Ù½ê㙠¨ûߍ°#Ï +§"s™™3ÀuaüÚJMgN¾…]Ìô¹:s+S&ðÛc/îs–kêõH¾3+3²âJidf*øc]•ÌÜ㝹ԞÕ<Ñl¡ý4k¨IãižYŽ’æ| óÓü)[ƒ¡/Ÿ«§Q aÑ\fÌýéÆÓŒ;%¥žæìÆîy#=ÍçὩ©ÔÈXò4RréW¡§Ù4åüŚ-uInØ|>Oô¨Íܙts3&Gà›¡y±
828
+gB:Ëßqv&6 æëü¡3Íņ꜍àÅ&GAØz8ÔÍÎÌNe—w¾Z¤­x–ìÙõY¤ôõ¬8Ȥ:ו½™ågð8ò¹ÈçhÁ㮁†ãxA#Óä
829
+„†NÊþPhGŠ CË •QºÑX]ÿM´œèã­\Cw£-½·¤ÑßÖw¡”£;»G÷>IHàdžXNŒô1ñ¸lI„
830
+œÌÌGišæ3ö¾ó°°o/\KK¦Kc$s†in"3·¥Jû M ÌtjÉÉL+6Xjz93°›N¥4Íéh €§Ù!HŸ•|š†Lm2PS@†úfØSÔï’tÔ%±ùe„¹£ÞˆbhR_È\ªhÝ«¤ ú¹ìš©Ž(ª¾q풴êÎêçpÆê [-&ÖY]f”¿՜ÝT[“Š´ÖÜÕàvJ‘YKª ­?7Õ¤ÖJz[¯0íÝZÔÙׯֲ²@¯Ìu–9i¯ºŽ{«¼ë‚¿=c“
831
+_·¦ø¹ôëÆ6õ{À–¼Ø ;ƒ`ÂÆKBܝÀ  Í(±ë>‹_‡R÷gÚ®"ûLM.¶ÏÄÝt¤«‚1}0û1Qä'ÙΜnl(yg«y.•Õ°Çp Û-ú7<0†a@’7ö9¼«Mp±Áom_‹]êYec¯ûgˋνW“êklrþ±Éf7á¯?ö¥/ü„\ý±GmˆöŒ%êÇîkMpþzw(ùÛþ^­Äj}J±’ì
832
+ƙå$’l‚Rƒ1(o*Ù¾‘B!¡¯J6=Œç;y%Ûڔ½³9¥F¼c<e+Œ/
833
+ ›;ÊÖP<$¯EQöxÃäl
834
+«!ÈQ¶Ñ⇷¡%QvÒrÔ¤,ÁGÙAåĀb“lN¥|%A/^ñ„!Mœ1ìÂn’}¤B–„„K²÷@*ÃuToœü¦‹u'Ùó€w¯öÀjˆ ’ìü`es™õ©N™2”m_í¢¨6,”m5ž5@7(û2jÚđÍr¿ª¨åN2U;—E}ºk㑽+—ÝÈÞ7º·S‡ Å~ŒÄ>vAC§W‘۔ `þØJ±È —£µþ±íN%¨
835
+Ø8ï6IĤþùð5¦žkÀåý±ïÌžËØȃÜà ˜eâÇÎãAÚÆæ­9ÔIRy³›JNá[…ïˆ Ç× g±w“1¨<€x=÷³³ÅƂ™6Îá;º[ù™0ŠC—Ú-öóvt)5çÙ³¶*|f̨ÅÖ ÓïNÔ,\‹}Þ)>%¹ÅŽ5õõFE ’Ø\C܂À$vGàG÷Ú° Œš¹¾a痋6ìe´C³Ú6lסơ†À¬™3R4lad'h<·†é*öK}΁GL˜("q#¿11xÚªa×:ª´ñuѰSt 8=ß›ÐEG!%ìíæÃ¬ßRZfuR#šüÔ¯]hç¾xüvD+
836
+*†Ÿ#l+)1'{aÂè»B"l<! «/ö,  þïó‚d‚]ø"“àyì¡=`qml&¿}$ñ–¡lÅ­Ý6ªûMN »mØê;Mn†»Ø15~ù/Ón«r>}ö”7¤öO¦@vƒJ Üë d¯ÿ ØùÄ »[ª¡d£M³4]Éæöè”=™±”£e»†uÙ®2µ9Y³i4L(ú-ÈØggÄÓ‡vgct¶›/›iSe]çD^¦½½3ªÁ¤uîeÚEݾŒ¨°Ò³j‡Üµ6`M€‰í'ѱHk/`°€ª[#aëŶ07Ë<g[¢_;T*+)½<Û²j )hÔ³}ÁLc-õb\Žg[òRÆæ©¢y¶É­î†ØOPg»Hpî"RÛDØøbÚRëlM\÷$–‘³+ð-¯Ém âl“ˆùžé\:Û¨æüCÁl 8Ûá`ÿ`k¨[g{»¼ð _ÛÕ#îßæk›kóœ‘2Ô Mþl¯9ÐîHÚ6n ¿È­¶xžÐvnׂºŽ  >€ah{µ{hQs·2·…¶e=t¨T¥‰m™—-¯ƒAÛ+™v+´Ý2ž±Œ’BÛA5$þ(ÏOmh»g¯]$–œ‘m Ótö<Éc{™Ó¦ŸK¤²’mè±M}kA d»©;¬'ïsZá5òW+Û jãsY>)Á¶šóöeË`›Eê«ʃí˜E.†éÞ[bƒmþœÙ`…€l—Â#XGeƒmò$Ã2Š’q°--µŒ„ZFöü+ۈÎ<l/Ê¡uˆH–ȶN´ :‰ÔU´ÎÃäjÛji°@ZÛÖª¼?=/ƒÚvK”ìMU+u¤¶riۛdeÜ^ØmÀn×q:õ6
837
+ÕhÿRAª9n`5úïm{@±:ŒxDù ¹©5œQ¹³ÛÅM,s¯Ø]‘¸«ä¹i{ÄèÞÁ$½<ݲPé6Öí}Éú…ÝŽrêEíÿcàϧ Rª¡h…·FÎzt¼ñ{y‹š‰ôÞsi©·Ôæ&YöÖ~³{Kö+É(×ÿKAz¤ù–¢ “öYßÂï{è) ŽÑï{J­ñ÷4ì„spf÷I x’
838
+ünÛU‚^±Ïtê_¾àCrÆ×á<3mð·MÉi@Ÿ‡#Í<*íª'|‹Üö­Êí,ÄÂqéPÿOýQ¨Ýrxû
839
+߸‡«ô=ƒx_«Q”?Ù¿hD$&~µBïAññ§ÎÛO<#úò;ÅÅJ½È\q„’—«"©®ÆomFLƳ‚HãЙï¶qïKBù•´4É´ã6òC 0ÎGü¦WñAŽÔ˜Aˆœ¼däˆäŠšëï8æÉœøªä—¾×Lœ)­óä$ãQn…D-P9]h’çDfÛ²òKcA,oýhØðí×rß_—ÓÆ¿>bΓÎ;‘Ûšd K3wGóüÇ¥œ
840
+NmŽá\»zó¦
841
+±qVÙ··‡lî yèöƔáùÜê9ŸâC®ùèüù+Ð>è"']†Ž¹Á ¢Ã$ìH„Ýgyþ~7zô±˜ú§Fú²É“”éT, Ó3všNÈ@‰Tœ>.uÏåéA8Þ*êÆ {遗õo'u/Å8N=Pª›3¯âªgõ®ð·êª2úou
842
+¬›¬S ¿ÒºÐ —Öïè ™oëG®Ëßã\–s¶ë—¯Ðö:™àl¡aÿ\=‹ØoCjŠÆnŒòÙóòC̲[NTØmöñ\1üjo¢P˜}½L,j_÷3L­½Z“K"Æv;W^ª•m—•n.ïÿì^ŸÀn á.­+Hk¿§Sæ¾|¶`-E÷d«;Q–v6w'ÎiÖ»+#¶‰ñÞ†‘ú¼WÁØSØ{ƒ;üÓÊbeŽ„ïÉæ¥ú®[ÑØü.áß)=8[À¿›E".xÒâÀ#}qû‚çØB„Wå üڝ»uRx÷Éð?Åú?µ"ß#âkÂÕÄ«]˜ŠË÷Å_ ñò3qüqë‹UeõøþL%ä3W°›¼Ï°c1LŽöäE§<S+–çù~»|2qùˆyHŽkæŒÞí´æß¼¼œ¯ÜAç_*Py~þk5ü¼‡² wÿ<”aÇ¿è/þÑg¿ˆ×QzwL¿÷Dk?ÔkaÃkêuoÕoˆ'YÇdt‹ð1ëg̈́]Ê8›T«¯*—w¿BÑÆQZò1¦ÜzÃv~} }cG÷,ÃÜù’܉@·þ‡nØ{ñ¶Êz©î+µ¬/Â_Y/ÆÛªÜzݽë©fm¨@ëw}ù¡Mªü˜»¾H£±ë~×;¶®xs×çX{d9ÝõAm‰²£ÀëoxD×Nq°†J
843
+n
844
+^{¼¾@V>øÃ¯0°W WìÝ#û½þø…Ôʽ&O$gí?šmñÛ?Ö5á)ä^WC÷¤)»çK¼Ÿ¼¶Ö{‘ÜRßKBÉèïýÝ2ðAiÛ<ø85|«´`¥ 5g@D|.–1zÅ_M‚† ñ?õø"¬2ò¯ç“O$0°üÓTŽÄ|k•4¶T֚/gÑùcým¹¦ëLšð†þÖäº<úaõŸH¦ŸïD¢¾`Ü»êcŸ&ZÿÛ¬Vø^Ÿö!ʤa7ög!õœ}9‡tÂîÚÿâó“Àý9Å¢§ûÈ¢aÉû4_z´ïç)K>¿:” ÿt
845
+¿K‚wZüÆzUèÇ¿¤8ö‹òoÓ@mÆüÙ¹ #ÅùK ¾ ß›‘Ì©ô7¦þ6ø×ߦh^ö—n¿Ð°B:Þý⢆"äÌáäô)õzåäO-qþªJ?‚¦õ§fL~OBˆÓUÿþäGB‰üO{ô_&Œ{ šÚ¿ØéEÿé,š‹­L%Hÿo¬8[àþÛ ´ßl»cýîhÁÒÄÆ­ ÿÇ:äû8Yü]ÑVڐ‹f3:aÅÜөǟ±ÿ,@ qû´÷—Ve3 6úî{ÓÉ{¡©¬öÌÀ¯ßÄᯒq–_¡6br¬¶Æ 8ß*é5u÷:I³0fþ²ŽÍ’J‰_ßYžt3º}¡—±©é¡é³oêúªPrøDtøVºµ¬º3  #“kµ>›ÉÚål}«‡é QÛS™±žçcø<œSɁxø‡ 4¼ÁÉ׈ýÁ?†‹+Ž{˜ñj´¹ )ÞiÒÏáÕ#ÇÁëG2»mJeÝmÜâNÿ°© ³Û1EÔ/yŠ"íoå—r$ˆ_-˜0×óŒ8Üaa‡•’2½ªÈṲ̈fÃ$u_7©ûi—ÅÞr[°0À걍ô5X [À5ñ¬,^˜LcôDðƒö
846
+±Vzp~åå3­¿fcàãé[cw¸bË[´©ÉӜ"5Ðr—F»ÐG¹óhÈ?Ì¿-È[…6 G$y´BÏb ­\y|šõ€äEáQF4J7Ò Š5@Ñ·Äxí»ðρ«îZ°ªàjy¦n EO\_âøÎ9(ü>õÂ|¿u}ˁ&B¶bµT- ãëVʧê,ã#„ÄÌ{®ÀÃôèe@)jæ8!þYa™}o£‹@5~‘…q\­ïô–6ì
847
+͹‹1>ýï´5,0ïÐQ½~q|èÀíéI ÞwîLЍ«7£ 0 çCˆ~¹GW¼Ï‹ŽuRãö³M»Õ_Mƒyâìs†v¹ÿ”4zÌMraØVïÆEàáe?Qù^´z¹éc\öRÖXÉãû>Åç°û¦ gjàÝ~Þ+år—nhµŽë©ƒY”› ÑÉÄk­Ê”ÇýÜÃ<¡Ç刋·q"Š&¡ÖÎⓠïUú™K°ÚÈv¶A„ÌÐÌq˜u(D°'à¿7•}°áãŠñ_m|D¾Quƒ²R†(êõŠ
848
+Š>ف„þÒP!u†à½zÕt´Ù¿³, ¯zñUÂÁT_ã= %àC‡”Lc(üò°‘“–öÅ*\­ìUμ•ÿ1äó?· ž~70=V86báð^ƒÉÂ\^¶?»Û÷SÀŽ'(ë,rbôõYö`:^.[0`™'1þø ßï¿t7ŒžSÖR¥Ë™•, ¼¶A”P?VtWóË[ù+ƒÞ§“eâ–5g_«@­=zFËø3ÈÃàËè»ɜÛco¥¡à”“>CUt™ZÖtFüáeqÿ2võà4Ÿ¤F“ýoK“a$3ËèÉœ>¶¡X¢3ßÃba! ³g€Ý/ý.f„'Sǂ&¢&ª¸‹Œ>
849
+8V0…°³Õ¶b…ÏyÉô×Z´n7KWÇ5ªDól4rö€ô/!’H–ÀҏӦ›(· ¿sd¿‘4¹F`Y}ÎkSIïÀÖ4?Ÿ¤–ÝíË—æ‡¬Êø]&:¨¼í ©á¸¬Ïᦗy‰.tvÞ~Ÿ$¾|ÊÌꫳžÍ0!îM KÒÖÐâüm`INVÀ%‹Q¬†'ýt«Õ­ÜyV!:Jþ¢Rmˊû˜eã<D؍Ž*²¸a8Âh±H{`}üÔµ~dn×ð
850
+Г3þ]™¸ëŠŒý••/ßie\Š ÿYäY“~DxÎڇ‡4$¦»)ƒWí£*Æ¥›
851
+ôA¿„LP…滁?3O;]­8mK«ø–˜LЕƒŸF¹ã‚O“yšgø¦Ë‰‡åY¶Œ´[ä×
852
+xµLãÜ /2u“}¢ÈoçX/âäÃÀA‰PNfÉáÙX=º9øAöAš˜#vßÞq‚‘½SSÖñè,e;Å ’ÝkK)`”a%@î–E抽Á%@‰®Ê-Ëq^¦HúI¤®ÂmÐ%^ „)/oÎñ½³^·®c0¡ÏCO~êÀàägYЅØkÔÌ\£c—ê\ª UYof5„¡%EPŸf i×eC#ic‡]ÌUÇa’×äevã‚Jè‚'ŽmsêÌFDò¼EÜ"Ŋ+#؝æÕð$7jZê4g!Xظ>hèË5¸.Šßʰ Ñ[A|C†,L8@Nc¡Ÿ9–.ÔGRhŽüV¿$`ü>¦ :¹@žh
853
+žHÆí‚ϝç‡ñÕǘÛp8vˆÓË¿«£DŒTñéuŠ®â͐¾U”ª „e%tÞí‰ÔŒ S-ìÖn½w¶†Z³>—?4ҀIèj¹-j¦/ÜFÎbŒâ\BMm"\ž«î.10&ƒzCeöžÇ"¤2¡T’œ J—Ê:–q¬çFP¾¹bۈyò(‰ë „”–µ_æ‚Wèǚl]A%!Dÿ¬f‰Me<#q=cÐepmd·´Jo<Mÿd¦¼/!Ò ¤¤\O-Gšbù>|kʤsêŒ6ÑLõWÖ¸9P0a+mØh²ëÉ?2S]Ým’é©b
854
+¥õ„y²r¡“ký·[ z¤¸e¶5Sy×˜"ð£áÀžSÿ Cä_¡$„@‡ˆž`©.—3"'7xí×\Õù‘£©ú„5ú@IõyFN“›‘ë!‹[É×h©jSDC `•)á0’`#ôX²è€T2Ù òÚvW¬-J¡?FxH¨[ï Ö‘0Ñ$%ù@—Þ.¤&â2½ dæ#ZЍèßp2KVãíáò7í}…t `³0¢1Éæ_HˆX|îÙEX…Á Xø§!d\RT¾r?ˆé'uþRHã~°îˆtä«ÛvÊê
855
+þ ¢âý~¥–xk?{Oû}ç‹¡Vî˜Åo‚õATËK½_Ú*½vgg Ï¿O³=ƒ—ÿl¤Õ‰Ë$ßzt
856
+³„½¸x˜éÁ0 ~µlƒÈØg§ l”¾R<c7ùËÞ¼C:( ëš£ØMz}±ówö6-ïÉ™§eª:nu¨~xϤ6·¯tNßæa¾uW<WÃàXû^gìP¬ZÁ@ÃÓö‹b†Œ]1S±»®ÂÔ¤ŠJóÒÀ¼Íà/þÞŠà’–Ûááœ÷Îü?ܹ%¹¸U›å¿(hóFH"¤ԗM÷5 tCáܘì”MÝÁã ©þ¿\§ßUØÐz,8Iʍ‹!š?‹Ö~u·(²€á+Õ'T4Ž~7ße²oõeÐ fʄ„" 9œêÛÙ ¶«w HX«—“¹"iʯFŒx–Ge‚2No6×3"ãCïj‚/—«_‘ˆjTor«m ÌÒ(ûÎfá(ÕÇÔþl`ìb±KÙVxñTUŒâ´nÿH'Ð–TàFÌÍõs*µþ^ ÒòlC€ìYº<.©/ØÈ‡-8òZbNâZ^ýì@Iâé»ýÌvè·µï«P®~¼Ã‡xž€þ÷©¥"ÖýG1nÞ/{Ë*lÆ
857
+X¯ìµsa[uQ.xU‰9¯TGøæ¸i¦à¢ÏçsëŠ.`¦á+;ýÏô–dÒ¨ì¦å{û Pǜs®÷ ¥
858
+ñ¡V«O%À¢nëK\p!&˜&h;LÜ[\µKãÒѽԱ¥½FZK…i÷öŽu-,(L@
859
+ô…vÍö?ù
860
+ù£s“Ô–?´¢ËÚx›D5  Ó(PÑÏÞmˆæöe+yýMdMߖr&@6Ô{jt{Ôåþ5çx”A6„õØ^˜öM”+©&3­B§JW4°NÚ+DƒÉ<Ìõ‘bN
861
+jVMÍ( „dñÁ϶ˆÊzù iaØpi^ûي¦³µýp% RPåa{aÄ$ JÜgemìYг­,-(p‹×9ÿí2£¹ ø··€¶üM¯¸'ÙÆZ?ÖX i—ª®É¿Nmy\ª
862
+›%4y4z ŒV‰|?ï׌’]Ç¿¢(ێnÊu›ƒ‹â;g(Gì’ìw ꑏ½Zð´ü´nQ«é^«#âßDnP S„Ù ¼ˆÜþ›‹ª(1 ;¡V›¹PØ)1Å42ÄÎäEƕ€çæíÄg…S‘Ð9:7”ÁRY³ä2$Û£ìžDxÁäýD̚\¬wÒaÅ5,2«$Íí¤¸Rˆú>CDØÏ¸dÒÉnÁ b`>.¿§˜«ÉêÆ}:W@D*òzQä?р—ʱ¦k5p­h] ŽÁ`ú'€²f諨°eêB*o¼*w»Mµ\x°˜™EÝ0O½ó¦crB͹—õJL™!ØávÐW
863
+É}žê|xSÙõ><9U»d»e­ú!—ó<Ÿi,Œçèm–…q¨.]\Ü÷s8‹‹øPÈýðŸ‚!:žc£Â¦1 q4Cm÷7Z97Ԅ^§)lÄ Îìÿaý9=~íù­KO †zxv@å‰HG¸º*cÂÙ/#u }ÙOüþÙf‹ÓB A½]!í†Ço®# •1"ßEÿÅ4ëk…Ó©„›Ö‰gSYzÚYd9{C¸ÈXQf¢‹ÀØ«œ*ñ'<ÕÒ|cå}{¶¦‰@yi»{¸TgÑ k
864
+M3ü¾mf,ŽÌyÀÈʈFÚ¬«ÕGP«Æb‚ô°…q@•F@õ½#àAÊÂTL.™ãRß«B",óXêy–òb±±ò·'X·>¯pÎô¥4Ï-ûç]d:©ÿçáûcO®´‰L‡±‘ÄJåM…o´N^xV«VWƒsüö?úrÎ[^Ȁ´»seÚhÁ- ý(ê 6Ü;ÄbåÐX¡kuõÞs¥uޗV™º²ŠÉÇÜ9ÆO“0ò k-‚¦ì#T®*Ž=ó†éYz«7åbhèÏ·óõ.ZÔ³í ÐAÛäl¹˜]C,Þa֍ÖEÚ©?­$Çâ/Lí(ûdúo°4r^’#éQñd¸Q†y(ªRÎL©aóuþ¤,Vp÷¶^°9£k Ô2i< Œº¶Ìì§Á¼§ÉÜKÇÏ"‰ çq²ïØöL‘͙眠ÝÐÚÛÙðTð¤šÃ.Ì-{¶ü6Ež@4bŠ¾š·¼~¿Nඐ¬Å)x³3-8<·3ʰa[Pç³W‹¼Øë_´j±R¯|¸á¢»ÂÀQ¼Y¼S†S½Šê”ßôUÿ ¤×eÏö“I®'[\·éT§×Eòn#>ÇüµK_bõ]dÕjábáâD´éʲÝ9$!#Dó’`_:å3òz*U½ËÛ0D %|:dM§“ õ^±ÉÔ´ñæ.PMT™Àïg…µ
865
+‰n[”7ÚSÞé/küãõz|x*mq%#ÀKË®~ûNŽêá’‹Ä[1ÂÍ %íÚfœFƒš0óïŠò_qÍd¦7¤Œy‰a2’?fó¡>Ñò`ïZ ~ðÈwU½Žë‹V/Âóô=}Lrj‚Q©TmY”®ueã•:V¨È7.q%،o½À1 ue¥‚Aø¤{ºB^êÑVâƒvûh6q2_¦ì³Èèìtåê å†(`ˆÌ=øQ.{x'â! U< ¶¦5íÞ#D¶ñÇéË¢.}–#ù4À¸So)é§;Šõr!Ã9Z¬r욆Ôp#ñ
866
+äærL>ýTˆ:5!ÇÚV&݈£8šØÝcÀÖÓ%]¦UÀä¦8\N{>&{¥<ZÉÔñ%µR›®û&ùôMÇdF_
867
+†ªç•›©¹ny8)ºâ´†R¤8 ÐGðy¬o‚øÍ.(â—ÔqÞ ¡ƒ±عìÈ>áåBN“ÙËðsõñÈìӸҁ1…å𧎨—$½VXb¿F¡`¿öÃ)ü„k‚à4à?,^È0E ^’ðÚnÏbŒIY>§³È8€ÚpŸKŸv~Òù6»‘Æa:¼£æ¸OÁl¦àøh=øpNì|ÎR8h<åIeÏgÛ¨B¡,çðUÀ\âҭʺ›ê vºpáۗå³VÉì¨p ¡´Ø˜Rò—7Ž=ULKèO•;=Uï1â÷ã)ÑDEýYðìwì¬EzíM¦nqV‘‰YÙçþ›2[VçÓe6{úª šÒ*UdÀ4§•ñÐH;§1¼Ê€•FþÝ<¤¦·n‘ê™Õ0'2è#¼Rrˆ:÷ôñ»=µôP ç‘S,àÃ2µå:&¡L#¥q].¢*.…ïñ}ˆƒ׏†èY5sX§\Û²ŸN·‡Cj$ øŸŒÜç[6ºå`š±Å|½ìsX¯ ۈDKL: N… i›-AQPZ|¤3mä>íçٛ_}ɽjÙÙÉr.d ±ˆyË;±å°v¨ÁíãZ®¨cåýj­ÊiX3.ö°ÔTe='Ò7t9.•¢Ð]«þÀe1Å]ï?fpƱ€èœ*L¶¾¸à{¼¯(¯•Øm
868
+S‘¿—мÁkO¥ÿ,á‰ÍÍÅT‚–Bé7Å%Lää<›¸å—Ú7g%XYJ:ÚtE…Ý"ì2ˆ¹ET†()½j` ÛkûÖfß-ëǰëOˆ^êÓíŒJ9ÞC0kŸnä˜.Ûç Åê}øn‚ÙçW@¸È¿ÊÉ4}ÎUöR—û³&ªé{ØfN¬5ëí‘G<p6üI)¾¤"|¤“°\z +BÜ0€íªKõ!“®´Î¥ê•tά\ÃB_‘-`¢ ݉*6Ê3HŸš0lÐã—WÍֆ®@ Hx—ŽG½%.³”–Œ¾ÞEÒWeê2UÏŽO¡d™½yԆœ'W:› Ä8/×a`*Ï-—b6åÆÌ_ ïat=LVuº8(ôŒKñJ„™U9é»ÅŸ${»ƒÇPGn¾À|l®?±ºØ¹ÊsOhk^_˜ÜQtä$à3ŠYúóPæçþË`hO«#_$(Y#K¬œ–T‰pS(RMðÖBÚ©#®ÇîMªRv—²n DÍvˆÿ¬™A¢Lq¯õW D½t8Í<8²‘'‚'Iù¾÷î©Î›ÚJ1L-á¦|‘¯ÛÓ89qŸ2ö]z"šCؒ¼;|ô z¬‹/F¦aÆÆj5»èßrŠvÆéÎ^ÞLÖ3Q™ãýxT7@˜ÖKÓ²Ü4`EB“‡é¬—a'opY!œ÷ÈçKvýÈ瑊r”ˆß+'-μçÀÉ~Wü…Ïèºgø/è¡Åˆ1Á±Y 395`ÌÓ<ÛÙ?c¨ªMl±i°+‰6³Ú3¹mwo'Êk”}IÖ œPÈleÂÞÊx¤Å:8¦ÈeÁ †^$_õðsRLGt±j¯ôuÈÆvÑ^e (dFΒöy/¿Ãí9ûŒN1æ1RUïßi‰7ÎA7ž”s£fØXjFì‹ÊøÎäúÞéO÷7hµ"QŠl¢ÂZžç÷µÈó¿:Š×%7uÊ$ª'… Ž•‹[ىE"—Û¢r¢ªlé¢,ÜMqé‡ä§Á,ú—­ŒëVj51;)ygÞßÉ2>41 ]Jž ŽÓ1ò@RsŠÜî~X‹øÿþQ@5îkÜ87äêëÕÿºO¦oâȨ°áz½<‡Ú˝uF+!%èîh C«M(~x³€«|6ݹp2¸‰*‚€HÐEô¦§‘AÇ"†Ñwҝ&3QIìYwvÂHŠ cw„“ÅƺY` ¤cÛۙOpåéΩ1p3Èø,\Z4†˜VEÉrÐÔ
869
+¸Ý·½eáP@–~mÞ¼¡ÅZó„KNEµï4/öab\ZçæB 23HÉaEP[<²ÿ$o½|^·ÑµáQ.µ•ØX‰qZÆA¼nEèb]oëˆ3{$ÖÑò¬ImŠsD¤ÔÞéSÂÐ2‡é¥‰z‘ •EÆBr"V(/6ŠÿŠakÆÇf‹|_Nˇ"fuÌTÞκâ4FÛ÷´´2"”Á•£ÈöP`#v`ƒTnªMîÓ.x´ç³ÉP-r(©Ì@†tL‰Gš$¸Çdwh¥ ð„\¢JFÉ`‰åÑS0‚¯iÆ+¯âè›wÉ͂ÉûØ?“¬&­¼ü¸š@í7¿SiOák”F¦8iÑãÅ!oryŸã©5ږå”=È:ÍPS8Õ?9:“ªöŠÿ ½°^¢—=œëbÁY'£-X(/}¯½WCfÕõ…ÍTºö˜FÇ»øUf±a³Å„ [I.?w×B 2Kt"‹5¡¼^*eP¾íy9XFwH¡örƒ _º*wÉ,Çʟ·JOX S6]gÛþùïZ¨T7øóì̘õƒPåý'j·^ý Ñ5Óº®ÃÆ¥F|<VÝ]Ï 16Kרº¤/ìHÀdÚ0·¶–Mu²ÌK¸”´ˆNæ©aܳìu~¡™Ÿ§£ŒŒüÔÁ‚B ®[Þ0:xmµ©“õ~n%#àe‰29ŠxI¸wÊ<cvBm=©•¡Ë¬ cGóó,L
870
+¢VGqÑm-ÎdâÃ5È/ÊÒÆžXmˆôsŠ.‹©Î Ñ1×G&là`†7ÃaL<Iè¨+¦ü^jN%d¶ˆÉ^e ßn+‚ˆý7^=à„§FY³Ñ&ñ•Zx<I_óA¾h^Ž“d‹p ”Ü, Ö|ϝ’v:uR“Oi¢Rh À䍂H쨍¸˜ÞlÂËm×N:dª*Eçl0»á­>]Kæ3ôxÚ¸ 3›5㞠á"=ƒÄÑY¬™&*T6 òá!ƒ§RTŸ=¥­Y<^€’¢‘ö6Û»”|0¯©>üëðVÆÂúžnDтö‡Ô‰9&.É.¾y¡ŠèHt«Ã5ý˜..üÛJt¶4CôÖ½»š¿€ÆA\&>.á-ú>*«"Âõ{õ…Ï¿gŒ/ÚL¸́LBùè™õhí~ªªD”¬*å=n&Êqr—çDæ)÷ù€heIÚ®DC¨¥¦ÌOe«Ð5UÏ:êA¶ Êä,L´»†^¹ùñfŒô¬:’þb¬øó&›i—ïÁ¢Œ×–ÎøY-½JÊ%Ôµ±—+œé]h ΓÞœAiP0'Ÿð²žÍÝ> L,
871
+·É’.ž†#L Ÿ°/ëD/™j®èˆ]yÆÛ>oqˎ‘©ÊR¶™ùõ&ʚñ{ÞAÞëœ'¥9ÔÉOZKíYvwÔfMè&bf|«?KŒs”ñü€C aFê>´žGéʂÍÖo ò²˜gãtaB£3ÌÇzÕ3 òû±ßt{KN:ðªTÑòÆ,ÈC>æ:µŒv œOžÐ ¦bÅbŸSmªÿæá(ôsAkõڗã IÉ*ËeIJàheT2e.½T,@qç¶73à @‚ön‡Ó;šèõ–q/PÒG÷ª!>`+-;!þCçÊìáxNy ©/Ž®™ýf=À’¡®× ž/8K³§  É=Ï
872
+,¾tIñ5*лØÌ¢W3«ª“Zgùˆme‚3„°I ì!}=TÂiˆ5àg5½tzՋáöb‰†±\Ä]g¢´¯‚~€;ÿ£ÝuõøÊ `‡´fKW46TIXO_4nâô ›½ý\vW¡º[/î® v9${™ŸxD¡Öp¥E`´wzÑ~‡´WèW†DÆ|F ¼7,‹í,LÆ|Úå%§ß²g+ƒŽX¡1ýeMõ.ÿ¢„> d¦ü£Àaà½ÒfCØ'q˜É简Œbö§NììvGU±àRÙ4œZ L'FX3_%Hk¼ºÔW î™Íh–÷,®‚å:„g‰€å£»×)—ñs¨ñeËÊP¶A±ñB`øá™Í’Uî2Qôr¶¨òkFÇyk¨LXÔqKûÆ“/›¦ êÂ;÷õŒà…‡,ˆ}˜ÖSŽÖeÌí [bü:ކÈɳ:½ ém‰Àá%³È$Ÿ ¤1²,•ë™ëNÉ@º,~àëҟøµj*uÏ|m®Î`|©¹mÝJ¹¨W… ¬ØŒ8>;Âbò;µíK€Ž¿¢… ¤+£+à¥A²§Fè´gø‘#£¾
873
+7% R¼ù¨#’@'†k¡%ÉÆñV°óÎè;µ(c‡Qñ‹8þ]yW`°ÑN
874
+ƒŽ¿Âmíâû´Ï¼Ê¥gõu®z2Ämƒzsd/ªPqA—ŠÀ„HE•>æÁëË¿ž~?©\†ƒÜW>gŠ•
875
+ <mzÁçì÷Ü!´pÕ¿QTÌ.gÎò+ö|—¯n9lèXõ
876
+“À£ˆÒ9sIƧ0ôaSâx|û8§Ú†Ô[ÅDÙÂøwm´3Q5՚eä§Fä¡íO¡…šPi ü"Å$ªM ¬%Ÿ^$ðéƒt–4üçD½Ù×8ŸUÚÞ.'$EÏþEàʽÛ^ÓÄT¦JÁÄBoñá[Ó¸lT§•Ó ¤¡»¢Ò²´ ànEaPÒæ/Q‹¼’ÔC돈éyáّì/ϓ¬? rÂ̬ݬŸÌ&Üu /¨*qª›Ë¾â ½®†;` =µ@Ê2õÑ(Œâ^K#ðÌñ~LÃ=:SŠWôËÀ«Ñ‘»©èüS´k;È@j”°®üZ¤†­¼†”"!c˜ƒ32í/y±Rià¢r¦†Ô/þ Ofy~.ú P÷Ý, †fsåpÅÈ©– m…š ÈۃŸÝâªX"¨3+‚¦µœbÓ¥Ÿ÷ì[äúø1„}Ec
877
+Ÿs)«lhü4uª«}šD­$XT_ÎL%¸çۀ¨¸•!º€ðÂÚÀÂÆnx&¬›_“¿ÒŠa§•–P½ÀÁŽÍè*'À›ó{9—í¨²í×WŠé‹êbßSù<•ŸÀ£ gS½–Q][Þ48)6.€Y´ÔôsÔU\›”dÛ*ÛÛȖR¬xÍmî2c¯µ.;@H–Å,½°|lã]žt²úžÂ!]À¨qÀcÂ͐wu[ÿ(cš"\ÃþÕW\ ܎ׅßjZGL¯
878
+tûŠ=fIüÀù¿˜>_ôÕhVÔþžYýçLÌU)–I§÷ ²„ýÙ¾ ©å„Ä•~†’áv#ã@Ø0ÖðQ»˜‰£Š‚òMÎô±¡e(,HJ€û—¬*nÃ'¬ÝgjŠônµPŽ^L|bホÃã¯1qR:Ý»µ¹Táidr}­p^­lt²Ÿ\XW÷£ÌªÝ[•ÀÎËÁTKn©wúÜõÔeÒЈHG ç7SèX§-å@îÇX8ü‰ þr!ŒÏ®ÈA¬o,/R²Ved×S—‹±¹0?í#§ïÛ²¬‚™ s·ç޳qYú«…?[%u„‚PDa:Òñ8΁³ñ»ÞS*¯†ñêoÍ®›-ú8c‹¬„ ÿ867Ó³¤Üãt2hš³í¤åî/=¯šPðêϔ×ëTGÿGнã…0uHªa³MjœœM'O¸‰áaãy³€*_%—¾šÉžëFK&+#!ވ³”á é•Þöˆ.%X«/ÖCREnt§‡{bÇ `OU1¶8HUÑÛzP5uƒE»B…œ.W
879
+VËÅÀrÈ H 0Ÿ`£P`®¬ˆî\¢eõßڈô‰Ī{çH缤^=Îc"NÛ› :éT›(ÅÕš*z*Û"X« [*Ž9ãF´r 5ðiÎ<£Ÿ,Í´u&•Éqªû0©KȨ%“@ø×*©^>Løg˚ÁÑ¡ø?Q¨f\^Õr…Èܑ>šÑR€…â
880
+˽Ycñd¡™÷€rȰ†VZ&V܊µ“1sg¥V¢Òiq<÷8ï ÅM\ýü}ï5!ç-š psãü§‘=g",ªåTÖfé 4%–Œ†B¢Oø˜+‹Qð>uµÊCõ>¿Ysõ°ù¬ìXÈÓ²ú‹ÃŽñzö{Á“ ,(×
881
+® ßA0Ñlº/W6­gSù,$Êìë'è`j‹ªgŒ¥ÆÔ;>°l‰IjEG“g]‰‹DôFCN¸@œC†í¢‡Üäœ!(ÿWºî
882
+ÈHô}dV½Ÿ‰ê+Oœû6Pz¨”ZúzÛÏA-ŒÏX¬§ I!mP:ý_#˜[U‹YÊd€‰+³·ÖËR\´OÀy/<ސyXõøÝApa§ÅqÁaÛ<iõØà‰E/¬J
883
+”H2R8¢V¼771q¬êpqóï~ŒââÓµºËIW’)Ñ2¼Õ.ˆ¼— ª8gà Nøˆçú+èÁ€^µolªºæ_‰XJނ™¨xbdXzþRƒ×·`õãÂò×Vï3Z–vƒTœ6)ä“÷뉅ã´{I¹—)•9+ìä[J€šøôsÙ·6a^œÊ,Ï55‹‡šäwªÓ´‡‘ùvüŽ´ÀÿÚlâÇû‚Z?&g52¦8Î*/­_¬RÿoÖH“Ö‹àªÆ9?­ëg–¾‚Š/b,ȃø@Û©=µÏñr‡R¨ú$‹¦Ó¸­žT€,¶N-„Ñý;£DãÒ¤szяG¿-”'Þ-£l¦qht›¢cÌ!Pò“ž«T`}VÌ4fÃ,ÿËÚ/¿E‰ÙX“Ùâµ+5d9EÕäˆÑ»¦e• –' ‹ÕÄéRŸMMû†¢R³¥ 9‡ã)(=7×?û|Ÿî.8ï²÷Ê5˜ypàìÿßô’‰uSüïxbú¶NhO
884
+^ |Ѱˆ¯‡l›$lŽkZ}h¨ +8Š[½_ÿ‹—fß³>2ÏE=&H>›†
885
+¶ŠôXjÈ*5°·Uá.Þ1³$ÎÉ£‘ €~c»n–u@ªÈ/rÕÈFiR$ @rVøÚÉÅ/Ÿž}Û}¶DäFëB·Dà\Ý5C°Ìx¨F‚Â]1ÍÁ<·ô—2ùHc€[$ ¹ÿg‚Dϊ™ 
886
+ƺZ¤…2+GìÃ*_Iö“¼ p%–¾2‡&4Š'‹õn$à•©ˆºä¸+±£ÐBœS¶Þãò°jÌ$K[Xõt'Á0ƒ±š˜… BÐ$ö'‘ÃqñÔND‡˜èÑ¢FS x8섵ašôX.ø¨/æót ÷3ROL\ ßÄN«a8vú´9ÎIMq!лFÍê¯O+ÑÙM˜ †yR`'’CR/µ銏ŸfZ5ˆd®Ð {3ŠM\Íò8“´?PKä²¥T ƒãƒ•ϐö=S‚w¥Wq‹à—G‚q'8Ô dãj%k/LWP¿2vßwáí•düWJ¥KX²Ÿ«8±D™ÛÄ>KZÉbÔM¶zYRà,"Zz¡e~îûdZR¢µ˜ú@¶¼ýí<ó“ ¡ê]1]ȼ–€QfÅ¥Órù]¤c˜ü©‹ãÂ]rq¼¼zú'6+rbݗOvTɃ•#±z2AåðÒ±`„mÝsI7k¥0 Ì0<‰Å6<ÌVb¤á>X1•ÊùÛ9+.óéÙ~a*@¡â2o[71A2`ŽWàU€§(ôÏÄe«J9à$íj-8«+fsä¬ñUðÂÃ²Ê äŸDŽ˜´SÅÍ4¥¿–k†X e±ÝsgÖ|†Ü¥lîM €cG4U=÷L,w†)~ôQÙ¾gîÂÈÍXr8¡±.8¡á0>œÜËáhèw#Â%̈́G#viþoš=H=5è¤æ›¤šë[öG¸gÇ/ۚ<ÿ²k*‹AúXb“¸í]D6ÄoE5ª¹ц|´±“üÜ8ˆÃ_Q‰/’›ƒ²ï•†ö!4¤¸Ø×$Xciûì#O?y /¯”öoÍ BYÅÃãh¢¸ T"?W^DËÊRšNjҌöä〔á’? Õ—x‘+–$“Z¦×C˚Ê×9ÂUÚi€ü­Íhqè4ÒμrC?£ž Œ ‡g]°Bm†H4p¸á/Ø<â¸X°5XšvX*±QÈJ=•åý{é#°’¡Õöİm²ädŒþ 'çùœ…»Çí²Ÿ§q4Ț9섲é†þV¼¦Ë +ˆ6씉2®§¶½à#!Öc³‘˜‹ kCèÇQåÂ@qÚ
887
+)[ÖÓõù]nêÙjÇæýÛ²ä×á–Û?Tk„ˆ4ø€¸–å%’#’&›¼Sôæ¶é+*"%W Y÷YçŽQįϒÛ%àQÃÙñÀ#ê´]ÂļÙ]‚¾]%åøÞû)3ÜZ÷â÷NÀ¤ïÅÉ®ž+ÓÖu") XL(T¹žÑ²]Kiâ=”4:áé£q2cÖkb õ iHÕY©}å÷!oò˞”Êd1ʼn(Ž$uD4T°pxù£Œ";@{Ês˜;÷xFÅxb—ð±"úë½db RŽt¯û4’MM…êå‰UžóÝþ.û¶wêgêk©\L¼ (úñR2çÉ>™´Dbp×¼°®,p’ìi õO}r± )'óÁº©ÀTäðŸ°ù}¤ð§®H,Z°öëGOë9»
888
+ß\#œã³Æ Šñý"K?{S£Ÿ¨V*}Ì]ª*éi˜^-c*O/„Ó?ÓÄ$›—ÈéêÆA{†óX8¨ Tr(ç(7`ZÔtj» Ÿ@°DÐî“üÔVó_(£pÐéÌvº² îÜB¨n1ƒ …¡IîhÃ{aS8pßöOPéDœý.­b#œ¬ÿlÿöÝ? ߙ ¸…E4„äáUÒå^Yhéȯ‘;ƒ'Ocm\Vã¶©ÊÀ1'@›E}݄ »çÄS;¿&`k4!¥¾*ãÈY…«Û‡“M]JØ6ýiòa‡@(nŒ2;Nt r)Na_5Ž´2{˜$Î#ÎC%yVMdòZíª©ÖšPÃH09éPoIm§ê‰“âžþ¸ Ѱ˜/Q"9ðy/”Õ!=å8ïÏ<¸m_R¢Qm_‰Ó`Ž¢AÏ큀Ãã™VxûXû%;¼¾üq(±#P;—
889
+x›n"!x¦K¿$›Á‚󠷚apûG¨ÜI|AÝ0¯æò½DQHL‰b•áŠç4lú<Ø$±ü¤ã3SÎ÷&¸Î1¿:žÉHE33Ø¥w¥;«•kt1eUžJ§µ4KК|7{}…u‡výŠ¡CùYöҕê¹K—W² j³:–vêáò´”˜ÝWBiیÇàÇ?˜Ê¸zAœ¼ŽRnK‡ýóÓu̝— ƒ(Kk ^¹M‡Yß0K2÷¬/ŸBKcL=DæD5#܎èTnö:¥§—³¤ÿ$IDB¯éΙg“—ÛYÉGÝ™ct
890
+°"`]‰´;àP^dR Œt¡ÝÈ!ÖZWfwX¤0æSê(N„Öcaþm”äâÅ jÙâGn0Š3¡Y‰ ®ýd½
891
+£Zü¢î!$e¦]'èÈ4í ®ZlNà‹Šˆ£ˆ‘¢‰â¢Ý:!`YbOˆo‰n¯™‘ˆÔ¡ÐP‘WžPŽˆ¨ƒ'Dü*(ä"F~‘*…‘;$ OA_œ
892
+ƒm¨VhKCt@L†àâ
893
+­_ˆ#X ÚBTQ.Z!ôà%…r‘…:МзsHN ŠÐ1jA1òélxP^Ê}áÌH¨C à„Z4-AA2ùAPµÐtU4-@] 6,%}èPO@¯…R€°@hàì`>tÀï*qæۂt÷Óžúª-¨–ª0Ÿ†|p=„»Î¸æ½TŠSa3ø'¢±iÈ—8?¢†~•ã'þÒDçrêãöR.Faî{ ˆ^7<0. ‘øì\Åa"Ah:ä0ƒE¹¨Æé…æbÔrÓ¬z‚ìGʼnëÿšò³ÑÉ[;Uâªç쁤¨ðÙN·†õdÿ‰Q֕\ú —y††(Ɏ‘L*óxmЧ]`Õ_‚#~#ª4ê±ŽDãY‹‰êé¥Âì’nˆv.š:3+=IÁ®SOǁX±Šœt ¬bweOœDð8O”ʍž…Ú‰Q[©'4çQÐ;é“Hp£@O6×
894
+ÓÚ½›ÇÐ#RµéÕ[Y: ‡þ=û.
895
+#6וÍ3whqeؾyºs£’$¨ô智Cœ
896
+Ǜ'­Ý45Ã7ϕº›ºMß<œˆŽc:ª§G÷5žë ÚטX,(}Y(ž°ÉãÙÏ5òóì3õYkƒÿ‚ä-›,ðñ 9°² GVëtN2çIВNÕÿò€ò)\*øSv_¢XvGÍxP†mÔ?[ÞÎ:{¥C,O‘-˜ï´B=23 ÞAGçr»ìV†À¹ÃQ•l”½I~Œj툡0³ÙÁìŒûK}ÿ3©(¨æ¯)ߟðDA7«CJ×a9Ž`ށÂNtŽ& e͈à˜\|¹ŠT€Ý=O¼àÞ!NJ1S§áÓ¨[øÿƲª†8×´u_I/î 4¤
897
+¢Îk
898
+>7QRÁÍÀbå¦qÂýÁreP§d,Ò̀[tp™ùEylÇÐ(ù• Ùäݤ¡'¬šÅP¹ŽžÁ
899
+ç[ ªæCIË<%ƒiAÃ+Û™†Æá>2»[1ƾQ´3ŠR^~ó‚Ao¡ÀbPêIL]Ø'ÃbΒàüa#€dsQÇ#1s)áŒÍ/JðπL)‰Lî(¯P0Íz­|ZDCÁH~gáôS ڀ†Œ~×_&‹ÚœøE«Ý‡ô|I°t¼¨|,Dõ‚þý¡RÈGs#î˜@±äëêz?PK+—†C˜Ìж+©¹7±wxù…𵬅™´ê¦åEÎÐòÖôz’+º†–ˆ–”GÉ¯Ä.‘A@,9Qš/|}>Ìâ5,r͆ÃUÁì1Åc9M=ñ£v2—øÕ+Ë©'¦af½ 0­ÛÊýJes†jÝøà+1á®ØýþQ™<õ½vÉÝBŸ_²–“?vGh>™ a’µØóAޚ…2勳©›§{FÖC•ö0ÿGt„Öx0Ü4̼Øbr›c(7G úúç¨d 7ë8õY©2¸üœòwyՋ'µvúigùÖLíµêTåí°oÓp;$M'ÎkÖX:âá‡<“ýˆJøœ:Ûm¶˜œmìمJ핸\>ÀèC̖É4ž<¨uEaéLÂÊOQ‚æ~zԂºŸŽ<™O ©ñ‰ÐòU[B% N m©'ÖInÑöë}•QÔFXϤRAPH¶cŠt9¨Ñ/ð))žA*5™,%ó¥à#@*ÄA¹Í>²€.¶·cÀ÷P<¸+»V4”Ÿqlš™ü0¨*ckGÔ uՁb ì)b~ë_Âí&‹ÚʬúÏÚ1j€AE}š‘ÃמÁ2—“‡k5ãŠô‚¯ ™5뛿ÎÐÏ!Éû¹ÕØRÏK<BKG‰Ë_gvµI¤ºv”¶¨™Öµk¨ÅÈóÄe»†â5’žMòêP¾=Òøãø¥{)»]y 8F réixœ õ‚\¡XÅîk]ÔEœ¼Á‚ùÇ·7JÌ$É@YSʎ
900
+»’o)~Å5(>»PxûN@äÛä²Br>$KŸs\´3ªàæ7.º®Ôó‚J[K]u4GW@M)c~LßLÂR¶¸â©_Ù%\%äâá­ªBT½Æ³Ë2S¾þäD_7óWÕmÊdf2²> Þ·C4ƒÑ“˜»ñ֖Er+ï)Ð+€„rÜ_/²`X pª¯·ˆxÒ£Ìèrãp:ršd°ÞNL~öé®×ƗØäzLþd
901
+M"–¨°WB
902
+܏I9r2Î3)ÂìjGÑë£%XC•¼«ü|tøü˒e€&ÛÛ£Xcò\¿ãþFI
903
+ØËJÇRÓié}7ŽXѪE¦ùÊ/­a
904
+ðÓ¿¾Û«ôÄân!ôJZLí’+’∦.=wè°"5äÓÿÍÚO_Bé_R~´Ã™‚¤J0&þåÄ˨†ÿ÷¯FPÔw°$ZFß"¨ÇB]ÖìŸÏô•Fÿ„{Îc=“°&•lòžÊ}ÿÈ…lU Ïd´ˆtJ -Ï¾ަO^ÇýTCÕrN‘r„À*VbSpMcQÕk“Cl2ï͸T?¶Æ¦{A±¼¸R ©W‚SÞE.nÕ³lo€ºÄ^I¡íz!Œþª¿8¤#¶~††Œ!eIqƒl4LL¨+«üÖ0Fʃ¤tˆ3ƘåÒ³½ hX낄ì!¤4I¨´h~›KiJå@ Z”ÆY”I¯Õ"FäîŒôdJz‰½Pj%Ʋ8!™zG‘Ðã*e \ƒšÊJ-¦‹B#
905
+É¿ðûbÚA‚‹Oó¢«:æ:Šãs_kæ©ïÇä²C@›ñ|‚ñæjædŒÁð-§(“—ý—B’Ê[¢•‰ÞÎ$èĸ]t…ßîeÁ0ùB¦a²t‡«}Vzáy„§Á$´¿‘M8*Ä¡¥•àˆ =tª¿yÄ!œ1€…IÊ(÷jÂ.‡CéÝãŒW b€„¨B0õŚó\ÎcX ûÓî¤%5×èà3€sÄrGƒäÑïæäâãGP®ò}qç™}5½xQCCWÜAð‡ŸðU,–H›%JCY xÞë+I(¦$1Sñ`îüžâYnb±õ%Áos;ò{÷«Ÿ ßïi½µù¨Úfq †œŽÜUM–¶wYHòcâÀ#{$ç@oêÐÖËό_@ՒzEéÍAÍÒv’^õYæ›Ø´©#@è.´,:N 7óÕR¶bÚ;•㿤@]·$©°.aQ¡‡}±ü#C'øiçåŽc *ö&~¸gBN1֞ž
906
+j¤°“ ÊtáqҘÝ:„=—A»U@GA$4¼JnluÐ.:pjDÚÖ]†N€¸’6Ìxv}€*¯ö3£»Q,09q¹ºF‘¡-ræS<O.—QÎzŽ×ºÂÇû‰;±ÅCУ =WÌ]Ö¢ÐÅݪvš6¥Æ†ûê~o<Öð~#ÁáŠ}F{øï1ÚÚÖaÆ;<} ¸ÒþùaÏ |3Åw}^©Y‡³®ª+~¨)¢Ø¾…Vå‹ë8ÂÙ*ïP¯Y®yËhW DóZ?¦œ;Ä1³¹5f1Wücª¡iÂGÅàý7–ž®êZ‰Çžb>ûÖ;óæ-ZJ®Kð|ù§,0¥ë]©äUDsR”tvi°ýEªn¦Ê@–1x”‰gTõ[å4_UҀl(×n Jp¡ŠŒ²;ÙA퐏6d Ôº=•*®?UZºŠDŸÖé7:¿ž>üÈ\%׊߄x녝2îs ՊË8Á›Ü$MíÌÖÔlbàkÀ¶o¨&f M9Œ¿Ä!3Ñx©—ÏLА2¡öp‹ø*t˜êoËkØñp~©–” Q—pR–£-·b…°T‰|´ºb%qŠÉ‰pJGÍ6JÙíËàhôIø¤I(ª8½ºEYIUžG‘Ä:=)WC$ܦÓA«<}¾?büe±æ–vÕ+ò›ÕS{œ•qÄ«6êqî@SI4z]2*E@
907
+ŠqVwIí½¶L‰÷AP‰’%Sú(’[b²p¥ìa8«+KÕ¹,ÔWˋ>ÊG»ü‡²á„r@GÙoxô5ˆÝMe<vnH=i9{A[PHŒ$íï¥þ™(I=¤Ç䏔n Ô Ý~ØdÕ[ Xìä+¤$ „QÁç ÷ÈMÍߘ¥ú²îŠ;)ƅ(Ɣ²‘"W9Peš¦­x‡Ÿ;\Z˜yûœååqH8TN )·Äi S‚бž÷|¿-i«àæ,^ŸŸÂfXn¹ÒγhYQ*,ä©õ;ü7O¬ÇéfY°8åCjÃÅ9Ko}ðí‘þÑԟވ Ëá¼T|†|
908
+æ”ZGR^ =ê‡-* À¼aé³½ ‹êAÇ~î§Ñã‹ë<&­W¶ ) Ó¤ªAô¼Â=o×ßÀí·HþXçÓÕ.·¸5޲ʿR\ë†FîvTò€˜»5Är¥Ån‘þ–!zÿnÂI'úÛËNÜÙCr͈›{pIw·® 7Æáè§vùœïþj?^콜Ÿì}
909
+Tðeﴘ²×Juâð€^–·èE¥¬ší†YW%z™nŠ^:V»Æ@bzÑ÷èýkàµ+èýJé®g¯ŽDP“ž˜V<ÎLQÙË×Bê¼NëÉ^Å{9èD 2Šiì­XÑ×+¨vZÞBÔõþ¼þÞHº/uôë–aW÷õ Ô.­¸HøCy5…¥—!‹k•–ۃDö`ˆxþWk1î ºÞ‹'а¥áÄyþ·Oùî@¹>,wv ÚL¼ Á:KXþ9”æÖ4ŽWKåí™.·=Ýj·l¿-
910
+³žŒʳ)­wZê¾Cò,“K²Î‹|~µ9;9/DÑñjãHl âê$ÿd
911
+m"¨2YÓ³à¥Ë¾ph$d¯$’œ ãk Ž¿¥mŽÔѽâñÄ9ŽÝi}¬–LOE‘ xÝØßoÔØ…¨ùꚶ¶=ƒÉ©?بg<ÖªêèýÏ:ªˆ(e³Ö &©ó³‡[9 §­¿¹æ 5@ è B‘L\Qéº;aB°†T§Úò`Uâ·ž®èEˆ¶ÞUˆwh '1 ¦Ì"LÛE0¨*c¹¬µeKtþv6è:´ çÎ`ª ˲gPÐÌ»%"rÂÆlÿ}l›Áúvv̟TËêÿe°¤Ÿ¢øû_EÑ緛§*¾F·[@‡Îóc sIµùq?\­þrº¯Œðw}hÚ²~(ˆA+ RŠEƒN抺zùWVrf%-_$nÑTŠø3èŸ(õkCžP¸ÓHå2ôB
912
+U´[;sËô Ij³ Nì¬ØîêV(À¦#O¡é›—edÖô4Üû‰Ô 'ÐïéVIø?`Ïþ÷}ŽúÕáBoѨ/D_{ðôžGñOáóýKëøŸ\Êûøs -œle±Žg"%gòɂ'V¥`èÙ#FàŽkIÛm¢Ï0í⌊£k®†@¿Ú¢XöXj•Î«Xgµ|hs\&û%C‹¹ä¤Í¬E¤wÁ·tϝ‚…\BÅ€êu K.>ûMƒ¹èòæ~§ßè§ýbp“Æ#¤ISuÏ_)óü¥òàካ»“
913
+¨êYïh¨¸[/Š1ÐJZˆž’âWRv]ÉÃRÿ¦0°áà^6ˆÿ3°(€.ÞðlX ôҁ;Q:c™bʃÂ_%aqî‘
914
+^ÏÀs12ã¢;øÿ úù~©•{ΤK\¿J8­Z
915
+ú+1h¢¤P智I!âjNO´7Íl‘ù(ÕzM‹Å™sbïýiU~ÕýV†¢QÄ õgÐQ0toQpµ_\Ãóä5˜{Áå‘ØÇœõ ³|c¼@? ô÷D׌DÝy_N\´½7J,÷ñ¨æ^¸±Xtz@æÿ'S´\ÑDbñý"Ðÿ Óþ±Š1 ”7¸äo9MÅÈ«û¡7IøÏ¡ýf£¦Æ<(Þ>ø*0Vå~¯:õ¤
916
+ýÎ4gþó Vô_‰äöÌ°¿fáòPÀ†š!M2 á›wÅO;f·Q rŸs¿‡Ò?õ_Ê)O"צ‘ú»¾§†ÚS?öÞ9î—<֍Y¥)Õ%VÍÊb —ýêTñêÆiRMPÐ]IXä‚Êö±Tý-\ÂÏ7¯<ãÈßÎ,v¿ƒÈ¯X~e±³~#¤µ‰í‡úƒ&• |ffffé+¸§íi^yê¡?‰üÊ4Zl´»Vö+SÆ=_×my›µ-ÿÞ叹˟où§™æŸsk)f÷­ßq=§¿>£ïÁÀX¼k/}íÚs]{ ÿ8qá#ÿb{bŒ|õMÝżŽ¿‹Óïx1ú¯ö]ÆëïÓÏ[»©¨Êèßk7Ï×¶öÚlìåýÌÚˊél·´»ïqq®r»Û-5q·¼è̋û~mÿí¯íÅÍ|{¶ëµuµ­WdÄSgL[ÿ·«[m=¿­çteÅs]}}æ_Û÷õ®ÞëS¦s=wkw.w絍~ºœ‘¯q™³'f.s„ɁÑ‹{-W§nnfïó*¯®ãÙêv^ŒÛŽ÷zºhÿœö÷‹û¾¹3sùÒu-÷ûûÝ»³S&&†ÃØ·eg[ýɸú]Wß Å\Þ²[U|Nýìe1ì}Ǟ·û¬¦¬Ú¼,&џ—ÁÌÈÍlkc0¦Lg jæò͔±AŠ1‚!BŠ1˜ÄÌÍÃHˆ\ï|ÕÝVg_¯~ví<=GV^oßïÌedÌ~{DuÌwvüGFsÝænF·][k÷ÕfKûG[í̮̫Ã\l<ÔÓôL÷ÜLÓLÌS½ÛÌã]=ìÎWSD\ü]dLýö¼f´|ÏM·6DÃTåÍü4Åç3å^?SNDSN\EÓ7\l4GÓ÷GNÜ<ã5³³3oÔwµ]ŒˆÎgjßh}¦zvÙøzþ©oŒ—Þ¯þ{臘}èçoØvÖz¶n÷º·Ÿ¾¹žËzû·~§‡z}¶œ¯fx‡÷ý¦Ÿ‡ÜéÇ«inØ}«ßÜÇö‡—¨ë×슆©§iì§¾ÿÖ¾íë¾ûçËø×‡yÓ¹m§ìÞÚüެêÚݘ»wn¼Ø¼YÿÝÙ9SÑüò¸ÿÍ?‘Sùôµõt½Û“Ÿñð¯Ï QÝP»±‘{϶ùš»™[÷—›¹™¯í”‘[Ïÿv{×׎Û»÷5ïŸ{5ßÚyú¡æ¢ev¢)Þ¦â¥îï™!ã!£â¿~ên³›Þö¦©f²©é¥6>Ÿ±æõrâ#ó/·¡ñg3÷7#³3Ÿw£{/¢/ö¡¦ó¢Zö9/ÞãB´þËvTtä_76FÃlU>ìKëÃ;óÿçïD{ÆÖû…kSÙoõs-ùݞ¿—£+.>ŸbÚ_ï=ž[¿Þ¡3~^.E\[ÜÕ^Ï¥¨è¾êَiz™Üg¾8ñ±sQ}ñ833U÷Ý9;ÑUS?ÕX¿ÿØßVUUWo5uqת>2šÿúÊÃÿK<\þÿãoû½¥‡z˜¸ºmý©þïù‹#Q?W½Û»máçï-¯ûÅŵ÷÷÷øÇk¼ÿÏ»ìñìßí×*¯]û¾Ž›º\µ}­û^.ww[×ŦÈÎêè»Ú—Í‘}™™Õm©£Ùbuß;¶Çµéëœþžì·øÑ³w½/ó|4\æl~Ë0×÷c~*>; æåÍÞìûžì˜®æ1qùòÖ]|Þqq£Ùå)/ÞÅۍ‹×U[y16"æÊ… w1"¶r÷:îKí]—­‹›™÷zýÕV#¦.~ÖNG7]ϋùÍæÜ{Ëùð±›Ó —ë.gMwã>G_Îk÷øË}ïÙÞKœg˜¾¬»Q ùµ»uvûBäK_Ùø)Ó+û°W¶jjc.å^
917
+£—6b>¦þáÚüÅø‹•]}©þÚÚ6voöÚÆÔĔyÝÅk¯¨ë{¾ø’¹¿óüµ»—£62jwb¯oL[¦ÍË×9ß¡åBï…ì¸0SF——ºb÷ž¾/]½»Ž½¼Ö™±›MÏ‘“ÛÏWoï~rÛÄ`w;º/V_íî˜Ç¾æŽž½Ü‘Ý–ýV¯¢æzÇL~ÇõG3]ö˜2æË6×­îLäÆGãç½Õ÷È»ºðr»Ï~ñZf£³ïÊ]ù˜KõYý¹1ÿÖ>ö®}då¿õNUÞû¿GîGL[Îë»×ÿÑìÌÞöש/4–¦ùÏ»òíì¹WZ¦LÚRs5ÿՊ¸Ô<—¢¥å¯6[»‹»-OµeʤãpSfìuyçy·}Ëù–ÛÚSÕ]{÷Èæì†¹ZÿØ÷W_:/¿Æm]–ºé» ?õ0Sæý®}ªåB̔хè»m¥³®ÄßLîåkË3eöùv1SfñÓÛUã'*bþê\ÖlôTµõÏ5·îň™2Í{Ëy9š=ÿzDü^h˳YÏÜ×c¦Œ™å«a_¢öu#fâÂTµå—‰¹‡ê™)ù4óui¦ÞÚ̔iÎä_œ™2}ï‹ïþruÞ[¯ÎËnÕf³þÌÕîޙ2n˙O3e2j¦ *26.ª»™±¹þ^.]~ȝ)ƒ¼Tów©æöRMݥ؞iKWï9®Õ\ëwÞ¼ØØÿ]áckr¾öêæl¼[ý©«{÷ñ>}5®65ìM=moÍ·3„±¾º½‡ghïw¼gþª¯y¼ºmÙæjì[­¿^ó·=¨906Èۋö ÍôѲm¡í¯³Œi·Döäåf¹k˕Õߖw·µëê}øî¿ç£W§kç%:"cêzþÚn^hù—é¸éš¹xˆËfن¾¸«4F;¥ŸÓ ŸÊFTÑHaå† +95fˆª*¬è Íí8ÑåP4F,”lX|¬`óÂäGõ²$u"JOÕ”ƒ„B†Ò<,1ipƒPŠ(D(21m ÃPå‚%¦:)½ )±¹aƒåǩƈ%;nVÜP¤¤â * ?$R€n6¨"TÀN¨|:¥ˆˆJƒÓ “ÔK“ŠD& r8r
918
+á^šðP!€pܬô¨jŒ(¢Cú KN#„ †*’T.F€˜D ñAj’ƒ´Ò‚if…š™QÎ
919
+4& ©H$ñQ
920
+á£Ã&ÄOÎM!;lZ€zØ xÁǔ¢!%–5¢RQœš!:J"€z˜ZzvBô两ƒá£ÒU³‚cC³’Ãf¦ÅˆŽRzL%”¹AÏ €ªN„œL@ùÓâ“cÄ£bQCPå†!Jƒ$©>¸“S8$¡J¡HÑ¡\”ð˜HÙ)¹(á1™hÒSÅX€ÉÉP@C冡jD&$;”‹˜N8ñ¡@ô´`óÒd§Ò$ÕxrŠ©Ògƒ”TL€É©šT)¦øT/C?ªN|ªLvL"†ô ‰ ҃äb‡¡’U–àd@勌œ^˜ü¨ZŠäجô(Õ`!F Ÿˆ$;nF;J5D6J0At š)ÁÑ©
921
++ÔHD 6D<ÑAâÇÌH‡š!ja† Ñ
922
+6RaDÇ —(:4.MxjX‚ܨÂG‡ QiÆ "%˜ ªÑD$Jù Qaԃ£ÂŠD¥N™ €ˆf4ࣞŠFˆ!9l´$É¡iQ’C#B(ǦeHÇÌ
923
+"*D6H(AdJÁ„•œ2VpÔPaåF͌Q &£74F;nh¬ä˜‘!º‘q‚HŒˆnN0ÁåL3ŸÆ$àÆÏ bÔ/æb4Æ-Æxb,9ÆùbN–Ø&c1CÁ¨@ŠI¡$†=†è 0 Å\Ì€¢ãÇ熍Y›1bl¹e`xbl¹cp·ƒ4 æ~nЈÉñã050901,—åó¿åڝ¡%/³ãéz®ôÞõlÅÅ3\Ègè˚³¹››{›yøyÝa´û¶öjï•ý—™­ŒûÙ1°ùƲlF\©¸›©êi5€Éq»©ª©¨ÿ900Zsu_þ:=å^—8‡„˜+5«»m²þj_׿îÛÌÞ6õ^Ç]_˜¾p3eº[7ý—ê¦nïn&§;¾6//¯¯5ï-oööþž¯ÖÕë¾|3s}‘};÷õõV·óòîÚÍîí¥›f¹X7s?7·õÖvu½¾æ/oõµ¬ÿ‹YÛúw±öZ]]ýµšÉkU7S3o¥>¢ÂÈĕªžš~Þ¦˜Šš Qµ]õðtOÝÒÕm¡ûª)¶jš®Ï4¿ýÌÏ\ϵş©î™)³ž—k{;omçZÎÜ^ßŋÿ¹¶×›×3;YWff^2b²yúúÔ{ÌïµdÌÄDNæÅÛu˜{¨z¸·‡¹1ÒtýªêZ¿Ü^ÞËO—ßþ]®nç×՗l÷˼X×ñsùl÷PqÓn±Þ®&^â%¯½Ë{¿äæ^k—޼ì~½eZî[¾âú{˔YGÍL6SDk\m‰Þyºº™mnñâb˵k¹«K­M-ùzת™šæb´=˵<»Å¼ÌøŸÿ¯×¿½¯ÿýÇþµþ¿ÍØmæìvßý½ö~-?æ.^6l^]«¹ö7™÷“qíûï~·åê¯>ÿê VK×Ï×mÆÅ>41ɤ€R BuP¡*&O(&Àä¤BTLžP¶‚n²(À3˜€‚)T6¥Ò@‡$ ŒPÈ0ÄÔ"F\HIeBJÒ (?&‚¨ z¢b|pr
924
+R(<ðBåB‡$”
925
+ŠP& ©PÀðcj‘CPÅâ†"¦2øP,d8RÁ0RáÓÃô2ô£B!Ň1d§"HÉŏ ƒˆœ<ðaIE€¼P-P¡p‚)Ux¡ê ‡%U`rÀ¤TXÀ…T/ª(©DA”J„¢à¼èAˆZa‘jDNi’% b¢:èIõ¢‡!êKL*¨ ©\„|˜XÐ`„áRªJðBÂ\¨TÌD‘H¢C"DÇ´b"§O„P#€z˜\Œø¨RHR½€PÕM*$;ÔHEÃÂSՀèa¡Æ…ÉŽÊ„ @¨ÑNU#‚ 'ˆ*šPù¡NÀÐcj ÒqãÂDǤb†!Ô  ¤—'=¤S‚”^œ1µà!ˆZS
926
+~L/OxJ!‚X°arªa ‚CSBˆ‡:ÉÄP›–#:nF9H5D43R`áa4-@9H#”ä˜Dí(øãf´ãD3Ê9ф‚æ%(‡ÄÄD#‰!Cdc‚Œ‘‰7"1PÍ(…QeŠÒPb
927
+Á³ƒ$bÈÓËÏi… AT !
928
+Ä $ 86/L~PÄ@„z
929
+RzY¤DâˆêD *ƒ”˜2À Õ˜PL`¨*ÑÉEh‡ôò¤ç&J‹Ž˜\ä D@O(üà H¡BøÁJ?<9qPe‰ée¨‡r9òƒzQEIÂMp8¨’äĆª2Å‚žP xà ãÓD%D©^è0T…(§:%€^0yP& *H(SˆP*¨ ©`œô˜^˜ü `–¡R¸ðS©˜2äÄ¢† *E” *… J’P/ª(©À'Õ!¡
930
+ÁQ* r0rJñ„È©„)DOÒ#>H(\*Á8é1¹(Ù1½0b2!¥Çt‰Oe¢IOÕâ“cjéÙAzY„Òà†$'8 å¢T#ˆ†ª †D åäANª vPR± Á¥bJŠÅ”"'zpr:P©°*& tHBµÈ¡HÅ"‡!”ˆ!:7"~z0ˆá§Z1%èt"Š
931
+…ª •‹‰„pDè ÔHƒ©E IJ.IvJ-FrØ´ÁQjAÅ *A'E|T%’ðTLrbaCPU¢‰È
932
+7£Õ KŠ¦jD$ ÍJ 43VZ˜¡ÁäTCBH‡ä2䃡$ÇT‚‰ªå'çfÔ£Tc¤c²Á"ä4C¢ÉŽ’Š )‘P¢cñ(ͬè0ÕXÙqSc%G ?84.P|ܼHá¹ QG¡$BZ õ8͌r("œ+8lfZˆè°!q„‡Äò‡fåM )D&dŒtL6@üàԀøÁ¡ù0Ѱ1Ù1ä43ʹ±!*„D(0 „‘NxJ/.¤b'‡±ÃÂÍËÏI… E(SˆP#ˆè”P¸TúÀ&'  ¡Há!¹$ùQBeˆ©ƒ–œ (”`B¥€áÇ4B ҈GifÔã4óâ¤çƒ€( t* `SH
933
+xÁLî‚J ü…úKª1Q/OvL(¤øP-r(R‰ð)UxòÀ‡%•hR¡xÁÇ䢩„©ÅDN T( †S79¥2¤J%ˆ2È)Dˆ;lPÀðcBñiĝR‹%;¦T‚*,0tz±Ã’Ê„”  %9” '?&Hrâ@Jp2°Iõ"$„ä2äƒ"a„Ç⎖+ذðÀ© $GMŸ7 €à¨1ÑÄÇ´"†"§SœVÈt*$䓤ÇFVˆ©Òçƒ*MpP(8 ` Ê >8Á9áBO5bÈN‰DЏRKώ ";%T„Nʂ¨o<HñA½Ða¨Ú Ê‘ª…HDvJ'œ9­ˆ¡ÈéEIN-f0rZ1‘Ó U1`rzQ%Õ
934
+‚¨‘Íhljæ¥ÉR‹PTi‚³Á B+ D½ ñœJ,Ñ©Z‚rn@9݀²Ą̂‡©†…‡šiA’c³ÂB Ñ 'ˆL2N`ùÁ©1Ú¡jŒ€h^ ðRÔðS:A凩¥È ÒJ 6dˆf@À"“ XzpÔHAƒi¤S͈fT@aäÇ‹èƌ+943F;&!‚Z qq¡GK”7#–ô¨Yia††( •hÄñ(Í´Áa 53âQ¢!¢1!Q…‚ CÆ
935
+Žšž¨ÔöZ ‘ H@$€8$ã!±LV¹€sj:ÖR‚0@@|‡)Ìýë¡ü£n \»¸ÆOô_Ùÿxå×ý§.É_m›®
936
+7ž¢• psb~¬}¯å̓™7“8ü™|  È'å„#·¡/Z¥mª{
937
+ÜǞ¯…IÕ4ån`oˆÛòÎ bö¶w&€d‡[ò—ô_ƒåˆÉ[JMõAf£Õ·
938
+°¹÷’}ãH0Né :îŠ̛¶€g3S'
939
+sâMŽxÍð­± à ۘ .Ç])LٔU?_¼ç…CòC›ÛæH V5K`?÷<òí o3ZÞff7:ZNvOÜWi.¢T0R ‹ë'!ÌMŵCޖ{l-_qÿˆ™[RvP*/£HmÚ@ÎõŸõ2«wú܇¯9q–„{nÛ|~é–ë¬úÜ]…¨{¡‰›À’ɵʸÈe$¬ë—™ðEž§V?G•C£^â·È³Ô÷¸d•QõE _è~l›ÿïglP¹§tÏæ:9¾*äòi%µØ/Èñ~Ë=wƺ }èZ°“¡ŸéQç‰hË£ ¿Ö·ÔýJß&Y•g+ÁÙmE‹‡Q„¯v†ÂŒ9rn:tTyn¡*ÑyKÛa£ÑäIRÊöúÞ»* ”|)"®ÒåžÐÇVì¦PtÒD؆Ò,tVol~,Yææ˜Œ‚B·ÁY½&”F@ûï¹ý¿zpß9T!µu€ÄZÜ XúZÊЄnÅrÒlðaì³]ºL'„&°³c~©— ù“™‡r»#“n³  #=
940
+žÉB
941
+Õ*BácXhDZÓ¿݉ÝÁŠþº6ØÈxe.ɝ#l¦7ފ í£GS#D“žÞÆ6 “›9'äO˜Ã(4’jô>ÞªÒ×ݛCnV0Š„ë¾H\1ՊW˜bV¾²µ"!À–7¢v¨Op§@§ ò*ùe[,zïfg™Ý)M}ÖP°˜ÔQµ†—˜¥$®Aœ²7—†ì£%v’*œÛs‰¡QuڌBà̱3ÐoÖݙV‘—lB_p9d}¸´
942
+$֚ÅÓ¹­³aÅÅæ³N2¹YËAl½îld½Í¨ßÆ{_§¾¬ò% ,5@| :W 8D¤Š Îð˜7Ufû•…øGuå‘öÒÁxНBÙx}#¼×Sî*07ÚñÄփ-((2  ÎRεÕÏ1t+IÓïBcj5‹œUhòCÔ ±!jÖ \Ð'/>’²(¾Úeqe»èÂëŸï£žàõ2”6vb‚ã!‹R×Èz’( µ±lQñ5»Jm©hà‹)I֌¨îLîw¤`¬by‘%÷.hîââýT$ÖU-ò_%Æà³ñz©%¶=-Úê’.IZÑw뎝 à¨M×Õóa6n9õÕþP„Cf†æ“1QpÀ#g7V€²¬ž8ñ
943
+GCœY§v̧oØ:Âð¨QJ,É>޾#Kd,ÏÅW5ůSb£À‚Ôs³qçëÒõáýPµšÅ?ÁÒ*BlÄg[nòÅÔ;+ˆ°´ŠbIÊnïLéè_bÄ„yaò(|é2©²Îí5¯ eYhOï…;»]ÛË͊Ô,äZ\± m`Cþu‡_ðǍ…ìíðèåK܋¸Ý³¹7föWj¢Æ2:9Ÿ8h+՘žs(ªîC÷› ÝÒ« ÞW²,IÚ±2pDPÊ"»ÈÜ%„Ž8†DلÊê2½3òD=Z¤°`Åq–·ž+Néi0 ¤¯Ñ0e›Ú%‡5³IY•ïI;ƒ;¦è]æüùµ…ݸ¹±•·ÿ5¼–£ÚùÇÕ‘Kˆ®zău&£è,Ml<؉Ê~oϤǼI#dOÕ܏Á€õ«¾6“eÅF¢9ÿ£º–1ºó‡”s5•~ãuŠ ,0 “µ¼õÅÀßÂ4—€f™$x•€´°•ˆG<«¨–ãÐl#ÐĹÝ8ÚOLÊÆFâ›
944
+xàLœ‹iB÷ ½þÓB칪À0üYµkd:ú‘Þ#n- ÔuZ…ÏWQ€¯Ï™uÐö…áÿgf¤”6ƒ˜[^s{$Ö5C¬÷
945
+›™S™Y4$,B†Ùž÷B2ÂËV®‚¯
946
+ÇP³Âh8mJÀqê\¿ ÔW^Iqä$Ý#C½ w‹œŸ
947
+”ëèŸN‘1ÀDc&nFÍ-Ö]r0‰r߸ >ø¨Z ¥-$h£'ªçJ/ŸÃÅïÅ40€ÔÛY’Ú:+0Á¼Â¾Qÿïc!ò ,¦\ÝF¶*ÀAš~[3ß¹ßâûr)ævæl£E_¬¦¿zì„ç2×|Ô[±ßt÷j£Ì޲CÅoe¹·¯:•á¦rÚvxºç5Ëë4¯$C„¦65´±t”Šú:çˆóÀ©2&Di¡Òðœ0rúh½!C­4ÂåËv+Ò»v óqåèç7´0`t¿p/uÝ¥>f4h+e=9”ŒD×T‡Däjƒœ c£þ²¤¯ñµñGmÍÇâ†ÒŠÓiSØ~Ό¨Ñ¦³ñǚÿÀHF
948
+Ë =*@î2öCÈй‘^Â8‡)e!9N„ÙgjDͱB8®sÀ‘®0P¦©ñ”Õìî>؂;yÌ Þ>͉aa/F|‚­Ö©Œyø»p# ›°4Ǭe3Âo-mîz%¾åotnróR–2 gTž^ò侍»,ª¿Î»ëIødiŒ™Qµa‘ÿ®œÎ²7 Ι¿Ÿ)z¸´÷Ëòf¶`2넋‘¿ÏÊáµÌ3)Þ%h°£^…Îñ.Žy£†M|Àñv†bœC uŒfA3!}%¡cÅ&µSó·AC™oÏtÌVÖ2³J¶ßçˆ â$ 6ô µ©‰…cµJ›‹ÂR–Ñ÷„š\@ÅC«ÆäéÖÒ =º!1#ГKE±áƒoÂj:,wuQtp‹‹03ŠÑ)‘Ù…:â¾°ˆµaæ8$RO•Ï@ñݧž²‰+>yëÑ+üžÅ'íÚ7 á)N\…3  „ÚLÂp—“V™?‚hi¨FˆÈ^ºzQÁƒóQP¯þ\t‡,SWð¨º,µÄä:O  kȰ›µØhf¤±"߯½J¦!y½8ø€Hã¾ZbÁ¶+æü¬ø’^ÌóÎ/b0—~¬hZ+Ðdy’ÆšÜ!Ë£>؞æè@Ÿ²EÜhÿªÍ¸ïv&L6»Ö•sú߬?W
949
+¡÷„è…[ƒ»ß¨˜@z&âΕP®[F˜aÇïѱ“Q'Gœ={óÚ[ËÈp®Ê×±ç|2¼—ð*`(’æ44oý›¬@'‹Ó¦)
950
+Ó)/1.IDÂ×#Áó͓fW»O½¥„óUKóð v}Pjˆ@ÎS¡Dñ
951
+ƞ‹†»Ñ/¶¡jl;ö|¸\ï‚â‡ó@Ÿžÿ½z,;J;¨ÈH:i&M`¥q\C¹2õøöñ¹œèYfˆ=Çc}¾³ÆA¿ä·”RGÉNĂ0œœˆõ R󋘉°h™‡ *à¦)fâŽê£€ÒBAå)Phd5H¼Eê•2h€iڔÿäÀùfѲNa `ÅIîÁ$äÿÐü¨&6ÏÆ˜tJ¦Öøh-Ä;³‰e ‘ÖÔ cލÖ!æÑm˶ÊWq%Xnàg ÕcŸV)%æµGê&ÊeƒáãZÏ»úŠÞj`Ès,Qq„~&‘ÿ+ÝÐcðÐBm,gü¦ ŸÃ¹N”DHÈ©à(·Tw²ÙD¨FrÝÓ¯Áœ)]‚_ì-S¸Úp‚º_Ù@“2=}N²Æ:`ìwñn Ö#¬ß Á».=æBæ À#)O‰ó|¿Ì cã¶p&/†¢…i(ø¬¡e›yT­kÈ6ÃÙr³pË#Œ…¼$ÔjýÁéZâ«pes*dVMKÓGn¤c,­¹Á"ÀƘ©fÓ§xæò¿Ùåóg„F×h˒âAwî+OýTø¥³‹dŒ lš2ˆß±kqÓv
952
+ê…Àm”é+x#$ŽäµÈªr™ûccæÅmV3PBÿ–‘àlÉÉÐQ‹ßê‘<Kpñî‡Ú·ì”Ÿ°e‹!ùi¶`;}oVc½fÿ€‹ZȬ ÚÆÀ>®’îû£Å°‹«Ӟú4L±…RQ­Û ÉqqÑâRªd‚Ô°³oÇ<µ
953
+ÀíÅ9 è€<A›ŸïP\ ¸;û)òxJü­c…ºoÚ¨bÝFŽ‚ý[¨V2"ÌN­W$f¹òbäõCÌá-p†Äk¸áù¿µÙFSFÆ9mµ‹:dOÂ24}`ÞŒi9ښ¶Cò°)Ð5‰iüÄøVòªÈ-)°Ø¿ŒÕ·ÌDêš?d»R½! Új]¹ª´äöaGÆIÍðôªJÐ=:uB éÍ_Þ5¤úDsŸ‘ìk !¸^ÃφݔlQacijó‘n\¢)y#ë C”6z&~ø°K4¨ù™ ÏÎ
954
+hÒeKØñ?™WŠÑQK·y28B¡H£àFº÷ÉÈÂÒÛá‰-ÿ«&*&PåÃ9s‡—ÃO, ¥<ÓùDO&v£ÊŸ?æ¤ÿÁ±¡ilEîLҕBG’¢¯ÊÛ BTœgÜ"Gó‹*<6 ¡eœ|$jJ%CXi®‰ï “¶wÃv¬ïXþܨܙw•·=EAlˆ\9g‰«Sež©æXz?sE¤—ƒ©‡‰²C.µžÎ _œ¡™†‡’·ž¤†óþQÀ¿h%8HC!/¤ÀSËô…6nÂEÇøô·³çÜR0<8â”.°—,½?Cô¡‰+f‡æžC-r endstream endobj 12 0 obj <</Length 65536>>stream
955
+¸%m }pwŒ¥ÍÂ6ñã:Ì.üYï(Ì%<¬VÃ?E”ÜÄ,l…ƒ¶pc$0!=ÇË¥N`[A)‹¿WÆN“M劑²ˆÉˆºÍzi ¢¢‚Ô%u™a°´&È[ÄÜQEôŸùðÿ'w^%9aÞðƒ¸BIã:6wòϼgþݕ4¤8ì  |ÈéVwo‚¬@›z´ú¶¤p$¢Èbú+­`Z~<~ TcÍäh@<ƒ°ÈÀŒз°¤eìÓoíw&iYê*+Ó¸›}ûŒ32Æ6¾0eV²y
956
+Ðnƒ½¬§V¢É$Á‰[Ò>¯ãÍ!ÅD*‘õbŠ|eF#®K’…JÌZš&vsüË>µJ¥†ÌC×(4´#Uã­¦I„Ç[η“™ë*Ê# áoÅÄò…¢qÅp%®-*4ßÄç2¥ßlÁG½Mh½sN=ƒ ¶ [á\ÆÒic4[û·íOÑl¬¯@®(yuÝ1ýr }—Â%T¡îNÁ.ÂÕÓـ'^®ûŒÜ€IpLíöj?Ô"V»ÀÐëàŽY|Øæš·¨Ðµ®¤ç¸7º+”½ÁÀö_Í ã3Ãcl¨ŸZü°:²šc—çqäú8QÛR ä’ó[9ⅱ_ïÛÃ5F;Hïè‰,âÀÅêÜz®ÒõÌÀ†Ùb@ÌV˶5£¹Oà«ÑV@ëïawâ?ÛC?íoƒ]úp%êk¥kÙ,”ÀÕ¨ÄhÃfÌOÿ7y+gìóÁ8W7*Øh¼*Õé Na>~êRcð”݆q!@|Õ0q/^žÂF¯‘ày'\XBpœQ§$OÞͦjÇ@ɄÖìêµE`ãÁLsŽ>à­Z¼˜ØVñL$(H8‹Gk@E€y£¶ÀÙÐ9%æ.\úYjémDÂÇwÌZ²¡)³ð×A¡5@¸%@'jþÝxÜIŒf¸-Õ€4 ”̓7ïkA¨òs€ {dÒ Ðá°ÿ4ÉUEN991sí9£5¤_Â;÷Svï`ô‡¬u(s§ŒƒÂ@ôd±;$ªI”©ØPd ’~‰YCîÖûšA{á‘râŠÄdiæQFTl¹?$¸¿@&7/z0Áw_9þo⯂á«zAüç¡(óِéyû®r² î­>õa²óN²†­ ¾4„êہb"7… H(.’˜£8®ð¤gÇpÐ#n :·9…L\'sÙÂt9/Í»‹¡öÜÃ%|ŽDºÜ‡¤¦q£Tx$Ò«”˧6p˜Ïs™^¬;¨ì™ªå’VýÇ äç †"²øaÍ­Q’úã­> jÔØ3ºìuMjcD‹ Â_ŒïÞ`ât†¼bšq@?v¬Ú룦Šm"rÔTÀrŸ¡Y¸BÂñ¢ü¦±lR-¨ÂCÙú¦Znn°oëï Ñðºµ(š÷¶ˆ l¡,·Õ1ÛNÿ6)…ð?)ӓ$Þ¹è4ÔMv¡\®øñxaòHØ&v<–¦ n{FP ˆ*|ªd™6òÒÅ×+ òÒY^tœÒK•ÚIBn‡;K…R~ —G®:Ò(Üj§!*Gª=Lë™ahÓ¨]͍æ€õ1AÈ\Ñ¦.äMƒ˜ÅdaVl0ŸÅú÷€šÆå«fâÍïvÖø ”Ѹ_\Gˆ¦‘Yõà”QyÆ58`zÇ]¿´ã—Òšü¬ì@‡Pªú´Òdèµûͧ«Â¯äús𶌜´èîŒÒÚ0éHñZŽ™ 8"ù´úÁa1ÏÖÀ’Ë|FõJ‡êÌÒJ1WïúM3X{¦5™ã§iY€›šµÔæð‰©’ À¸áà˜éï"`¾ìÉÄóRÿùˆ
957
+̰¡,c‹]ø¥
958
+=qFð_D®è¼Ž  å5‚¶wìktüU.nH2—ÁVD-ßÜ Z‘=Ï=DÚ>î`W4°Š’Âü ¢Új‚¥‰±\î–këÉÑG뜯yVÄ8tð›nàځ3¦‰šÐßZ“Ï…ÙêXaÕ<ô 2ӣ‰ÐJ‡22|3b¦™F«)ü¨sہ SŒw|‡üµ×ëŽñBM(>ˏ»¾ÊFg<·êE¦&})ù~ó¢ÙU=¨ØÏÛª‹ …Çý¯ˆå"@,-¤ï##;¯ŒS>š˜à=_„ïMôéŽç7ù]%›Ž(>:w#`)ÿw­ÜGý\jºEN“b¦zOðâ¢X³pÏÈcáÝ57¿™(Þe“L²´~¸~#_ˆèè8hv^8NtBL± €¶Ùµ4%¦!k‰V¦Ža±XÏ×0|°~³YÛñæ‚éè'FmK2x6í‡òaWþ]œ¡Š>1¹'èÁ8•&É>*½©Æü®OȬ¡düߣQ 0îÁ•×òvš–˜ÌDê†SP›Y0çCbªšÙZ\;td†æÖ©:;¹ÐƉߓèÞlKÑ¢ºœ<§’ñÄ ÏkU‘x|Z¢‰¼ŒÀEöaHzp“~X¡©+o“c3‹Ž×¬¦–]ÛÍ/ÜsGáXã:Ÿ]…R
959
+z˜ÕµqE%>Ïdû:Àª£ß¸¦iÀ FhÄÑÚ*„,(.¼:7½œO HhBG»<pnæø(¤jä}×Å9^˜Áєõ†ñY´»Z&нۉD¦Õ0ø¸k¬‡˜tߨp~´Ä¼üõ#álê㠞?Q"5) =”ô˜”‘# ½\Ù:~FL&x‹'Әrû†€ŸüŒ­K_ZTé–"Ûýœaá7&±±c*6¡r^ã.^œºhÐñoÞ1¶€Ùªk~^‚Ü×ÏcŽòcœ÷
960
+'Î\jTI iKäSTN¨Ü~‚ ÔÒ8IʊC"MPQ††›èr;Ïgóvu±Œ¬fÐýS$\C^Ü8c¾ŸT÷$Úí SUt!7y^!Öi…0´BÆêrì•X÷Œ|Æ ÁW.‘ÎKæ´Ø‡°,šXO¨f¦1à óo¼¦oÌöš 7Ã^®×|RÏ_ìàU@Џ=†fsÕÜÑ×{¿ÐN¶$ 4–7‡ÛØÉ[— ØÙS·/ˆÑåü}a>o¦s[jæ{t'…[B£'¯Ï. ´¸î츂ãå†þEmW(N
961
+¥e¬ XŸ xG@$à^+
962
+e¯y
963
+.Ò•4+Ž­®±.kq_¹t×Ñò…œ=4Tœ²{23¬X`Üw/±üZ5ŽñV5ÖɰÀÁ֘j‚Uðî`NŒ£¢;P53…c³³ç¬èù·£;7ƒGô¼4r‰ï+åN*ŠLOíŸG°EF7¨Á…‘j¤a‘¶}…œ¨i† -"b¥¯PÂ<–‹ˆ·Ôu%ƒç¬"[ýÛä.°Lòr×4'f`ëz$øGb°—§WàÚ5Ö$äpÓ°Êò[0TL}˜úË-ÍÊå²TºiÉ!Iv2‡ÁÛ~}S(ñ<ß£ôYçqĖêu8•9Pðå¤ Uۖ•h"y»Þ” 8ê*ÿf|Oÿ ‚¦®lô xRR'6ð÷
964
+k£·®[Ý\>ܬŽp.ŽlR¢®€wª4ÑÜÖ«2¬èJâ0,
965
+. ]`<1;ÈÑy€Â…1{ñ¼•Ù(Z³ÄŒ&Oå$h3~Æáˆô“O6¹¤ŒªŽ'm/«ƒÒk=‰ÉsVV8åøÕp(Ðl˜&Zt­qÊ¡Ò#P³u3xdˆ!„’2’3º î¢bI‹›¹›*¸¥±ÑÔ\DD€÷¦º¤Jp‹h²‡°lr1¸è‹`z¾Íâiø8Ó+Ÿß­hö¶ Á7“vÜZ X*XÄ+Þç×
966
+З‘¿ÄŒ¬ÔzËÓÌm`À9?š!Ɍo²gâ_ŠXɜ/k£„#Ò¯÷ï±Šõ1à"Œ¬ÿy˔ØÇ[´ RÀ™Þ4‚b7J̘Mî."Ÿ¾éÛ¯)ô–Ž>·³¡1îÐÓktáÙ|ª7Öo})ZÒþÐüÑd3.̯|Ð"LöF§©màÿ–äèT»ö_¢âë&‰9GØï­¢ø¹ÎÈ·‚ g!1ð1ãæÿ¹Z¸K†à€_©€åÈÌËvMRó:-FîµëÊÄJÌùÔÆ]‡ŸVä¦R ¹ÛòŠá«ý-q¤ÍPޖ™ë<ËÁûÍ.Å:‰àVþÀ¤\¶ ÆeÈP¯'¡h0ÒîiE9$&®XØð¡ß­ôf"?]RSÃ2Ô¾‹,4bC¢¨u2ëc1ê}Ó[OODà˜fü«;~žú˜ãnDÆî á¾Å‡•
967
+’¨£î•rõ”%³Ï;‘!3š'iÉeÔäô¸LFt={A÷òl‘
968
+<!X¤*4!ðþ͙M0·„R¿#Œü"Ç$îrÝ¥¢x"ŠÐ#mO-
969
+F‡%SD‰:Eóc[Ü÷ Hì…l×cE¤(¥3(Ì9ÿ®žï6~㖅ƒ5Ì &öë`sª¸’æX¢ø›$(iƋ"ËŹ2WU{Q÷ ªî/†.Ykü7èù~ fے¾3`í¶Qžÿê,‰ô…MÝô“=Ͷüô?:¥™- X,C°¸qÌ.»Í+Œr>`ðY§Šè¢C^ ¿T9ÿè)ˆ¡òn˜\47û¯w$¶ÀÆwËÄ0•€KwcùbgÐç×0ñî-~
970
+ì_)nϳÀ¯;a¡‰)ëw’Q‡¯ nѝ(pth"Y6ɆAÈFÔ%$éJ>M㠗ËÕ(¹¦!2Õ *iQKv½Á ›š dã*'߇B…‚¸B¹“’ƒð¥GýI~Ú°¹‘`yz·@ýr›‘Ä÷½âBÔ¥œÀçpÒWùÓÚ=È'\ÑùÅF‘)Lyg Ö®Ú%XW"¢ £ÿø*¤7oLäZu:Ô1’aó.“:T‚ÜBi§ˆÆõªj¦˜ÒŒƒ^¼–Özv;T§É¯ŽA¬àî§5Ó ð~yNÿÇT\õÓ!KuÕÐ÷…d$pé²Ñò¬D³LzEkë´kéçV E[Þ¨½[P §çO€XaEá.êmPx®.JZŸ7¹ ŠAPÒiîrØØeê~QÔy¬Š*„»"Åc³Ùr8KtÓ:ÝgºàAlI™!JIÙr<[Û ë7†òXƒ2≭K]1œxØ
971
+2ZŽ
972
+ÿ 8Ø+KOµÆd<ƒ¡¡]+p†XïQrzÇDf.Í{ªB¡”³¦1ÖgÎ%n#Qkº#àª(ð%‹¶ÅQñIôWˆÚyÞp×~0hèÆTtCÔ(‰$ÉE6òáxÙ`à=Ãó+KÑä›|ŸÔ^µ6ÝAõš›ÐÝÉX£č'¹{,f¦½L”®ø‚hóŽ0а”‰Ö¿, ]ø†ä~/™œ…~嬞<|ïC䀊 7x#ÌdkÅ£kAòŽ9yÞbrdâ •»Òóo6‡"&ò¥Ò”p“—ºàË !áF#“ óÄ¢@>Ԁ/lˆ“„°À%Ô£ Ó®Ú²ÓLl§ÁàžŽø[ÂCMgoz >ù?‚~ež‘¢í9#®ñ”à.™1S¨úõðúÅÞÎÙ¸$mS¡æ}fl²˜<î­-!wŒ„ènž²…™$´PxÃB#MÂu×0¨ÈúºöQ$îVZ𐵃üÌD´ mp­¥NTÉTÿㄵާ}ŽíS.›½ô©éªZ”¢Ðħ‹m&¥•Üô3ø§Ywâó4y¬*¤_Ƽz—2¢#œbùŽˆ$„º=Ì$cáYÒ÷xÉ!–.)õÕQ'(' [ÅCtób DéHä_P…òÙ¬W3‘€¯¬eã.¯Qòaô©׿üa"ÿ ~Øï›ñg ëáv˜-¥b0˜° $Ï>Xwʌ÷¡üá÷ÆÇ¸Mǹ,T„}Ñë Ó£ô]?R­éèf¼]„‡ÐkÒ ,·U«=úM$†>°AÇà.²Éq R”±cyk›¶ßk ¶ã´nZÏç°52QSªáà|&RH,ÕE(cž×~ŸÎJAÓË*¯7ìh£]xCöFËå.eû(ð2°„ÅÅ'_˜«?I[_xöHl†ß¡ æA"«ê<孍F
973
+œ(P•çóòpÃ6/¦uèB±Þj¬¥{þ Í<Õ·ÐrÎÖÀÀàï±@›Òàõ„|)PB bÐnRqv.J ¡kR `aÕ\“‚ˆ‡Ýëe7=yb—P@°>FSGIw£Gcaý%tbìÉrʪÖc % –ËäŸg(q/Êo“Á[È9îÒVï¾OÇ {Þ=GV&€PQjm4÷Ð8 ‘g鯊‰A›ÀËÎEšÖí”A©@ì <;ý_kñ0¾o°[—ÉÊd?Àސü£,|ÿ"§Ù$M‚‘ÌŒ—›"4÷}JíNC‚ îFh­Ù|¯~aÿô¹ßn Orã3~M¤Ç@H¢B=ÎI Âùð:†f_#sç'ÝÎçë¡×  †<8:\jà<¿&s
974
+˜Û&%,ò[7{D:ô”)Vµ2Ó?ð-EW$¡B÷ åÄ”ikÏcހ Få;Ó>âÿÝU÷@ BѺV ëR—³7$v­z1Oˆ6vÀyŒ`Àƒ'u¥è¡p¢wŽ–Ø÷TÛ2¦ ‰.‘›ãs1õr]‘Ä|˪ Ï …"¨‹;&÷©t®‰­²‹$w&`Cú§Òz2²+—Y¦GšnAlæ ”*à3nž¡Ô÷L´µù|FÅS$˜f¢exJN°QâX0ð«Pñ^¤K£¾ œc!àÌ·èàÝ΍nòlÇäÍ_»aa#S#xÙ`%£[äy©ñÒbä‡G‰BaZ׆٤c 5$$‚Š[Lº`ÀÇː"…5ßOÙFÚØêQ4ôÆÁñvs„G֊|‚ÚtÅÎáB_¸}؃RE_ׁVhu+Éïš× ,%YޜƒVRiä„Ù·v[D*PiÈÒF/ÜlࢠÐk҈С-ئCYÀc´BD'NM¸ÏËV’Õ‘xçp ˜Ÿi"ÞÁ I¨ Ûép$hm\ M˜O–
975
+Ž…P¦2Ÿ»’D¾”ÉãÅu˜á¼?S¥W†£ÇZhðCäqqž¾LW„No9P2â5lʐgrð4Þ`)I’Òm¡x(>–>PƒW½ŽUρ<d%B<”Ücà“˜8PàŠ¼÷֌R›`ъ„‡aXAô×W8àu¹ =°Qÿþ½ Ý€¹ÞÐráówfÒ¸dnËj–¼5FÀ>!a¸.©²¡å,Æ©O2MV;)UbfÃFo„tp4e½îŽ_Þ« F¢JWœžŽQ}tp@S±Þå³Ù¡øÚø¤`ΰq”€{~QÞ#5d÷¯?9d1d•ǘŽ#‰»! ¤/ú^)pQyKšÀðÐW¬PƒÐ²U]1b`tö9WÅàÙaÀpê!†8ðrв~d³´À\c%ÒËT„ëgë>L€ª›Øž ëó-ñLðjN½,ß~¹ýt.Yð‹Âªöê-‰ƒ ¶!I´«°ö ß?N2IǬCï0±ùÜ^œÎ]TY!n§ÄOo#ïXí!´"ð÷+ ¦ÁùZØÖ«Z)ؤ¾üÎ2èñUÛd %Í´ýd‹$]ӳеí7•¡pá7˜¨½o••XÆyÂý éGÙBªp _Z9Fš„۟¼0àW‹‡¢Sgº®{9~ïVáà·C0RëÐî_£}ÿ÷e;–Làô¤D*XÂ@›MZ.D_½F†ÿ€sÚçh šœ!yеÃE"ã><‘ÉÖE¢‰€ †[ý[GÉ;Eº(ÃQŒMä–qi±«W>À\UŽá îžO6*¥ÿ+{Kš¦lð5¼)ž@İë^xÞ,kg¬:¼„± ŸT&ęD<¶ƒž4PJZ‘æ¼IRŒH ˆ²ú;ÇՁ¶æï ‘‘v iuå˛âÈæo@áïÊoJ`µ¿AH‰|Åeà?¹‚>=~iƒê7$ÿk¢óýUÄä#¼a…ñP+l¹ÂŸ‘¯°ªÞ7pNL
976
+ ÊÚ±`þË"=Òù,ÌÉ#™Q ±–¢T–¶ oG²ä¶à‘Z¸©™ X¶º€‘Þöy^¸[ðó3¿`¬±HÁ€pGŽ (8 j‹L xpnG¿b$p €dð%ƒËó”A—· 0%3àÒÏ6ƒÂ9’í ¡tDùZó‡†vB\FÌÓґð¨zŽ«†¡8G$Y¬²tÓðŠ#cÃŽ w6XmR:`Dàˆs¸a?T7\â¼Áýï7HêFfž¸á`ž+õqk”ï7rŸn„¢Îá;ErYb#сg80Ê]uÀ¡Fª×a?韟ívèjF.^âîÀ<€‡“ed‘x¸Å–1"ó®y˜Œ‘côðFøXÓ®íÁmß0i=>,÷‹4õz/Ö.‚(ú0ä"»öá—ÆƒÛ"óH‹HÜéÃdPÝýX„€nEjï*@|©ÈbâqА"ˆeR$aX¤AhÜÅ2ÆÅ—Hs0TO“ñ8‘ô¡‰@Xˆ¡7^8CjNE„({Z$2 <à„̈Lۈxåc„ݶ`‰ð‘Ùaˆ #*¢M´ÆróIC°"Ô.áI‰c>$´ÕCDkDqx®†„wû::<D–>b]‡¬‰/Ó9¤«"qVÒ|$
977
+oˆ‰’ز! 1 Ÿ2ê$nА9”¸/CXL‰Á1$W%â"kÐ+ñ‚Ÿ%`ð…èżɟãñ¬j!>€‰cXHþ%:X!>ǧ5† ¯QȔ;&>=!Ÿ–‰ÇLïgb›`cP5‘›@5BªÜÄH±á„q˜;BÈtuÂoáPýQwž¨ìAîO˜í –.?Q“ƒ¸‡dç
978
+kdÞT(neë=§³þe‰b ²~vQ|õ ëFqÃ‚Ì ¤P§ Ï$ō|×)Aô”"_Ñr)º ÈÉΑ"S„r ê4›¢S‚v
979
+ „›ÔH¼?Eϒ†¨`^D*¾dZSqñ€@£Š5RÖb•
980
+¡V±…€”6ˆôUL ­cEh¢¡½üO²rþÃW\ÑÕ?ŒuÅÁ>›y[Ÿ^‘Å?Òú™ì?XTÃ'ÄB˜8cÑ?›+ÚϞ*êïG\Y¨k?R4‹ŒõÃõ,ÊèÇa´5?lO‹0òÃÃZÌÏ尅}ü·«¶`ußܰ}{‹pìÃF¸´>¶Æ…„úX,÷èãþ¹¸|>ÐOÛæ£i]¤–Áð’Ùv19>ÒßEžøðD^…{ôÂ|Ú‹×ØøÂ>¼ì‹»÷èÑ/‚»‡Éþŗ{ ±Ã<³—0µÇ÷Ã-{x€0
981
+Mˆ#…¡æz8•a(©”‡åaøS‰ˆñ==¶MŒ¯ÒZ1VŒыz¸ÎAÏã†cøp&yŒŒæaȸ/¹"í<v“ŒÛä1Åɸ馌ù~e(‘Ç@\ƽãq 3ž2ŸâèÃ#83#Yx,©fÈ «{3N[sƱ¿üΘÒw”ˆÏÈ­wÈ9ñŽW…†1»Ã‰FºÃ˜£±w,±¤áö·cÐ¥ñl;Æ0žÖލ†vܒ@f'՘‘g«ñ"vÐk¬ÄŽ–­‘;<èU¯ãN_Ãå:Œ†Jë0üظSÅlÀ`æhC½êHX¹©Ã°ÚFAÔqÖ·!ìtØÈq#/ÓaåЍU阹µ"'ÞЦv$œkt8âÑQÚõÆðÏÑÒ7Âöº£šâÀQíÛ¢œ6„ÃÚæ0“á8iŽ¥ˆÃœæØpÅq›2Ç+¢8ƒ9`‹;†)¸3(‚¯ÑúÉq›r\Ñ+Ç FÄßxLÉюÛ(¿˜ù̙C%È¡Ã9dGtž#‚ãõŒãê¢Ãöâp¥# OûٌóȕFÓÈçEíK܊Ãs«ãCD¶Žó GS×đCADE¢ã&;û5$G¹ Ê¥ù8Úžá×R0¦–v —L Ç¢þ¥$+HvÄO8Z¯Ð }*p8vˆº[JÁq¼­©ã T¬À‘¦ÕÑ86m™ÕáóƒÐ9þ²ÖñÝ7öX— .ß;î Hxz#:êˆÊÛ¼<žD"·¶Ðº;ê@E7̰:Z{¥È¿jX\æ†irc, 7<Voü¨cã6–«Ü²§mÀžÀ6†újÃ%;mÀ´Žy6Ü«ŽX‰´í±ßëÀýG&Œú”‡ïa›lŒg)¸þÈÀ÷Õöu €æÇ5F aÚÀ`´FÔØQßÈwǎð«AC;0[ªiÕÀú츌j “Ûkj …vœ#5Æ9¢8Ú!ÿ4¶9; ÚQצ1ÅdØó-ÉÒð‘4à(ÚÚhL§"nѰÌ}ÝåmZ@·¡ñC; ’>A£4Bæ>:ÛAÓ=Ãßv4ýy·ÃÜÎØoÚ±‰ÕFµ¼ß’3CàŒ(¸Í@r;¸]3Lz;Ò¥îoÇçÌÑv&3ö÷{¿˜w´3&¦¼ p3\ÆTžex•WpЎUè^‰)î0CV¡“¬Qà*&ÃMwt” yÇüGÆ0ï0,2öp‡Œ@uGʂŒ1çÇ@Íç1Ö
982
+,‘±;@pŒçë°ŒÂÔ²Ú<è˜w¬ºU$:Ü8<ÂcÀC¿¾6íÆaýìu¬ÃÃ8ñ€3!yUyøþ™‡°ÆÐx½µèÑ՝¦°)©†Ý`5^¾h­Ã`MòŽÅ°JT ùĆ,1 ¬èF s)!÷b!Ïïa`±$‡ñé^þ‰a,}†ÝBaà&GyÜ ö ¿= Æ@{+0î±Áˆê=ò 7øèàšÀø|€agãCÿ¿ˆ–ØþB}>úíߨuü„}Tí óÜÇK$üK_Èå‡J¾((NÓ|áå~ÌíEµü‘®¦Ü«ôb˜ ¸9/ö y<‰vH¼°N@þîbb¹] 9 ¦ìÂZ®‹!ˆšºÂ÷,8ºÀn †6ΐÌËE: Ò&S¥ Öq1gŠ‹<]¸µ.üc oagƒL¼ÅÆ:ˆ¡[Ì~÷mñqù®-˜ÙÙ¢” ý¤(óZxY…ü¬EqRªF^ȵX-†L‹U3ä-NkÈ3´ g÷³û 9;‹‘ ¿v³ÆC®~l7ýäC˜ËÈÖkÂOѕ…ˆO²0("e ×#ro,ÖO"ª‹Å4Lä™XlµÃ0NDö°˜ƒ"Ó
983
+‹ßRäi° REF‹ÜÉÙ¯0Ì"_qœ¸EœfÔ-¥W¼w^á‰×v‰‘ë¹b–ŒHãŠýÍÈé­Ø¤‘¶‚·FÖ¥l#nµÂÑC+D3+$ ßH|f;„Xa:”]Er$¤[ÅÄÎf/äH’²Š~LñN®
984
+<rNUœEG°R“¹@_<r¼© ô]*°Q“Šp=Ò:*&TŠ
985
+ĶPqªGÒ¿×#Ò|
986
+_§Øq%Mó90–RS„gt΍ë2˜B\ŠÇ,,…OuJ!²#3OŠJìHfI¡©3RXò æðÈå´¼Eo*ŽÂ°:‡§¿(ž±#ʊ¢®o¢0Ã#ûDuKÙ¡Èo
987
+4'…bºŽ2ŒÐv$pS@‰5;¯#Ø…Ÿ;P M (†sDÞNù'¶ôù Ks}›9r<>q¤9òܞàµôJđWžxjŽÜà Ò:²àN4íë„/B°‡G¶¡Ňð;²úœ¨mn9áџqi9'ÂLoÁ¸ ?õH‚6aÍGÞ×ÄTþˆ9& $ç'vd¥LÔ É<4‘DêL(*’3qÎH4ʄ:ÈÄÈ#ÉV‘dÿÑIr&ޕäL°Ð}‰¬øläR^"©Š¤M—Øö$b¸%öpŽ¶j”ØÀv–7Ä ú”p)D§J¼TbSVbÓëJ4§„Y…%u¦úfÉxéÑZ’J„ú-™{©Ò%9NÂO^h7¼/qÃ$¼“À’0qÃäIW󨘑€Ë†°dÚÕRGb€2‰ CÌä¢HTՙ´‡„whrCÂ419ؒSjÜ ¡WM„Pøh¼&ƒ|Dc6 éæÛ¤À#ÞoâKa&N‚sÄÃÔ³8!‹#|TNJøÐEÀ5[Ï 0á7(U#ê”h„|Ì™uÜI!ƒ'õaÄ©<Ñ~^ӓXakO~¶ˆ‘ñ‰&‹eŸ\­ˆ]ýäGEÀü'ËûPd0‚r̓A58˜Y"’㉸ç
988
+)€ÏÊ Žw(‰¢=lÖûÞ$øæ!„ʐQ{Q8„g”‚ qv~g(ò*†XÆ §CéìB8) a¬¤Ü)ÄNOŠzB̖R–b(ð.B¬:n7ë‚#¥æA˜É”¢¹˜A,À”² ÂJ¦ D‘¼1‘¦!o2år úKSR` ¼ù%MYé „"™ò€PÀ”0Œàþ¥ˆ &Ȕ×À;\ØcJ)~ ¾ôàìԝÿðv4%À”¦øk_›¢€X¸#VnŠ-Ë)Je˜9 ³Õ‘Ñà8Nß¶)hi
989
+ý Õ6€ˆžDHìú^Þ¦è~ã0:âîýNœ‚|?{õjÎüp˦ôÃ6ÅÖ}0Ÿ)í±ŽÐ”ԇ¥õ|€Z>,Š!Ôøàz @ÀÞC.÷€‰¦Ð´“È” ö`õ¥L«‡m-E›ÖûR^‰‰Ý—bç·;HµÌÒ"]Äóx€“V<šáÁE< ù¥|}‡mwÛRºÃt ¸C_; Êä|6­”^ìÀ­¼à&ë}MuX¸O§²t`VJGè0R¬÷FI9‡ŸæŠÁܤ”|_®°¤“Ãz”"ºÈ¡“R’ýlhåqâìöj“«8Б¤<ؔ6mÞ&e¾wH)5āµR¹k°9å-¥†A/w`J5ÒË1wU&S¸/¹¤)ƒ{ÇÓpž¦&Ü<(§¬#;ŨÖS„V?—´ß ÇCEÙϨ¸A¤8Ԉp"ÎJÎ$Må ʶ§²›£
990
+(àࢌ*°àpÂS…8¿ªü¬bÿêë7½z9¬b¶UôÎ:¾ªà|“ÁáþÑæø¡b`¥ó®p@Ò*Sÿ°ŠÃ8–Á‘ZpÈi,¤€®Ò¤ Nj„ 8¸:€XEº¥UÁóY e©¸àànU" ÆUAr·*Œ† 8`ãÎì8U—Á!C1T'=ä)K…C½­J¢ÃÁiU*‹£p@ÔX…?Q‡„p@oî)þâù·g«¼ð ›ë*¯ð«@ÊrXä Alƒו–üŸö´:š‘Ás­J¬Ûð­Z±^6[¹± oÞÊ1j¸¸2ýl(ѹ’[6Ȱ+ecÃÓðŠKØàõJ¿×`6_ÙË5¬òWŒ´†=X&°†ÁÁò®˜/, €M‹ŽipR,ÅÓp”±ˆ™ÛKHið–È2×¹™„†TLj4¨ZYúEÐ/‹}!.‡†Ò"hG³¨}†,Βå|=KMg8´8pÑR¬Œ*-·3ÃÚÓ"ZÌ0àÔòäe˜ k¹g4¹–׀`ËÊ`°Å]sÇdø![d … -QD…méýc¸H™@?ºv 3ß1 Õ-¸ÁZޒÈœxßòA³.™Š¡¹á/1— !†ãÆEå0¹”0 îU.…a ëÜy ì—Û1—4ƒ›sù肾`°™tQ8Ù§ÔE ,o]\ܲK?\µ]òóB;~«¾${­ ¾`$ténøYy9˜™y9çXD/±Þ…î«—‘M»°JÚK®.Xx//ºP:Ãræp¾¬A.´ŠÃ½e_Öýªˆ_bët{¶ãúezl!ƒþj-èBԂÕDZè;ÀdD`ª6 ÷¦q¡¯oj“‘,üŽãx‚X\ƒY—Xã^ÇÄcMXðÔf `¡?aR÷
991
+2¯«» ?ýàŠ`0·‚7‡)¿ña0i…Rˆ™%+$GLþ« êÓá¾ê—PÌ!CŸ—„«˜Y•
992
+Š´˜Å©pz1Ϥ7Æ ’Ϙ<PA`c*žÂaÂ1V;UZÕ1m¦pšÇØ.Sù1e½cÕZÁŒ_R2¶ÂH‘Y…WŽÌyQ yPIæ:Æ]2B¿Éì…Ž@™< àü“ÉônIO°Ie:z‚íVf|'lÂ:I–q¼Ù–AÍ m»ÌXœP{¼ ú/3޳¼ÄLPM0­ÐP#3lãO3Sÿ%,£[˜°Éš9| §6óœK@¾™qµ„€œ 5Âö ž«734%dÏE ž=ð$Üõ9“àáŸi)€Ú@ÃAμx‘€ñR‡„Dí § áoECò#0ÑhÎy„sìÑîb¤¹p„õOš…°biþ3¦ÙÅY5M¤t„ ~S5`ސ€¶3š=§1ª œO#N ÙÅ%Â{¡&ŽóÆKÍ"¼ÕÜ\&&ʪqêËOÕLiBVÁö‚jW“ \bM!Ѭ‘>–¬5]ƒàèù B]3DZã5!Á­¯y„ÅÀÆæ‰aóÝ¢WƒìZ²<öÇfÓLñ2ÄúÁf3âGÎæ‘}ÀÚL@$M›Çú0ª‘È_›í÷ ¢mÒ¶2n“[¾ô6rÒ“pÖ<°7[äÁâåÆ좕ãw ¤nDºƒYìfDí`ènNØ2¼™XQ̛èé@¶zÓ/Ÿïõ&ú¦‡˜*ßN°‹¿™­¨Žön‰LéF"Dã +8@T%>á@€3ú½+¹`ßo¹Áà¼Û„(m‹&8°*fk #“í©§M2 8©sÂiO@EW“ ü&8‰gpãà¨7k„ÓÍ üÁÂù^c GQLáù³¼ qêÅق V-΍c@,ÆÙ/Í'™ˆtœÐap‹>Ž÷|È9¢GŽ;ŽÉ1 ƒ9B9ë¿à³r>UÎxÓrü©—£Ws(ƒÁóÌA*lŽPD8YÕ9Ø<=‡=ì缃Q;ù ôCg×ÂènH{^élý‚â4gE°u
993
+ÈS±:äÖ¹ +Ó:_)×Ùõ^g1á]vÌÂÀÛØ9ƒže§˜üì`ƒ€ÚY‹ØŽáÒí j†;K@.åPåŽN‚ótG /p¹;_ð(ï¸ûU{'•\ï;®]`ðttíϋ\°ðøß‚‘Ãsm ž%ž§µ€¸x¤ 7ž´g¾<#Y07’Ç»°7ò Ä‚{-òW@Žy®]Á˜Ú
994
+Ø<~¤óèd²ÏS¹þ|zÆz#gª)µŒ>zþ@mI~”¶WÛ2‡D0É6‰ý"v€D‚§TP“Æž´ØÑb¬ *ОË÷¬o%ô"¹®D”W<1¯3VæpªT`{Ä4
995
+PñÒy T‰úiHeÁÌMAµ±A­¤MÚ]
996
+î«CPbPJT–(Ä «ÖK—Ÿ²|3~l£IAy:‰
997
+¿tàÝ“‚*°>œ(Nm¶&‚­¸O®4“艜ýK“‚˜Ø[€£ò­L
998
+,-Ø@»²eE˜àŒì
999
+UL
1000
+†œVÁDZYoR æhg²}Ù$«’‚åÃêNŸ6oI”xÁÿQWæ1”ôqúPLk—7ÊC4uïÈ)8Q6®RyH mUÑîì 5ê $æF2°Î‰8ö“'
1001
+¢°¸ƒÄqûݳ““8Qñ;_Šnõ™(øoJµ•aô]¡dq™(дÃ*lW‹q°]†£ ©êôs4ëÔ§6Mà.¥q+ˆ<#€q ' Ý_>C­“BÁ‚ &X(¹ÕãÑÐM_ð y„.ŒGÞ ,<©MÔíU2m\ïÄñÛ-q¾”w9²;ó8AsœwoUç' êÊÀøۘm<™ŽŒ%)G°LnÜìÚÄNðíÁƒ5F~±!;œ`O Ic*éÔ[íFÆN@åø•+®:YÏ5NPúñRs=8m²Kú/……ÀA¨¦¸öC);ǬaäŒcW*/báKðÊJ2ˆ&$ÿZ‚›ÍÂ|Íàl…G°îœ¤2ô/Š¡þk_£—¼>ë|Â"HÇÊ=ÀƒÌúÄÐD“`*nY­öD¤Ñ$¨Ú™Pråiös¨ô¾q!–\ Ö}%Û=$èÇ ¹ȓ¯xŒÇc#é^†m1JGj4×@Gá½ãe%œvBéԐåÔ2¢ ì[#Xˆü W2›wOJ m¹EpUY<‹²y¥Sž8oüÓX¦$‚ÅÄ9‰ àÈ2 D€ÄFùʹdÇåƒDjá .öIâB Là3ça40)!hS¹ ðl¨¸¼z f¢6ñ ‚L¨@K»R/Û
1002
+2Dûd%._Lì*Çê´Ç€Ïç2_øÚÍáwìIèЪŽÄ­2ç÷ÂL"{%[Èo:ë¹Mç֝‡‘§KŸ¸öí¬‚.¦vôO Œ¡IGª°<Î켌§}…˜Ê2òø-  ,
1003
+a0þ¿]çþ՘÷8°hy [)ºC“nƒ½ûÓû’ _¸Ñ $©µ9ҟçqø›Ú€ÊLx~µ°@TîûKÌ÷“´օ«£»ö§÷I°kT8 `=É·Ú3©œ¤ˆöDѦŠñ§\4ÀÖcÐ+πs…ã‚Å3 µƒ¸QLWÌ †Êáß㕁ËӒKÔìE‰H±¬ü~WII&ŠóÅÀxНÈ}ªS$tïN(PB7º‚þ¿@hÅÝÛ×ÿçÜ+c³»,t·þ·ºÀ<5 Aà4žNµy@…„׸ ¶TøŒZ]CBĆ-`‰1sEÀYÖl!ÍˈæÄùYdÆŠ)B'†Ë¦ Næ4.Aà’´½wlÐe«íŒ÷¸ÿmXT/­¿;& 0¾uÚíž?®õ@
1004
+4,1Ûé„ Q 4þÚf7í¸?:Ϲ—sÆ?ÃßÎa½ÆJ§•v՛Vd0Nmÿä"¨m“SÄë¤.ëB&ÐQ.¡íiK€®‡Â÷l’‹òEI ¤-¾*R ðxËl•‹Ó aŸª¼ý®¼¨FñqtIÆÜä徬.‹wð3'@o¬£
1005
+f%¬sôàì4æW$eÌÝë
1006
+° iÉÌg¾ì3^V ďåŽÁÖE4ŸÀEUh,RQÁŠðÖÙÁr\¬ÚnwrñÚ@´·ÍJH¯Ú]€¸ôý81a瀢Øè(~±U(›,O”HB‘Kހ<Öd ë
1007
+D(JëílÝq[圸!é«ô®‡.uÍÄ HV'ۘgÖ-\ÃøÈŠ ¤z}{àVà`åVNCµÏ—:ô¤{¨„ܐNéN˸s9Yˆª£¾ZI£óˆW_‡ÈoxÕDd'Hº…0µM{V@”¶‚³¥6€»LˆŠá ;
1008
+ÈԟՍJ>ãŸ1RœÂDQV ;Õ,˜% è¿c…Ãm ˜ÈÙY~HF8¹iÂ>²A5"¡Üñ@/ŽJ ¶&`FXŒo"tsШ@
1009
+¢þ¸8j…±éaê,ÇB“`R;@¨×\AT `³ˆœ¬ƒ„¨M´0Çaì罕Ž`HŠu²­ æAüxjyß¾‚„&ƒb—F<µ2÷]A%¹ùdàÒÈ+Æä#ښ@ÍV» ÎAá&Àçv0Ò9Éàz–ݳÉÞ Û¡@qÆ®
1010
+é{¸ó—B=4… ˆdt_<ô¦†Ï}Žó À©ÅRä •UÏüÔjþP·4ÓwÝiSð³j°i|ˆhD.:×ñ꟒›7=åT‚_J¹`]m‰¨5o5ՙ€wpصB¸B(|áš6ت“ô‹ù= ÆO¤W«BÃpéö@5:;xTSÀ›Ÿ£—f2 Òt¼¬m¶ˆR(;YTµÐ‡èÿ_êžNk\Â=þÿj¦tWaÒø¡ ÿ§*ÑÿØ-¦˜ûzÿ» œÂêµ6pÖÿÈ¢¬§A”ªŽ‰Í¦ÎÍ{œ›»ÄÿîY€XO¸û÷g1WäÓeÿÍÇ&'ØbmdÿÕÉgÙ¿ Âõ)ôœ"…Ú¿“©ÿynJÈ¿TAÿ ëô,·8F x&Šà=Æ¿,›=Án¦=þû*ÃòÞpà¦)óÚF…šÚòkíšVòÿMáµÿB…f@ Åþ㦇¶“zhÊú‹0å§Óz  õ'{Á€ +Øým±šµ6]á.±áóOüÑYpªù¯g TE
1011
+¶å?—¿¹¶ø &ù'§ æÆ_Çý²‚ι³ôßێrPkºŸ‚ü™­·âçK)÷ï§êÎÞÄÊ«8ÁÞ?‚¿‰ˆž¹÷7Hàžú9»w–¢w‹×< O0ÐýœÐgºƒ›9Œuǵ?jšk‰D¿L*®³þÈÜý;ùT(éQJ*ӋýZˆ}%ùŠßõ;¤8 \±UK²þd^­žIÎ¥úò³!t]ÔÈO k]ÕÆôƒ‘Xþ#éȍôvvU;zX‡Ýžã™bþù£ oÖõ<vþü#àa›ßäÚL•(”d~ÝyÍÌw’®mù9ßÓd“Õ5àlùƒ¸ Åè«Xš)¹ÈØ*’¥Më$¿Cûï9a “p ;¿õØA~¯ß:Ì8~v@7ÕÂÍvG_ü X–'ÍÄOۈúŠYxª-)Mág‹·—QÁ…0–0ÉJÀß4p‚—ÇH+H~¿/±ìB2àûóg˜w"uCz(ÓØâ¼¿Ž8; *8<³®wŸã™»7r«º«î[ÚËøgîû•a•`§gýÚpÿ=TÆ
1012
+ù J ‚cUÄ='˜¸”² ‘¡ƒ;3ø(fmîß ç÷Œ™n-ڇ›"ÝíC«MR 'ۇá3_†ãF§öŸ¶Ö6ß÷˜_™°©}Å^¹´÷ð|†…³ü4Ôþ÷ƒÅ<¼j¿C„<Ý*«Pû ¤ÒX¶T(j_˜„À_'8µŸa'R@Eí?3õr´²³¡£ö¡mO(ÉãJÔ~‰cg)ʁ²Ÿ¨øÙçZ9üe¿•Ÿý é~Ɍ‹|Ÿ}áÉKòtöُD¿¶}¹ÖÜj•}–#ít—¶Ê¾~`~œ¯Ð
1013
+cÿX¾Hq_ýøìªÂP­Œ“Âë‚ý•ø,Ë%€¤Ø/Øo?ۃ4C°è RûÜNý¬=KRĚë†`u öûßK‡ª™Âöùûü·ö…qññÝrñú‡ +×UrŠÞúGÞÃBa< rºYßîp1 JÀfý%­(àM•²S‘Y_£V`g
1014
+fýû@nÌy6ÿ¨
1015
+S1$d
1016
+¯ù©~õ&¿S}újN
1017
+õrêH #„ß
1018
+ÈQhW ̱kÀñsd·+§¿ÎüËÑÍúåçíV©-±)ô`kôÁþöÁæx,ì‡ÒJ(ý¡}ò’)¥”¤ÚàCþ&¯T\/•T"°Ñ¡ùÕS?õÓ× uy>9^4VZ_sÅí.Mԟrí7¬ñ×®D®3; µ«$Aý ˜ÙM´HÏgÐà¦I½$ô´§°—@‡}æêÆÊ΢4ý*IÔÝ%í)FN–øI”¾N‹ÇS¿¢ý0QÕEìô%S"§M…÷Mæ¼K^»;Ž›ä,NS.suý)HÑ^˹¬ù3Ÿˆ“æjÛEôèr˜)«©Âz/ÍA%cÀ•<b Lƒþ<¢jc•¼+Šöš•èsÜå.üü'CIoËy +ì(GJ¯'¿m[Ü$Q íúõt\¾Øk¸Š½²§O¾y©ÉK¶ÀÙ%ä:!|{F¬éû…‹sKuv¡²n*ëÞ)=wJRt¯4Q7 u×ðÐòEÆ{oG1҉›|—Ôì8ð’Æ}“<'…oÇ St‹”¶ "_oÑǐ6ö‹¸Ã{?ïE¬k¸†œ† ¸k¸€¿F /ÃÜ5Bm"tt¿.¼ô8ï±·0M}
1019
+ҳǚ@¼W‘G‡výÑ5¬ß²Æn˹N¼ä+JQ3uíÙc'qiY3ˆ6 ¹۟#$ÜS’¤Û\ä&^$/¡
1020
+;mêë³j7ù"7 UÕ£ RÄgª„<mä±#,súdUH]Ė—ÛôØâºÇ~Ë»ÉÉOÆÌ S•Ý#„|7 †xK“•눜\ÊQˆ¤\GÔô,LSôü,LÔNc%TØs,Ñ*Š(Ñ'Vï+l­ ;» [ì%Ta%hYˆïÆÎOÂØßhu½ŠQô£ ={ÌSöçê´ މßv5:y +ì&Þb? /½ÉÖèoڢυ‘>ÅÈùY˜¦^núÖøkWb¯ ¹I÷ØwGMã"}-+ì·ì±§E»
1021
+’´³4E=̔ÕÏàÀÖ5XZo"…¡~£Õõ(`ç§9…?×Mþ]_ L›ï? /= ¨¿|<Ûdkü28®ÿFK¨çò$ý'`¥G!ZÖ:ï²®]‡ž6õu’g&im–(¨¯ÉÚö™۞bH‘W1©KB‘WI‚úW°óFz5d˜Œ‡œ… H\¤¶‰"`Î"å&ߢß=½ "âÝBN´
1022
+í €¢S¸@ÔW õ ‹ä8.ÒÛ®F^«ýJÒÔßly»
1023
+Æý†‡·ã¸HOs{ tèK¬A»{'CÈeÌü8.Òã¸HO’ Ò/`Ïü
1024
+îÐ7mÑ«E¿.¼ô-KU•í¹!åŽ%f™ó=£囐rŸ|™]nz˜ÙM¸H~nî“/³ß²Æ~Û"wî«ì+MÑ~ÃÃÛEôèò•¥)¿i‘›fn“î±£ˆ—>ÅÈùY–¤ç‡÷¯ˆa‰6‚˜Ï\e?J‘³ß¸F~"Nö˜X>¢Ç×ç ÷™ÛÎâ4å/QVÏâ4å-RSž£ÂÐVáÒ6±Ïæ9A½Kë[ž¨}gäô0PXÄÛm´°5 ÓÔ³4E= µ»@U½ÌTö×äàú¬íyºöØùuC͎»M¨Øq\¤WA’vš*¡_c%Të¼O:öÜ7Ù[š¨?æ)û]š¨…¨éuCÈú¥éúo²¸ßFÇö·(Mk”0óç¶Ëüü*HÏ¿RDý,JÒÚv5rÚ4ÈqÞãß9}Ë´N1r~ÖÈmXâWaj~%¨wi¢~¨ªWQ‚z•%çqª~¨ëo9ªÖ;±ÓçºI%”pó׬Ãïþ”±³õý/PӚd ÔaÅúõSϱ#Ï®e¾†v×ÏÖqý»£¦WyZú]R³ÃDY?Mv§Kë]¦¨Fò˜ò¢Ôô9*t=‰À|FÖÛ¼D:æü‘cËò,úã'áæfa¢ö(©·u´+¨G“7MÜ$J§Eƒ&òšÕÈI˜Áíú}Ùõ«çÙó×gP .ƒÚà0å +öÌ%U`ŸE;D]#Doë<}t
1025
+Ò³“,úMèØSŠ Ãùåû2ÌØ#Û²F®/ý XÙiSá.‰7MJ¤oBǾÂô4á&9Λä(EΎRää&\c—5ƒè4¸W” ¾&G¶S5­GðèÖ*Šñ›¬¯·Áêú›-ooY²zÛÕÈmØãŽ .WÑN³%´S´`Äs‚€g®´¼„
1026
+C\Æ
1027
+ëmV$Ïq›{~Ö'àfG?ùî(ºs„q8TÍ)X8ê69º>'ا`ላÐÒÖ¸­Ò׬Ů +ÿÌUöcu=‰¾gë»#‚ú›ÖèMºÇÎâÝ!-땢é¿e“$ùӅ—žöv™ò·K¢DŸÓ*k—&ê·Éú%~€ë?Àµˆ+. ¶fI’~éOÄI›۞†"®¢$å$R Ùü:®àŸñ*òè¤ Mé8°ƒg„Ì#€ˆ|A S² Žm·Q'¤ô/RUó”ý9-³—P‡=¥ús‚€½ !áϒ4ÅqßeiZs“5 É3Æ;3¬Ø›gUŸ#;­úã®[ç5¬urãc/nØqG†-mðlÙ¡§Q…ôM{Ü9±±+-¹JÓ³³4I;Λä²è v´!˜7htØkY"]Ë»É×ÈkÙâž=ƒ;éyÃ}IØmV¢/¡
1028
+û¬ 䱣φ yfÙÒgÏ ¿ý2~ÞH¯„ŒðHÀKèåØÑgðLÁ‚šv
1029
+Šø‰!C^… H4:´ÝEÊZ"…¡^ L»„ï‡‘ÂZ? –¸9Põ¨êø@Å_Üà´M´ÆAÝ/UU.ƒ•í*\@ÚLàj~á(šFKÈϤ?:–ü™Y ¦œEø6<Ñ&V â+NPO2ýÉ$Ñß\Ã
1030
+¹­ì6ZÛ¾b†#Ù hñ`¬9FtÌ-ÀD“Øö5QÝZÅ(úgOà>jr š5È¡jõmA¢þ$h͒­UŠ¢Ÿ©ê_š®†JèÇLY}ÌÖçüû'„½ ÕõëºÍºVz’fÐÆu»±ó›h‘Þ†%â¶IÃ?I¨ËŽ>^³=
1031
+øùg¦®=˜§jMc%ôqxtkš+lýÂd=ù2{,é3¿Š<:8¯r£(bDoÀÕ 3…å® _c¤§#ãeìñlÚâfQªr8(Í%ˆàY§(ìTà]A NôíŠôºpÓßd}} –x‹–¸L•ÌTöËàÀÖ¹_§Q]G¤ü·-¬Ø›I¢@›„ùÛ±¦,ÉÃwdhŽ!}æ—ÐË/¤—]¾º†ëÇiĔ=²Lú#Ó¬¾mÛ÷ŒêÛ0d-‡¸ÑiŒìèÌù</ã—gTMBý¡Iž@ZÅéÙg°„ú‹”µã¾I—Ïó^¾ž,kþp“°‘—\ƒÜÄy.[Ç5¬ubLW±ó^ÈZ'öäá¹|\g„„ˆrô”±Â~˜)k
1032
+Ò³ëÄÌ^‚%Ò8®r·Ty¬ì8ð‘G·ÛèØ~š¬ëÁAý(EΞ#Br]ҒŸˆ“$Qßlò=n—§ëL*¤_CÞ,œWš¢}¦Jȧ(5=m*䲿OWÔÜ7¡$=ƒþöLÄq]£wªö(„{
1033
+hÍ4*àƒ Y›Å I¶ªÑã¶Ê.b·« rÄo¶À|Wäì&[ã·a‰»1ó¯$MS”œ~Gõ'^æß5¿ÊÑóïÄп+jÖ6k±ÇŒ@´Léã³(g¼Ä:Ü8-³Ÿpåýºo³.q¿mj¬SŒš½˜¦læÉZ¿0YKRµÖ½­zì9îÒרÅCÍ1¤¬/ù
1034
+q`¢qCÈâs0ä/e êòTõ5[Üý": ŒÀolm;XÉ,FÕo»aH‡¬ATôݚ+m ã„õ¸nÒϞ¾Nòê³é×®Àë;‰ÓÇ_ÆLÙ#÷ðh¸|h/¢§áú°%Ï\ÓéÙ5ˆ†-kùuô:.¡¯áþ1åOöüɸprÓ¬À ;úð`F ì¡aG™fî[—ØqCH¾Krr—)jGA¤ˆ›P!ìiUáŽ)oÐ'`¥o’ú—§ëM{Ü.ߗ]ÀÏ Äk¸„µ,¹Cǖ7䘓gÑ#ËÁ3Óě¡Zz7ÉkX#'y
1035
+Ò³Û´ÅM βçL£iÖÈiÔ§Iƒü¶EnÝ÷éS¢eìä6l±wdÛv¸[¤fO -{úf¸eÍßüîèÀ’>¼I³0Q;̔՛x‹=¶ô¡aÊpq×hmûÉÙmW£§I¤´eK mÃ7 !ã9ƒªx/z˜’m²º%ÐaI;PÑ.E›ð!ö9?ÀÞfKëub&ŠÊwHKOȶfQ€#/Se­gS .{þл£d&êúo¬¸½$ê7±*=Í)ô2åoÓ¤Ã]³}­:ù3fŒÔ4JP¡r–;f©Ûu]gŒèã6¬°—ûÿ,úã1¤Ï\³UÄPÄW¼À´c¦l²º<F
1036
+ë[š¬<ÇMö¬DÝPó„
1037
+DþD
1038
+ã3e-‰½ÍZìZ¤Ïm›^e,}‰²zšª­ ˆø .‡‰ºF¼v%òœwÉQÆÌ¢è¿e‰ŸF —H‰¼¤ô=h¸|\Ƕò]“²OIcž²)cg/ÇÇPWADìe¤´ž¦êË](ÀŠ rp+ñ\7éuâ%/$ñ”"¨/‘
1039
+½Ízìº!æ×™¥Hùuá%EÆ*HÒNòüá¯boŽA{äZV¸gS -súdñ“×`m? Vö×´DÚõ“u\>NÃÆ-Î4<°\‚Ƙ“æ$‚„;‰ ap¢Aø!§­ÿAV½æJ[ÓTq½DŠxE–¸ Uö%Êê3°AjsCÕ¾`N{‚!G~ ZӞAo¢5Ö48„z8@¶¸mò[C„ôà}À-Æ8d`¿CrJÀ¸cЩ;\m P5£P¡¨ÏXi½ŽhéeM -sÞ kBÂ}£Õõ1~¨ê@`ÊÏ\YëÓÆ†)yæ%§—Áºv;¸>F
1040
+ëkQ£¿Y•~åHZŸ€—þÖŽ=ôˆ,C† (ӐѺò è¡sÁ¦d(¬gQšú™È]?=¹vþ)ê¯U‡^Öü™wIN.A#š ¬f~ÈÁ1ÈÇ|ц‘Êv$©²ú£g •õßìøö/Ñ,fp¢U´€´m²„lY£¬$v~œß^äaœ²¿!/A‘q¯ÁÚÚ®F"nz”"g·e‡ÞÄ[ô9°²›lþ–-þ\éQÄN¯ +®›ü4*°¿~½[É1§¯¶ýqœ Dô‹àà‰€[þAHŸÑ‚W}oׅ›"´¼=§ÇP7¡*ÿìù»Ùêú›,î߉öüõ—¯g›læéúmt`w^ž¦u.Œ<Ù.ëš5ègOÚTÈ[¦¤½FkÛcpdû ˆ|ŠŽxÑóBôðhàŒŠ¼… H|pÐ)
1041
+PÄe´°ŨÙW–¦ü‘ñ^q%… ã]Á K´ˆ-m‰”ÈOÀJÿâ”í"ttýŒUöÓTiý- õC†ú®¨ùK¢CO{=-ì·+±§#JövEÍÇEÂ"«@ Åã ,¹ N³ˆ­._‰Šš@AÜ-@@Ó¶àPt1(m™©lIØ_E É3ã¶Ê^b¯á€Hý¬l1}æ×ñój[ánYªz)Ñ.h¢ovx¿ËÓµßhu=MÖõÓø¸öÙ~Û= iƒ'“þÈ&c#MB…ð~qÔlžf›*¡f!ƒæ¬í¡ö$Pߎ!mÌ9­òÏ\iù‰"â­ÂGû‚¢f6DÍ(†ˆ{M®7„ˆ/ŠxéuCM#Uõ8?¼¿
1042
+b>‚Ç·ÇHaýNìô¹0ÒßV’¤žÆJè×\ikêM”ý%Êêg¨²&ʪ#JÖ-IÕ_s%TÓX Õ.KÔZfþœVùSÄкEiZ¯EÿËÓ´F)rvQ²›|‹–¼Á“={虈“`x4ª†¡Âò6°5÷$À‚/! ô00Í,KV®jv›õØqBJobUz’e¯U‡ž%iêElu9îgY‚Ö6+ñצ:¾µŒÔµG‹ùØÑg»€>&äÙ4«¯×²Ãþ"öx°¢ ^JÒ³«<1¿n¼ä+ISÿíÁHa=ËS´—\ƒœÄ ´UœšÝĐpOA€#š
1043
+ގÂÄÜ5-‘.¹yÉTÈsafTÔㆎ[Ö ¢Iœ@úäËì(b§gI’¦$=kÕ¡wèWpg¦Eƒ2¨ Sîб¢ º¤ô³ègðÏ…œx)`(â)0†‘ÂòÝQÓËäÈö)Œ{
1044
+"H;
1045
+HåÈêo\#¯e‰Ü¥‰ú/ ‰kª¨htò-ÀDÓ`q9gWà¬+bî]nA R<"p%OPdi·LIû.ÉÉe²„¶‹4í,`EŸ BÄuã%‡mÈ´ëC¼{’æ "@%ãœÀõ0UU_ÃCËW$@‰†±ƒ•ÌVt8\Ñ1n¸â1tÀÑaÔ@EØáý¶kÑ˔@4 úóµêð„¡Ï‚IE£N3%ƒ$T§8¡èÈ®sÝ䇑ª~˜¢aø`%ã ùÒ4-P–=}<’ªo¾eýfËË;˜€–BxÌ2*°åGÈ@Vß ‡ªyE Kûæï¦Ù±Ý&ˆˆ÷ "D¼‚–è>†þnüü7¡c¿ %i@ˆø>ðØð€5[ ƒÿ@«^#57HÁ†={wÔô$ü ÕedOðO‚Œ¸MU÷ÃDe» “ÕÏ Á-[mš+lï(õ2<yœ_ܶ¬‘ßdmëœ`_ƒ¥ý)GÍÚØ#µ\ãåëÉ$Î ¾;ýŒT¶~¢Ö&[£‡wf×Ï븀8ïä«ü+\Hê)N8ú1SÔz¦Ö$Æ _òþ˜Ñ§»lt¹VzCŽvØ¢EB×`+™‹Ë_ž®…iºCc¦°¿E”v7\ý nˆ¢OÄI.[úh¢¦±ÃûW´Pôk®´µì´Gþ¬ãòy^
1046
+““ÃÀÇÌVtÖ¶¹Œ!ˆ0B Fd€‚ë÷kԲ;Rκ¤&]ëe­*oр%ÚF‹ÛkV#/y;î[¬gN ?“q˜§ëŸ€H—Á±íµlq“<t-K¤S’ ^eéùs[d z˜ã*;@Ž9Ø¢_¨¨]Ä!T²È1 -þAW›„î_iŠæû CÄ Ä_ÔðÄ3¸!оÑêúÝQÓôóëÇC˖@]¶ Ú8­qG&
1047
+[·Œ©½œVùWÄÓZÆ)Û»ÉÑ­m®¸¿fŠ[çô×%Pw8Ú1Y×í*zFvL Ƭu\¤¬|ƒ¦ö DÑ,bhÚ @JÆæ;£gŸÙÒÒ.0%àY´Œ ´¾ŽvÔÐËß\}¿JѳWb úœwÉ7˜À•<Bvp
1048
+ˆ(ñZ`££ûi¦´,FÔ.8Ñ´€Ôg¬°~'–rœÞoÁ N{ Jœ%iŠã"a Ê·pA‰4צÅn³kÚSègÌàŽbÄô Ø3˘>{æôõ’hÐëÀ̯’äìͦ>>2“PÂ=B 3*PÇùáõ28°5Œxcá´NˆM‡ØÙôˆ dŒÄ€!€×ðÏ-À´EàÀ ¼Ȓ'x!iÛdu¹LÖÏP } X÷ h`â8=¾FêêE`uýMÖW¶ôÙ._סI…¨©bý¯àÂÆÖ{f”±““2´U  <vü鼈Ÿ7²@ˆ4À |0B‡ ×ÏÓ¨e…Û„è8Ϥ?úeìñfT \"Ü!ll‘%˜0"c† —o–eν†váÞX³‹lÇq›[šaGóŒܳ§¯çºÉ¿¢ôK¢D_-îvÉO¤0î`@kÆu—|eiÊ)0@íÁ®è2p%SÃQ׉—Þ$\¼ ²…‰Êv›¬.'áìqxtë+¬ ù³gÑ ¿¢ô은‘5ŒÈ3Ð<ÛV-~­±n)¢òÔLey^’®~Ö8ì²vYšÖ)c©Çy/e‡g‚køg¬@IixÀò1v¸Ú-HÔo›"=N(ùmY#—1}6Ìè#ëÄNڦǶ·P€톨ÇG×눖Üv5Ö`m œö‰ŠvËRÕ¤[¬K Ãn»½.ìì4TÛo"…¡S˜räü79º5N–·öÝØùg¦¶Ÿp]¢‡ØÛhmûÎèÙmX#¿Y•¾F-zôçI˜¾}ÛÇÌo’Mv&n‹¬sÞä÷%Щe˜ sþÐ2X×NC¥­cÅ<ϬâsވŒfŒˆ‚ #<fèÀM‡ªYƒ°t^à0%{D–œ¦h™*k¯¥‰úS¼@äaè µs‚€=̔U¦J¨ç¼É/[Þ aÉú¶z—%jfJ¨· ?ëØòíúõt^ÄÞ,kþаcŽð× ‘þæ9»‚7Bƒ0B 1ç7„Ü*LѸ¸U˜¢©ÉiQ! }ü–-þ'i-BK[—òý,À´=°@ŽY du4H͵ê°Çž=4̔՟2ÔM  æ´€Ôo´¸uwéwcçgAªŠà±ý1UÛ}¢…"úERó;@É&Zâ2WÖ¿CZz—¨©WA$€­¨1ƒ‚ 1ˆ¢Œ „Šê B!"têš: ;ãCù-§0MBŒˆ¿[<'ZÒ.7gŠüÞÿ§ß€»šWÔ±óí1ï4³Ñú ƒ¯é0˜ép<ì<_¼Ó"{Öý1è,7Ð pkǝ:Þšcù ›Ôj£€tŽòi$¡AÀ<…ögX†‹b¿‚r¾ÛÙIX|bi™ÔÛËèyJð¹ì9ìFCǑG×u*8_•ø ¤“1‚¿iÉ;Òú£~杲Q}­ü9Ž÷%3>ËCãWøÚã(nЬ^¬Ù[ç”(פÿ™ƒŒ-¡Ò6{ÇφÍOÎ »ÚŽúÆg@à€k={£ädT׊³÷[èÝÂúVž<Ž{BCÝïxU4¤èsˆ^_Ѷsž¤Ãë„ö5Üò™2²þ¦ÂoKö
1049
+NýÌ0Gõ¾¿jÛUJ¯hu_¿`àe<KêFåùPÃS?«Ê%´Ÿv¼ˆï—èØ_àIÀ€øVjÖ£“ç|}¬ÌÕ¼úT?xìߋïêþº ø¨~¹\6[qQÀçڒaÀrqÅÁk?ӚG_¦¯É![j¿ŽÎ —r¤—`nØß†g³(:ì-¦Û;†Ü z'+¹-)líÊÒµpGD½:΁ˆºMY¡;3A *(@4D™U;nÕ5PRœ-…´ r4)S’I
1050
+N€¸‹$®E´é83 S€Ç6‡ `ߕìåXø…/¥ÁŠ„šÕ‚­êC~òТ|‰;«¸ªYC?ƒwéAB‘§ u„7H2r@‘Üԏ³%/"«³0äòԜþG=´<53 ù2¡Î8 
1051
+r…¤N hÍHBj cLHRÄnàTÄ#ñô„rj®€î _%¾„Ö
1052
+@/ `IÝXR¯E’°•d Ön!ˆ½] fYüaodRßeÏ«³¬U9¨þ|՟/ÂNÊÿè {糚%®ªSð2ú¸Ny†- ·«\Á°nÂ.ËKà"òX*b;`õsƒX£rùÛÒ-¹uË–ñvåG´]u8ƒÂ-\—<aO8‹?ìý‚k³¼QݰE·ƒ«Ÿš‚öÈfy³²] †Ñ8šÑ(è¼z‡³§2¨¯«£À»ösV/b‰Õ×ÀmÂ/d•LÐY= 9­nR¸7*œ%LµaLÉç€åOàmÝ1Ã<ñ 8õøªFfX¢Ikrœ‡q<û*ð¾Xôiû AíM¢ ߐ}Ê)X“ä¼’ä¼K¶I.zWObËkð2ýš€îøØ¶’øoW¾î
1053
+Ã6‰ÃXÿp6…s“úȜr
1054
+_E¤ž@ÑMÝÀ©ˆÇUj‰ÓºOÜi}ájaŠgàÈç;€
1055
+ªpMò¾˜< œ”o…{"ë¾€Mú¦„@Bä^`ˆçNÇFÀˆM€ÍÀ%!wÕ"ÞOÀF*ãmÊ÷ Ÿ}
1056
+Èd4…l€UšÀ -’Ö>¡gõ¾–ê Z£zÃÙS÷àÕ5€•xmY÷3Zqȵ#dýœŒü cKEŸÕBVé–ÀEä5|™þ7©›µ»ðyÝ,jRx†ï.âíÊ·´Y½ ;«§±Øý*ò®Ðñ2÷kDŽõjR]B–¨s`{ò:0Ól™òOҌŽ@ðË¡6õ!Ïlb_G#Ÿqøí!ÂW€Ÿ<˚T> ˷ð³OÄuùjU&\…]—‡,
1057
+ßð­Þ$ä´ntVÏ"'Õ5 5õTEhª>5¶'ïÑ+}1è­SÜmùp 'ÛzyÌvAØ­G¸e9ˆú鼌¼…/¤/Ášä@VÉÿ &õ[æ¬þ‹ öž1³s<žõ•fö
1058
+À­M¢ÎÚ? Eák
1059
+@Ï]€æGGrhé$]?"¤ê æMq”ÕhhU~D›ÕW÷u‡[ý
1060
+YIø§ ª…®$5ʞ¦¾”òª‚ð _&_£q¬W ù¾<áÚXG7„*"¯ÁëôKÜiaÐ.áH ý _Kx¶ª¿b¯ëƒhƒÂ'`‡¾˜„x,õøÕ ¼ÂV’鳩߲ g S} Y¥RBþÁÔÐ]!‹tSÀÝМòxX¿„–±Äª'#¸Œ¼†¯ê×:’ à¨ç/0D¤+€dHPš6X2‚#ðccàæÏKàL@``&dý“eö‹À/½Üô€UHDœÕ­ÁûäT…º1£ŽâË6Ñ·eר\2“㨗ÿ8Ù³©Åpä˜ÑFe«£žTB÷
1061
+ړw¼Ú;ÈeŸÆb÷£¸ÛòpõWÀ
1062
+ åôì™t¾4G¦YgQFo@kêȘn{W†Ø[›ÀûªCÈUuM®}ȯ]£L–C\v×h»_n»‹ÞՃ@“ÂWƪŸÙÁj(§°u„ƒ@«ò/·ýEoûG´]…X»ò+aU<„Z>"¬%Ázt“`BåI4¹ê²I츄ê g+fQ}„—‘LZ£2®Çn¸sÙÝ"
1063
+—N¡÷eW¸"ùž€n¦‚<J|zƒ&#7†¬Ò°$¿‚öä_
1064
+³öŽr¸Ó—Õ/Åh˜Ç4#FËq –ÝÂR¿|&H>vôh±»º‰$îMsýüq[oY²uC˜:º)h岊(y
1065
+\ES–³©œ„\Ž!‹”?ˆB2!÷çpôæ5½Ÿ —Peô@
1066
+ɇp5´ò}°]‚PEä'\‡6Œp«ÂSÜiå,fTynÔ.·i
1067
+v„€«Â]˜`{ A.¶€Ëº3„5y$õxOA+»ü Eð—Áøµ3p™>,!–4©)
1068
+»«<CX΀"Ô.S@ Ā?ó€Jèávå[<ÉvmP_µ¨'0´C0—µË „Cã@êˆí@Ö:Âuȶð=²KðYmo~Ëméò•k½ñØá·õ¬G²Ž$pùŒ„Ø $ɑVØ"Ù<ù²i4~o‰ÜD¸šKÈ*ràdáz”‡hÃê.~×ÞR—e¢oË7&m[ÎÝ2ŸsµLè[™2Gù¤£{¦]ï•t÷Œ¥ÛM#M*$¸Öñ©Vזm§òÏóDòý˾ÛOÞÝwåÝ-ãùցXºu“hvŒCoMX¬~Aȵ[üiû˓/Ï®ÖD˜¢bàZÊ=|¡¨΢>
1069
+¾¬¯£RìבiTsNƒR¬›àëªSðyÙ0z;Ž2Y¯ R,Ïá–ψѦ8t5>|Ó"’~8îÙgÿÏ={‡ÓÏ3‰q¨ÄÅ©Ðeá/Ò9xm2ÚL¢“½êò앤PÚ8£‹478”îP´m
1070
+@HçTki}Ò£uA\"½A<àIÑ+lPö5'û‚˜QQGÕ[bmg³$Òl
1071
+‘kŸØ»ú/·'î²þK¡×½áŒé+p¤ÓÄc›`b5#òÛgÇlM°þˆ;©¯‚°ËÖ1ÍÖyœ«Éi¬«™a³#\‡lVAµ
1072
+(Y©É±B
1073
+·p=Êc4v»ô,w{J;ƒñ‹Ã(Üö²'<×釐«ê5(Õ¤<6Ã6-^’×ä8óˆ—÷åw&ž=µ™c.­"ʵvA¼Ö=Óï>MI×}YîKËrwx.÷c;ß)á|§´ë<æ>Ü“ðº,ü5ç¾®£Êƒ2LJ§ }I×ýØÎϘá:Ì&›mã­¦aYV»ˆÒ­_rí_ZÆ#¸Žñø¥e<ŠÕHŽÑ6Ìe¶qØ)¯ý
1074
+ÊaÛFÙ¬¶q‰F¿ní|^6‹ÛÔÝ2gõ]øº|Ë ¸+ü… ·Ž‰Tû8Äe7 ³Xçq^³sX†ëe3:®Æ¢·v‘È¥)(—Is`¢Ù3Ìf2¿öb±z±Xm£r¬çè4ë=6׺Kµ;G¦™‹Aì-ãQ¬~aè­Wøq}
1075
+ úŒGpíâwí_¦é®¡<CWɟQØý3‰e6ô¢ÙÍ_\³©#Ù¦7Èd·Š¾-/B®Ê‹Ë²!sú¼”þQGòI>S1ª ¢pïg´Žcêu#ä'xP¤“œ§Ì‡ÓhÆÝ9>Ã5Q5º‡(›}{âÙ7¡u 'uLwÒSÚhb:ßì
1076
+DÛè‰Yzeɓ}Al©†à5DWè­€²¥[î´º‡·êÍÁ JEŸÕ›¸Ûº;„¡PèY}­‘`EâWΔàܜ~Õ"žªKÈsHƒò#Þ¬(xy¤ŽøXC8‚ëe´o£²ÌþÐ6u_'õ Ú$ö
1077
+(^}Vï†ú,K¦~ D¯Nã\VÛÈ4«=¤I%`¤§FàµnàÉÈí!leÇXüÖAÆm÷ ʲy^w‰º+‚1§ÏAÍéƒ`“ú'ü¬Å!Ön¡ÃºYÞ¬ì—(\Z‚EpýÌF‘Ç%c ®+8‡í˜É°‡áF«ôª]»l…ÝZ†YLZ㲬&AgíÂT}MZf¸E˳°Uý ßj‹›Õ³¨YÝ$è^zkx_·Š;lw1ȵ_»õ
1078
+À­í"J·^ñçÕe0z{
1079
+:®¿Ö4­p5ʘúiáǵ)P$«[Ú¬+dR·ˆ8«L®,gZže*‚=¬-Á!¸®If»ÜvuZD\βd
1080
+a×^ñw½A„©pĜVÄ ~†®’vZ¾ƒYÕÂ×Ñ¿ð¥ô2ˆ½Oàaá#Ø®>ˆ4pU¾žÕÿ6á¼Lƪ5¸J¹Õ#ÿ6 gôÖ.³6
1081
+>- `K>×ÉcкüuÝ&ð¶n ]¦»—*wàôð¡Ò`—"0TC[Kê.Áì¯}™ÓÝÀÓOW`h‡Vàˆ‡f€É­@‘N}ÀO MIt¤üàôÔH(Úéh Ý 8 ¹8Ê©¥zîU"ÂZØ®phS·¯ÓŸà•Äk‰eÊ·ÄUá°Hx„,$?X鏐«òBü?ÓzN ÁŠÄÃ¥<Îk6‹A­½AÌé;á°Šî Þ%<Ä[•7‘§å1x•n[HúlÑ}"ë†å[KÐ8F¯ðÛÚ#Þ´\øºüˆ¸«›Z”  ÕÃPüÒ0½õ‰<-Ïá¬z¯¤EuPÂè“j4ŽI4ûå ˜½Rå?¤Qù–¸¬Û„ÝÖÝbp[³ðûº]þ¸îqYwn‹'Ù>£‘Œž1«[ nkyW"L…WÀá²J®DÅݖçAFó0~íVDx¦Ÿa‹È‡˜£ºg”Íh˜ËµnClV¯xOØY½‹×g±wݰ­âÊ¢r¾O"Ôªpy]žÄV„¬$¨’ܸLÿCXꓘÃz…ÄSàJâ!\•`%Â3x—xòñ¾’:˒©ÿ!,åC¸Iá'î²¾ ÞN¢-J)
1082
+Gì ŠC.‡Âô̽‰˜Z”4;Ä^T—@,ÝQe­ö1Š7sô9î[ÀÌ-³'ÎÕè™sá*‡hï4u¸?s023жzx¦mB¤Ó:!®q©¿¼ÙH¥lÞ&N¡hî%Z£¥;ëlÍÌ?`YˆX[©Ã/׺8Å]«,E¶¼}ÆùŸŒËƒ”Ûn!F'S¬ÀH*Ñá“iÍøîːÙ~mŽ»y"ùþ•¡d 8orÈÙyH,®Ògë'òïð¦ä°cÛÔÀüP )gÆC)š£v16U
1083
+¥IeGæ3¬S'kÒ&X‰ÓŒ*t°¿„’Yiâ$õpõ_ ³6ŒgÚ óÉfϸ$«WÂM_ÂUGÑgí?0ț)rXµ Ú»?k¶k”Dºcä#[/$‘,9ä53}á*‰€ýqæ`¡œ©Næ;ˆòð¦v:±Ä‰Šq¿züü\ÀN¯]¦p¥xî²[¨icÕXž:=B~%FF|‡ð¾3ñúÌgý£ÊcÉä¡ÜÍDþá?cÁ¿3 xߚ}ôôrïÆ+õºã\ Ž£Ý´f<—ë0ÞMÿ¦D‹€5;ã&§[ïÚV¿@jëNºlP¼h œn}z´\2Ú[eQœ›§¹suͯƠ^)ôÒ"…Qºs"M5"Íi’.)m-ò·2wz+²æïrìœv)jN§$+?Oga-3Ê7“#r3ˆ»3,vY414Ñdj&õî ÆA<Q0÷aüË{$ÿð›Ì'ö&à}„ˆABù@€ùùðS :R™ó£ÆÂ\ˆÒðû˜Ÿx%s"¾e8I5"â¸&_¯AílžM'¾g’ÉT‰â ˆü—Óø4£mTQ“ê€Þ; O:æa/„´³Ê–¹urÏž©]»K®r'îT€Ïz ‡)„K¥øåµ.NmÍÌ?Ù5Ê®ÄO<ªó³WuN¹±Æ¢þJó‚ëRÔ[Aqë¡(Þd§CŐržÔ…Ø+ݐ¦„¿,fmžgwŽN3Çù¬ÞÁ™fÇL†½ŒåÚÿ帼ˆØOB ¤V ož
1084
+kŽ
1085
+ §=Žt6ô¤Ú”èØALóÂÉ•Ö Àý¹Gw ¥=¨ÄÑ;ªÀјÐãê: Ãò¢?&;E‹„yŽyço  mæÄ£× …­#DÚÔg1¨­]DéÖ%ò¶l
1086
+Ú#ûX’WÑçeó]Rëp>éH˜’È‚q½3*ž5K·Æ ø×¡gÍT9ÓMJöœ² íÍu^Ú©GK/ëêÏéWã˜z½kâuüÓ¯>‚Ùؑ\2öÍÃ.„©x£Ü:Síiç_]kêÑ4–w5] wÿ£a¦¼Õ6•}ކl‡Û•rþf›-£g÷I9OD‘o*døGåaԛ¡Tó70Ãtʵ~ën›2Ž[æÝ6f]¿+ïn¢hô•c4Ð5[º9gÛ\6éJŠÿêÐ2·J¬Ì4»è`í¥Jk¨<©u0¬‡X¥qö 3bçñ$´uD{O¥àcÙÄߝzö”³¯÷hú JB?õä³¥RôhÌI}Æyäß§–ïð™I9{&Z‡¡D»sXšÙ:0Óìéã[Ncœô1m¤¼öc&Õ<Ì9í–A³a<vkšî"ƛÒd¶ù”`i)jôô±2Ô³1
1087
+¼ñQij¡Šå¦ùäÜ?2œ"Iâ=ç@3前‡úÕR‘ù÷¯RHV1“Ê%‰9ͺ<ÿ­ÈOœûVٓ­ÛÌá2͟¨tÚÕÐÎn$Å\ÿHÓV™žÞ
1088
+é‰'1À¦”Èhy†% 2#ƒµ™ ¨œÍÀð “֐²Fsã\fó¸4û0–g¿…áõn™«ú.€Vß"ðë–Áøµ_ ³¶:«»Â©—`‚uÜÃwÌYíØͼ-ɖהkù·„çœw¾æL÷›LkrXÀ&u@ ˆF`G柛™•b7Õ°í†Ȱ[‡gٝŸï|úW«Èëò/Ú¾âÏ«³üºi”Ëj›jý‡™­Oçr#Qø¨DQœP•ñ!ÊDï§øÑTJyBoۂ=:fʝôÇ;pҙL:ŸÌ»oÌyøTÏוs·ŸŒû7™x_Ȧ“;õ«ï3ž}ÃÙwO=™t ¡rõP¸ÚǧýCóÍæÑÉfã]Bcc3Lϸ4£a(†Ñ3Êbug³»‚sئQ.«uˆÑºg|›Öb¶iÌ8ìX®y™áC‰æud¦Ù4,Ëê—í­âIWŸ@rŒ¦¡yF×Ð<£e@’IuXžujcÞ2ü£æˆñrÜ\÷ÿ¤^ŠUþØT™K›4¾Ë&÷®Iʅ\%ã´-\&ÏÐh™™ÑIM¡H¹Y‘QW#È­¢rèVQ´ë¨Qû”¸æµd(˜U…¯›Åˆ•ÍÛÄù*ì¬ÑÒeê€EE9Ë6AáË>¾eŸ ÈmŸï°K‡€Y'B:ðÖcT؜å%˜ä›t°ëˆ:éH›’wÔ§gǺaî`ÑÊ>X­Ä©,Tá[¶zx–…24ãf1Vm5^ðTɜ©1jÈCîºW0@ëzČÆàŒBÎ$QÁ¬•,Ь±Ì¢þ›9Յ’äv»f"ïZ¥ï¼óµZ3E>{&LL›J³«VYü%v*ÊÌ*3qï4wÀÏ8_‹žÓnͰWÒÛEo[|ûv‘ÀXÇ&1´ñ®1gþÔù“,#o'²¤×j<çe]2RJ1 ®ZԒi™Àt“=WŽT$³!ž“”zǨ]e­|tò‡)Rh)Ç*·”#•{h4™#£SdpFAôQO?ÚÙ#õ쁏nú¨Íüd”2Y8͝-Ô£·[%_»l™D˜29ëÁ¢ŒKy,f‚bG1+{Y1-¨¨Åôu„*0²† +ùÔ­ÃäIz¼´y@Í2DF-e²z8Û8Lž-G*êÌُ°I[Y†z°¾Í­ç wî’ç»fþ)S+Ñ&–qt.hâ{ à­Î¹@ÏcQšs+ù2ï"oæÙ¾3áæ4»fî#“<¢“ Ó6*i£
1089
+ÃÚ*bתQ«‹udâÚó¤6‰V¡‹F«Ìø$ SfÈèf§ó5wîÌÆ4.ó2b•ÄtX§Å3,Óã6©ðj4¼ÃWÈ*ÅE´8¾Áî2wÐà(–l=Z—X»ÊäÈ>ÖDÌiP³ôÇè ?F¡ühý¬Ãæ0{Ĭ¯bbå!°6riUx6UØ »RÜâÂU
1090
+é%ÏЌ>‘qÚÌ´ÁY‹ZÜ(C±îÕÑ©{]¬‚a-bm³µ¶T†Yk"æTéq7~#HDܧRÐS9>N§Ê–^k2ôk—Xöh£»Y%ˆs[%†}Ý&ÿ¬’" –)‘ v©qîkÉñíkÉñ-ëéífIF}­åjØ搧HÌ»ëÐ3S›W!¹]'È/x[FÚޝsº$§àXÃN*X g¶“*GY„lŒ<E.ûϹ×uHa“ºÓÀÀ&B賅”6eÙǦ²,F-)HqŽ#°#¹ĉȄ¹N¥.-¯á7:ÑèŸkÒ 2”5´´±Ž©UCDê3!Ž£Y—ßxâáÿ³Î×e£iAô
1091
+âGp ŠN¹ZS[¨Å±í“âÙö©±Lۄx‡Urì»A^"¯Fc«ÙÉÕh<èuY˜]r¤ÛF=vq±“G`pš<Þ9M!Ü&g«BÎ|Û$3'M͌¤ÌJRkŒK •…âIírôÌ«ËÓ"bÁO_öÑ4hB³”9Ù³œT/DÏ)–¥jóÓ¾.ŠâWHÏ<ê2óžšÌô[eΜ3ÑÛT꺝Ɇç˜Bփ„²ùL½ÿ9ó: ¹N“»zft&ȑtvO'Küù»œxÖpÍÆ@Ý«Ä-íSb˔ˆ÷¥„ˆèuÔ¸è…ä˜ØeôØØe$FôJbôBr,ä*"'^ ±KrY§Å0vªq Ë%¹¤ÍzœêfÉIgfå!°]evÏ2Ç+W9ëɘzd1ŠŸŠí¾Ë%=H bîÃ,»‘Lî´9Ù·çœ­áæ e”#4-H M3 :Fÿ~…¤ô ÄÒüˆ3D,0´±1ó18³›h,Í|$l‰Ù§*sÊ}4
1092
+JƒEý2f·Û6ÓÝCÆ}xÑ#a4̋Œûr›Ï&ýÇюÚܼ±y›7`\É$[+F--Ö¡Ök±J[eüb•0¾}1‰×²MŽa0¨ñ˜•dÙuü”âiƒ¤2Ò®2œÌˬSÝ'Ç1°2JÌ
1093
+)“‰°‰ 5SâËoMĜ†5Ñäùö]
1094
+©&Bæ4(â0;s‚‹Naˆ•Ú €šÔfsÏ+aLÌ¡k|(ñ¡lõK°šÆï S9–K#Ã5ôdÛ§)Ý|>Y÷o2ñ~óZw‘È¥WvÝ%ò®üŽÏ³N¥¼ÃHqë70 "$ƒGš/&6Û%”=add!mÞ9G‹’Êתõ[”à^ŒRr®æ˜ÌŒÌ%®~­ÄZÞ*㗠µXÖ Oúô`Pžé13#ƒºŸjAV<¢ÙA€;¥ÄÇ¿ÝËÌûãÌqŠÔìB¨ˆ¥C”Œ½e”^Ÿû¤A0`BS#:(õÁ4ìZŽ™¹6ÊùÆJ2‡Oú/GΚ°=K!Þ&˜;XޔӀ¨A G@Œ#â„Ä$ ­!!„r{ꎋ5O*׊5£ìžÊþu ¹³Ñ5g¤·Rw ÿ’±#7GtÏ+ç FϾéÿåk?ï²]… …÷Ø_á£$‡iÛ -dÅ4nµè ÈÿI ›.؏C’öþ̶„•ÂôêÙ;øÆÙ …ÿÿÿwíH0»I È÷%¹r ܺÂeÓ`úZt¿c¦È2™:üæð¥¬ç¿ Ñ׏ú0c.%çᩌˌòL &·×Œƒ~ý­‚íï½+»~õÊÙ?l3…¯O'†îsÚ^Ë?Òû݋g{”9À7£4ÄGTw«²-7s„ÔU«@l½sŸ<ö3pJ<{VÞk7àXa»â½¡·‡}‡ZQ[7í°—åu°*üèÔ-&~ìá >Os}(’:Æ þրúŒR]áj©±7Š<Ï$"z,~zžg;ÄÙ5w×àÂÙï= ¸ë4ÈÝC´ægnÊ)UeÌÐú™õa?c=× U® æƒ
1095
+< 6˜XJi CCµ|žfa“`Ö<¥£:}°h°<ãùbˆ<ü<¶ò TeMõìh©ÿÐÅôb%¢ŸÒÙþÏßü Ì»¼X›­áù6.m=õìÍW‰ø¾“y«)ƒÀהp;ÍND5fè
1096
+¼ÉPÄuåg
1097
+u%øZމˆÙén‘d€”møb‘ ƒP2a®;;u\¬ ²^+ÁGáôÄü‹†æqþæe^æi^Æå_ªomùjõ¯_}ëÖGèe„ºC9kï8¿óT18G8×ùI(ÂÈ&{ÉÜÌk3ŽV€»;EÀ3ýÜ|•q8`æ_|p3ïÝ"I†7ŒäÜ.”Xxÿ]
1098
+²ï*Møpg×dʘÛ?¹UE¸ª—k°ôaZ ?Âæüök>û3ó0ÿò/-/ÿò.Õ·Zûÿ17ÕíW=AUEÄyíØà«êÜð[ožÈVÏi´í6s¸×œ.Þ}›‚p¿ù ÃA붟%
1099
+÷]ä#È$üNÒ®¶Ô‘B] Ä/È{-®yãýGñDbf:M)d²^*vcänëApŸ¾[TôH/=Øÿo©~õ­4ŸóqÝ,nÇ, Ñ­„-ôÓ¯¹“¢ÅuÔ.àe4»N“ž¾Lâ^Kþh«)ƒ¸Õ•:Új9‘·Þã·ž¤ï¾É¸{O¾øÞ“»€ã=>¾=çâñNoF%ØC”D,²äßR3…ŽÚMÐiˆñð×õ¶| ÏüÌ_û-ßÒÒRó:ó;ó5Öwùÿ–‡ù™ç¡z4RAï° ]/[-Zx¢#)N€¦ÿ@0*¹rv¿•sï]ÆÛjKìô¤ö¥'4÷<‹ rêÚU:ÖaqãYÂpçQº(TKÊÝz‘0â2”ÈŠž¢'tOpº§Ž?tTp¾°—@õôM9Ûçùš·©º¼Í¿|NËË×üËÃüõ]ªÕ·þÿ·üõ]>æg>æiû/_}ë¿üÌÓ<ÎëüÏ/ù,½nº½” ®…~8 rpNôÑ®äݔ+c¿Ï)g?ṘEJŽ˜SºÕ•:ÚëËíõ$öÝãöZ’G{-ÙèÆ‹Ìá֓4À½'_|÷Éãn–p·Ÿ$¼í'Ùv‰·Ûy•§gýFXÜàÙ¢<ڧyš¿>ö­}—y™Ÿyšùëcÿúׯ~Ë[ßú1ýë_ÿúØy˜·yœB€dQAlÇEžYOŒ½²ª8±_rjú¡$¥ËbÐí ©FÕ'ÃäºÝB¤ 8½’b”Ê`†Ònƒ¨h
1100
+>N÷O³E¡¦¼P-‡l«'‡´Ó—BÜx—ÖaB¶Ó—?Þ{rn½ÊÅvÞ¤Œ¶ž¤¢›ò0… #$ k0©¸Ä šÏI([^*è°Ô” E#·ý
1101
+C§òë¡\¡ÔC/š! º¬„o[¯fõCÙ£ç±ýÎk¿æo>æe>æi~ækžçºý£ž¡7Ú=ÔÐÑWw%!14Ëê=̨ØQ¶€
1102
+£Ù¥‰³žé4œB˜ḛ́#{ºÂHæíIÌðN±Œó@O|Pò‰Dh§!!èˆ;ÓÓ2ˆ+¤ãvSð>ÌBC–)Úx•4Úw”6 ù(QÁSX¤/Î7‡Ãñ6Ùv–Aéæ’…v—”…v”rC=JmKÒ· S(Ï:%¹C–&âs7’Ö 7’ñp–øú _ªçbbú© ¢Ê}LÐ]·ÿSÅùkÍû|ö}èƒr’¾¬•eÅ{0V.{¶¯¯Gúú˜ßóCŸýŸÏ~Ð÷<‚ï¹ýP‚g;ÃiÏy©¤0¦•H‚Å\8·äÆàÜ7ç@… †@B使\$ŒŒâ&×hX0T
1103
+:¾· w¯3ßx˜‹q>ʈ~óÁCŸâ8F)r–ºù=1=Ç_€`hb“<Pr°­'W|ûEÆßòB·$w‘E6á<­^B…ÌíH¸L ¼Ë2B¬ÅnÌõÞªßUåô¦¼WUÔaUýVÖԛ}]=:ì Êá-̚ÂØÍ‰ºnWræ!(áöd*ÜÑTB`+l&[ŸÇÚö<‚íƒ!ðù®#Ÿ/"z¯CÏDô:ÕìÛüÍ¿\ y»’²vžœ¢') u'‰#LYQ‡Ä4±®³ ¢Q¸º~'ùh¸–ÿx“<,¬ô+4ÎB¾VÓ+ªsrùôY5IPPYqÈE½ 5¦¿…àßhŸK¤}¯í›}7Я-8ðmQ¾{ôógG>&¤…ºÑþëŽO5û;¯ó3oó1?ƒ­Î±9yp‚E—™¨¢îˆæ
1104
+:Q(‡tžRCaÂ®Ë R¨ŽÌ|¯#?ßwœm½Fnƒ' °×¸¤íB?ývõ$`EÝÆÖŒ'ŸUÕFœÓš=»{ôjGoÑÇ= =œÓЛý¼ÔNÏ'ÀÙy"š'šÉ¾ÑÌö‰b´ßSÝùìgy>ç¼ì|ÑUûF0Úšáùí5û5åãƒÔot‘ …­½ÞtÁ¡ùY8b.‚vˆûižh¯%ßëÈÈÅ=H$+ö†QQ¢‡Bvdž‰—¤'KÏ:/SÒus€Vµ·Ï/=Ø!&ô!¸ü éï¸G?·•ôrRF?.Bð[=@?•õy¨í' éù¥íUwþ†æk^æwÞæªÙ'rѾֺãò2՟ŸRŒ}x„\=¯ãÛm–ÚÍGßv—ó·šòÇ;Ùíž4âVWb²MLþNê¡X!ÿâҴ̠Ϲx@¡U Á'’™þÐÌô€]¤·û"ú UBÿõóÝ#Ÿ÷
1105
+òù*ŸžâÑ~ Ͻd[½ùmÕæTuu煬ÙªfÿǪó>UkµL’ƒî FèW¤/žžS®ñ9Ê"mdTÑÎs ‹t§éaz>ꮛq«'? ï$Äõ‡¸‡Äýb €¥[Õ/¿–úŽ®œÒXÖ¦Þόé/@=Ú(èߖ‚¶²;¯•Õ¾–ŽÏcñhß)§ç™jxþIGû h|iè}\z>çu¾Æú.77-_U£2jëXÌÜz•‹ˆéÌNuž¨qºN(†uœ¨†éL&m»JÈ8Þã#"žä%bäg
1106
+½!™n@!ˆ&Zlf ‘4„~ÚëLÄj<ÓZC‘ýü¼˜–ç½¶?NÚ>¹èÙ½ÜTÑÇM=†+¥osBú­-ÐCåøü’ŒÏo«<#s…ùj†ç³¤Œª'ä° ô*hí´%wºrÒ­žôtÛab¶Õ“n<Ém¼KE8eb[ïÒðÍGyØ^˸KLÂÝ~’p·`caº‘ ªSvÕ(±kðƒgN¿¦ôeD</¤ýï‘χ|þk$ôbH@¿äóS=A?•ú§™Ÿ/Âj?çqb`^æEæ_Æ *Wkïa¾ãéÌÍwڒ\m)é^[戯''ãj¹e<¹‰x7¹_Ë5ãw‘–)H€ûH< éä¡SIËqØ ÚâLÕ²Âõj®‚g["ú° íGÑì¼SLö›^²¿tåy؜ªâ¼ÎÌß|Ík¯9?„Õ¾•û1֛ª¾ùW_:ªHÏçˆuEDY¤;M×E p§ùÄ=KÓw–K
1107
+ؓ]̛<àÝ'Gtï5æxûEÆ 0rÁ„ и
1108
+Ô»Ôì0ܬ^BÔÑ{õü¼MÏ3Ùù5:ÿ4£óP/;¿ fç©tzފGûWYŸÏÚùy)›í#Áhs¾û/ÿ-UëöÛÌ$1QäNèVÒÞlÑ9v' 6ˆPÑvݥܝGi€[¯Ò…{O¾ØÎ«dÁNOqïÉ]´ µ èˆê8‚†n®Ý}ò¸»OoÿÉ Ó’¦f¨.酅¤õk®OÖ³ý¦˜œ7²ÚüÑõ摰ÙGPÅy ×ùì×|OËÍ Yy~ےó3?ó./óÖ¿Z£”œõ¹
1109
+¥ÚyEàm<ÌE· 'ž›½içfoÚµ÷ä,Ük9ø|H¢úrÎORñN’2Žéßs´ñökL쫑dB\Ÿ’&Ô]8hQV׬>Dԟ% zªžŸ'²Ñy!œ²Þ¼Îː0Xës¯ M'mDBáÖBy¬AMšX³â,\ KM4Ã5r”ü„Q©Ù†¶äÁ¦Ö™£\å¨bÜÔ88fi6§ú(“M‰A¦òDíðûVeaD“ë£à¹%¼~rZž°gxÊI ¯½¯ÓhûKÖ»æ®éµÐ›¨ÑuTq„þùMë˜hã®ÙwO4qOr6¡KéfèW¾º•/„)aK]WvTP«šè6õgª£_ºÙù›§yëcj€þÕôb"îLû‚.LT#¯<6åÙ •Çùle#ês!tPtl  Ë] Šã+LÃò ˆÌ/Æ5û+)¯ªœ[·«÷HëcBÅ,x¤
1110
+zDT±†^
1111
+†ë¡^n×$›ê=Ƭ:î¹;1³k2eŒG$•-xdÝÆãŒ³ÕšŒm¶g
1112
+}4±îDLªkzeõÐ/t·b6¡cA“Ð@#÷)dW½È—¶³È²Yòw…}¼`õ}`¨;%½•öÀã¼ ö_¾ÓьŠ\*)Š_´i5ò'#šA#áVNÂÚ§}»*n,‘[¡Ê!~ƒ4€3FåÖPHËj½Gx+Cý½ÊÂØ•Ð5Ãf]Žæ"7þp$i‚ì­—¦é•JY“Ð@këVÎÀ}ʘ·[á
1113
+Ðè΅f‡8²€˜ FǙÀxD
1114
+©ý îX¸ ú$WŽe!ÖU……_GÆz½±Õ_‹z5)¤¯ú£™ìÁìüÏKös~æ«UCED©‰`pAN="æœ*PÉÓ; ‰Y,EÄm<‡êY\…íM¤4\ˆ©„»#LÌuž æP“ˆá:'¸Ü3½ß>O›ê3ΚJW˜5%ð‚ÌܕœÑa™"ž«R%LÂr
1115
+!%qi+TÆpÝ4M­#1ëF¸E (~ÉTŠÀzùÁáª%p\õ窦ç.-½X“Ò“§|O߁¬é÷ÀN‚›ô¬ŒþMу‡|”NÏÁè\ÿǺc Dw©õÊ®%k”H¢+ùñ ÍtÇnJ3œ•lj`4{1°(îf±A¦Pe'™ço–ä¥JߥP7šPf Ù¹;9Ë«¤böŠüÖ¯œ‘u&bQýGX†^Y%~[6󵬌 X-îSÈe}Q¡*I`ƒ¢nc «ù¢êE¼–º#—P¡eÓ)he•!'õƒlPObÜô|ã§×ð¥ôß%í‹!èù®­ö¯´<5£­>ց’Qˇ3׏ =¯˜Êò9tFۖ6ÿWZÙË^CÂ"jw%Œ¶šòǛòmx䈞>÷P4¶>Š&îŸgcÝsL©3‚õˆ
1116
+vu\ZÝóË©ÿøªáÔËz‰œ«‚±´£¢ùô£¢¤’Ñä£Â:ÚA]€€‚¡Ô“ŠÁü‹r¡ôsºò¨kzÂ8¥A^z cN¦ èŸr‚èEû:Ÿ½Æl¯Ù,¦¬.”Ê8E³3Q͉ê®Ã -‘9gÛYy¯å?ÚjÊìôdvzÒÜo~¢}ºá„S8¾J*纔ï†.EÍ«{†1u^9›`~€À¢Ñ\c唢¸Êš¶³|X¡¥ÔpAuI¯¥.„ A—á€çtÐÁµQƒÔà2ú3"Ÿw²Ùù!¬Îk±:¯½f?èÊóB؝·™™Ñ>N‹4ä~JæÖ»< ÁyŠB„¦f ¶çÚ}ù1F(†x ÈÄxßc‹8 Ð lM$À_ ¹@XC4€½Ó'f¹nêë©Ý¯ÎŒ«Cñúé>®hH£¬B(L}¼üô&ºO¿Á+éÙ}¹‰è½JDõôRY Òz' ÒzŠ̄ô¬~Ž›àã }XÐ7ÝôükÎÿ̸¸X[T£ÍVöumõLî…Nª†wÀ3+r2Yסfևx!X™‡ßx@àjyåâ^äf[ÐñDa!ä_Q7:Ñ)bo/‹êò¯,ŠZú,ÑA0šxQU ž…øéï˾BTї•„Þ[ô]Z¡ßúz-Ÿ ¯òñùª-Ð[Ç·Ê‰¢— ’Lřæ¢2ŽÑPg”$iæaӕcF`kEpÂÁh Ì [EI!–5s«Ì—Goœ½¤5ÊFŒ€c!Eâ­Rà±)Œcðã·Ïç·Ðè“‰ä­ ÝµÙ4‡8´ Öè·÷úê¾T‚­W€tõma³% €ã%!~þ~WXœƒØ\Hù©æY„е¦$‡i-ÐcÁۅâìªï(wÒ2 ÝÊ×CO¢c ÿ%±bnS¢¾ù]†º­¥KÍÃ@,ðÄ^ ÐPÔ }xä º¼„± ,Š ñSA²Vçaù‹T‘¬T#°ÌC8wæ91œ5‡›ÛŒ¼ˆ`&ºÈ¦”£oM Ç_y‰‡à˜jæ•_¬¦öVTdöž·…soF0ðäÖÎ/ÆÕ}+*î‹u¥Y/´…iö0”¯ÜÂB,ôÈ ‚Škö<ˆ±(¨í¤H½ú µµ V'…Œ…
1117
+y­?1 ë¡b8rµ×{,=ÑLÏ€ÉþP Ϗ4Yù"lù8–àò¼È3›éóàÝa#Ñ(QK•îp$²M}™é¹áŽsî&À‘ mc¨1ÈB+îֈKœ— !›Gu¬™ºSA"Š¥|’§$ÃQ’ñ0¹a(^¹
1118
+÷@\…kCÿ¼öifàßÒû20²@ å te!våmbsÖÐyۂnÌä(ÎzÃ;å©è=²Áþ
1119
+µT#ЁB­Ç€»®Œ›ÃX¶F7éI 1©®cl«GŽmuÈ1§Žƒ«í<áÕBaêἊžKÁϓ§’þAׂªýÕÃcm¶àTE·*Uыô#¼ó ^Cm@é¦aț·vC1ÖC„°‹]ñvQ9‰`X,Ë µOÍ:y<ð‚Þ '¹ë։“tŠÅ 6»’# ¾â#\Çɉ®0JY£’CmJˆ{í‡D;q20@ø12ñEýÏÔwii夸 ¶…%†šX×á½¢²ø]Pjøåê:ÒF `:F$<¢Vq¢35µì„ ²,;±› ¸/Œr^X´®0(\YÀÒÉ,ÁåÕ9¹z¯ÓÏò„T9Ù a§GÂq˜.ÆB+Ù:”Y3‡Ò@ƒ•¶(G9®qKYœÅHWœ—pô]æ"”cìäÐNo9HÂÃfÒ e<²MEÆÇoõÅý&­:Òz £¬ÿ!²z0ZשG ÙA&üœÄâ. „êÛØüo`µƒ‘ýZÖnZ6ÒÞzç÷ÜKÑÌÕ,®OI£Ð£tËýI™‚€°—´>ÃYӃ%8ðL8=_sÝyS hÜΊh†©2ãã°&/ÆàÏè%;Î<ìUÎßBdN>(#yá¦5›“ÿÐV왷)Òbª#†âðiŽ2
1120
+ŒqT¤¡xHqÏló eyø ïÔüÜ38×ökáµÇÊ*û3¯³žDc4*³Ztޖê‰ÆZ¹†Vàq<¡
1121
+%ùégYO ³!'qlGT¸¿OÌy£YÈ#˜`?è ˜mõO°¦ÞèõãäÝÕøàêÅVJ/µ z +ÎcÛbò!ú iZ4î h:)æÔfú7HeþÐ)ðòA·ŠŒµIËB,Öf=V Æ/V;³np g ?ŒË¸!V;Àxm‰2ߤ …ß(ÒÝnôvuiB~gOQ\˜;§÷5
1122
+ùÍÃTŠxè\‹J4¨-AÙÈLu¨a9dè>¬ªëºÊ‰!¢Ìܕ å¥V!ãU¡B–ë¦_tEsëPÐ6ô)jz”³®^$ìÆÑΫåόõb¨¦ß^u~K‰ha]½ñ •H2&@ÎbQ ƒ‘¾‹U‘!ÞB…¡öaމ¶ ZiŽ0êh¾úˆfk’ã|…¤p KAl#˜A\†EÆx‹ßë„Ëà ñ­SjÞ-=›õJ4#o4›=µ×¥Þ+…¼Z÷Ÿ×Ûå]¦§â<PÔµ’©g0‘£Û ]ãöG4­Ž5šL‹ dÚÆ=2™·#1kЋ€h †Íf_€ ¨=L ¡ˆˆ"ã1P‚!ș2ê@T6Æ($‘`‘!)(j©Å³Ó(ùã$h^¨ÔåV’2ߗò/š À “<§hoþçŒWS7°O—YIR3SM×NøM€œÚ;ó@p|yßēšzç¶e{Mün³çtŒKë,Ÿªp±†>ãéfŠŸ~?ÿÈçgº`&KZ_ºèÜ4[Ȇ ë¶j>¢tIæú7(ý+ç³DÜ-àteºÖÙ'ǶF­ým¼o¢¤H­Î›ûõ¯ 7´o«¡F,შßE
1123
+?¦íšÓ˜CÁLÚ#»òùi$z¦pÐøeÌï$f¡lœë–˜¾±;€N»ZñðûŸ¯¢áB#4ÌHª«eõ0þN{†*¿¹®_åaºY"R³ JˆÍ8 I$p¯í¡í°S`¿žù¢Ãà½ÿg€¿ªp:°sQWǰ÷â7 Skô]Åދ?<>¶Ñ!~~qïÓþ! ý{µx“Ð*ÒïQûafw?Ã-9Ò=ÀÐý({1¶âý³
1124
+tî*ÜÑqG$í9€¬y¸Zÿ=·»Ç ³Ð.ÛÅLkÏËKô˜žuï¨aW)œí
1125
+!RʔR’"»ûów·þîîþ¯Ù]Žª]õ’,%ù3‹’Ý„§ÐήÁCƒ™sa³¸Øú¸ž³,Ü«ºÃfžÕQ‘Å/d†ö‚dÝ-b† !ÒkEÅÚÎñŠ£˜§D|#ã@ø‰…‚N¼ä‰e',¶u•­lUÜ¢H)fJ±"6:¡"ž˜",¢É?=ü®.ë²61Þ°"„ f“6ÐÌv¤;€örŸI=ß¡Æ_BrØ3|Úý švÊÔ²£‘ò¸*¤a¬N­® 9´LJ({Ž`\Áo­ýóPXö"%”²ÍçaÌ£±RBû½ô¾.ѬIè ü/ݱš…«õ_ÚÀl˜7îm£§vCèrk—î§vaeaèÊúLÏ-¦â¢,b#"±ÓRKÚVvYã¢YÌ´°.na²‹X6öTO1Oˆø‚̇(Dì%Cýø³VOoÈO ½j§ôèr¤ lë~ ±
1126
+S¢C¥A&·€éí+fWW¬_ƒ7F/ 3k›êàO øÌʦ£´W”þÕ¸v‚úv‚è«i9ɔ«â¤œtA¦LÂGŒçЍG\ã7‚kžÒÛ5púq(r¦RLZ‰‰%mD¤±YôO¦3oú›¢Hú
1127
+Œs¿‚¢\TÚè‹ `ä<ao_éÚs¬µJÅWÙ)·/9'ñÍgÍ£sÝøL_4
1128
+æÝxK—Ûשø–š¢†ñ+Lw–Ð'[q—ÍðÙ'³Ø`ÛD€X'„b
1129
+0jŚڠ™2Д6÷ü`·¶ë"(¤•¤`ÎN°äZ'¡w”Q›„Cš*v_©b66Ã'O2Å̒øqHO€|›C(@Ho€ÞZDFµTG0OcÝgVÏԝiiîδ3ydÛi`µŠÕç-b\v͞٠SÇõ+.´´ÊÕl¥zÙÙØ:U¯(bŠ›Œ˜âqM,!¾q!®")Í ¾ÈÚ ªÍ*[W*ª·®¼ÝS*dôumusÉfÝ„Ðz|•—ÕY¤£qãø†Ð?^EA( ¥ŒyœI¹–GWºÀ’îÀFq€Ÿ¯ZpiÛ- $ ò’‰Y£æ²8В‚àòÿTÂø$¿h_¿@yçuçºO¦g¢`SÖùÜò%w '•ž…‘ðœD:É[ ×&vÞ8~j[–²,OÍò²Ê•ǪXý*DoW’‚9×ð©ñ˜¨)á(V*R¢†ñ+ËÚÕÜò¦•¥šÝÕ 2Ô©(¶r­J5ëR1Xu)gt®
1130
+„ˆU§ÓUëik)ßц0=#¥Úm<úYžJ/=ƒ—ÖgøÐæ%pÊbO¨Ížù½}iM)L™iœÙ¬6h.ØW0@3™rf6ûè ”{4…F¹®Ó×w$径¶¿ÓèíB6
1131
+é( 2»Ìij¿NR£¶‘а£&Øä"xÒ>Áõ ¸«¹+»s áþƒ90keª8ň£˜ƒ†¡˜(E’
1132
+W}0؝%8ºÍ7ŠpWO±Üt”  òzƒHg¥`‰g5B@ *¿ Xíˆ`­§@ªI§¢U"hVS\PiAʈE'–)¡×J$¯?¡à™G²ŽWp´£3t -PÖùG·>%Ô£•. MR€åãǕo»4 !‡sR”såŸ(73i )ß̰¿Š„bQAÑü¿7¡V¤žUÍ;, I»«™·3¬­­s«W¢â¥Jqê‰Ê­ã¦#¨øˆ¤8* *Ö¶˜Š™†Žb{Ê©&†ZveM[µW¨ØŠ„Ôb§EA`•‰ÓϨªS¤°N%¨fF©Ò§EªhøÀR @Tþp£pöC.‚Î>à3‹–$ˆ-ø#ʕa¿"
1133
+ä|¥±K™^þ,%¢Z-“QÛëZ+“ÍÏ $¯.™Ô.EPI{ì6mô 4®Ó>Á€£ŒÔ¤r!*è}&¿·VQJ,}Q@[&Ž»kž{¶oå+:³9© %¿.Ù¬«P8ýË[Ù-ÅHDL±ÓÐR\•ä[Mµ˜€é­jÉú=€½všAÅi¨˜L´'Ñ.„Ì2§9âžVœêˆ‚SÀ³ÜÐÙSWøÍ6…i=Cg^'*•”eSÐþ$ȶÏG,»!E´[NrÜ@5ð¸à›œTo¾¥ðày<ÈÒC‹ÂÅ™¢·S`¤ë>–yýÈI$m”Dr–Èæcì¸>§ONc¨óI;zg2ÎÓô¡q´¬ì
1134
+÷žY¸V݁¡;ó.Ý-W­RñÐÐR|ÁQ %µÂÍ®”iU]è¸U>:©¦N{Xÿ©ìÔ)Õ©Ó TT§HUbuŸ@ªzj
1135
+UtÊÀӉSNª è¤"JÀfµétÆõ)pr"ÒFº&oí¯xeu
1136
+†r¶ŒÄ³ö
1137
+2º]*•ì7€k;O8tû=ẺÆÏ¬vÇ”™ã«c+ú[—žT¶®T6‰j3(x®0é¥OI¤£¤`ú%)’=¦olŽ‘†XÄʉ‚¦œ<•\ë$Ô¦šÒÙO4 8ë ÊõL°·—Œ~¶ `ÑÌðw?’lû„8Ù¾1R[EÉñ«R>y‹
1138
+2»S‘Êõ嗓hj¥ŽTÖF¤\‹žÄ^ä@伂IX6áƒQþ
1139
+´™g_{¸yÙ:õî;¿M?[HÔÏ.âHiäßü
1140
+™V–%ÍJ~'&ã ºuõ?ñÍ_ ü~F:;åÞ¯áCûq=E?%9Å5”Ôƒ¯mÈ!?‚žK0°(ߺÑ+cYYê×-¯ŒÝ\ækæƒ@÷<ёFúÉ´s>*œ7Ìðã7ˆlób—¦0)G—cŽ
1141
+€']e(mŠ3OØÛ}.ïü‡]ÉôRþNntí~v꫞`~( 4iEÞ\—P °3A¡ì'0ì>˜v>èsï•JÎN`ÒK\ÒP¦ž2S›²ÐŽA¾9÷aìÈ蕳m6¶’«*[46æ[ÆCìð«;Œò}˜:1¿R¶]Þ¾dI¹ŸAÆ÷Û®uo]ÜœAPÃ >˜/—¿¼q¹Ã6
1142
+Šsþ‚å·Û®u „néüàšÏA|ó8„o\î}â}œA·¾³èýHR.e§ 4çAyˆ‚^„CnAñ®†y+û5wÝúˆ4LCEÁìB¡…ÞF·>Ûâºbýώ°§VS¹¶²
1143
+ÖÏÆ·,«`õl|c«1ÕÑS|"ÄP\URºQ\›3ÔГ)<Îq 3øæAbp$ (g¦“´a—ŽPؕK IÌR) t¾)À…çìaÆ ­cHç0÷|ҒLÙ:A§ÿjÂÃ&câÃîààKÈÈ*Mɔ³M@»Œ¤ÓVbæ#rzœ~¿ÉIe—r’铐HvKÂt†L0ÏQ”ã*ïj7
1144
+»)£Ï®Û¾°yi©[ß~ió²zÀæuO(ìn7Èÿ¢~5ˆ}ǐ·t·¨.¶Y–3¯,„·2SWö[θfªÖ-Ç\®ÆYª¨¸…QSLbE<µb‰…í
1145
+[!<LJ’HfM.R·nk<c§Zμf O=¿´A¦¼tæLBÈá¼dª)' Sæ¡´›k
1146
+ÑäH9YI›Y­(
1147
+t,(;j' 4ç7çF¯7р⌭ ”)Q æé±Õ.­·ŠŒj­Œ|n­Q2k""g¡ƒDKçÏ;/ƒwÆÀ‰ÑèÆø ØŒÓøõÊ:%L+I±œS$I¤9ˆ‚ýN¤œP÷ÅU¸¼5öUS-mWòŶó-£©bu–:vcaÀ.h–¶«,õ«[WζY0—ÿÌØ£™6¨¤¯„öj¡4 ,e O0ǰ™×Cè(ä#xÄ ;ˆö‘€a…E9¿®ùr}£[ÏatóB;ùS›ô2¸QÈÙÂã·çÊõÉïÂÔ»ƒ*ùê K6~ŸB!]Ü­Øx;g[̶üN º›DŽ¿›ÅŠöSH-νۦí¦nméXžªŠ© â%FqPˆxˆ‘ \XvF°ŒfY˺ªlÍRT³úÚ·u½Ð™'Y0‰š2yAú7s@à/ uOy ŠŽ;峟â(ÿXöq
1148
+ƒuµP0':Âȝ6À¤¡6Ȥ2À¤­xöۉh­U2jÏI:ë##‘t…Eºÿƒ ö×%šµMÄS[mÂé2û:Œ·Œö¡üÖJ¥aÞÔdò§P ‘ÊEÓ*WYšªÅ} W뿬‰Ù3ß3¦ŽëiøÎ¼M!Û¼ÂÕºÆW©±õ©EÜ«RñÇJÅURQñR‹¦¸J755Å%FÅ"€†â 8Bñˆ &b¬*”ÍbWF"@絈‚pvDÃY 0êG§²8/a`I+]€9o˜Ñ×_â¸3 /*•”Î
1149
+ý0ÌaP)oMèfQðb¥@>Ÿàdº™âa8¯h"9[§tz™½:Á'W’b9;QÉ­ÈðStö¥RÉnô$ýAð°­O@„£5€‚ùΤ·ÇܝÑ/sbô†P°Ÿº@³;Yî!ì=˜ßރéí
1150
+_p*™Çª€u«ƒ¹.^#ˆÆ+PÆñÁ3þÀ FS¿¾5¶&=Åý Šê‚[_¾b²…Ì/]T*)÷ pp®' x, è²é(=?¡Ñ±O<=
1151
+ÒDCå^ç
1152
+ؕ¤`Î-¦Tz#%´‘G:„Bž#ÎÓðuwaüȉ¥Ì+ýQ„Ê'Š0Ê<aoÚ؍ˆHP/sdr g&'”|gÑûcŽ­Šå©)j™Vžé+ë:1ä~”FÚŽŽ5…‡¯—Ô¨‹€œcâÎFŒ~&#’¿ ÉäçÐÙ÷u ç¾$^­ËÙíªµ¥l‹Žð‡Vë ÆÝ6à®Må²çøÎ^©`[9ŸZ’£ÛvùŠÖU%k¶ÆTJNq
1153
+!¢EÐP̄Â(þÖ¨–îÖ “'F»°uÑT2ûâ £að\ôØ_«ñSSÏâ÷ï4ÎÕ4÷8Q)¤…AfÒ “&Zò8{ Ñ÷q
1154
+Óì
1155
+Œq‰I˜®>Á´­ÈðJDz (v#ÒGN‚¡¢X Ñü%tú§#‘öÉåýD$\‹5ô>“_žz·H¯3¸Vß®u/zMßÙwaû’m»>C8Ï®°H÷iöÎt
1156
+å>Ïâ÷÷DzíM»»Grî¾ìÖžõ˜¼²Á.̯”]egò^tÉ;¶0Z%ë_YȲä™=3O!1®Æ)Tû-j[¼%mk†Éë8…m]אָŒYÑ+d[Z&¬¾®«Uaä^ɧf$ÇÖ^j%qì;‰töKÛXMƒ‡f‹¸QؙŠ„}‘GŽaϞàצ­Ù;»cæ*ÎÙdüÕD?ý…ȯíÂóÜ\ð †l·Ðçß-B°Ž¡+û-eYÞ¦Íþ çÙB¡öQC"‡`ßaœû4{g¾æN­Ž™;«Y\dõ¸–­Ô0«ùÆo †Žì³ˆqqi]5„9.—0çw½_æîÌS»ìkœ‚ryóÊ•:ÒMPr0š³Wª´/ZgñÍS`„ÓPc?‚btp«'8ê) 8ù…Æ»»/ÍAã¯î¥œÚ:‰ -
1157
+!18O#]ÍÁ³ïoðìë8€luˋ,Nõâr šÇñ[»}í¶7àî½B¶å*XóÌÆÆ[¬T|mÁk­Q+eZ¹em+W!9Å*6ÅT+’T´fª^0z‚⟁ÆiþÎ:O$¿)ìö•0«yëªãüµ}øy{JÏu¤Î*= ¶NÐéO(°8ó4z¿‰ ;T“K¿%"Êm®4Ț‘pÞ&zz7¿@6
1158
+ÒÉÞ"I¥wj2ù‘H'9%øçÊý/÷³pµfª‹/;xóêþÒºËÛÖ¬²u[©.ê«70þ7Æ©]v–êb›…ñ–u
1159
+„tõÁ¸zfÏÌ·˜eñ¸¾Vc_5åୋ[˜´£†]aU¾üulK³ºÒ€Õ8…E9¯ƒ÷´uy®ž¥~y,u̶â$v½
1160
+"Ž3†Ê»ú¥m¬»¢WÀ®æ˜º3îdÆ·VàÙM `ØeðʾŒY­ÂcgAxî ì8jôÔnÂ¸;ƒ¥É®T$Òoè×rbžfïÅ¿ñ[³oÀn5]÷ç¾Ù<Œ^œ~Ÿ(ˆ#Í4å’&JÒHuÂpYãêñŸ­ñ\UÕÒõšuÛlH¹Ú†¯ûaìÆ<Œ—¿Ì‘É5€i4ÎáZ—Ù{A³œeÍ,dYr„ÁîÌAìdäù—91Z…ëÆÞ ªù;
1161
+;P¿Þcéý?¡x½hË«¼ÁŒž½ ´›H`‘¦ùªÕÒ\ø8¿‹jdm‡ÐÐZxüvjagÍ_×Õ9ˆmöM Z óuÑ´£•”‹[>x¶ ›–µ°ÕXË:ł–u¥rµV•®™*æÎLÃ瞏¯²Q±Š+â«Ó¼°ì†üæ£
1162
+ÂòPŽ3‰‡sˆ‡s
1163
+ Œs›²?òyi¤Ë–  \
1164
+֞P´eø¸{“Ÿˆ´‘#ðG-¡ü\ ÌÀBãa£ ŒZt’ÎJ‚J=bÐ@ù>€úÕ(Áuæ†ðWhÐó0zm–3,Á.Ìoøäó"í¾
1165
+˜¯ŠÿT‹Z—,£WÖ°}uj؝…ñ’õžÇºZ„Aßãø­[Ô´è¸ÆRÅP,œb­ku̽Ÿ$åRîÙ¬ãæ\Ì.ݰy…{5S±~6Öf«/rdôgÞ?*œ3\‚=UL+ÇZ™ŠjvcЁÑ?žx¾‰KÚH $m¡ÑîÇН}scŸ&/í[ ¬óFN&e( 6é¨ 6¹BÎÓèý?—xu‰y‡O¿ï©ç9töI d«ƒ:aüN*½œDÆ×B0㾙ب©¢Èè løÕ4wjþ%N¬»°}Ñ+\¬,µËjÆ d³‡‚,r<{"í¾ƒ>
1166
+%­dJI°ØqÙ<•ì–U¸jl—}}™ã2xf<Ǝ¬Ž0˜ÖmÕz„@5^ÁÑKOˆ×qÛþ„C¸.!†›×i„ë=˜v}'ÒÛgôÌü˛XŸPøö9xöý
1167
+ö!%Š4F®4åR–
1168
+XZ]™lÖP¥•ŸéÉäO>ÿSywó,ÒÝ:ŠñµIj…{5÷'5¾\B®¼‚àØB=Ѥƒ.Á6P†fÓÎ̑]IðS³ºüju™ŒHúª$‘Û@òžGº»&¯ûkðÐlÂ¸FŒ—ìfÃú.ݬ0δ0^0íÌWKuáç±?· qÍ,jZ2„ï—©ä,¦çL>ë,MÊȤ­AèR¯úWÓxÑî–Zÿl§ÐÎöq¼»#ø™q»úŒ]ٕ¶G9AÅRNQ6ൺéIØ«ÒHï8ÊÙ0udÆï¬[€¬ó>Á5£÷?ºy>{ƒœ ƒÎì©­Z]¤9´IK,é3ø<‡P>ÀT#¯“øAȏž<r žxõdÜ !1xJzɈ¤w:B饌PÚU"’VQH µ(t Ò|Ñî3,O«é˜c«¨Y^–©3«CäßSL­ž<Þ>–v¶Ë[gI³¢mÑjQÂ.D#ð뵤au,ŽUáú³ŒY b|G1yÜ:q¼{Âu5KZÖL%û2»0¯c8÷=̲̳wéì œz8½6†M;[ænÌ^á^Í-]-9†oŒ̀эŒ<rA9PøNë’æå[ʶ8†ð×e«¯„eÑ3ÞwÏc]-ÄãϗrȑšHÒQR0€LÒUH,mìKíi˜SUc)¥(®[0" Ø×$ž¿ƒ¦ gÓÚðu_ÖÆjœ?4« Ì¼;„(Ÿ¶BŒ·íLžYͳ8w'‘.ÚRF­ž8ÞC?
1169
+ëym0se?fŽœfO \ÓZH”Ûî Êis×´=rZD·:‡‘­–¹+û+cۙåÅͼuq ‘u[JlÜW(ŸÝ‰ô™;û3u/X\då¾Ý'~úF$o$$žÂ"œ]ÃWfGèKûA–xÛ¢~ÚE8í·°/· ¢zùì̞™ê„ñÓyWߦ}—´.Zåë[ã{¶®Œeaa¾\³WF× žuF¸bAnńÆÍ5Dtk}²ù™žLöM=_qîkÍû, LÒN¨ì×4ë))”vz¶N¢[ýÓy÷CØüB3?
1170
+ …ž¨FîTÒîG0­®F0o%"“„¨àý²&f¯|mé–Z?çÏm˂ˆãg*ôMLö("µ,Jû§ž¯ñK›€èæ…FýQÊéÈΣèµÄ}ùp_uC8-‹!~©tÒ/A™ìOIµDC9L<OÃwÖÌuqš½´þƒ¹ç‹ŠDÎLJ(w ßj †mß'óû‰ z¥
1171
+&y~u ÍS¿´Y·®¹BØÍcؼë$x z4þêFºÚ§òû=ˆöžp] 3Çõ3_4_s—¦ù¢y¼®—ùªñ£þš¤ó7)¡ìE?½TJÛ; yÅDúhãø­Ý+.¶G°[_‘`Þ4Џ"G9Äè ÿ‘ vÔÂzK™V¿éÕ®²øH´5hîÕ2_®ÝbÆÅ!̍y Ê;­Oð¡ò®¶éK³U®þWQM©Xq¹-‹ÛÀèÖé¶>t[žrV-d]ŸúUË/sa¾†íoÝó"ô5~i½g©a¶u…ì*‹#øÖ™4àÌò)5ºÕÐÇï‡ÐƵg¼i߂ã÷÷4ÖÝ3whÿå-ìW@¤«Uü@ôTD(oC"û .nã—6ԃðö¼»[Ƹxì³W.Ÿ´d’'1‰ì>–v5„;]ŋ®ÆQHM1’ÑŠ¸éHIË[]Ú¾h¿2Ú¦PÃì‘Í=›sÝH‰#­sïÇxÏ.Læu»]'q®¯h"9WMÑüS¦˜þh $Ç!ìÖ3`²¢`Á2¯ûDê}ž}hÅÎDúX/ ‘ô%D í
1172
+ƒtÚF;;Dh mÄ@£Ÿ2Rig‹P^Y„µRPÂuSu
1173
+!1¼‡Q¾oÒÛ1d~¿Šû’0?ÑÃð_˜ü~œ?6Û'òk³Ù©”Hj©šHj¡ HÖINˆw$ç|…Ç8ÏIçQ±CEp關Dz Í=ïÂÖESÇ´2Ža÷‘Ö+–4r¡_ÂáÚoéne]Þ¼hs.<„<0ę÷‰†0r¥&”SS4»ÔLo”rþ hgpÌÓÞð±Ù,bYóŒÞ‹%“gdÞD>9ˆ5ˆÐ>­‡M?CäݽCèՂ øW4 ÉUøPœ(÷?Ì賑„@z" ‰^§înAëê0td_Ä Áz)Gí
1174
+C'¸~y «[Ұ藵²ÇÕ:@ûú,dZœšUËñMcW¾¶4k;³p±`¼b°K“gVÇÖ-â*p¨11ˆ2Bˆc rœ×0B"Œˆâ»{8«©¦<n~ýüëUv_Y_M@üÏ
1175
+ÜÜâ1xï¬<Ž%9æm¬øY°7¢ÃIŒû¤¹W#^Bç\NüÓp@27í »}xîF†?+{Õ ÆÏúó‡,œÇr¶$mžÁxóëþ¯ø´£œ}¼ž|<h ÃIÉö¿ÌÔcâžf—-ïO®·4Ëiä8¬ü“ómiSJûºžùy³ŸÐð77ÌÊBnÏP îðÞ;µaüù‘.<"Hy1Ý"†ÅôÉÒø¸Iגµè³îü¾"饸O‡\Ǐû#äÅ+ªÿúLÏ­T&cüّ §Ì Ï]kÆFæŽÛ“dèêyP[Kóã—ãžþ®ÿC޶ %ãÿËëӉ™¿Cîëړþ{F¯ñ]úëÕYÚ.nÛObAl¦º,GS0A­PPPPPUÕ>Pl§žÕsnƾ<¬Ø¤ÚöÔ 7…S °LӜeŽ.B2bR"ˆL)¥$¥Nµ“y°íX9ÐÉӌC`$Ú[_[G0”§ŒQÉÅ/õTfe‚ÅU½T
1176
+ãU‡*v9OB¡xQÍ/U®ƒÈoÍ3À޶€øÝC‚j1V0ÿBõâF8°*€½„üh¢C5ºèǑƒÖ7[¨— #;%‚¼Z_íHŒ=áªi2«~Ã-›rpýZ1«ê6lÍúgVãÀ)q¾N%ÎÜÙGÖUkäõßt™5ÍVì¯,³8J—r«YuodJׯ…‹Åœ²TV§gJí³×À-=ÊrJ¾©{Î T°×C$Šc¨a]eiµQ¾ªd™µ%ͳ‡váÇwÿì]\Áþ ×w‘jù$Z¯ à‘ˆÇ¤-}‹ÙMóFƉhdù‡ðÉPJy‰D?º'Œ•`èæ•¹>ï—0¸ý9qÒÏC'UÒ´-ÆØŸ˜[@”{Aã-f_{&­ŒóÔMŽm…é‚§ˆUq3¬¾²¼ò-M­ºå™U³˜]Õ-Î݈Õåb‰§¢ò j'/Úè¤ÉçR @QLž€z°FÖ9Á›;XÀ'•¡ˆÝ,Bƒ>y„’=ZB5ÃuƕÕ<uÒìÒË\ÅPºªxÑGE™° ¥TœV3 µËϨ‰õœñ³ºq§#Ý$ÃêS¬’&,f(“ò“‘ëG½X¿fš·%_qn%[,V¨0³’=|S¿ãì¯0·ü5¼
1177
+v(C$‰Ê@Ɯ¸÷”ƒJò¦ˆøÖêYf™~íœ/Ú·€(ÇyôΦ2m`žh°ªÄð#î÷ŒÑê«–Ióâ;ahŒ!ý<ßiMÓFÖmڞ9áçgqjqêÖLØ'¬*™|Äy¤øLɽ:º0»¾ËӋ£yù•²¬]üP*ŠÊ2ž@én¹è×OérÁa¤/”f-ލó…z%Z®Á;ZiÆ[Ç©{Þ|&kõ—«}CéøIu nt¨
1178
+þ¾ß]$ØÆðv#ÁµŸzp]Ö3Ù¯)¸²oWö!p™M?ètÀÒÞâäâ([Z²LÚXŽJ£…Q¿L·>J—r£tQ픮*~ÒbŠ>qQo£Ÿ‹É)LZ$£^°\»ëÜ=k¡>µ¾¦þ˜)˜¿ysCÞa¹“âdŠ%ÞiHx¶ycz˜i—W³ê.f]1Ô¯¯æÂêK±>}òbŠf1ÓbµBpC]°WP"¦mäȺ1k*
1179
+ey!ìÜMAèè$[š.ÙÜówÝB†Ù#Ã톺àïK ©ªZ‚£.q>® · ±DF`ƒ=nBI_'‘˜ç™½ip ƒƒ²u%Z«-eäÚQ+Ϭyè/ûKl0î#„k ¿i½½â-hY<Çê{ÆUß#¶zoΞóEûAXSýêF­ž4ví¨•'Ö<b‰¸Hr÷S–T4¹2ä“"ï¨ß¥ùÕcÐÆü ×ù±2Š'ãÖ¬é7å"0˜üVu2ÇêSʬxl7‰èq©€ÙDcۍÛú ×ÃZ[ØÑíL<º/h4[äí'ÝØö"YOá†ö‡Ó¦u՚'ŒV׸•ùãœYmd¨ö+ìðÒNÜɈ€é ;àè À,·ñ–ñ[2:ø¹¯Ü'ëà
1180
+†Ä‹Ö0T0Îb¦µQ–S²ÑWaÒBJÅÉW-ÇTúƒ, ¾bVÕYÎ\ì#4…{i—ãÈAk"Aµ~„{Ö)aVÛA¶«VqVm“Q+Š»Ä ›­™[VSIãՖjy¾Ø>ziÛCcYNrØGl°G/ñèò =¶îƒGUR¹lâÆþñkVãÄM;Q ›Ó:úƒy;¢ßGk•1,E«ͲÔò0Ñ/ 3Öê
1181
+8¶HoÍóÐI•Ǹ¨÷¹KcêaAÇÜöɛÖ-Ï-ŽâUE³,µ:LÌã¢>‰[ÍÔCÎ#ÂqŸ0UyŒ;û:pÔ¯d¸ýCcµðÙç€ÁÝÌRՒS˜YQ+Q¬f
1182
+ƅ³ý~2 œW,ô' Ð×= ¡›ã!–èÑŒÔñpTéòÜR¢pUílÙTS¾ý ‰ß¿°€—'Ý`û”Œå À›-@Ž×´5»Øº„ØõPÁXÆÄnöP&1¸s(ÞL>â¼Ð ÕC€sö£×ÉCgý?{×/چÂǹgulJh|J’ñ¶B¦µQº¦f“¬9ʄ*)5“ûLˆq~B¡²eɔjirq 5¶(–øuôÉE3Üh f?‚ÝèPÍ'ÙÐvd؊Ӎ~£À¶Ó=û+eZۄj^QLš8QL–8qÂååpÔK°±å8೎ÃJ6n})•&–ŒSõ3Ú%ÃjŽ¹ÂØ6[g7¶PJeO'\JyåìŠ6ɚ£ŠÞŠ“*ª™eÙÅuÑO¸”ó —R>Éb!ˬ…õ”ˆ“'0¸/™›qꠞ¥¹µW–Z/Ò.¡¿¬ ‡¶#áЦµØF>ib5Ë'[,責®²ÄÚ©“~¯TI“-«Ü³ÔwýF„mýhF[ç‰!Ua^ñ“®/]lùDkŠ^!ûª#h¡5’®ªÒK«ƒÆØúç[®Uè·yü¤ÜøõŸŠÊ§'vÑ °ÛBÂ2‘Œ@+‚p’„úfüyD†2)`mØöuºÐ)o“Å‹ôE½ó*CD0Þ$$ØãDkž¦ÉwbL9Qa¶²ù¦ t4ˆ Æ4ÞZ!t» ‘Ž#p„«Hü$ŽŒûÒ®÷ѓ*o¼Lï#®ÖŒÜqÜñ¢Á5™ªØ‡ðfæ…øØºÑ [ß KýKÔ˧|Ym0«ÞÒ|ác¬Z,^š\S3U²_㶬WšX½H›@Q¤M ¦yž:iâUE94™Ú´qŠïb
1183
+žŠ"8$`tñå @三Ê 2à“—»醖fïк‘aÖýak؜gîÆíYŸd)ébÔŠ""E‘JŊ˜ìWg"ÒÝK Äí‡Ú ¾ë¿á:‹Õ¾îxðv/Ó­&°ÛPIü¼OrX? €B·Ì§Àh±[žZ=f
1184
+ƒO¸±í
1185
+ Ùë8"¦‘áªÇ¡{ÖÇîsCðV²áVùò"Âì÷Okž»©’qýtd}N]´Ï¨‰å€£žéG\çO²±í9`iï¹»þ¤Ü!A5_t˜ævf>¥IE£„ÕrKTkçž=‡Nڑll7…Þ|Ÿ5…+k§ŒaÑ-ή«Øöœú&èæ <´@XėöƒöÔ<…\“Z–ZÓÚ=ãªorL7ýðr=«_1â‹Ê(©¢”OÅ©dÒ¨µ“/S®>Ó6¶iÜʼõÓ°-=
1186
+ Ú¸¥”º‘3ó€Øu
1187
+9´žÈ0ͳ eñ%Û?´§ö)äàú 6¸œ/úyÂhõÒ®‘D¼CHÀG¯˜àO‰Eä°
1188
+ŒG¬­tPIU`Øe¤Í :ܾ“‘ðŒ0½!‚<ùD ç9ÑÐ QoúÛîãêeÒĎf´u!¾ì'
1189
+LûB}j]éŽ j Ù4‰1gb·•jÄñ¢@-.óãÔ==R/ÈÏú}Ôm¥C8þÃGý?yWÞSW­wÂÓ¬ïé£ö›0s«8­’*fXI¤ß”kHÄKr8‚7/éˆë;vÔ ?¼ÆÚ•S͑“®,±z±G%Q¼¦x
1190
+ô¶rõOBãØ`o'Õàò¤xê^³úèPÐmûŒ±þø=Ëù¢}
1191
+9´¾)H·gæ?zXnÍZ&FDˆýMCºÝˆ†Zê«þp›³ ™ãKˆÝ-ÄÇÖuè¨hë•lpù†"à]D#Í×À-= ôª«0­v Õ h/Í#j=`6†Öa¤aÝ%úµgÚÆ‚«Ÿ‰Hw[øÑÝ@؎cå<yÒ>ô—ýD2²~Ç.Z»@¹ø‹ÔëèEƒðeò“.ÉbM¯(îäŠ"W±Âxågµ|çT!Þ”ˆ¹M[YíÒ|ñg²bß5ìG€{~&G!SÎEª((‰x|úî¡H¸'Ýh{™rar'ȀONÄÏC)äs„…5Rá[Oé¢qêÌê :ÚþUùãwíE„n Çí$$ÆÜ!‚ñL‚‚qA7dC†Ñ”ÒÆ”5leÈoÍ;ó&Þ?ˆý=ãþ3Îö
1192
+8â:"˜Öà€í$„n²ñءժ`Eƒkމ»Ý´À\7’ÁFÈ֑wV/´—ýCc77æ‘ځLÞÑCã@XåG…ܽAãä‡ ú’4ƒu‰%zƒ‘ºy©‡¡ûô.g_tËóÅ~¡rm™¬Xï_X›.B¥€rivýŒy§ê’½o>žöøàÍŽÜu"¨GЧtt·Ò!\?v£~ÆJÖqºÒ®4ã­k2×+àøîìÒ«„em•1,fúÕo⚵Øê…þÔ:Q  £×pˎ
1193
+Ý|ӏ¹=T˜U)³šUʲè¢Â·ù„€<EùSl$=@0ÊFûä)`YÇ/T{ôNxjãeî#Ú‰wúc¯ñc7êƒü²]‰†‰'­o¸Î¯FC†«Þ†ÛôÖ¾8ŒÕk?€#›…ېnpi°´pMÉpûmڞþÛòh°í ®y!À4¿eÒX0N¦¸ Ï_ðAGóäId™Èºê·Ù6½ ·‰TøÖ“j¼u =´v»Â/½ÔÃK_ðá¥oh9S¹™k™‡‰‚=`[^@œÛK Äé€ãC‚jþ؍z°ti6gŸI‹™‚é„£D‚j>œ³ßx͸Øê‘p´õ!¿5oÃeþ;4š¶¥g!ãâ0Ó¯î£g½3½Í¶ywÖuÂh<ˆû‡øØŽÞçG*|ëM;¼éPû] ^= ƑyU/˜UYZí3/C³Ñ2½Q![÷É»þë—GÑjAe©ŨP)`X´Nøì#jqê þ…ÊÕwð¤½g¯Úk´eÞAVl¿˜ydÞÔûˆ§õÌuYÃH»|[™G2Ôz¢>-ï[wbD}ºæ¡vu—èV
1194
+¤2ýðò¡>5ßÒìjrm¤˙ˆØÉŠäÉF…p³–뀧^Oʏtgvxé D²Oßµ«0]È&[J嬊–ÉŠñ A¾Üƒ‘¼½”ã«ó¥þ¡@6î3Æöc\´Gø:;¸çþá«þñµ?Њu•&–|"V'SšU²`¶WØá¥ˆàÉpx72lřƒ¢é„Ï~Ñàšç¹›ÖÀ1-ùÎNà%;$ê¿Ðþ³gõ§õŒ«4ldˆØí§ ½Tbà¡DoV¢Áõ?{V$nžÃ¼ù€Ä³‡ òæ¦ä8Ò .G†«žF»Lº±í ,ÓŒàå þGë}Ìí >ì·yc"ñ¢µÒŒ¸žtc«S¥y#ãGð³ã|¡¼P®tcۛzÈu¡?kýröÕe®b9wg}FmŒÛô.Ñ®½b†µ!È5ùQì?šÁևÓ¼QášÇàÃë‹Ó`¢`ÞAZ˜ƒ* ¿B¦µeÒºNŒ¨?"tó¨á2i°´ÇPÅzÑÏQE
1195
+¤@Ù¢™~xùÒ®Ï0ÄˏtÏ©(©1†úµc®`¼&Žl§|]Ñ7qÏ^ãVæSĪøÉՆ!tÄxþh[™rÁuš5²¯3'ýC‚j¿ÊÄ@wÓI
1196
+ÒÂñâkÛzÔ~!Èws }xvj †œÀ’¿é£C-_fÑ&Vó
1197
+㏒¹Žõ ˆßÝÁÈÝ6*Ün =¬Ð_Ǜ/"tã>xiF„m*fW´±ËK©4¯h<jOªÁåvÌÉM@ìf"A5<k3wöàÚô8ݳ¯4ã­K(t{¹rÑ=w;YD~óĹ Äwý:à©¿‰sv£B-?
1198
+¨QÅB”FQ„d„ŠÛ‘DP„ ƌîàŽS ’ýÿï/ƒÑöH°,©zr`‘øl]ÍIà^i¯JÝôë˜:Á¼ä¯Ø?-³ì¬o
1199
+òKCWNÊÛ<ƒ?%0ý¯ëª 2 ^¯ÿ^S¾n#ë‚2‹«…wd䒢„xH1ÎôÔBZî§×¿É#±ÿû†Þgøð²ò‹Ø­æ·ÀüH¼Î°—Óq<^%hÿÄùûº¼•†˜oõxæGGÙÕ[‡¬ºäßÖè¢`@¨¤‹uôÓ¼o_Äҟ.ƒïKì µ“K ^{žK<߈kÒ=ê«òìB¥W±réCïx@sÎäV‘kþ¸§£·gå‡ ùJ«ÓÒÔòKEßÇ}GÖï4ô×!r‰r_žgµ¾“œ³$Ñ[a­n‹ú˜´5Îzƒý¬ïã\În³ögµ™d1óuåԌÉuV%/›è0Ï~T@y#Âz‹Ÿ÷ü“b³‰±Ãôþr,ޓI¾±oOóƒLÄà‚àMsµ?Ñèǝó³nw&•=§Gµ¸|êÏ®%¢U±/ªÔºÂÃðȵûé'ƒ¸™ù'„üÝǏó¿ßýã÷ɵcBÛÑñs,%lÓ ùYø19G=ù{˜|†Ãr€ÀgÁœì,'_םø€@l}KDïgÕðl Çº¥ý·ÂÃïoGû»¹'¸îåáðã;偟5ôSÿ7·ŸÕâ4Üû…ËüŸcª?kÑ›ä›^™¿Œü…]œ{•Øë£÷P°MߐN”'†ÔÃ6ü­žÚ—Ÿµ÷;ØuŽïªþ¬ O–þoý>VRß¶aÔSϋGuƒ‰ žý³ªs¶ß.F×b-uÃ@Íò>M…Ûóß龭ˆð(¶?Tj³w¸J&ûgݞqÁÖº&׬9ˆ6™!?n®}m½+GÞ\~’÷ÏúΚås£õ=ñ,nà;™lQëúLàŸö¼¶½˜á’¡˜ùY÷sõÇ hÈÁKjm<ú àÏJhæÿ$
1200
+d ÿ%%EndData XHEndRaster N(c7ea85e6-4a38-4265-9968-cda6cdfb741f) /UnicodeAI24 ImageRawDataUUID(d130b5ba-640d-4e62-8197-5fb136258cf5Alpha0.24al /XMLUID : (Layer_0_4_) ; (AI10_Art; %_ 5231 76518Lq.24 77$ a„£ž©vß;ʙ<¬HÀäÄÄ÷2áÐÈáÙ'ìÈIÎé"؜ L#˜:`;@Ò-¿yX™ë³LNZ.ÊI¬œxØTÎK"˜Ë|ÀÜt'¦?迏¬`ë)¢í¬[-{/Ê``(¢à=¡æ sÍSY!T
1201
1202
+­1da5b814-d2a7-4543-82e5-bc383cf07042b6ae72a4-44d7-4bfe-8068-32107029ab6e10-7105 7616l0h W n Q 747a41fb1-e009-4cf4-b4a4-ea0df48d8c30d418b7b8-2f861-82a3-7abeb7d7adba950 6231 !…!D„Çžß·Sw˜áî¤wçà¸ÝwjCÇà Î9
1203
+/fÍhü7uƒAÀ™ÿ7¼$¢7á¿ y·2tý¼ùÞKgÑMB€wN°œ()Œ‡é7g§I°Òi±À
1204
+5ø‚úùåZ`jRP»Cá\ aìÿJuÄý›^Aʃ٤cþþC_¯Düß!DGüß!DVüß!\Äÿ7d38b4ce-66da-4f53-8c9c-60e4a43907175d631255-5b2c-43a1-9dc3-e25c12f565898034638.25212523713±ß=HÀZMÔàZMÌó<Í9ã¶S5‘msj ¾Ø ^ Óã„NG¬s¦“ÍÚq ˜€.º0 H &¡¦„DZüß!DTüß!Düß!DWüß!DZüß!Ä ” ÿ82787d56-ff10-4654-a757-addad3bed434a4306506-6cdc-4da7-8c1b-643650ebd6775ml10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1typ/ArrayeTurbulenc;children/numOctaves(2attribute; ,stitchTilnoSresult(turb9 ¡„Iˆ‘ĝØ®PúE"Ä*Vù2(=€‘™‚„ÂÐ}èq\!KiŠ{èñ@ÍNÔB„'7j45=ãî{Ý8 BM âÙp‚þÃò¹Œƒ»"Í+ÔR‡#kDÑV¯Îø2´¼žqˆxháé#{͹dì7é êH8ωûÍ*X8u¶Í/Ày“Ï´á@ Û´àäe+}œæ3k],¨*aL)‹hXñ(† !´_MúÜlÃ#ߊӣ'²o{§™»uÿúY'í²¢}&}Pky ©‘dg^éJЅ&ÉD©Ê”xf4%J$7‚<…#±Ð”¸æÜFÒl2‘@1@ëSž
1205
+Aó¡Q™ÌT%•ÎgB± ýo=ùX‡ùdU"÷¹“èpÎ+¿$®3žQÎ5‰j;Höi â!Â!„ƒªäA²Ñ|ÝçÒõ<‰2 uB©tB¢É+t'
1206
+
1207
+ šº JÅ+o=èî_Š ²ô±Žh>­“†ë8N¥@ *äñ6¢&8ŧ‡MK¡L“ÁQì5ðL‰Îâ © $$Ú*•‰¥ëMC€s²¥öa2#†J£é6@Vq¥Õɕ,åN$·Q!ÒkÖ
1208
+ÕÉA*e>nï5Ù1FÉ0.>×í5UÉF7b.°ã (Ôs’ŠsRXÞ«¬Eœ{ (jd¢
1209
+qpF3Ã(4-<ƒú<¦D¡iBf¤@‚*ä
1210
+¢éaL$·q`M¸ÊŒÚÛ_k8*’¥sryAçópî} ÷> ×qÜs•)5@Κµk¾>FèÔúwïn¯Ñór<Nû`ˆúT›Íè.œ-¤ú\±¸ë@vQ§ç±€j" ‰û<µò*e‚@l¢ŸûûUæƒà©uì3¡@RÈ*¤Y'5Џ’%`g_ôós^t?wÿâ9÷/œ]á ã s#…¨6›ÈÝ[
1211
+ÆsoãA)¥”:¥”Fú”FúÜëH}ÌK³4‹’4K³@å8ps«
1212
+¢u¿K֏¹r0Óº±V þç÷œKÊfŽá3ïõ³W ç½-åø¶¼­÷«¹fÑã+JÆ,ŽîsK5¸½{1¿k°›1Šösöœlº¢Ýc\6Y7å`ç.v’iÌÃÜbݘ|å`3±%s‹ò£\ _{éPoï1÷ #k›¿“̹¢ï™óÖ²Y»{EåxÊÁ°­è+²÷¿˜\’µ/EŸsßþQÖ~1¾ØÁج½tݬý{tÈäâcïýëűÉÇÜ/vþœµ³ó¥$üܓñÕtà‹½)‡j<ÜÞX/²féjAÅ`p+H;e0ß/~‰3pñÿbg­" vn¹¸z0”r{¯Õ¾˜ù÷ ‹‹½-w ”R2ÉÏ<Èd{;7ٛ’0ÃÞT7D5d3N*ãÇî,ûY7‡j°;Ç_,¥d¬c?“üÌ,–±-刯$ì¾â«w»¢ p»šD5â6Е¤‰á؈!Yû4ÈfQáÿ;vb¨ÏcB
1213
+­@ŠîdB¡ù7K³Äç€ß\BÖÊ™{s’¹%á'#tù}kÌ_Mg¢kÆ5†/º‚‚]AÍÒ,ÍÒ,ÍÒ,ÍÒ,ÍÒ,ÍÒ,ÍÒ,ÍÒ,ÍÒ,ÍÒ…Ѩ3 ¶S
1214
+Ո$IA
1215
+shp@F‹&SA’;’€ãð`$‰‚‚p @ 0 „BA‘HAàÀJúžú_®Ô \ÇL_`|»‚éÑJNJ]4eh¦<SÐÜr2 ˜e%«_Þžüæ2^yߟ:Tà  HlÍߔ ûÒZ<ŸF¸<ø‹{ЊB‹§ü¹+žºƒ.츴%Ye Ù c¤U˜•›°ª=« &º`·Þ ܹ^è‚=^i_†K6¡̒ƒ6æC¹¤'Î3‡ï8ƒÈ=û$>i~¸2úC¥ø^œ&ƒä¶bÝx_8ɲÞh"³Yæ¤Øq™ ë™]eB°
1216
+ÆE‘V`-åÃ6½zfq°šº4ñ‹f«:´õŠvzÁ}ûf畮íJ[í3'd&ÈhaÌKi2j^®þ„¤¸æ=6â<æÆú=­ŽlåÓyƦ@ ô7œ%|–1-^åhz˜‚ø(ýˆU¦ÀÂhºZé¢Pçü¤¹Ôÿ!Rò7?^â¤ÄtwŒù
1217
+‹×t‹r…·Á3‰ZäÞ^ƦýAŽ‹¿E!‰XÐBže[P »¾h»*]·,„öڈ\!…ÎF—m0泡U u³ÇKÐé5¼M¤@ٙz0çZ8WsTJúöð*£ õ;ã=îh"vžu(†è¨å2ç9…F"ŽðªÑ1qYżQ¾äæs$m˜ žÙך,!jØÊ¥É‚æ¾î´Îˆv43åZ)³™„ÌÍBc91ʼ_¡È Zâ‹x£š//fEº,Š‹‹äBQxP†„8„¸º1ÿü·Rä«  {>÷âí#xdÅG¾(r¹Fœñ^ùôý þo•Fþ9ݖûÝʃڤA_\幯³6»g÷ø™“’,G¢„$q¥Æøí¿šî³Kdà²×¢ïCÒý¼T(ðˆd[PmÜWl¥¦¾g~ÀÜ>¸\ßÎC ãú‰íó‰Ðnì•}S¥{ÜoÔÆ±9øƒàÿ·cдâê(„ˆr£Ùf“ø’wQn 9pŠ5®)ˆß¬ÀŸr‘Æ"¯]Ùž›­Z
1218
+†‹E'´ˆ¹@y+`bˆî¯»k®Ûšo#lçŒèg8$›£…¬%SŒ’©‘Œò~0ÏυnÓ@yÎz•8›3×?kceÎKe§ÌIhãÇÙŠ¥‘
1219
+æ¶þ-Ôb3Šz(ó޵Ç,zùRñ{Ðߥyeüìöf
1220
+ã`uµË埋 LCÀ<hL,ÒõŸ§$vŒp¸m2-mßø)÷®•>Ž…ÑYhóVZ"|j¥X# ß±,H'9ÁUs‚7-©*#hç0/(€{$lqÏIYÕÆ‘\'ÔVÈøçvçhù,¡V‚^Žx Ë c'µüÛë§`oÆÍn4+óç¬N7 žLÆkda_²§9[ÒÞ`9h”(¼å~L.¢jäCxš¿®ôòø—©«’I( ½™£d5ÿõ‘y9™Y((­«‚qJ±–§†‡B-t~‚öÄÿG%Mõî£ë}³/9~MLÜùuOç¡e2ƒß± }xfÁ  «ô@Wd±Í•l‡s$™f±JFÙWâújhz9˗G0_d8‘»àºÍ½a£pàmê'ú8$¤Apáš÷8ý]‚º"¢ªŒw@sՄˆéÇ$È1· DŸüç4 ¬VèÆÚè© v“O­ró@uKÉ¡ç"s|‰„{ ¶”‰Â³¿6 ÆRG+TºššYúdiñzÀ, •Ó‰ˆá¬&Kð «³Eǰ—“³ÄØÍE0ÂV·Rÿy}(ª# ¤(NÌràá¯5û-Ejx­ÀsçýR¶lªã×c!¿BzxJÖ@ï+¹Uu à"²o.K ÷á´º>G™_²öK|gkØ]²ñºÜ.*YTܑõ×óèT$²¹ë@%9€‰î]ÂÊ©ŒY^$9üÒeîh·êd)æøh¨ßl
1221
+¢òR)ÍJû¤<x]øhV® _ÄӍ͍JÓYŒAÝü'¢)/*€Ž>ËÈ^\ÂGØÖU„TÜJÃÿ  á¼k£P}€J‰ÂﳔpD·ÂJRÈXFúþ›¾ÀbÒÇ´ ?ÓkeK`øä󃷸ùñé‰7DĦ¸' tžˆq¬ØÊañ6œr”½J…“±ÆÊc$SvºehSŒ*‹‘ý!”jC1ë*54Àʁ8éáŒ]VÕ©©hDœìCù‚²pS` !¹m¯ëP©Á ?K5¥3™-%2 hÿ+K\ ¤X ¨‚Ë 6Ոe;PEiˆf% 9ŸØ'ýtwµ²?䒦àÒÊGk L©×_rQ~ž±ÌÓ²Å2L¼¥0åÅ%ܳN÷B ‰f¡óWľš.¥Ô*w5P¥Çôxnþ+¨ÛaVDÈ ¬äk ¾/lC’/†ø¹òšëÈS–E~#÷⁠€-Š•„¼ë©7ê©\%{©NKÁë ÆÌ-±ôA7s•¹=Pä,ô^å‚О§2i<ED¥O¢±‹ÞAxh'þ)­¾ºð@ƒàz`Iӗ+m:\9íY6'œ»pö)aJÅ#UªE¼04Rém Nr¦2-Ƥ8RôdÝŒÔÓ.âºP¡H•„¸pÒ6Iª~¬5·¶Óã§¶Ð7šúaKoÿŽÄDZV‘ÿߦ(‹ÜFÆS•ÿý7ižÃÀ—%/`£6m,S¢ ¦p‚LÖîßñߚ ^¹ÿÒÍs(¾$Ïò±Gm¡žÿÁ}}Z҂ÞÑ3¿šÏéF¨¹Ã!Ôý©ÈÐáäg@.BÖl¥]´ÃåðýQ·â =VÂ>C…¦.°Ï¢ ŠKŠ #hS‰Ãâ-QkHdÜaX¥Q’o¦ã¤™E!Å#y/À3âÆž¢ý û¾â
1222
+Æ3…4mSñ„ x´>¬ÌbÁõYÒG9I¡†?{<eréš}ƒ2ÏÕ ‰žÍÅ«|¦`\!®@Ã×Yù´hT'mR‘iO]%Ä;Å/ƒ,ÊÏk…ÐÁÞ®‰"î]k©§øsò†lÒÝ'@Šè—â@ì»G?‰7RèõÑzS—“†-íöÚPñǚî_½•Õ’¥/‚èj’³•=\TK[ÑõˆÑF­Oa䋱AÙ-º¢¤^–•Ç÷J;ÔTZ½quÁû={â3Ó\“]ËLp&ۍž¢¯Gó‚¡ mT±Üµ1¿s6[ %¤ÖŒbÇÔŽEíø.ûÖÔqŒè¦XÀóað|à—…Ù›4‘1º$*¿K ØGµè !7ñRݵî|—ê‘d:c9X֖v¯Òb,[ä^WGՑÊÌIz6ò­¹6 Û ö銻}xsnšGûʃ8ðˆYàùïIK¼JHô}-9½"9P¤ÑH¡±àá±%y›$\(·ÑŽžÑÂÁmOÝFO§JNÚÅÅhÆÏŸg˜²#@Zxã‰<Kl‹Ú6PÐä&þƒf‡éía{È+(Œ<# 2C±÷€¶œŠ–ø”8âÝ$á?ïÓµ›T kÛCÔÒ
1223
+[jgû§¤ø ù:ÖótíÇf`hùC10¹;­´„î”Íä$
1224
+Û]c‰º¨FŽûÀÌw†³Ó:üÚ˜—”‡$_±ÏÁû“aF|I÷%}GšWà Í,aîPýß*ÜE´!“¸x“˜B4¸»Å;^r¤`µæ“4Gǟƒ#¸h°BÂ5è|˜½x‡¤péᤠâ"áŒÐ\ Ç ”` º-÷W9O?¿AÝ0ÆPˆP?q$ûÍd‚È#`p`႘:CU•lB†ˆÏh)©oO”‹–b*:^‚[„ÖV "žÍÝF å瓹iàš·¦Åm%4åçîÁñ?N›#M¬BÐSÒ»835TX"ä¦L~œág±qF„¹GÑOm@På~FŒÅÏ×.QÊFŒáþÅ^v«Ä46‰DLZž‘¡ºËûWÆv-#'EãìG<W|ÀÐO``™#Yې‘¤Î34ìüµÖvNyPn|³\‚Éã% ì£&Óþ¾ÔC)§`‰~±^†ƒWwŠÅ,´UÜ9â_,bÙðƒ RïTV7o҈zKUWd1xP"L;û\fÚBÛ.W#Ì*þÆ,‚4q\qÅäéPRÅìÚÁA£2D×Ý&Ÿ¡‰m\@êÛ3b/HUM‘ÆÍIh’_TÇ=Ôãyª¬TÀkÃ&ëž-†Ìçv–xaЙ6 TßÉý¬iDhŸfëY@½°ÊmSÕŒžØtž=dÍé‹* GgÁ¥ØL9¦­¼Ïk`…£“²2<‡.f6vÌÊtoÌQ`L¡ r…ä4Ö±©&(Æ2*#žÿš¡Þ톖<´P‰Ir!̓¡3 Ëð¤~À˜Æh8Ñ’(›ˆ®ZWª,~~Kš éÐ\”Í’³A¦¨}pÈJÙ2˜«Üp¼T;£Z‹ûÈhf
1225
+âSh¨8»ƒ}&()Ÿ’8M’1Ýâ¸ÒÏ~FQ*â*ìäøB ª`îœP€=äJìÏý¼¦´P`¼8dz¡kDoœf×Ç]ŒÖ¸#wn¹­ýłðô+züre¼å>Ò<<ËkRÃî墿a(šeÐCY€0À¾Ö2qù¡: –~T¡ûN¿(AÚ CªQŽàӍ¦Ÿžu–`œÃúÓÈ'‰`'åJ>³Š €Îب «b0«,IüJ̳l•ª'!؍âh|8dùq4Öª@t”ÝôëSœÂ+&Ñg3vÓ¾À\Ñ͎?ð6MúŽã fe)-Õ@±ul¤‡aXÉm\ƒ/ÜÄ&EÄî1&‘ÁºˆÏ({ì­¬’ª€÷d~ƒÖaml ƒhT$Y:‰%úuàh&—‹«âBÿ2s¸‰Tš™$Âj…âR|$SröɶTÏäB:Á–ÄÚElAPæ /豫¦…% ÍhãŒûv
1226
+c,˜e¤¨zY叐ꐣÒJ°Û0Ù/:—thî›7¡¡á©TÓî›CeŒfÇ!8#‘¦Š‚‹=
1227
+rd,Q€8j‹hE+´ÿ*wºÑKxLo>?d`æã£Öƒ¥ÊÁ…‚™ßÀºp=[K뺑G;¶H§´c7ûŽð-sÚþɌ¹£$‡ö—®é°F[‘¨«Ú!Ê Ç@!,‰ÞXÐPͅÌV-B™Ky¼¹ôãËÜ£?æb)æ1ŒÞëÓzU×ü<ÒimÍÀÁ ؆¢WÊ^2Ϭ9}'uéO² Xš4˜tõFIâ£* äY.S1Ð2sM…ñnqJR\Å"NÝho½lÍ]N>­‹ÕÛh§½£(º»÷“cØ@íJ‹uxŒ|
1228
+®êÁ~z}ü²¸L”pØÌÐwXRw*Qþø—1Ì,©'£ ih¾Ýf6Ûè3”õÆDlàZÀ!Z¦’ЊYïiÖ¶«2(Ƹӛ4 $J¾7`K’ÔAAA8ûôø¶}·ºŒbk¶±8¥k@”aÐ_>ÑŒ””””Ò"†¶ƒ@ô¬Çà´Èi¨šÈ^wú_þpã8yæ`å]^±€,€‡DĄÒàH$Y9Y§‹oxÛ¶›¾eԆù—ùŒF|{¯™÷š˜ÜéŽWhêfv¦ˆè_}ˆœçG †N»ó¿³/†äKü~3;ñrÜW¿á_»rSî „å¡@4Бñ’†Ä…Š*("$¯@„Ä€ńC‚Š (±³¢A1Áh@P1ÑTrþdϔcÕ¦ Ü«þZlÎc‹éö(D ³°Á…
1229
+ iG[© ÚܔÍçÙg(ÏÐu[a€ìòN!h + däoWÙ­«wžÛ›¹«»ªšåPny˜!š!š«¡FC,ì´Ì»435³Ì»´³6d™wÉ֜›¹ËМ ºuI‘ذ2°&rCú|œ†Ô”CgH—sU——aëxK õrº=CghyË¡5ÄÆÐH™›˜¸Ë!6ÄlÚË8uïZ·íÙ4ÛÝ|¿ù¶B¢1¡Qá \‰ÏNAˆË1æñhL9GØâ£Ç" !DÄXB$FCˆD˜Ÿ™u†Ïÿ±M9¦<‚Â¡Šˆ’äGƤwª~ÎlȐAvƉo†¡ö`ÜjЁo²¹ÿÎa‡ Çëƒò›lì›L†šÝu“ÛŒTÆ @ÈvfKz¤
1230
+ˆ¹ § )§ 9ÈA^ß©ÏvýúöSL,»rìîîøË)È*¯k6Zuc¹{9¡?+Èé+W¢W–c¥»üY뉪ey\†Š^vVøÀS6{MAÔ?ëÎêŽi+ç}kMAZ׸4W?KOãx½QgwSæê‡;ÊA
1231
+²…GڝÌW˜…gަ!êõþgˆíg~lެheÄ̉iõ’ ˆ†
1232
+DÐD……¤@’Äd‘,’E²HªÉ¢<0$‹daaòdqhHTp`€.tЁ… ô—ýüàxȆ:ŒA8 Ú©¹Æ:Ì>˜á?àç2tÛ†!oîX ƒ!Öð"ÃÁ½‘,hHÉ @€ÁÐ.q#Kª€Z± Éâ‚É"Y”$Y 4P !H<8TˆÐ¨ hh `Bþ[ÝÞ2—v#ê-7¡>¢^k·y/ººeÇ;îjk¶¶ìËCVämÔZCl¬Å}ÿxÏÝäÛªwÌ׊¿†ŠY{ɗ¯Ýoۖ–Ü·jù—í»ìµí̋¦¾èw¥ÜýuJù_y†¤Õu=½¡+Çë×Ðn*×,6^fØË°¸œ,.¯/Žr.¤÷k¶JÓYÆJœZG©¦0®®ð½”״ΐÛV£N?ϲæzÒ=·ÊL ŠFa”vma¼áSÆéýÓ¦áò&eÞ- Ò϶Hl5v¾7šGSŽ9[׌wçA[}úØ{OãQKN/È48ˆ’oc
1233
+bš¿.rw9Â띆§XŠwû,óAlïЏóª„—åPybþrÞöÓšù–ûµ¡uCˆŸO„ÞNvœOS, 3tgÈ¿œ‚P»uy–Cv¶X»<ÁÄrk‡& 0ñÀêÚe¡y¨®·¹!gÔ–zaª÷b,ç¸➠ÔsCì3tŸˆ7W}Übbrê«&÷" )§ ÄôôO\zz󆞫ßP¶1ÄåAoÈفF… $‘hdàðÀó}mW+ݒ.gõß©a©I7h¦cq”cþåZ¡D¯ûÇCÍìgó:ô<z†2ó
1234
+±<Hó/k ¥åc"?ÈArs’E²(ç$‹s’EA’…»%‹dQ, 밆"Ž9Z6 år¡¡¬Â1g•¶º}óþË"4еòæmóiša;—*X`L8‡E„
1235
+`·Wž»-š‡fš¦¥fš&òÿh†6ÛZo|³hKË1o¶ %Ö=8T
1236
+† ¶k/›Ñ騆å±]Š æºF/ ­=ãæ ½·oÝ£ìÌ!E¿òÈJø§ôʃO¥š›ò0Rç­+Œ¼rþ¿Ô
1237
+ÑèÕÝQd¶âÇÚ4ÎU&±n¿þ̝-ĬFÂGÂí­öº´ò+ȕgéë•Yú֑âÙÙQ8 4qÁ-fíëgµÒêããÃê+/ÞúÙ¤¡Ë‚œÉ£Czæ-¼|·ú‚$’R¦i–^)Ò®5åW«\£Ì¬•† —GN(Èñ¢›CÃBóJºÝÚt\MúŸZȌ\-}–q)¡2n™é3Ë\Ԃ*î_~5Únqyü·_m7>Mà8ºMºˆtmz ϓ…D²HiX}Ê\ýg]]$¨Ï±ù“·œ: µZvš"Aþ¾¨wõy}•ôºÅHúͅ¤mŠ„U’šêí×Ýqîޙò8 0(ø~‹b¨„Të9é˜" SP%"’‡²T‘òê€uZ:ºhJÉb…Qcˆ2Ȁ0efˆ„ÔN¦zØPv^í £ßAŦ¡ËÞUÁϕ©«õÏå\ȬҺ‘Pìn«íuôc{óÕ"nË={ô¿ÔX;òÆl.¨ü¥tãygç+ÚhªîÁ̈́l)_¿ú»;¡ˆŒ<’º èÁLx•` Ö7¢%7rE D³ë‰@F‘°€½#ãF6ÕÕâÂÛ¢pƒ|2êì4ÒìÙ¿Õ|÷Æc-WièÇÅ1ñ…Q+h0üÐ¥ˆF‚¿(òŒ˜Áâ c:ŒÁ)£ß¤>m«d’LR¯phøµÅÍ4a©@›I—rÐ~³zzbû¥!7"ÏD×>tØ2¯¤ò±Üòa¼Íöâä4ŠÂc¬î±Y_ÙØä~UŽ·7âT¸DËtÆÃâŒD ÐJ͕'òœËecc¹Æùñ]¥mïÉé¨GN™<;b»r "Û»⪉ÜJŒ¤rGôÛËL†ôÀÆ?®vü î/Ë_ã(c®Äo9”ÿÆÍÞlàìtÌó Ll¥aŽ‚ª…qFۍߊß(ýî'ØõÑ¿«(¬~}æÖ.ùҘD@覇>‹÷lŸà_(®ÚÒwEÐRJÉY9ï¨ ã#!×þ ¦UzýÙ,Qp«ÙaùTeäÖ“”MK‰FÏ;̈ÕTñºï¼Uó¡ 7w© Û¾¥Ñ„I ¤q$ý¯âÌ3†&Ô¶:ÄÜmÁ 5¨*ú÷UHE£ý÷\omÑ®´É|³C…©°çÄÑ`Ȑ Ë${Ü_ñu:+®ŸHþ¤üE¹ ÖW×ÔrÏ~Sœ¦awþÓ)¿xcNQæ)éÚãIœ“E%ç‹5“êߨ‰"É ÚEx¨“ÞØîJy©'Mï”~ªvÉׄ€à쑹_­æAs©£RDMÑ IÞÖÄ'”šc@CT{î3ˆÂªaúdg€Z€žr!ÚÛEˆ0ä«èìLé ngœ°‹}X>è
1238
+SR³÷+HCÖçõjóˆ™ÌC½5+ώRR,ÓÅ#ÄjtÀùj¡¢´°›Ëñ]è^˜` ÷#2]rhŽe':hޒݿu)¢pæ|}±†Á¡¼G˜Um8°TžÌõ\Ñčªäé,h¤ÃÉ1,Úåï€îë| à9ö"&oªV˜Y¢&úX†®IT²j“çchF#”²øÙ»“n¨¬5ëP[Á¸Ü Ù³zïªðK£D”\̸è90Ì õu?÷Ž-zâ¢9£bj»±!Њ€5ãkÒ5r<–ýU½n(çÌÝExBˆâ\¤]¥]+ÔÂ[mAr“fn† §Î›Ú=eÂÞS˾ÉÎ7fåRúë{Œ­¾>Éì¹L T™K$‡ìDmàNÚ¶ÄÌB[ DëîÊÅ¢"©KUψEZÇ%œ_"µàæM,eàiê=WLò0gÒ wæ ›ÊÐÛ Ð»='y<Z½e!ý°Í´ï–™5vf’%{·^2äs¿BoA¡rÑõ©â³!Öxé¾C•»GT¨;Í&¹òYš+Û+62†Ç!1KœFîõì/ºÔßÝ¡ä±h¯¸]nPâÐShÈ©£ö!¬.‹aLÞgã7 §ˆÕýƒ+ÐØ~ü”®ø^¬äÝV2ŒùM÷È¥~Ô àçw_Jœ#~ɽ§1ÇЩ=hÖ…F¤µäºØIø¶¾œZÊà}9ÌÂÆyq.cKœÜiH•°È ®ËäµîšzVÿo¡8¶Fùg¸"fùò°ð¢.&ßì¯ ÜpiJ_
1239
+nք×ÎH@K{а®%Š·M—_ÆÂ"JL–}†mb‚GQ+÷e+sršeå*§ºû
1240
+Ì弓y$fåt‡ÕäáE¢w@it£Ò½áʼ úßꈝøÎdÀë>q—Sü Ò96Üæ§•Mò^êcßÄZ:£•p Ò¡Œ°F±;Ó¥R#³²c@Jp”]á“"Þbº…ÖÄDÖLç<j¤PÃÒ§{.Ô1l¢ãçwû9'GtL1îhi‰ª
1241
+ÑÊ7 \÷Ð
1242
+RmT á.Ò!œ¯áØÄ¢ÅiÚn&‰ÅF-`¼ØÏæyf Y˜V´XĶÿP´cEt£ðâ%IâA9‘ ÔQc`cÇU‡8}âWåÍ@Nm½w[°”0q“y¥yF7­ð‘€34Σ
1243
+#¼+„ŸŸÌÛQ¯#"Ä#bēgîˆ.‰úÚlFjdß)»Î+y5¸&`6D1ÇÅ3@qÿŠt>$$ íF@?Ð'ºD{TY¼´v:-h°ÏÍ=,Rˆ£‹gºÿ*a
1244
+èMáEç´i³Ù“ÛƒØÔs+å³VMAÛPO°‡ æ¼Ñ‚ø„ Í4‡ÄÀže1Ρ5рŸÌ7ï,cAUåïq 3Üúàª&|ó@€Ø¹È„I@ÔÆ:~+¹¥ÙÃhT;Ð0xFõu -—ÙŠêý(º‰©³†å:#¼‹«ÃJu§Õé)Ù£ƒÞ%B”Íæ$÷Á¡›Œ«cin&>_º‚âAG]:~B¹a+´È¹cŒ ¢¯®‰E]JQӜޢaac_à¨G [†º(W3ãzŒ›KdÎRµfÉ:N™ï«2s·µ–’¹DSéã>iöió+¶Àòáҏ)F ·–«éN!Œ+‡‚3v%Ö‘mi§Ï2åØU[lè×ÜM„(˜«OYÆœìTÈ}Q“ ^'Ï5šœÚþghø<¨?º ×@mº’à¯@<RiÄ`T‡9áAq€Òô¡§¶FhŸ›ƒµ°Üþ2Ö·5 «§þuOd PaøCï#Ú,|ý‘¤aՎ»üñï³ÝÉd°‘¦¶—B^­(©a €·öƒÒ­Û…㸵\tf[h…`-'lÎæ|ykÖom]Š.ª]Í\žêá×|2Nu‰ž­ÚŠžþJ,!ë ֽƏÐ_‘ß
1245
+‹ä^,å+°¬Äòç2åâOä-E]º5â¤C+Q£çà Ãr²£Î£»E·NGõ¸¸³.´PN Gy® øªÕª^Öðí­Ž[ªnî©\ۗzáã"JõÄZ»ÑbH‡ÝQ(/u¤mAÃԈ&ÒE¥™•Ô²2âޓ?3CË솸o+à†òi÷aeaÖF‹¡dbb#¬÷Ü»@¤õ¾"1î˜+©KBêùe#A¥ºÎ6C)OhŠ(§?UÏPæVu­0ou s-+®BPaS恱|•Mì`VC²ÿg™ëÑËbýÿ-1"ü!Lғ{(‡êmí¸2…Ä¡Gè HÍ ¿NÈ1꜆üP}ý¸LO8¨¡vfJåÆ%Éi8Ì0 <I¦ùOÞoŠQ­å¥|§ëŸ`æ8,úÄ<¥ÿª!ƒ-þQ>áhúæ£èî¡8 J D q­ËÕg2ÈÞk¼wÀúªãhšÏ™¡b,w˜ŠËˆÝ©¢(d,ÆÐA?Z_ó]ð
1246
+¨Ó'!+‰—òÚÚÖ'”2 <ÉÅm¶_êKÕXùˁÈ)½oô|8rgTu­,EWðMvT÷¡æ²N&㈱'²nÄ2'ÁbTÊ¿x…âÃ} Û¥Ö¨ k3kH£(Êêpz`9b/=Bzìýýcwþ kÊç âµ»ŠÕÕ0=+ Ìð"•^†8ó¸w»9q’ÝyˆÀcŒda“FT€ÒÜ_0ìu@WÓ糡 *V]>Œpö˜˜Ú)P?ŠÖ}}õWÌ Ðà⾊¿¢ÑØ¡~`ä±wkÜ^VΧݐ?¾¦…¯Á£XÇþi,@žÈJáìA>‚(~2ˆ®aR÷»ìlRý‹Ó×Åû­ºO$¸\iÿ½…bp¨0ÈÇg«ªÊ®̵ñ죋”34©KSý&¦¢'šæ3„ÿöÃEÍ»l3ú­¨M7wéÂݻe÷CCm¡\)/ýz ËÛÊ®åÁ/i*b0Q[ÀKMWæØ'|9WT.4s0ýª7î/˜¡ÀXF#å2ЈæÅŠ%#ž 61™[°†µ}ÝRȍÒ=ìMGûgË£k„Ï(KÈ0|ÞÄW£y,H6á2Á¢A‡Z?°¬<À‹Ò“ äH¡ŸH`ÆÀ\a©;\ˆyEøëÆÈ™Œ9ÖUQºÎ
1247
+6¥0 ZèÒ¨Ò‘"癄›£ù-bc@@[‚òÇx.²g•aõßJk Á±À1 ZæYõ ËKB\ÌÌ_TZff[·)$K¦cÂ× ®õ#¿Ó¥ˆ á°j0”„ó‘_ `Ç %߅¡ÐúP՚—úRÌÓ¨` iU}ÁãZ*µ+t¼¦´´` „à]˜+˜¯û@ªâ{/^m…oÿøÂ
1248
+³ñáCÌ%¼ò èCsF=¸Ei«ñÎAîÄ`\k¤¥ÖHQ¦åé)Ë!¡}ZK•ÎЩZ‰Ñ¢8ŠIêÁˆ¢Nˆx1ù]ŽZc’쬞ï´jÝØ ^>½[éÉ6ã!ùY&Z =Ð%£§!D‡+Ð ‚Ã$ƒ‰
1249
+¿»¶`€Ÿ˜Ä­IÆ2r5]H—˜«‹òøcµH‚Ù(²åè¬(á0êBöSé<ŸhÍ2´VMˆåÌe›oÎt’6(N'RõÌá*ç2FÀdþTÄæ:¾ì×§B  Ùr@½ ¤×úãa狿ã
1250
+¸ÝïÉSIS›;y¦u}­—)‰9ÆT°#a*>—ÆùµëþzÇýÿ,ѼÝî’K·y˜ÍLS®|‚”"Nþ¨tË8{TÁq)[g5TUÀz$ÿ sý ÈbŽHÜ<Îd„ljXJY†éÑf‹KI‰µl¨ñûïwÔlêCÊZ…v洃 ­e†G(!’¯bʐ.yFrSì8­e$A{ «µŒªVø÷ <øhŸ›@¤>INœO)Þâb'zƒ^Ôõá쁠l’Øá>ª®¶a*ñúÁÄë”këhø$à<àįj‰og†g+±Â¢âÏsz_Zû[L:"¿Ž+Ï)S Pó’Á_¥_‰ñe¿K‘#ÆäbH ¹*aà0{?V•d·~¦R3 ñ…<žž×º'\Y^‘ñdHVâ±P›f#q–$†Ñãå°}©²G _.ø1Y¾ Ð5UM{9Ô< /\ 5²Ì„l`¹<m—ì‹Nº6¬²Ô‰iƱû5y¨wrãð8'LÝ4!šÝ,yóØŸÀŽs¹J›@ÄÇíP‡ÝçIË#0q旔ÞgGŠñ|øŠ3ÈÉÿÚ£˜‡dI 6 £´öL”ºs"§¿‡ ›Ð#gn'‘À.?,›:{’©$OęL=ÿ ¾8º¤ØÞøÃd$í$ƒÆÂC‹'2(=–p»3!`Á†`ç³Xñ™ã÷£u£µMÂSyyÂ$ÇÓ¡UO~0F Îü²^ ±H‹6WŸAÛJ"{²q{òqj;°&þ¿IJ۝môøÆM>ȘχCÁU’.ãðõÿ&e¾‚})ÖqàðiFŽ›¨O4÷b•Ÿ@ ¢$ñ
1251
+Û¨Õ—]†IŽ æ·EŠÛ-tTA
1252
+ØttF,¸âì~Hk â#'q$Ç0=–sÙ!¸–>§ ²Ö)É´çgÌíü+!mÚ)b°Î«m|ŽÄù˜(9ÖÕ{o¼fby>n?.gÿ)TšDsË¡‘Ößu„68£|F¾=ÜRg®㯠$àA5ë€×e]‡Ê–´ÞQ­ Û“m~1vcl C³ƒ³Ö»”¤Ì1K¹þ¼»¥|€Ä$o›<5G¹i™ýè—¤³uþvX×ÿRÊt(l+ Ø"ΜdÞÑ9D«†g ‹@:ÿqÆTŽeõÜ&®á§*VuáIË4!¦ŸW*A3³->Ró>ê‘fðh_è©dŒN.k\%Aêm<âá¨JAk“I¯g‡çåÒBÅ´¥SF-ôihb;X'þ.}ŠÉp ]0o“a¤ä”kÒýWíæ!š;³DZ‘”Ÿ6Àƒ¼PnïþKŒþƬ4‚²†ž7J‡-9o§;ìÞ<™SOÍn6i Œá¶.)뿾0¸ Öq n®î±8û½˜}ˆÌÌÞ^؟«²{{ (Á€)þrËÎ#¦â>|Óï…Ð1ñè£ïÖ°>ðT/ƒ_A‚³Õ픺4gAiÓà†¶YpüŠŠ4÷[ãœiÿìS9¥ua%äžoì1÷il'¸l>ç94#µü9‡ˆª}[›ä &2"²íÓ10)Vyja녽—ûùiiö§eô»uˆp‚n o"ý€±Þ>£Aؙ 1X5¡Êqu£ÓΦZ+4 m94,Š»&¥ðQfͧ¡+ñHc tԱÑYòP´*ßȓt`DF=`¸(%}õÓP ã8óA/4;Ô+âk†
1253
+…j"Tűé±ÿAº ¢†šÛÂuw“}T Ñ.‰f?ƒöŽWwwL-â0Û·SïE|E#š'>6”¬‹Á”ž6È2ë#Ï$xÐø¹(á(¦Rž˜""º˜}‰©\–ëß iԀ×Cʨ(¯[ìÇPìAÃßýQ޿Ɖڞ;a8֝qÜ Y:€ãEt]ÔsOX·Øe/VÕKgmjIbž0 ÊÒ96ÊÃÞEæ…ÚR—â6¡[JǨÍ)hI—k6vÊ‘uz!Âþ ò‹©7À‚˜ý½(ñ𒸦&1aT?ܱ¡-ðEÿ‚·*ÉO¿X"T‡LÕdÆAÙQ'À8×ðAÆÈU(omQãVt±Xb©OÒ(UÅÀ]<Žó/RC“pÌ‚h(޼ÔÀcåóø!ë?ÉÑ÷}½Ïæ)˜(„~l°à)p‘Ý ڟfQ{Ϊ ióèÞ,<¤Â¢y´»l™M,§öpôͤÍü ÃQH5n7jì íúã¼¾õÉڞòú‘žo”ì7ÀUµ“€-˜÷LI¤´MÍeªŠ¦de– mx›:ƒ%|OÐi€ê¿¡Â(ôÏfŠZä_!´‚ŸŠ¼…_^ÝuM×ÓªI¸f½E‘šc* cĪ ‚ìŠV‹ól8$Z;€³h(­Ó£»ƒÏˆ%‘à:[ Õi'¥è:lú"õÓÖrfvRDSR¬ «?|¸—\qÝÅAæË]F•š"höŒ_CèbèMÒŸâ¯5À¡«¿õÚ¾…|¥y­ ­Á¯X÷yç~Phí²Xb!ȰÎex¢’¥Ž‹íÖQÇV€ÄnÝôÀ.wE~Mg‘‡ª²Ðk:‘üÏH‡Ødµ¥\r³ÛqÓ9R´R[øÁ²äð±­ãç_H¹ø780‚~¬JîOjΪ]ráÕUjmo ûR¼k~*ü†çJh@;˜òò-¸kÂntQôS>vÑ+'b¾GóÆÌµ3r ëDÒ§cv
1254
+ç†ݓàìnqHIY¹]YߏØqüã\V 8IÊïÍ5JAÑ/nÍO²WçåL…Æ-´ZêwÊCã `ð¹Bõ‡I{)ÿ”6Ôà½ÛÀ%ÕYlŠ’Y­{ü<ɋõv5HöM*÷Â4È·9îá ÅcÀ†ô»pò-Üî“%D`]í¤þZŠ|hH+dÆ3¬ÑŸ?âœ$,Å=Ó5ì=™ êÂÕÿ¦´?a“ÂÔD î¶iãbÓ`亴@”ݵõ\ŸÎ¤*ßn1W™jÐнI>6ËëÞïŒpOð¥ê‰C,_Öý>GþZÑí/mVQÌÕÇh¿ î€î‹¡FpéGÚWhòœÖ†¥»ØGU)Á3JKE"ò¹dÉ,Ù)(³ÜL¨a*]|–;”>8ÊP×b;li iÉ£W©A¥0Kñ?¢2×kjŒ‰qšÁ£
1255
+»Š51>›«§òRŘ[Qhk:Yãz1eÖý”Z“¿u¾žGOMJ4^¶vKÅî'eýÔgµ$d®Œ¦k3Ö8Qó{]°8zTÃädÖ 9¹úÈß©mK¾Ž¸á[gJ?‹¥ºO£šàjꥩ–*WokɚhN&‡5¸ˆœƒ‘µgËAe¬Ð+qÇ6„Eð#`}Ü5TjÀ’î:“X‹‰©sŒí¥X)¤ôûC3cΝ/ª&Q©éh·y{74œ} ÇاÙA ”«³Ÿ†
1256
+ÃþpóD‰j±É1ÆMёþÊæØ¦škënV‡:N;³Èý%*ß°_ß4ºi:«ôigBß<*Té“äE¬¢˜õL|:õJûÝV9ê Ž8?õÁ£{&ûdîÌŽqúÃSñ5þu^Õ=¨ßs±‘. öV¦f^CšP—Ò<°Ûp¤påq³Ã­ƒ¤†H?‡¾H,@>»~ˆoÝGÛ+¡÷ö‹·M±œE‰l×°X[¡>j¤+´²±Êš`¦ÎðÔVH6'ÿ+¸¯ëLå ©OЉ9S‹E:¥­Cš0]H élXýõ•ÆtÞ@šFÃm(8ò°¶VäqEÐIœ²ºHq¾‰ÑF‹Õ¾¦æ£E™½Dqês„*в8*1Â34À;¶㉙)K5EUéu7%ɊˆÄŶà
1257
+¿á
1258
+ec 0:B€Ä¶>»˜xäM•©E&âÜô©€\M”`zH.2Yš†ÆkŠpÐ3!¹H&㨼E˜gÚXZ‡’Ç£À%jår©ˆÚ†Má1à"™»°:âÖ«+ôåv•¯‚ž z&¦gs‰0“äXHîQà ÷8©Ò¦#M–GãP4Xœ Âðhž’‹w‰6’¶á™,­Ãi ¹F%ƒÀE0ÑÉCÃpo›¯Q@‘<<<‰Oâ'9…<"G$cr ‰ŒÆcŒˆ ’ƒá¡hФy$JF·Ç
1259
+oWá)¼uyD ˆrhØ!;žh‚qo#‡ºˆ¤Ãi'5ŽÉim³aœ&ÀäDph6å=–¨YÄAÆ"9'áÐpX6˜“Mœš2ǘÄE$—hƒ¹85enOr©]¤Š“Ú†9 ŽC³‘(÷¨ˆž dñÇî Ž+ýY³ÎG_Ž›þÏû²Âˆ=hžÉÚEƒ6"ÌòrîœF»È€¡¢"‘ÚÔ:œG¢Bs‰Z¦ILQɉ Ñ´èm0‚k‰#ñî³òr\ø«
1260
+o¹j¦j6+[«›û×¢3ìým^…øË>9ñ5ÕqÙ§:÷bÎý½½7ë#[Ž‹Éë¯j•­ç&[ýÕ¾Tu)<ge_ù¼ø])[컝‰ºó¶w³w'®2s¶š¬ÏÖÊVÖÅÞMGNî<—ÿÞ﹞
1261
+ϗ"Kí͕‹ÖàÚ¢¤ l,>³q1%÷¿'ıþµ‰î(pt`d*™–‰®%… ÊéRm]¹Ú—‹=Äá9»*/ËTx‘öÌÇQt=RŒýìk}wl¼Þ å^'•óU^ÍþdÏZW‘ÿq){̵Ê2½ý*²b3E^ʱTnYN. ¨L½Q!ÿbeË{ݝ¹ê«¯'ûNgŠÚ†Ã9_ái#ËÆtmˆâxˆè^Üú‹Îšê›?9jMª¨²ÌçÖ¦ ÎºØ®.næÌêÒ.ŽR¹€h°8òp&H€<‹Åãña'‹6M r,.с –À€ ´q4š„2ÇÇUNjÓ¦ÂW½¹_Ù×jîWe‰»ÊØâg¬ endstream endobj 13 0 obj <</Length 49737>>stream
1262
+¢ïáùR*- ‚¶áQ ‘Z„kF£Qî9™®óq2’Æ¢Ar.$ ‡KmdÑ8M³±8™ÂpŒ$ÁªÉ–ÂSí×^…2S”¡ã:.2i40®¼
1263
+!8&Çâޟ—Âê¬<.d\›la«cêÚÅÚÝy5S¸ÜÙ×Y2öŸÊm¶ê„ré9¹€8ç„r¬{µ{¹®\dÞë“Õy)t數Žì5sí«+*[®XWۙ'”[ˆÏp)<×ÅØºÞ¬—öó²UÌǵ쌿pÿu‘±^™ªð4[13yÛQ[W¿Z>¡\>¯¢ª}DngLíÂT–l»—7ËIåp¥ï#âbÞL\Æ=;ñùyy©ç~fs'˅‹ý?Õ®N*§ºŒ©W×ÏÍÅxB¹öäÇm…Ç”z3oífV漚q'”ó•“ÊùÒÉ„)OÄÇtUìg
1264
+¥¾#ClíMED…lR¹\ý¼’=ÕQ5{mƒ!¨R„24D¤I’4¢„8ŽeiCIIò`°aФ0Œ‚d !†B!„B!„ŒÈHÑÜ æTa¬Ø¸Vy¹FîM´‘¾ëWܶáÞ S}¹´c!©h§‡†Ülû—+tGA¨*A×
1265
+<4®çßæ‰Õ£Ú©3:¨3çùe_D«sٗ9 âõ[€öŽDÏÖÊØRºº„ΉtۇNâ1M‰ÚõQ6Òø+ý{÷c1¹|“sÀ†£&机`ó7î ËÁˆG'ºKÁµYüÜ[2Nò[ñ*Þ­ŽòAiÈáƒ6ˆéA“[Os²FN_ŠA0k1¿Õƾj¹¿<¨ ¯æþó¡3(è¯ý†»˜4€ÜuõqG~öÿ̑.ãΪl¸](ñ¿þß­çsè|2¶£Èx˜ù3Ø”3W"a8¥ËÛÂ6‡@<þ
1266
+ã9 eo¸£ze›/ÎKÿ#´ÅŽŠòbž|šjV\¿ˆ¥,<–#Þ({@µá NéJi¬?þ—ÑÄvJ€‡N³±c6eœÐ _˜O,×}T{Cd°Á<¹¿Ë:‘F€3ºüªªZM®ÏT™8‘À (ʋô¡BœÝùöâÝX‹x.3­¹á:>Nå 6Sܳ]ÚÓå+$ºà×
1267
+{X×S5¨÷X¯Ï‡='þ¾qAT Eà‘‰ãkŽœ½=½10ðÈÛË©VzHíyRlH¤mñ¥ #°ÊÇvmÎßZL£úµá¸Dš©ëÉ[«YFÜù=7NBl˜hhu,UW-2ìU+éÞüƒÐòΜ·]g$@Ãju#¸ye oׅµÊ«tŒIl؍+eª7+Wݓ‘OKWMoÛjGÿŽë÷ä¿âˆj[‡c¤÷²™$€Ìqz QŒSà] }/„j£!o¨G£Ên·`”N(a^…¯w]zÛ;
1268
+/jý€D
1269
+dF®O­ 5ŽDHß1¡¨@ÇAö—ÞÇXÈÎc;¡˜?§Sˆæ‰ì%Õ÷§!¿Cö9g|@¸Ëæ›¶ &«,÷~™!±R¢V²­,6ìIL²©Å¨?Ù´)BÚ#¼Y&õ"Ü储‰þw!úlØè‚Œ²ážc–‘Úgnáš?m0KÔïÜ&S¬W„Ö‡¡8tñ`æ)ðžQ˜¸‚tï÷Jm±l<Ãn}½uióƒúïÂ=·}S0q%Í(F×ÈcňEƧXҚNõ(“ö .IÍG«ô³oWžì…“¡S!swœmeb< R ÃkôÝ!“l‹€«• nWûÝU™Ü1bÀîãovä¤x˜_£öJøGE™N
1270
+  ˆLÊ$ŒÓ½wý´mLˆTíÿéRµÝ‘TÞÙqªN3㥼7¿;,øh3³Sž`ͪ¼aqñ!SZ ‰mõã õzŸ3—è˜FÜèUA} u”ihÁH;"cª& ò‰¸s¯>¸ãñû“BôÛª€èÖG $ǟV°}ôºï'7½BóÒ
1271
+hkºÉIœúËΞ¾y ü¥ÞÊ¡¾
1272
+¶„Û¨«è²cSìö¤õ§£eo!9O¸!4jM!ˆP@ÙQiÎT¤:A»ØT<)b0ºi„÷-…Í–‰Tñ '%VW Ö¤hrh7˜ªì~p—Äê´æÊbM#ÌlY•FƒÐK ’û¨¤·Ê8îÞÕ¿­¹Sњ˜`2ºDÅf=¶üV1o)ÉÖ;N§¡šÜZR2ûÅ¡öë¸\ÿÄ\̈́;ÐJ…G! ÈãR¸3)¿n`Ô9û;ÿ«ßI‰8 CîâtDÈŇKãõø…7êÓà‚ËÑGIUñI·›Ï\Û9wš #BšD1‰4ù_/âü~^LD*ÉqŠTWÃwÖ,SÚà
1273
+”éí”)ÐYÉbŸŽ#÷Ôæø„‘C*ü ‰DÏÁA¯'A%9bف@ò£XYIx2¨8W· Û'È
1274
+8hk\œöåΞlç¿-rºÂ|h…¤-«4ɑÞµÞܝû[áé}‘þ®£üµj*< ³]¦iV%¾a_‡Èg "[•þOo´?¬˜ØÀ”—ŸIZ ±Dl¬’sJ(¶º °ÝXwx­rÙÃnY٩۾Ţq 2´z²OÝô3s‡’ɰìÙPœÇÚ ìˆl )oS9v†]++£å%s¦õš§˜ÁŽz1Ô5L!ë0¡îŠqª‘¼6P²¸—p'’¶pgFOPø?¯Ô Ão\cLÄ«b%:'{€
1275
+ë÷¤)ê ʃ3Rž¼Ç+Ý^ "¾(©–lÅ¥h‰¥ãÈ (æô÷ÉåEøD£¦ØÇ]tl¼tT aà#=ê¢ÓÒòùÓQ¼”öÕåOK,[W¯èBa“Ò½¼-»U²¼
1276
+@ÁCہ½Ï_íÀl­›ä°OÊy¤´¾oÖÏ#µmÐÉó%%îý{Säæ…ÙðMŒÿÿb¼2…ÉUšo^ƒ½%Ìço8V!tĝfÿL«E²2`#ҝ“¸Q›É\ù®>xQ!Òþû!†Rõ‘+>tPqoO€ONN¨ù?sӈˆ*«þ!±tC¹Ð‘,iºfÄ®ü¸õ4­'ÆOëodƒºj`èÃé1dÊ€µ4CºÕzºÛà™]¬mÍXZçÌTˏé”J& áÖVô æ½x–aP‰„u–n /ïecÿ²€:£‘œ7À¯Û,zªgt†™n‹KEÅÛ Ç9äÔ*ƒH5 I·A¡­-F21·‚%©¤ZŒ· ¡„È—­Ã½RÊ  l]‡Ñˆ
1277
+²8¥´q@_ù…‘¯4­Þ—„à&2ùxöP$¡± ä0óÓÛÙnq §‚R ;Á ž¸Ùü™JL‡Û„Dÿú²ÜдŸô`êpüÛkiiþ¯ÿ®ÏÛµõw$kíN{¬toÒ½æoÂþ wƒ[‰iNÇå¯_¼£oÀ^”•n7ùUc0t§®D ªÁû¡ZE½'§Ýªü4là]»š nCᇊü޲·æ«¬¡p†P.ó0¡ü†Œq Jކ$z6Ƽd"g,daab¹¬ý¸rýwñїµfêgçZŸ‰Ìë×®tÎÍo̵¹+u×k¯leì¿×.¯ÅVN(ÇkR9ÅTèìÿUuû±_י‘׳dʘq1/GÌ åPêZ¶‘åZ¬Ë³u¹×šT®W
1278
+1eæVì×ÅV˜ý —:.+<æË3'”[›“Ê-ç®Ufüþ…œû‹‘Y=—½.…Íþl÷Kvío×ÅvýŸ!cÛþºô_5uñ×>ûöEÕ^}tÆ4ya¾?ÿÂöV–É&”ÃIåž«»v—¯'.íÕÏIåºsµºî'*:çò_¶’-çÅÅɰù×b†˜Ÿ‰¸+»‘õêmtÏþ]íû«p1n՞P.}R¹}]…·¹Kû™%Ë¥l±þ¾/ä\ØËxYÛB9Æ&•ãôµK™­.w÷/]½['”à ‹Ë‹\Z,™»€‡‹GGÇrúà ä¢BýVxkáãz2wê;§¯¯õîÄõ5©\³åwg|Fgë¸6“s©LUÈköú•Ëú™ñ»]“-æþf³ç×el¿q€ö¨Ñ¥C4#’6i Q„!Æ(H!)3Ì``s¦RÊ Ì̒‚¤°_Û‰g¨Ýd·ôóRÀ˜p¤QóùÕ´§ûÊ\Š&[TeD¾œ|ðõ.øØKÂxsԏdÁ]ï‚8>/ 8’Õ-4°ÈÀ!à­ØÞt`èpìý½:¯õ†ÛCŒ÷¿GÁX4}uÉ¿C ¼È?I]Æ5¤ÌWnU)âô¿Šþª 41Q"æ$(á!5ÅӄOq‹ÚºÞJÔ^élDúˆêI.—8~©òWX¥éÙ¹ñÿAmué†‚‘ޝ·nk>ô¿tñbX³ðAåý¡/ÝÏ©{¶^Q…ò6
1279
+ÂBcºT†..{ÎÛ*ŽˆžpÎáªÆÓ¼Ø„É_Ñ!.HÑ¡Z2½¢ƒ8ŽFZÌ@i—QÙ§’1ia{òìÃÉæþ2©NÓÐ ·b#˜å§£Š¸¦b6Ñî±X#0ƒÊÑør²–0×Kª@€ª£ÞSâ‘b€î…%zqBùUÛj7$ÂÈ;ëo¥Î:©ûÌ(›ñAW@l#<“Óã2Zr Ø»)Iª’jøOT‡i^yezÙ ð!ùÑKü ¥ÝÙi(́/?Êé^zúúq˜Ä³Âvì¾ÞŒú‹9‰ñè †h@:7¢¡F•ýÿ#¦³‘ÌéáMÇ JÁ!bóXEqáiV5¿²Ü É6€ºÅ-j ÇyB¨®¤Áp·ŒÆÕÆNƒ†C%(èxsd­ T·¨Wxa³JpºíÑ´VÏ?ÅِMÁ°;䛘:s¨º­!Fٗڇ“®‡ô©¤yØh ¸xÞ¼a¶—M˜P,¾A+Š‘eØ[ôû©©‘ÄÖ?³™9+ñ.~ô¼`§¨ÂÄÞ1±3¶¨S‰Ãa†›TùÚgAH'D¦ù°gxÕQák)´Ï„ .УTŸ†?d&@"Mˆ¨³™údþy[B i#"¸‡ª9IBá³é¤æzFrnB5¤P8+åˆÎ†sîcúßñìã:»¢½V}ü](ºË,D“ÐóÍjÚüïN²oyÎÜÞng¬¦®&“F €sÎyB
1280
+–0\Á¡ùwv½:šëzaQˆöSˆZ+4 =—âíIqoçXóz§öímõqÛ!·ûÕñ¡yfIšqì/¡<»ž­æfé¹t–^î±è†½§%—ýeíûÊò{î}ýÝëÖÿ(4‰½¢²×(4É {ÏLÏ¿åk ÁÇtlv5úÇnÜ[íàQkwF›ý×
1281
+.Û´{Fß³v®¨Ò³Hó­>kÉݣѳ۳*Èâ¾=‹Hs)ö$*úŒåwžtC/„¾ûó!–°ø»û=Î>‚ ‚µg¤O$Eð+˳ÔÎRáq¹£ÐX‹Cíµû¥çúl“Ÿè…giŽ 8ž¥ù‰åù üº}åٜº?þ€íï··gëîÎñAÄ®ûÁA”ÄæÛž¹,[F(ä8†Ðï®ú˜Žu;r aqöíY·ý×ýàëwûíc
1282
+w²8gP°¸¸kÿ–;ù­¨àoÍË?¾g³V{Xó¾ý÷hî÷ÙHkÉ_ö÷YÏñ|¹gšÝX÷é·dq&Ù¶í÷–vÏf˜;˰okµ§;­õ+û¸ÕüÝãÙþ¯ö}+jkï¯[ZWöu§m¹×·v®h«&(‚cKû4í­ûÜÞu×Î]Q3$¿~ÿ£Ý¾¤ùZ¤}õÍÆñ,³¢°ÎëÄOáݞ¹aïݖüðÿ$Þ¢hjßù™ß—M®Ö'ùc–æ(–d †H‚é {yš#醽'tÃÞÃâ
1283
+ŽzžãÌl¾Ä±¿|,®à`ãØ_ByNøõ¼Yï¯5"&¯‚åUkc3WI£ç’vËþ}°8÷«>n{I]kË«ícwwö¸³z÷MìÙûÇ¿ýw§có%£ŠZò½oc˜[ž3±ùâr¿ åãϵèõm c×]´¢°Sl¾ï9}½Sºö!M³m_ÓôŒÕÊ/¢AXÜ .X ë¶¿THEàwš_ ‚&xžžW–æø}bHŠ` ~ç™Ÿ8‚` †“T;ÁϽµò4ÃÉs,=ü¾R,ÃÓ Mñ;ÁðOQIÏüDÒ$?ïÁÔZRhŸNR ÁIªy^çi$y‚ç7š 9šzé}g)~c ž§hz©F=ðÅQː¿<ËÏ?Ñ;?òŒÏï,Ïò+Ëò;ÉÏóȲ,EôLó#MÑOÒ GsÃÑüÂ14ÍOüÄòK±AüÀoBR€ ÷‰_y‚Ÿvžé•¡~eé•áøã7†fYš£ø}_YžcYNR­,'­,IM ApI2ì¼Ñ4I/Mr,?3<?ÏKÐ$ˑ'©ö’b’j$Žbš¥‚œÀ½ p–®d¹Å¤óá\#—†ca/å(P×@o’“;èãR‰Yƒó€W˜Ì$œë47}˜Ù°ƒ«ó†H?ˆNÔAéP‡‰í FTãsx áæøÔˁÓÊAÆJ‡˜‰‡WGâ\šUãк8¸Ú-a\’là
1284
+¯ø2ÄØ–7Ô]Ô }ª ‰…aÀð˜¼Jq”&0”ǐñ؍!Ä©‚Éb€%»ÇLC#DŒs ü ’}Pí_\a8Ôìf M‰{ã
1285
+«)¢7mˆm²ÓßÀUo0Ön,β¶-FS›¤{[ét›6y“6ñó†¶Ð&åÙâUµnbg•ÙX’ë²ÉjËД-%G$›"27Nä5n\!öùÂMÒ?ÞfÀُͫ\›IÀ¥Ø†±}RÚ°ÍúÊ· 踹 åʸ¦ Í\6‰ñ‡€ñ»Ï.0?Ð/gI§–;ƒOÅ£/M)Î\Ç8f¾½f'nðL\ü¬,ÿh;â+‰ñE£â,®{8:{t¸­<Esn‘‰2üP#0œe(¸p•Iyã“-¼59UxˆC¡ð…˜p®p»®„¯¸)Â7bæäáÇbòšõ•|epœ€9iš…üpBîKûã#QÌã“ß‚ðÅ£íø “zðÓêäàé6jðNÒað™Å,xA\QpIp®0†&Î]%ÇÛxà ÕaàbãÎ9çœó³µ°-ø"<sVd œs®Rð„sÆap™hÁ7c±qÎùÍ©p~©1œ‹(•ó׿Ýx̅øã[xBåóIÕ0õ€Õ­{˜h›¸XúC50ˆI.>cÑÙã`QÎhã<!AuÂßêÖhې²l¹1NÃØ§\!±¾«Z0:iã%+¡°a ƒÎ^‹ mìUò1}±RlÀìŠXÒ L€)+¶W;J*Vr…ûmý‹lq°h„#—õMiðIHpg‡e<˜FéVd–ÏóÁ4"›É¿œÜI†ÖL@f֚c¨ †x¹B(!!!ý2‹ãÀR2•j33QÔÆJÖê\!!A4@0)¢ò’PÁ@ªù:P*4+ì(-Ik‚sVˆs.‰lÆ9_uœ×œç \Õàœ‡6ça} €1`ӂ󄄄„®Ð Ä\ôÁ1 ÁÀ£D¶>‡$-õF$$¾“)8¨à'\UÐÅ hƒ+„«pÖQ¹MV "‡£R„"‘b2œ-+¡¢$ OØ¡35 ³y¥ã¢I2a¢‚/™ØH–,ãY·.0OÎyWÈ(˜‡IVûKó=8çöƒÔ©c )Ùÿ‚áœsƒs‚`œ†´qÎiç܁v W(Mœsø%2рs¾)8çt82Q7â”,¡ŠÄ S gu 0‰ç|!S,#眻œs® ñ–TcnœóÇ9[ª-qÎy}àœ먶€œsžÂxF“+lç[‚Á¹j°à<!!öhW.ÃÔÂw«RDD¥€JÉ,5R/ыЊmI kBxË1b¤
1286
+Ä<‘ÊWX!y"ˆ‚´ ðˆ+pŠ34ÚæŒ9šÁ*>ºW7K4KUV‘¡»@Q†‘…³­ z+5$É|ºš
1287
+ˆ@†*À(ÈÕ* .I_ð›JŸKú)ŸÿŸWÁÉåa  ÖÃR5ñ Ô¦Âsÿƒ«svOêœV“Ž]Rt(þäâ¨\%–Ó0x
1288
+ΜZs¾Ö‹[`Z_‹ºR:%Çڊ± ãØÀj‘º¹tNoS/2ÍÇåT®Ð-VÍÊ|ŒšÉ"Â5öj3&˜eND’±_¨Df Æø”§L˜ÃL1Ÿ‚€`؏­¢.”JíºGµA¡R}gõ¤iá ç¾Ù Å¢—ê.\¡áÖtjФ«´öèN›Îô H¤®žx¡0ª…B[/ý=DaªGiXìµpNÁZa‰Z šÄrvº®¨ŽL¯ˆ<t¨¢ªA”
1289
+ìòxTô§)\¡ü°(+£¢¨ZuB©;%9ô¤s8±&®«ƒ&‹—A™\*‰, X¤Ì°º.QÀ],£Aá ¼~KÔ+ñ¨Ô’ÄN¨ª$£¹ˆ’9î$\A”~„vùˆ¦²q"|ËD"£Ïˆ8LúT¼ÁàŒNú„HOQǃ'h Η¥óM„B`Šé¥cқM€‰
1290
+}&Ú¾vɘ뷄”S)ÐYiJ®ygIŠ)F‰8ed¬ˆ[’Å’J$ I3äÆà3ÉJÊ`%Ã!½ÖÃ!ˆiä.͸•¨s¼°ÆhB[´^¼ qk pDD0—"r/„ÚD³åy…–é
1291
+9i)
1292
+Mã%4Xˆd(³ê"L<2°dý j:†8°ºtÀ3SÀFb‚è—qàI´‘¿ùòµXΦïãõõs-ØÉY€¾+x+÷ÁÙÃQë¡ÔÖÉ3ˆnŽ—écŃL¡€*^»É câCV$¼#!Èj3»@FÃkBZé 9$–9q·1uzwðœ:”âÔé¸BI»,]Ü"ÈîS6: 5{¸HìñA¥ aj<=f8î<P2ú@‘òÑ p¬$o¬90¡ëEª‡ÁvCŽŸ±1Ž‚ùà­БX
1293
+W(IÛÝèÌÏ«ÁÙ[oÔT#V ì¨vÛH¬ÙªÖbÑ(`Í7£@õaŒT[ÆÊÏŒ>#F 7 ˜¸©0dªŠd
1294
+£!S9ÆhƲW¨”(Ñá³Áuá,^X'ZتL³èìUeAñxʅ¨q,\Ÿ&['½¤—Æ
1295
+ÍynO¥V.)(j㣐d0ŠÛ|Mò$'Ü)ø„’Pp…Šv'X«'–h pâ㚭´â£JJ”xÙКçNšHIF’D§:‰ ˆ$(‘@-3D‡ReDÁè[ñ{ÑjFˆ‰QBÈ0¢s"5® @¿Qð‰"ÉVŠ:†è£–@ˆý刘 ӜȀõâÈÿz9,^Tû·Œ’ICð1ýã [šaymgN÷¯kçWÏîìíÚø:î=né³»v~ùVGµ®_¶·g*ÿvþ@fÿþ¤õ(-öï{iº‹o;¾mšŽo»¦é®¦és4¿rl;ßê±ßÕ4í™5MüZÕ´Úëå{€®¦éÙÕÕ4ÝÕ4ývíüjÁØý[»wíüòÚùUÇ®7ÓuÜÕ±ì –,Žþ1ܽµÛ½µÛªçV=û¸>î®Ó²ëÚÝ[»w÷֮렣{\ûƒ¹{k×»ÿÝÎ//ÿöo[»ß·:]w°X«õ¼×û¸ïºƒáنÕ=ÖÁb-z†k:~»[†Û™ÝÝ2‡mgÓ½åå[ž]÷‹;›®ýÛ]vgÓ··;›¦;¡îh„ºÕÑ·ÛÑ?v;áßrŸ]oÏ^zîh»£:Aö®<ƒmYî]¿u€˜ëoùƒ±.æh‹”(„b)íõw×:¶3Í]ÌõìôaE˜ñ[ÑÚ{àŠÒ]þf«9±÷-ÏÍ‰í´æÄʝvݝö±–·Y-ùÌí¶¿GƒÉ«ö}nwÛ1Lþžø…—Œ*Rh’ø—¼måמ°ñïﲿ{íe¯Á½Öøø—ôZCŽàÜ¢³<FñwäùÃêþ©ý-ÿZ„;X=p×hl®3_‰¼{;×.úÍbW^äùÒåÛ^­ý‡ÿ-ûw}åù@ñé~ÁÈ̪;Ëóçs<‹à[^Adz«(êž~ô¯]Û« À,Ãä™fxÖ¼=Óâ.Ë­o{U^5»k.wf»?¦é®Ý³9@µ®É_»¿¦Í·öz/k³9@=kŽ¯É¿·Zò¿ÿë5yÖäÓÚlàmÛ¤uUîšÝ5X“»Ö’ÿA·5Ù»Ðì–üïÛÛÚ«y×­ùºkÞö®’‚¦{]aï©û+÷›åï!µ<i†åÕ·ºÿO­GÝvÏØ°ºb¿.}ô\úÜYeeT‘ø­(rÂÜÂ֔ V}Ru–Úw!¯·¾¢d#ÅÀ”qoÌ´‹цÒ”Ö5£Â g¾»Ò1O<ˆ+§¾FNœŠ„Ìɀ«XŒ °Ä(1-æ¿Ù@lŽ0q§_6¬DÕì'l²¶èW¬‘b_«+"_\!áÉ¿ b}É"%þº†Å®S "rIäQèâ³ k±l¨µ†`Ø
1296
+-0 ž  B°+ۄ0Ir‰}J0ùÑãˆ~QpнµçŽÞWËA¾}íÌnÁg³.W8Ý Ó%µŒºÞS+‘$íH´Î:+²tÔÉRé©v=t÷.XÀ>ùb0[ŅAÃ%à²ÊO±²0&SÇ21Ê¿‚ xhe »¸*ãÒ¬ò°#“ª€$*®€èT\E¡ÛTŠàs—w'‹¥]½«VØ)`ØðWàY`bsÄQ"¨x\øwN`‚ªÖ¤RʃAcÀýÀZE#$ðRmH ®Qg Lp Eq‘M¨Ÿ>×çôMVã &)Õ¦‘…%0E:©Ép
1297
+„é¨c¹ažERdˆF$I
1298
+’63@ d<,™É„1ºVjF€AK…‘¹@"KQˆQG!eA™’$mjåÿfä$E{ÖlíÄõn!QYn:' $Rå?o<!’‰b"1‚<Ž[ñÝÒàkÚb÷8Q}µs’9–´ó¸Þ©òdöcˆî´¶8?r«~õiÖÈr]^ª‹†«V­LjÔ'…™\ÒÏU(üŸ<Y‘»^:r!§žGcÞÒä‘¥CZÛæå&‹3}Õp/’ 1…RŽ}ø¾gTÔ±4¢~ ¶™…ô>ž×ÇÛA Qþ–Þð#潩Âä‚:!<qžçÜ{ Ì\}É BÌá]É5ä2IÝF¼3l™=¶Ĩ-uÇT/
1299
+‡/2 aq³²ö o¯ÙXªÐبÖÐävô+7ïj9^ö›TíPš8¬åè‹Gâá!RE ù²¦ö’=È6s–ªšÊÑc›À¦™pdùŽÙ2?¬[„½­B×YÑ£Ç #Í=aò¯¨$† š©‚2³o1tOÓ&ʟL
1300
+Ñèe“y±¯J“\‚6õ”ó¾0<í)è¢S ø:5 3îcGëfs§À
1301
+ +[€%UX¨ÔVu=ð
1302
+úâý¢
1303
+²’=Û bw¿´žÌC|‚bW`4Áf2°WzÊF 2­¢Âú±`*³äœ°Ề"NºØ IS ؆)/Tå·ö³aØc‰d…,hAÔ…ããG#¯U9KÄ¡*S]a*\„‘F¤ì‚Ú€ûùåÙn•µ›Wm®Ê9wŽÙÕ&^ç g7„ÆÑÞ`ôS|k‰ù3x¦óW]ªG5†Á„©i –U9ãԌ[ôCPÛ¢Îƒm“m¯õl:,hL£ä6~¬ÿy¶‹æcÁ 3¿ ñ=-&h°aÕq*MnœJ¨}äd"ffÂ1·ð~‰7o¸>BYO>õ’_e<U¶Q'MebdNY“̯—~AŠ*+.8v@j¤ªqË+æ˜Üx=îØÂ%­Ž^7™V ¯Õmÿ£±T¶JHµÛE}†ž¾a•¿ÔÈQJåB?š«tìàø,DÖ-KñF×Ä!àìç9«ªû:£wb\_6B9’³!Ÿ£5m·3–xüwûoL5J²bþ E½Šå1†âU àû'‚䯛0NÆÔâÕU?Bƒ‡ó›P
1304
+,‹¡è©nñ1³ö|{ÝÑ
1305
+B`N°¢‘·Dçßpúû‘Bejž¥1ß&kG¿ËþÆKh•rWÃ]§¤V#ƒ¯7vÑræ«LÆ å9=f x.¥»žà¢ç¦‹¼ô•´¤5죎KÚBäùIȱ’šup¢’jxt4›³6 ̆‚D´îP°€êw ähýæ«d¡G5#³’ŽÔFÚÐa«Fs‹eýŒäÜÉO‰•ŽáÁCMEñAÓ¶mÆc¨e–Ïÿ²Cˆ<iè˜RÈLÉq£~ ‰XqßKòÅ'sâg"zšÇšŠm¶oON72[ZDRðfñ”Õ$Ù]
1306
+X¢pŸ’'ßlÍPjZcüyõâ›Ã¦ýÊ?ê§çWöæ’1$æD3¾DpfB;[ÌJ›Ð‰k¢IÉG_|öÁ5+ØÅ5®”(²</ºøÁöb’"YEúe šKâ ¼(´±KFÕOj»PvÌB†TjÝFA9ՀàF%êyšÚê¬%µ\%Èb¾„õÄcýÀU†\RËyÿŒ{–ÑÃ4båäãîiƟÁB”±øU¡ft LÝ$ra悈òTÚª$@ió2žc¦–¢EOJ®çºõq»´>—ÍÅ×*ށŸ•ͧÖwº\¦Ã’“IoV"ë€v·{ ÐjÌh¡™£!éŒGxŠææþO‚êvm“wØófRŠ¡à¦#ÉÐtèlÆÐ
1307
+·º`Xqùª 8eE x§ö?«Yg”{©Dú@ §cŠîÊgё‚ q‰¸X’ _ª~>,]WŞ¢ôÍ d¿y`4¯ÎD7F£Š,Ù
1308
+5K¾ÌÈaèâÿ=unƒÂg~k§Wå8ÂoϘŒÐ: ˜ã âö¥vè{“j:2ãqÖ>èځ˜%ê° C¯µôI³ª˜¤à²ÔÁož3äýuÙghw{ÐrA´g­øJÎЀº(ªÐ.2Ò}ßÙÖ¯9q§:býSŒGž€Z­Ø\·×ûúÍ`D‹¥»²¡Ñ<ÃrõÌkY›"¤Z°Éøê)^T=ª¬'' d¹© y£,FÓz2Ÿ:,Gi¹K?AÉr÷V0?+.)¤ZV˜!ɈOÀa{JêšÝ?³2vR
1309
+b%µ97§G\³¹ïÊêqâA֛آЀýø%mà‰§–:w ˆ{ÝÖÓ»U'°ªà9$j²*$m  à|¾¦xýÏvž~ñKx¼êv(ÞPQ ~YŒ‹3M£”cc䦼Ò.&‚œ2rPzJSFÈâåü×R%œŸ~äÙ®±Á°è’p.¦ÄºK°i™P$o#Œ å3˜CK™ÔÐGÊã¥Oæx :QÃ@9ÁكVÀ¸Â[ÿÕ¤Ô9Œw¥‰rt+…67‘^‚ÿ°ÅPЮ¾"äcáJ¯ KyPž7›Ž2 ›x׍€ÄIŽ’P›õ¤Ý`Y5lïEZctbÉA íë|ûq u²ì“Ðc¨RG¯ŸE#*4™`Œ–ÿ³›1!@ð=Ûî¹h1dûOSrmEg÷dvՅ“þ_ˆÃrç@Sçïr¡„A‘¹ Lëð@þk‚8èÅ%كÇw¥…"'ým¢6 ðb2×à€à¹©<§ÕãÊÌT¨ô]‘@(*%m'ú
1310
++ž1¨†‚GªÆ®ýHÅ16Ánš›5–±a#vœ*d•Ã…[µ•™8ã>Ý6è“Cn:;LJLš¨-„RÂ/þ —^Q]]Ð'ìjaóB4ԍá´iãLË-Ñxr&™çœ¥<j‘¦Ívåpf¹ûr,èjèIÃ6Û°I>%þÜb@QÙÕחæ,AïÓ¬'Ž‘@1²‘&Ì_À&gšÖÀŽ °.&ÍÖHí©‘¯¤GÛ&} À%¡@1¯{‹Ð„@?)¼Þƒ•>¿"|.’sá4%¥1 VOLe
1311
+­¥š~LÒM‘@i
1312
+QËo{…ïšV(vVbÓ{±/‚KeaµdÑþFÉ5GE:2GüRv6,MïQכD>e¦Þ|ƒuE@ùì½¾³ùúbÒ"f!±å·-ČïåNÕ¼2rºP’fL4œx€½áA^ó?‹úx5‹òPÚþ×|`v3×j…O›î·­`9«ìïÉzM§1»¸‘*S+ÊÚZë¾ÒZa6stœ†o¦oŤ Sځ&>c̟ rõöwWI¤Ës™¥Ø™4ÆÂ^{áŽÁ@Ð5SÜi"ÿ4rw”YÁ_\ÚÂÝО¡É œ¶R…;dX»é­ŒÁy56k_<#m9/&ÊßC¯•æ4¯®+0FNO,¨ŠÃm}6+Ž69Ù6ûJs*Ø9̺˜ÚË»û‹mÓT"d{&¶Æf¦Bh¦‰>¾ó5ÍÏÖfܹ- 6qz™1ºU§sýZd^"ë
1313
+6§?k#óõao‚ȾÝGó/d:[àîäÙÑÑ«~'©4 S%“…U• ­ P&Ý"G´„ŠaûË2øÄ˜è²oá”Õl?ÔÍuëÀ Ø%“ù¯œY«ô<줿+fݍ4w3µ¯nF÷Š?;vkîìAÙ(GÄkTP"` ø¼~û‰ghiU|âŸìT؝ Þ~͍¡}Êkar‹VâN̛AÑà—b`uÖU"¼rtÇ&Fѹ‡g¿É"$쉶 h(8Õ¡3Ëçº?Uü!}W£'Tÿ0v¸‚¯ÛLÎ=ŒK3&û¤ÊR44úܓ™sŠ»BèʖJS¢1¾7?Î ªýP냦ÿO‹HIèh[\Ò|°¾kÅQŸÎƒX.•GRªk’ùÎ7›y|ªX¥/(„ÚSÄdÖ¼vµj°ñãÒVy½üÛlëB õ‚i­¥0¶bqdÓI°õcŸÏV#¿z¸ààÉf[If ‚îG w<‰fŠ‹ôKjÈʞïîÐÂ?ÁÕ¨dmà™"²ù³ÑY^r727 -|ñš3GU¿Z X‡öPD1ê I¾&l7s-qöô’˜•ƒí U˜F%
1314
+¡yšEØcSê>G:ýAR” ْDÍ$,‚Äð*œn…% DD˜`¼Å“1ÐËiÕu=&·>³Ç–©tƒ²®LÆSx\އQO;êp¨òÖ©’ƒqdUß\á²ßÍhîÜGC(骍Ó±˜>òDˆ¢ûÝLÄ8¬Ô†%>˜Ê‘“ºÛ"‡k0¨~`鞺-’U®‘ùÁþÅiVwÝÁL­ªûëiMd5|%’" äZ ƒ8¬>ˆùnFØ[MYÊã1¢=Fô‚;~AD5ä°ª†\ã°úçn0ò¯G>¨PðÖ©’¿uª\|-ƶ _TF“S9G}QÁ¸ 8͝sôÜ'ù ®ÞMVÃ÷~->´}ÅGW„E5¤˜Œ¾vßÝȵƒœEÙa6WèîIJñl WkúfCËÔq¿Ù B˜®Ál°¹¿ÙPjÇQ… ÿ çB(Bt#Ræq-!• Ÿ‘ºÅ)™ @$'67‚ C¹)ÖÇ_±ár#$85â‘Úœ³Á4P·mYD 5E’]†et“E® ^™Aõá¬^ÐW) ¾€ãLcˆkHŸM@0)¨Ÿ'ŠîlLj7hAÿ‘åÀrr¾Ó¶gEÙ;—R²äUe@òRè]’­ª†)PaÙ+ Gq¢èþÀ¨¦å,{è(®["nÜe%K&àÎË)¬—˜ûÕ¶)°FÂFX£‡ÿ>Ԅ¥‚H 2LÎ\¥^¶=<ÄVSm»YÕÝ% e#áözä~-PQ\vS–ZYœv=©»àèRZP¦/3š Ýõ¦\ÂExiTÀk3š~ƒ¿µ>°þW“ -́·q ÉUâõü Ž"(jÈCj¼jQ?³ša™jPqZ‘¾ÍV’¸Æ^…oÆeiÒ€?„˜C¬;u®Ý˜ÄÌ͆™T
1315
+H' éñWWøàZ©Ãý¶ Rº~Ã'eL
1316
+›@ÊE «û"ò‚€P¨UuçwCn¸·ýŒÓsOeZžÂáZú
1317
+q˜™ ÕýBׯÀLRÒ5U¡7×¶g꯺µíî"l{°%n:0éÈ Sèèðk833"”¹##&7sÛâ–`xÎâžÑg W™‚{ݶ­ˆ©D3[´œeoSîÏ9{j÷5pôè|³á3I¢‚hfÇRÎÔáÄn1bh´àŽáœ\ÛB ·]#Cd’LáÚȺAÝð‰M(GÅXI@ %$‚UH€k¯cÕt‰, ‹2,Ã5E‚1Ü|$`ŽL—I4%eA¹ºLçš÷u<‘zv>‘¥žnZj‡€À5³CX*[Ŧ1ÆBúŠM«‚€0êxVàLý£
1318
+áUÏЏ…GOtN®}gd «(Ùœ‚Wwm—w†å>✶Í5âZq!â.ù­Ê €Š\‹ôCÜ9œSÂvV0…ª) >Zƒ˜ú¹Ã͵JÜ -ñAxæ`®Ðkˆk~#öâJlLÔBÑ®›,údsíur¦þy–Çäx²á{¨³­I-èé‹Úù\»üY¾ˆžKl²%rŠ{ˆs*>Û5àš€À:q°`ÁЍŸ?ßÉ5˜Ó¼:BÄîÓ8?~bsÛ\ó¶—„Gd"CŒ d®Q>ýy9œ©«1Ã)Üÿ>¹MVÙáa’‰»ƒì¡¢ðœ©s«Wès-#‹ ·[‹<ËYv†ØùؗaÛ÷ƒ28<L2E¨(Ԋ'úò҉MÌ`X;Ò¦¼Â“Ý~» Ë5途ôÁ“ÍM#ù²ãÚO úÅçnhE<ïÓ9ªäs7ÔvwBϝk,UCØçnhâô0I°àâ[/¸øvÞÁvqÔã¶8YáÖQ¥ÄM®¼7$©–ˆÙŽ×"ì'n)&æ6Ñ ¹-dœÜÖ)‰ÄMqûtå¸ý¯ƒ“SIáûœ=™êDÏè6ÎĄäƒúš jèqe?9‹q»¨RâÖGøq­l¬8S¹§Þù˜è)8eeÍeeo[Æ RFD†­P–kÂš¾þpy ~Ix ½8}@¥ÒŒL: %à;I£yőZpˆ#ö‡…®€»hJÀ}…1:`›SÀ=ÄxJåMrmӕãzpkã/n$ŠkÜZÁHaݍ+zÎJ“²*ÐFùÅFòíÝá&z@J%P®uò·¤øaô¾¢ëa6ç))sn/6an).Á!vhsëv²’•*ÛäZˆñ¤ÂõeÀ˜ÛYŝ÷ °Í²•€;Xñ”J;<á…w^‹ dÚ0·oµíY¡èþê¥PÃíð0ÉÆJ ·Í¡1n.Y
1319
+7®9|Í·ÒX
1320
+78&‡›e4Œ[fµŒÙMÞ¦ÆäpkxpÝß¶ï‡Ìð0ING
1321
+MPí°ØÁë2a_®“3¹y³´«Plô–¬)/‹Âì¹&`é‡/;naZ6†ãÕ< !<[Øõ+ jh Q5\ôlÊRkH˜÷¹‘6™ yJåˆJÀ½$¼¿còÖWÂEèŇt5ðÿ̚ČÞ%É5˜UÏ£({ÀBöm¬UÀ·¡&‘¸Á¡Œ¸Nô·YÈR¸Fø1Bq;mûÛR„Š"ü)%q~HXöpiMPÖâh½ßU­¢Ï=])¿Tò\›¹; Î|Ìð©‡Ý¡ 4ª†¦nj
1322
+¯˜¡C0˜†…©Ì•µp¦®Ò’õ\½¨Æ«ì;HXö’”Yͪ¡&  ¾x?z²RÀ ³Ü¿ôzx×+vÙµã%›µrÆPªí‰œ±øÍ 5©YYäŒå½¼rÆR“ZÈË«ä‚åŒ%6¹Fµ+à!»GSk”Ùu&~'^W@€—+ÀÑ2Ú-õTÚÁLMµ¬ó)÷úýwX˜ãûâ#0òH€„— ;?°WqÂê¹#Ô ŠÚMâK8–—€!µÐ]Dt~..m×@½t2‚Iݍ¼Âç dëêä…7®¥ÅiÜY:³Üë¶  ö¶»1bÛ_(Aw^é¾!e îXI@ý%­š>hÀ2=晞ru™n"©0}±Š,í–NÞ ¤s­Ôñ<ºgQxôÊL”û ŝ…q7a¸w)&dm….R"„XÒ¿Q,/p‹{ÚmgÁÅ7¨‹¯°m·mš…žqÛhàڌÂHÊz
1323
+‹å¥Ž²ïÀóý–ʽ?æ¾ %åQB¼Áå4:Aa±È úãåќ ‚ª%é†cÀŸÆ€?i4šJ`ä3›L&ãvZ¸ºÁZÖ*°V¹,²zÙ\`…O4ªE£O4²X8f5I>v˜ÖǵÍuƒ±U fqewy®}õ4?×+8$rÍùpìù|=q7QÃ÷õسXõ´1õ5èn®õr‚Ø閰m®‰ #ø0>!ÛðÊҍ`q cd±Ó @0E°*ÈKJò¥ì¹²áGdÙ ¹¶Í5tõ
1324
+}Ùð¿ô±?Vlx|ÄTÚ󦷝v9`✦TýàLGpÞqˆ~#ç$áðªÎgFˆ °+è™]ym c`OÏl®m¾³$jx.…®^
1325
+µ°Ú”9&&‘¸Í>·.ð·y{Œ±àe³´¡k hcž÷!])ãYò‚V ñ¡è)Ân°Æ,5Ka$’s“H÷ÔI÷ÔI—S’îHº.é¥'ÓɛÍfc‹º—žúfüh˜ï%ٝ:Œ#Ã80ެf6 ëN`¬;ýpu×wt-èÝÕýÊÈfFÎ`ÂÕ]«»î`­úœ©Ë\ÎÔœ©wæ'Õæ'Õ½5‘Uˆk–eó"é¹8JºrŽH—]V³ÑŠf£Õð™L‡_™²µ|«²¹ÿõgÔL‡>ý}èӁՖÚ,~e9›Å—M‡•lÚ+õË&ùÞ(ºoV±3ýORÍx›ñèíïöïöpˆkÛȁC‹Êèõ_܄ÿ7±´àËM>$t[ÐsůÂܲöì ÔݒÚ(/H˜k1 ¬R†Â.ö¦F­H©¶1z¸hb³/U?Ç%ÝS7o’¬Þ$Y5I¤‹Qtßí>ƒ:0òîð§nü©û€?õØGv;ScÝIŒu§ãÈjfóe66ãÃ80Î+®îº¿2˜ ㆭ‰Åûè¹8f50ŽcV“kæFIW‡GIWÓs(éÊ1«)›¤k#v4ZØa`r­Ñê|:0~m´¸@:0åê00SŸ¡b,²Äx½õNg”h³ø_•ý[åVٟQ~&šçûµ˜ç±G`ôú¤kp腉8‡`‰/òs>ND€.Œ›pkÃ5®Ñ\k¥pcU)qãÚft™>ÿTûhyŽŽBG'û*ÙHƒlÉߒL@ £(êªÂÆÏt\ãpÈoc‹6 ꥧî¥'w㥢—B£’„FÀÈ»hÀŸbŸØ'ö‘GŽjƀ?õ0àOk0Œ#«™çg>°we’ìÝXwê\ ¹†¿ËF>¨.‹ì²X8ËfÆÒswGuÕ}êޚȪGÏÝ흹QÒõÜ(©ö)0÷˜ÕtÀ6JºÎØØap˜³†_or­Ñj~½~ýP†*•ºAŸkì­¼¹nÐg¤ôWïmf®}•m?ÀY|Íå/¢ú˟QF©2»à²È®Áa¥6V™Ê/ˆlòdÏmXɦ0ŽGòAaîv‰œþzHт1ã&¯ôì´}‹›ˆŠÄõDÎÔ[ T­°.Hàœ»kÎìA©gveP Bç"˜š° T™VQ& **¤ ÈF@B7B6üI敟Ìy¨³Ohǘarޗ ¿MAzC‰¾-‘*xuDZe¹lÑLМ“”)W\@ø­8àáœÂ',âNŽâÀ†sÂ@ ¦Pف}JÏl
1326
+˳z_
1327
+…HJˆ¯D3{\TF3§©¼âæV^q‹Wj¸‘ª”ÈY©áã2ÛQDqêþ¶Í5N2~?ëHúÂô}ZEÿåAUÊÉ«KyîtÄØ,„ay€c¢§‡"$ЅǿO
1328
+×*àèŠ6‹ïÞ¯EIº‡_CΆùI²'ÝÓMºI¶ˆôғ-Ú VŠî RIÑ}W¤Hf“¤†[´ÙÈuÔÄ>±Oìûh¤ÀÈ»³M`ð§Ø'ö‘ÕŠx†®q™Ïönwê±îëN0ŽœÙ„ ãfR$¯Ì+óʼ2˜Í6iA?{´ wÝquk¯Ì+#«¡Ë"«`­ª{­ªkUݽZUwð­‰ÜšÈ– 'SÐswyJÏÝ=é¹»¡hT÷Šå,{k"«¡ƒÀ1«¹QÒÕspÌjšXŠY͎’®¦Vá!f5M¬œ5üÚñÒSo´bY ±ƒ9kø•kÞi6Z_CxéÀl´Àì00¹v7üÇ8e¯·º›WFVCF
1329
+rɬ&çÉ@Þª1T_ì}†J†ºAß~½5¼I²β,0mF‰6‹/ˆFuçd›ÅçÚ`•Í(ù jHŠm•™6‹¿¨Œfoä|xԙúŒÍï{†k™LFÑ}®VjH‘M ¨Ý_TÀ™HæÚ,¤è¾Ì°ŠU ÐË&Y¾Rå‡h%FVw6æQ`$¦‚€röI\‹C90j:‹KˆÂ[ˆjÈ5“í|˜Dâf²¾k£?é™ÛÃbK‰hi35Õ:2¡J)8 %?ƒhÎd¼TëŽP$šŸk\›iNY˜â×î:·„¬dA¡—€IÉKl6„^lÞKl¹ö¢ÏúÇPߪ‹r鷋A¢5#Lò2÷)7œý„ ˆ´\!â}Ç5®qôi\»ÇR¸ÅJ¸Uâ/n&Å5nXLܾÖê}¦ÎûAW´´/l}À¬z®1:ºRR`FÉǰ§äYŒ{êòÈ}k ÿR¾¶ ×ÆÏ™z
1330
+‹nUË ¿Ï™z¦^¹§\ O¢G9fC¼9×K¼±^ȶ—Ør-… J¾¢(S~+9­9ƒ ý9Kie\ RÞ‹Õ÷»­±ä5ƚra"ȵm³v®y]êÚߨv‰Öc#bSXm ²V¢¸ô,"NÛÞDqH…¹´°²ªéãß§…»x4-ô.ÉX *¤\YÝùÎ5Û³Yü…†ðy¶×ë¸V0ÛÑî:áÖ0‰Ä->YáÆzp‹T^qcÑÒb`¦ßòS€3á"Ær-¹LØWµŠþL,DÊ٘ð^@VÞ_v\`µY|].@Vg“{ê
1331
+ÔXò׸v žÔÑ=®Í\›­ŋ£r­Lq—•¬%w^®‘tn«¬d–…¶ø*ÿ™>L‰“ݘ8…½TäÏ ¤ÎL©f’žx„H~”N–k˜ÍÂb ³ÇFe¯ˆ'×J”ž¨\ûŸk!®id•k\ë\ë
1332
+«Ð“*× \ˬ6eïèMÜDÛþ¸¦ší¸Yâ/n=”·4’ø,ª”¸‘d)ܰ˜¸%Þokrm P[3qIúËò-끪”¤™¦<+Ё´,Œ{êŽܚšÑËp-Ð;Ճ±BàÆµKV+
1333
+®ù?€¡Àkš¨D`®‘^×L0îôR\㾕k$—âäÚt…|E©‚E¥ÿ1$/¸öוn,…Û‡â7•ðm¡Ñ0nâü,ˆ¸ÙãJ ·GWŽ›þŒÛ_€ßÆÆ_Üd)ܝȷ:æ‡üQæLrÒa±[¸µ¦«d#%¯´)Ÿ¸;¢wNV<„ÈϵŽèãZbãžúǵÿ]…|Œ:sM…9µ(ï¿»ù~\Ýjáº0k\ÛÈêÎ5Ь†žønvkNÒÕ¶9öübc›.ÃÚ\àr+‡Qҕe]c'ûŸ{iE¯k¦Ÿœ²ƒÁÖýÐ3¾<-ØÛ.ž*i}c;‘,\ï@f—¬d2š½ƒ‰…JH FÀ.'V“Íގy‰m ×7ŽPJ-Ûabá,4ðïäQ“%Õ]vSÞÏ©M…¶±B¬º£Ã$ß*^òkWœ [9&ì,ђ_äÚ=ãæáó}«O²“q­ÔA²ºA<þ}®’Òûù¹¦…D_
1334
+¬`P„Qç¯ 6àÍ,-×ãõTˆKË©t–.c.vÓ#˜•]Vñb?𘨡' ç®VHuçڏ™ï¥])dùý¼Â78±R<oµ¨á”­<RkŸ(îÊôþåØÐ ôÜL ‡‡IFîoÛ²ÊYö€wáYo|´o[¶1ÖLf¸²j X’‰bM‚$߯ÍßçšÍAÕR—ݽø–
1335
+˜:0ٍFð£2Ç
1336
++ûP#lMæÒ¦:!| jhxj÷çRrMU f/蛃ª­ª†‚ŽÂ¶_7õ·mw妜ÞÁù^ÚG%i³(ŠS o™(æCáȰuæîÝ0øzWM˜SçEÙÇV‰›ž ®ÝÏØ'¹UÔ 1  ×TbbˏРÎ_N,×*õB3ÄZð¦ï‹K#‚½X$sËs{€L@ieÑ|ëq2g‚êGYÙ¤+å×È ,¬ð´«%{H̦ZL)Bÿùe#פ×]°[s18ÍO£žFÕÐܼ­YÒ¨XYÝ ·ŒãœI‘Õ¡j(èG{nÖ˵ËÍO/knupÈY|% ؓm zR@ϽôÈÊFVp"Æt.TÊ%Få;v泚$´s¢¸¶b:‹Oú£•ÂŒ¼öûQ@Ͻ3´ ÷r`äI̪ì,NÏ}DQ$Fbú“Sg³³ø\-Šî™Àȋïö¢€ž;Y!•½Er¦>$Z£q´ó&‡æ%`Sú>×B gñŸW{iaŽBÊ¥¦uS†Ð1\++œ²³f±jX ILH¹§/T#H 'Ðsœ|ßuYÍͤì·é}OºA¿W&e'“²ÏFƤì®B zmAº“ƒl4wP@Ïýcä2D[Ðw‰\–¹ìcœHC°i4Ž–k!›zž©zî_*/`™Õ|¨
1337
+iò®‰$Á˜½xÆÅ7´«‹ÞáùDñ†Aš;H£q´÷ãÕj;-»,ŜÎÇ©3ª†c8£jƺSÿfT ÁZå‰Fu/I¯wYë00ÉÀªì± ª†*
1338
+%z˜Uíí`¹&Åe÷å(ÀExôƒ·N•áç ±QÙmA Üæ DÜLf;n«ál²n‘%Ü]9n,û‰[ixÛ»RÃ-ӕãvF߯5N–± ¿]7^ôŽDBôw( R>4eÉÃï†J¡ý$pkj@‡©t~¹Äíæ‚Ì6zf7<nªš6K0CŸãZýyAjö1ž'Ȟ9ئms²‚(–Ò –JLáf„å,=‹ LÓè³5l rOÏl·q¥ÔD"…zýŠRö28“HÜ,¡Œ¸i*¯¸qÍ#à& ãö( *ÞäesæÓ ?cäEYl•jgoU)93›3çH‹â²ÃBw³ñÒS·E¦-’½—žú'!×lÆö¢¹ºkÐ-?rü蹋=÷ð£ç~ôÜÝQÝ[¹5‘;A£Åø²· eŸ¡’êŸQ}þ¡˜û$æa84Â"î!¾¸‰†/à>'#¸kÄ4‹îŒ#âm‰¸£zƒ¼ñ†P¡• £±ÂÀ*ÿÿOŠ#Eeåé¢Ü¹Ïò˜²AœÅ†Ìbç³)$û£rKÌfG@‘ûa”#Î) \.¯¸›°ÐoUBiŠœ_i!Ý#\F» p`ò™âÏf"‡ë{±„ëkiԂWÓ(®_½…ëœY,…ƒ­Xõ8õ„#{N°¦Zù‚”"gö[XêóþÍ9ÓSè ½=‚„ç¨ÝÝ)(†{ÕòÃ)jÍBB ùœ©ƒ<«÷ùNÄpsm0Ýv¹%NωÏöÖÃësÛ ñ¶„m¿R*Ûæ[âÒ¸¸6 ƈ]è¨Þ€ªÈײOåTN:„‘Å@6×h (Ј!e'èdɅË)@dsãÉÈûì͍0±dӀº?¤‹û1±Ž,¸¸B¨msǦ€¿ŠøW© 8¼…‡¸… Ÿ>xo„:@ÒÛ"𰪀4"L°@( õj|ÅZ‘³ …:×֏‰À„úáÓèX©€ @ŽØÔ=°´©jF¤ÛfO@ÜBB
1339
+±Ó@A§O¯Õ\fÔôØg0hÖÈæeºƒ
1340
+{FŽðÜn­v¡Lgx&Ó¹6{Re¤¾Èz¦à‘ÙÌ1f
1341
+éääp|Æ¥ŸÂ^:é9§, Ü%Y0!–ŽŽ¯Å~‘¤£Ó9b§ª1,–¤‡:g…Q’t˜‚!õ©õè¹D›ý\g!¶úœ©›„ÎE€¥fÐ<0]õ¾É>º¢S±¬b(Aª{Æ@‘7$‰Ñ±ãù¹FÀ+…Łۭ+3(î aAqÄ=òU
1342
+‚)îd„Qw6&>ùÀÀp§p<IîÎiÛ’ڟW£ª¾r®ɧ2 y’ž)fDÈ5̇F £ÔgfXXfFS’ʼnq0¹ý—¡ïlê†ÜFŠ) ƒE˜ý,ìü63žm@ÀØè‘®”P#å+ÿØrf ÓQ¶¤ßgv_CƯw‰mKÐ ’*Ò]#5U¹ŽîŽìì)ßÌbg³"47Á7am)”’g;öûVHöÈ} IÚí#Ÿ\›Ó}7 >®‘0cíÔkÅ6bÕãH¤5aÍkÅÊ$6RÞ!ïÔ¹v9H¶Ê‡ñccÀÃO^Ÿïß\¤ÿ|6Èw[k2v¥˜$¡ÉµP])lOhèßndu箁üð`kMY¨”®§’PDږ#{%™³®íøeraš  àQM ÀK&BՐôde÷ÎIÝÇØfAA¯ãùD±âÑqgËTyý£¼nòz/C^?€6gRRÝі¬ìǟ!|]N†Ž)\;Oä{ª†ž†£†„ªa—|œ BÕÊ Ólè;ˆ0·°>¡ƒªVƒÕK³úôçZ’¨ƒª!¡…€ÿijP5|i4¨~ ’UKKy¿¦TXßób†8e§ýUÃ>1uà€ÊÐÉõ`"CŠ…k‰xþþ½_‹Ç©4iAÉZTØõûŒË9~`‹æ.HÔÐÄPJT ŒµäK
1343
+ª†^1–ü"¦…AI¤ jH†(’çUC³²ÎÞGP54ãqf³'#'J#$#ƒT ÁØBö.Lô"s }«eWk÷A"«‚ÀTy(6D'³«oÐïX´ì±Š¢û]Šv߉–½tÌj’©ôc£²‹¦YôÇÕÆUKžÀÓȪø>°—…ÆAAª iÁˍ»ª{šNk†”T÷CJª{·×ØjlT)q{¬Ôp™í¸‰q“l âpÛÞºf!]›tOâ'·™,…[g4Œ[çз”8£jXÖª: Ã0„„0 AH#•>AÁOù¼Ýöù,÷ûm¸öAB®}>’Ã5÷!I7¨Q—¸sqH–wî)BEá<ºVér äy¨‚:ŽŸ­$sè$hv| ›k›¬"YGžGaM®‰‰g†øXî7Qžô–à‚ç¹Ïmö"éY>#ÿñp6\¾¶¨%e`XˆJ ñšÐ³¨aÁÕKa"Ý V`lô­6e塚ì½ZRö¢õýN£Ã|¡\‹£Ø:Ü›fœ†Ì1ÁIº¸_ãH”L°Er탄å?ŝ÷±•,H18Ä"Æz‰%†ÈUaTÛö^”}¶aV3ä+rÙoS]FP5,S˜ì#¨ŽdHö¨‡‘ ŸZ²ž_*›ÚíΙ‚r­;
1344
+!ÑÇ®k±"Ý ï¹jÙaŒÀ(T¨e}cò`ª#’YÍŒ˜a*”œlPФ{ꠍí~×â&µªî1U¦†Ý\s“@ÀÚ,þjóš|i#Ìíg“aɪëÑA\È/f‚¬d'6ë[4 ì½$ tS‘A.<3 ÞMwÞ™Ë êÜ.LߗvÁr]^;Êr-¢àöžÁ eåS93@ôZ±²÷ýOúèÌjÞ) !iÈÅär£pãÏ94ÆMá¨Çˆ*%ÈR¸q ŽÉáæQ¥ÄM&'*%ÿ¢Rу’2åݱðýFo} ÞÿJAÒs´/¹6ˆqísk×•ãÆØ˜T¨ôőª ¥B €C $ËeÃé¢É€<.">@@00&0(GÑ8(‰ÅqGb…±‰9!&ýJ¦ÖIú]›ôý]bTüKÒÇŽ¡MúÚKÌI_‰ÄŽjVý؞‰fZ蟭 éWhô«ˆæãí{¸d˜ôwòׇ:d1›w2Y=C<wQÐ݉âYR£JZ§úëñáÂ÷ù¦«“ï÷0ƒ¾[”âÀݼˆk6æMÏìjtE!k9c`$ßÇRS$:ƒïó×Lj|Ÿ?›Ü¾Ïõò}b²ŸTäôª?´Ô·“{obEˆ“¾¾“ cSXò€“U§”/u—mÿB ÍìÄ×Rz%ŠGTÀæ– vhʨ6ûf4%¸~ʅ¾o• ¬E¨‚Öÿ}µx®v"‘æ¼Q7ª˜Þ„ÐÞłWÎT¼Êq̎C‘ë³Q®*Co£®nü¬@ÖÜ㽌ɾ1×­¦d[v¹ÒÐäTEª;v¹íëûþŸ]îïñI~BË2N âPõðòPyMGK½‡oÁô߸ÉC˜|Òm Ò…võ³ò‘C§|ô"9/qö Œ° Ä9{f‰+ˆCuÒ¡GÙU‚8~w˜´2BÜîÊ*ZV¬·dTBœëö¹@p‚8Jöl]4r„v(ÄâqÕkïÓ£àÎõ,tšö~*z!L–ñˆµõ>:ÕÞ/¦××u’l³»L
1345
+IR2„ÕÄ׶ۆÏE³Äjd~‡ý»ZÕÞozÔ´­÷“µ÷ºZ,<®®÷@5T<|ϙ¶˜ 5”ÍÚÀaQÊ¥ß9·ø¥Ô7ã©Üáø‹lǾ¨­Ÿ-ŊŒïpƒ§)·9#!Ÿ´à ìDñjˆ)„ÙAÂVä\$€ï¾¯ƒq"UV:°"ß ª³B˜ç³N:[y0Jê²-¦Ì(¯.ØÛU£¥}•_xšìÖvs—¹âzD Bãÿ"¸ø(cõmåݞ"¼{çr±ilw.÷º¿™áꩈðŦû‡âe4òòú%YßÌéç:—ÇÕþòë\®"Ôô‘QsEšòó\Rp °¸`z¨õC´:=}8ZØ5ýNÞ§Ï[«¹™uÆûNÖ Ôn“é Ø]ÝÊT6±Ú‰å[õûA¨?œ°nOÀdÒêŽÌ[^|ـûpˆÌÂúýáDaPœ± myïßE‡òN_ñ4JBYûpfs "¢‡*°y¿æß)˜µÃț L‰Ë9&×
1346
+ü¨êÔCí4»²qy!~&£?N”@È,0sÁÙlÝMæZÖn9ºÇ\Ìî|vl~öºÙâ ÿƒj4»ÐXø¬ uáh’XŠâ²ä"a-]Ê܀àò„h顜4ìþ¬Ê\ìÛåWlKd¢éps`¸^?).púÒ¬@£Oà,7k]Pcx™Œœ*@·™ ö@ïB!]ca«>C¶t»àQ¶ROž©Qþs†8㖛½ûün´i˜ò7HPdÞ ]lò­ŠŠŸôãÍóH']~B)ÂÕ½W*œ,K žd= ˜_œ©¤k²ûôÇșV͸ÂÜÆ[~RJ¿•«^LGéŸ2BÒÐëmQúéïÚV§uºÕ]!N”~X²"
1347
+‘=¸Hfæ/çCé‡ã²}Džß˜ÌXxýö¡“ê1A.KKéçË;^{9÷è Ô®ÅWËE;ïs΂…ÖÞlâºÙD–V©r¢
1348
+ãÕ s6 (Äá¡¢6삛ujddÉ{éÉ#?š<‹±^C¤OÐi>h>,ó¸¹G)År%sðØØ^FßÁ­Dî!}Ós#­Ôtø‘>ªEæºqœUËqj¡!ꥃ;íHÈÞ½(Ûw“Xó*š=<è;#»)¸­!JcaeëŽÀª_Ýڟ¿’‘ð^-$ÇFht=TñbPr,B¥Ô¢pšýüZ’ξr›µÖ°!8Å]I0­°cKãÈq?j9õ'l?¸$õ"£ad¿<A¾?!jDMK|ʱÂÑGu¤ä|Æ#ÌQ\äÙÚb,´KÄ%“”Ÿ 2¡/—PgÔ¹6<E£A â`ÝqÙ•«ÖOˆþwg‹¼:ŠöòöwÚõCTëð‰$€\’˜üè̶ó®èѧuŸBú1^éå}Wdö¤ –ç‰Y¸¯àº+ÂhG¾-Á :¶í\fœQ41‚~”–¤jV݁Stm1˜%‰a¹ˆZ";P~PäÂÈ7(Úò6SGª|òÍËS Ÿ #‚™$À—¨AÝ"÷¸ Pßõûê´ú‰O8õoËÓ§üýk×ïúyÔrˆ›ï¹ªî“åË8D›Â!>õö6Œ€\е5-œPYOÎÂ6héYßȇÆÔ”bi8 ÷wÖº7F] €å¢¶“!Žc@ÛʵÛ:FqU¼4­Â _‹u©Âö¦„‹‚,‘5WE¿¯&#yhœªÛÛ=zYfÎ §â€÷ÝZbJg6’`Ÿ.Ê1ó¤<-º¶ìd|æ­ \2à¸<(ÞN‚`JÈh{óöY*Ôpj%¸°}è_R¾5>Žm v ¶ñ ¿!›–Òûla6õ ¬Ç)ŸÃµŽV¦°–Ô\õ— $ðàocÉnUŽŸ#è$Ռᙥۍƒn´ÌlUu*7p¡™€1&
1349
+ô…:υ*Ö¡W¿#‡‹0ÍU-JW{.T®÷æ±¥#ˆ­»ÝSzd©²uhfIŸå¹P…3»ƒåëyÂOžUA-°1z)½÷¦a©)mü€T²ºžgmE#¡3™V¥‰Í»éÍȊ(twPl·:6¨}"×Pæ>µÁDæ“ËÈÁå4?.Sš¦àì22ŠYu­Ph¿a_š+(Wüoî)SŽ@м:î æ"’%m+¥æwZœV<Ö«Ð[kº¬nE¢ÉÀ¯k´í 2˜Y¹!tV::×èá]ðÓ´:PUDÆ]¶C7W¡"˜@` •¥¸™lé³Ú•Hv‡,^8qð²Í±ŒD7Ù1)þ€›ê[µ¨Ä`‘©î*‚ô¶žúlüXÁü„¢‚YZY¶R6pæ'8÷`"2ÚºY^ºè0Ÿ=õL QHLIá›÷ÈCÀ48'¼@Úÿá¦Ñ{àÐ`°½+­®Uÿi*y“$£ eãŒHªd±'ÁgבHŽ'§©­jyWݝZÚýìlþV [øhdcëdZË}àñy´;9;2f“ï/¿ªËê«Þ…üªHÙIúª—¡k¦Iøúm(öfÿŒë<Î ®¿zç[,
1350
+±–uX&5ó µDmàî 5Ã{»³_òq)vý¹
1351
+öŠí÷ƒ ¾’Xñ¼bó`SlÚ{Š`y9,ì1²q[ƒÓ¹"ýIÛ ÐU‰ÔŸ©KÊç蒎5T÷a3³ù܊–ÄW€C”pŒ©`umÿ1ˆÔKŠR#¢zŸ¤»0[¿AZ¿©4jìc_§×ȟ¨möÖKe@ɲB{ºîjég?gÖvà)*™‰(ÎÍÇþ{þ/ø¡¿¨\žëAt_°Û–4deÌåhåÅ:Ûö
1352
+¨¤u‹üüùNBàM?ƒÑ­œ~Õþ„T‹VÖ
1353
+¨Qj
1354
+(Àføý£'⺘"Â⥔ÈáåAX@ÚY¬ÞT 0^+ŠíΈ|õqԝ§Ç5b»‚g.>?…<×WÜ´jÃ<éêO“Ì)¬1µk>3>ð~'í6 ,É0¸)Àdµ„‚–rN€lˆ\þ]¨(=a ÒP4 çgbÆup(žå lcýéD­¬#ÑhÝpr
1355
+nh+’º\ÆšÓxàPöv²b_YòâRøÏ?¦K•veeeÃU@ÿöâÊ´Žuô†T'eíŠv¸HݕÕ1hˆ!›}J†Ø_@-¼lLŠJq³iÄ@3H€Ñ@ý®*ýw¶FíZi„Û°Þ¸ÿ÷ÀL\©Þ”¤r˜]áœMÚÐpÓKM&c>4¾Á©Ñú*Bøê[ÄzÑʯZ~òy¡0\³Lëz›kÞʎPV!‹ËE:ŸqHQùþp6˜¥>ÊFòàÀ j—P<J@ùú%`/Úeñ͔៨ì…ÒÏ iPqŠPv!¼„” ˆÊÔ'‡_Š`V5ÀäˆDàºþÅ2À˜Z·åEÚg*’HöK¬=Ö¿I³¦–«°,s¸÷
1356
+ÿªä„†KSQX,þ”L6í¡õ_4"ѱË,×6ld”S3g>~ˆ4މ睠ô4(Â\E2dPV¥TâÏØÿwhn‚ÜôÑâèÊÏ<1MÃÃÁPbEHI¸p W'$`ÍorÓK¬Èßo4‰’š àš_°lÙ$ïLÂ5B†ZjðÝRÖ—=ü¶×ñ„¦Kÿ~Ù+·£Wmi]„)ôŒPþj²ô„6ºpõ6P¶ocGúK7E¨ß@P+hùkz )jó”pUÓ1gesÓî/b˜ôD¤¯¤0¢®;w–-—ÅQÚþb–‚N.*)-ê:©¬œw¬!µñã¬(€ ¾D{,œú‰__4í¹²ÚOú’èþ l~ÄAHŠkÎ43Äßé4R?ÒE…ku‡N¢€Q`IŠnš„¸jـ0¤b±—´öʋJDìoÙ‹‚<ILñ[w”ŽC à=®WE„ø¨“E8:…T²ÿT…¡-— ºŠèˆsà*¥¥t
1357
+y éÿYÒÞßks»IÅ^`¢ZPÁ##ð\ªøªækSœÇ,áfZ ˆÎʈ&#ud¤¼ŸÍR#¶Ð¦Iñe%R_o@ý;ÀñHQ–/5¦Ûùs†д:†¼/ÏÓîŒL8ÿÄØªÉB·´.%³%åˆ
1358
+·=Íä²4_¸.Dk^(ä­!¬‹KµÖØû‚F·V„å-ž,…\7 »€d0rùg™*ŸppC)÷È#þ§åKDo­e™Ð¶:PK\&’™‰ÊØR…²óûëñ¢¯v 6‘ë÷õÊC‡C­žLTÝ·hé"ö–â‘ÿ¥rÄ­Çí¾˜ñfn¦I2a¹·@͜Úm¼Ulì®õ'8«çûÕP«Ã&íQåá÷,dE½DGé²I˟úý÷´HÎÑû‡œCòCáqD;ÞBöð(u\3E‚¯ù±€“ýôx#Úº}Š[ÌnCOVE Zol"ЉÆÍûG6oû’äD[—Ü'§‡S„ƒÚÀLˆz7u»Œ‰…Å%+²FŽ­–`Ϫ_E†Cz²'Ã$«•| õr/h|¨¸Ä¸w@îpY+”Lšh&ÕÑö"}7Á?#)Ðl¯"NâØ~¿pâäd ŠËî"ÞTÙŽÏó â xfäfTvwR‰4¢»·Ö£çÙ nwǶÀ‡×5…w‰Àº»Þ<¢æò|e1ÞS$h‰‘xèî¢û dqGB}º[8x;ÇUYYº»]Ð’8W‹PÂEBqQi>3ŸîÖ>¼ÍWâÓ³kL€ ïïp÷!XÝUç’ÿy^0ü¡Z »kôÐN*n›_¢í%bÀm'¨¶q#þ!ÝÍì ¶ÑOԈ¯ãvap`?=:׫–‹Mª¶Í޽òài›u3_y¢ÑÂÕ¶›²µX%ÚΔ{¯s—&A¢ôgé(…€5·ë2p¯m÷V€mÜÎv½œÐ¶é—¸Ë!ð»¿
1359
+¥í\)g6:äj]B™µ¶‰i)Ô¦)It¦_aŒ[nc×NÛòeºï„\Æ'Zùa*¾ºä ’«·ù¡MÍ $ÒÇn´´$/ëö##'¼|Ɋ€þk–¸‘V¡wµ8RžÇ©³ »5_¼¢Õ×¢ÞGÝÎøxdÅõÖ:l§œ¯U„ëCúvŽ˜îˆã‰) KB¦~ðv›D@P±eÛ³Ti–´¶7?ôlI€- £mnaÛ¦aY䰊9årlã{Ÿs2kå[Xx ZYñÄAÛð™LjÉ=G …xrÑñ¤™d-»?~ˆ]Ë%´™4R=†ëÑH`äšFLöàÌïûÍ–!Þ'ÑÊ#c²'£] zØ
1360
+ ȪæZrŒÌòŽòœï‰âØ&+$W{|÷‚ «µf=¯%¬ñÛ;"Ý/`¬—µZx3hîî 
1361
+l—< Ù T!.׌"ƒÝ]º_!ýèbC>Œþ«fj׋eÊ«Bínjz¦©óÖ6µ.5·Î“¿¥ãœõÑ?2‡d6ö_­r¹ŠyÓÝi!\\¿¤'.¨UFYm†sÇ-9bìl•Hâ9P>Úr}Z‹„Ôñå®k¤RvëïëCmÏï¶´ý–«—¢Â
1362
+¨54pÌsê²oßaJ‡¦¢SWÔêàeö]Sûkû­{'š!•£†q:­_pß®’Jà;¨k¨áƺ^ú5–ûµ ²»9ê„Õ©»,_Íþ¨®r±¨³cÃKÃJ¿¡áçð
1363
+±.Rì"l¬X—š3™žˆ&—*:A_êçFMÿÊgêñŒÈ–ÝVá;B*’ï݈¡E±LA›ÀV·&+ÅÊ«¶«Àìul*×Â-Üµ»JNJëÒv¾*ÁÇÀU¦èÆþG¯Ø#†üÉ +ÄÝøÿÏé­Œ,DžseêÜò£v(ènWXŽÒOIÁ%Ù~TáX­Ì‘Ò.{ÙJ\Ä8[øƒÙ»>—?ß
1364
+ƒû³ç"ŒÝ@¹ÜÛ®ÛàMôt­´<×áü 5úƒ™´íG ³¾¦êÖb¹9R~~1*6IËjû˜IÞ~¬/ÞUùg•º­±õ­X¾}µ´©WäC%v¤š•U±ÑoMÈÈ’}ؐÇASH9=$¡êZ..D+¿ ®1D“ä!Êx–<ËO¸ŸßWúä‚wµ‚ÑbÇx\©­7F>­ö!+Q$,²¬s#ª¤*Ÿýž&HQAeî!Z™ _S‹ÿÌ5þmUåG ‘nqþ7lp»ˆ*èҐ)O¬p©p D­9¸Úsø“cԙOÇNkž%õ°•ó±%‡õ÷ÈË ö%x—C-ŠDri¶î°©C¤ ÒKÿ>µJ02B®Ý?¯SE•ØÄJæ§*Øæw¨ÆýªYYd„ĤÿL|<U§ýP$bïp‡­Jåâ KxAÄ\œÜ!çët°Êo«Ô†u`*ì …VjiŠOúÁQú…•T YûÅa Ùö×yçPç¤g€4„?NN­ù¨§¿ŠIw…Ê'çÚØ§˜5™xi¶ý¡µÔ#’DE(‘ê7QM}f X>1˜zÂ$å¢.ª©.crg ՉOÉlyº¯ü4£qý|ér@Ütphð(z)¹Žžç"ÄãUԜ&NŽZÊӎê)¼*SÊ ê°.öõT… z=Ë˟¢ÆþÁwëĤc¥×ýŠb䷤ϕQ›ŒÖâãæ-ÞªœmûQ]àmç;çe"bTz?”©4ÙЏdñœ„ÚBú5Ë­÷"É>‘h%Ï1¸t¥U÷rKÌôêH
1365
+Bì䶐Šé‡lãëKPÔÿ/w4çˆ$áå·ë Îå°Ê÷6‡øÈnv>{üóy¡‹ÊQz©­Æv„úÙÓ™)ÝÅsçHý ÀJ›îYo²wÚ3Êl~©´ÀSþ¶`ã÷¢/ s¼¾BM0©
1366
+˜ä"1T7ˆ “— Ø
1367
+rð¤”cÝòð9ýúcM­ØñK‰A Jw± fÆÅŸp¯ÿÇùŸRUj
1368
+N•ú…xž 9÷¥ò
1369
+(ÔÎ-Üõlž§~s¶ØªÊ<  ƒJ{µâ¢ I•”Ä7û¿YÉ(Þ¥Ô´(bæDpÌ_xÉÊîÅb«6‡Ì](ÍÏ|æŸXBõœs²ç ¢rêþtXdþéê5ºƒð1ž+¸Œª”F~H`qþk¦¸â\ʌÆ¹Ù,÷ïú‚Ä­]€½Öò¢_°C›}Ž”ýӳ❞&¤5·—€ q3å;´ôzˆ½]Z  Ð·¡¢Þ¹´/ƒ-l¤™Ô ió¦;qœ&,©ê‰ý£]|±dH*$R’fڎúVfkù´*Q)dA¶ºCFãè_eM4Ù^
1370
+è#Üc–Šëk¯q×ôJ6m«//€¹Qn+™t«|?
1371
+|cI/݁ø¶e‰Ã¤+ÛÄÍ8“c9·a Ÿ•Í—'jžÛÆÎÎ
1372
+àHÒW&)mç+¨®Ì{¶ál-‡%"*ײýÑ#ÝéËDöa ·j2¬·ÜéþÓ¹[T¬@“@Þ1ª¦ËøŠ¤°µTW¶òˆpÖmƒ’Ź;Õɛ;Dù7݃žxÊéS+Lpƒã4Å-1ß<^Åøþ„\)îçy¦ø‰{Ú<\ɤÓIûÊUL‘ê,i ¹)4ÓK85¤qî÷5€‡´7ÏMϒŒk3šôæÒ¡A.¦rrèwAA óÐI·è“.óБCl83=Ÿxm»ÔùÍl^Ÿuž7?ù!kz•àPË:,Ñïq‘L„¾CYç‹ÅÅjdµužpª3>ÎìÂÛôᓼדµÁXO¸F~zñ¥Õü×ø ªp`ª}5"G³Kg¡p’##Hësf[/8a*Üm¹þ®´#ü<ƒ¯0ÙaÑKž¿>4¦tÙP‹Oþ—¿G}§Qiw8[M]†¡¥=óZ¨"סÛWø4©–¸!r‰f¶O=•»šPè}¿Œ¾•à—þYîc;uÊgÞÃÕ¸mjõ„–˜ÃÓ.®Âü¸|­´i1¬ŽX¯TK¶&õǚO%F˜wét#^²5
1373
+xÿí[^ã% ljMÓ´Ùz ¬Ç»B#€ùP›½ ]•_öÐ*"/yæt&vrÓáQ F܀Õ^[˜áoш۱XŸºµwo$¡DFܳ6j”˜.ȇ{WµGĝ”ƒ|[ê’óü¡DÜ÷õÊaZ'$âN§Žb²eWVàÃ-šGÜùGÙ[ö(¢à7ñ!a®5`ÏÖLLæc™‚1Ù)Ô0›e¹ñàÉ£€<?”ÄÄ8óÉñfb8* bAãíLLk
1374
+3ʂ?ù‹ÔS=éxÖÏLœ®íç–#GƒÇ[èÚ[Wc㨥¤ÙÊ©ÐtèªLæúRý¤t©ÏÄÞ X „‰½Ù]+:•=%lÿ¨1³ICmtŠå©)a·;ÃÝRCÌ%*Š4lòï;$¢0Üq†²%ˆb´b´~AC„,nm@ Ñ ¦‚ÛÕQë0j‰i&ç‘›¹&eÊ4½ó—¶Õq†9ÀÁUÂÀŹ›O&˜‰"µý–“ú“Y´Â&ÛuÖêÄ=™r0Áü-"@'c$®êùl¢¶öÃ1¦ðÆÕ-Ú&˜7nêP+‰Þø?&˜¸±`ë.bØ5фî<±5ŠWNëSÌiiئꆫ$6‘MVÃC‰ϟÕwü¢œ®ä‘9]&F—æ$bÚTSĞLÛCK²J”Ó·þ“_eLà|nbñ^0Ÿû¢´uj[[^øTô^h‹ª';
1375
+£·6v͐â.zoˆC~ä^Ù°DoQ^“¾ñÛÿA+’ì -C¾¼žè‚øªÎ²=Foû3Î
1376
+ù—Œ6½ï”šÈÆwÐÑÛCUÏ2’ótõ\îßR$gM à/ó*.Î2Çõ}-üà­À+½‘`Àì,ŸC+‰oqcQf†&ñ!¥V,­Ÿ,KgpUp¤Þ)ÌI×Ö"8í&Ý˧EJq]ëJ™*뀋Ú¶^¾}Ò ù <i aƒxãã ´>?šnÑcuüo¦D)žÌ%8>ӌ
1377
+s¼¢+kyçٟQlS§iÂ66JxŠz ¨;Þm#bØÀjÐañ8Ù2úó(µ&H®H²ŒÖ7²¡Öõĝ ðôÃRZñ¨Ei€N0Òj;mùøþi¥žRb y6ëØµ;Œ³ûãóÀI8FR€78x® GíÓNûÏvÐÝ}Ïùó†\tÐh*•;¯çŸ¬)ÿâÃÕý5j¹ë/%Ü/&õ¤÷ Æà•÷_&¡Rä­hÜ_H/ç–[[2ÇÚ S7{>z±d]/ˆž}Ž÷¤d­ãÞßuÙÕûöŸ`Áýl“’ù KÖ³À]Wõ9¦wƒb€ÉƲØïVêú¡ŽA;sá+hmæY¡ž>õÚ¿“ßzUê=ÑøÖ˜0êi¸WCn“Ò‰ùõ
1378
+££Ñ@cµ©ƒ¾î§wàD¥~@¸ðnKMC êix žn;iºðC͇ªJûPÎà¬flî|»¼Oc§½;Zpî™5ÂÀÀ¨T¬gS²µ#³l¦åçÅÅqÄÈwþ©Îqܽïò³Û]KGâ(CÖ€Šü‹.¡kO³å2Ÿø$“ƒÍ3b½LlÙvécðàýJ™S+uOō°VÇrg†ïdU†Ti,^”BAžvˆéž–×RÜ>z ꒂ3^-ƒºäFΩʇQ .XOñŽ-л4–Ëݖ#§U‹ê]!żÀLÔÕXP×f!ݏC ‘·A]2G*uºL¼êâjõ×´IB„x‘ñk†’å¯oi·ƒžßê·f©fH¨ÐkófÒD˜B%Ûê’9dÚ7y úK?»}¾D«Dª¡û ~ŠNÅó5ã''ÉQÜàœ'ÝeèDì!X±ÌáªÆlá]tLD¶­Ò0í dUž)öU>úðhçq¦By«&~|XD:Hwrž¿´Š[ØM~ÙãΕ¶Æ:›$Ц×&øR¼ÎæXcÓ¤v äSSšÏnuÛ°õ!T-qG¿§5ð|ήÿÝub¦õ>KnX0®è–oЌ½:ß#ØQº¯Àºì[ HÒSm͙Ø5@'ÚþU£ ? T¢º©‡0œ ›D…É…ÈØpàªU¢ðºŒ¿8žÙüÛJFÜÌ:ÚëÛ> ¥œï³·P–›¬Èu/q4/—[Âú' `Ù9ã#Å»„»¹:Z•᝸z"Msmä°Yz¹Û~ß>¸MæÐ)uI6ÜÖfrJ]Ÿ}/@ÓX§&Kà—ºþ¤Àî¡0Ô9ì5— ¿³ÔSۑ¸Ôõœ]å@œ‰¬yP›êÔEMΈoH˯8%Åï´ý®²:ä$/”RWÖK)
1379
+p5«\f©K§Ðà‰!2‰ß¯Ë85 Š´K«–,}ȟtÏ8£÷½•%š†ûøT8øÞÂ𻒶7X|ÞMɟ¨tӁŸà,­¡g×Ê|z=ÁM
1380
+„K/ƒm1¾-ß7µtÀáám çƒ*øTá]¡î“^Êçñ¸ ¿\~äî±LŒ…’eÇkwñ2N·× _…Y7*wÐßôXGÙ +ëþE»?ô½ƒÞkj&€«€¥~HQsîÅ¢Oþ<DŸárô®X¿‰³<NKé0ÖÔ§Û͂î¢!(åÍýÎR¼'Ž’w_«–¼Ož¹áë¿Ê@0*Onyü߉²ÙR×ëÛär]°Œ•«”¡*s×ϦÆ¡Š^_*ªô<~÷3±Tù¯ÒÖá,Ü6šH¹/l !0±TcÀ`µNR¯g(-‹ê¯¨…}¸ï)zoˆª-ÃJ2e}³´RßKÜ¥žQPãANïõùi ÚeÔ ],NYC•ì¨hž–u˜”Æsz#ۑíõ|N?/<—£7ªx¯¡¯¸…×Äûyö&Ô)¼RááR%1„’…MZ•Š´˜¾âû7S¤Ø¥›¤à°ëÈe;So_1ªÈNpt7º»LÒb‹!FЙÄR%šˆø83$×õSðc爣¹$^‹·Tù
1381
+t€,FÝ?À‘™÷¥f«É,#$êþ\/ÒÝFa]eˆ§]³©2óë¦|i‚îHPôê†ÝšõL|X7*kb×úFëx7h`*â: ò šÒéV^HΗÉZ0ܛ‚¥‘
1382
+舐ºçyì/º¦‰8WDD}ëV¦>Ϛ›±Äް uØæ:õ1¨èjåkú·Lx>Öyÿº…D†°t`¡ƒa&æöÍvæÅ#f sùM]X yÚ¶owý“_†t ºò̘2nâ»BߔÊ|Rƒ„)j:ßePŸi¬ëã$Œj¨èçPRlýW*ý‘nV,º‡r›o¸ôY:}Çiኾejs_Ò `ŠYz›:¼››öRƒYÿré¶A;ðl$fìÁe»!Å0Öú Q”[ÒÌ-nžf½r«Å3˜©ÆÜSn‘Ù0·˜ïýЌöŠTnÁÜÒ p²Un騫Ür¢ˆ¹•àÛ«Üj* :Unm)ÙGû‡½rKÔ$à9Ì­ì¿Ýï*·ž>É©“ jÊ-Ú /ÂÜByµ
1383
+Š•[Œ/çÌbX¹5ඇÙÑ ™[š¸­ô±û_zf+·ÉTÔBŸbŒæ%ö¬€°³;Ⱦ€gÊ熦°/t¨‡*Êüëdnd~³ëíU•À ïTå‚þ¸u^ÙKt»g›OÏ1kþõÑ|, ohíw™#›¿ÅÕñ N©„x3,ö˜–qc{¨Q·Yá~§ÛÓs ò3}&NHÓCû²cr"䄚)3Ÿ²@#fº“@ÛʍQ!¹å3 àóz¼ëœî’èðùÌÐ+–g“÷ÚSéZåvÀST,Á9faäºcêž@ãl§(€o™– ¤t©Ú–ŒA*ۀ-øéþ©Žéªá7›‡q¶Ø lÃÐ" —¡Žç<°-’æ`¯Yüß.å?–À ÷¥6/Ҝ<’^%T2cOÙ~ˆÎlb- ͬ;F„x™%Ê·>±MgfÐØ’h[ÚöìpmƊØPԋ?nA[ŸÙ®VÍjxؼQ¡8XžÊÔß:јۦ z>ÎÒ^^-ÆrÄHù9°h\ã;rSA¡FŒ, TÛÍ­+.+C­ØòÈa®9ż€–¢G-㱓Ѯ<Gñ×#áqôûƒâøaÖ«XÀ֌ª˜¾oÑ'/Zc/†ÊâŽE­Ú£6yqT^Ջcâ€cšúm·Lª Àê¨$…´*Ki x)ûÿ8aê汫qʚÏ5óç®_+ØÊ0þð#ßH¼u EH0—)“' Õ&]ìôGÖÝáê#¶É
1384
+º+aùê΃F££šÑßÙÞg¬ÆRHc´ÄÏÄ4v ™í¦‰:|8³‘ã*ô¨–ý¨"9Їˆ0*A{ŒÎ Ï€-òÑ͚é¿ \ɶí@;€u HÀ0ýoûõkÛô¼'AªæVø:5IÀÉzds=™¿ÙYóA°L+ ºÕ\·¯{mâåpjý}¼ÜÈÁ Q­7j"&]߆³J$ ¼t’¬kW;جŸÕCFX>EWãI¾Ç]Èt‘~,ulÜSòΚz[·2KÉ Ot…ô4ÔU«"…˜&‘
1385
+­ “áÅ:ŠÇü-'ý8UÎõÃv³+k2ŽOyÉk÷á\«˜Îø‡ŒÃ˜ C²L¸ü‹2H±­³æWV­zw©YÎö,³\'yµíå= J¶\Ù9õªÔ@5dE«Be¨ûßjfnle`)s^[*Jzž,·b2[öNA¹·ŒÀ”ñdCêÝ?6özÉõ"<f¢¥p à:»¾bB›Ë±Ÿ|=V¦Ì”€W _7¡ã‰Ã ³Ç0v]Ìè>o҂ÿÔÚóîö…œºÇ‘&Ri—¨Tá•À“qÁË_‰G7 jNÒWmm>’ëlȲÕ@ðÑsF)^³@\cÚ¼Fÿ¦‹´.à=¥îN2™$QÁÞ¯7ڟ7áûÝ ¥-JA¿–UA€X ߑ€‘ :ò€•.úò¦'·êS}Žy´çÉþãóÿÖíEHFäªóš.DÍ'
1386
+uÞ¶1ήA®¿Dê,%]‚J¨jÕYÐ,þ…:›>.Ö.fYÆÍóe^ô+uŽbLå êœøRd t<¥Ÿ°auŠó5àoC۪ήk®=ԙ2%øÂßAT¢Î .•³`n+
1387
+\¯puN"'¦ðê»ÙŸ®>×@PçýaIr«%%N$ºå²uN•3GeÖBÔ©€¾^Ù_ uíÐ7e7¯7!ewä‰ê
1388
+: ¦ Ÿ8¶G$ƒè³_©Œ®úö²›¨•‡0¾…oè=Í´„ªR4ƒÃšX”ëRʉ!ÇꐪÉJؔ*Îâ
1389
+pԒ–×ùØæ" ‚WÚÖ¬÷ÓM d†ôO[VS©›Q3©å—œ^Ñu†Sz*|P(¯dp–IÀÐìsîg |6ªyJڕk'lOÎé3Ë)ÑC3QJñJŠŽ
1390
+®kvhFðÀà`ÜÂáÞæ¡’âäMØÓå3ë|M3¡y¦½øÆ8?–&äêf0åë×ñÏlÂÝÑØ󛘉ü —^hþdâmrõTN¹‡fðûõ3;b“Ð/î𝄿i|æ{`„æ’î;õ«‚Ç„æ6ŸYRV¡ÙÔû3•te„fYX2æäÏÌ Ö…æÖ ³|ûj„fWô-ȵGB3¿Ï,@ÂÐì®Ý©?ÿ¶ç3Çn-"KàÖáy{ÛWñà^}Uº¢Ÿù-Có²Í5âg†3¨ð±ßDhŽbUl[?3¿\ͱ͕cÉ 84Ëü™Ÿœ£Ðñ/˜p†ÎüÏìÔ6Å=—·‰g?³Äl󜡹Ì&ñ™·ŠÞ(4—â=r­ ë÷g–2úß6¡¹<ٟÞ^õóÍëaóP@­ ¼®CsèÓââŸå&†âù}‹ÊƄúÌN;é|Yc¶?MLS"J̬Ð÷Ñ–W¸·„ß!ð]{¿dv~Q=fßlåHÙ³À$ÜS5ÆÏ¸ãô F#݃¬ l£nºÚË{*¨nCªïNŒ“Ñakp‡›–RÅÙÀƞ 88NÓ(6F¬¸%¬ÒԜXz¥86ÃI5 £IÇî 陵Í]“›©º‘_LÊH¨œ™|ù>7ˆHƒIö'€­ó´ÿ:ñê±÷}~Çú^xÀ—eGGed]F©Ã”`‡á™¾$ê¨Ïe°Š“Å`)‹é%Z=s.ňnB6íoóÞ’è˜åN  :9SÜç"9h-éâ¢XfDæ3‚
1391
+ÇGcÙ,©‰£/%è°¿®¾º¶bü¹ ˆ_£X>§ ±"XwgIã(E֎TCÜÓ«Nf§’¯ ¨d`W®XDi|< „ÚÂJb;ÇÓ¬ÝE’f[vnµ'’ü yމHè¤zíÈØD<`šsŠvü1^‘ W0ÍaéEç¥hÓLšS|t›fìï†D ’ß4_ބü›!Gš_y›f[!Èë8يxjʳìcŸó* 91@éfÅÓcŅæ<V­ò,ºy‹–xáãY3‡÷ٚÿ©«
1392
+£P#Û×f·ºI¡¸TD
1393
+[FФ8€X™ž„¡’FäÂ6úÝCÜ.~ý²Ð‰§˜~¶wu“Ä.s„h ãäÌzƭ厙DIbô·¶>óÑ/ûÈ-¬_IY<‡:–ý85Œ‚XŒ1×àG¥cחqA¨.ÓH€Åösƒ¼–€¹›t9;žSêz§ˆ]Ä%¾ß;Î%€ã_¾ ߣÕUKj htõȨλTf:/…Ñ÷ž1SÉÞ QkUÊ`oéÖ0:–ÿpôýœiÖAVì˜È 6„°\妚وÄ]Øh8KwYNAòGJ`3&+ï Ÿü_´•ÎÛ_ gg§¡IÓ&–OÏwF 8P…iíÕ¡!'ÕÓ ÓO&º·!¯=n4´.ÁމK»è!Å_©Áq˜RÁÛ&¯
1394
+Ź{ZJ+mû:z@ÿ?斷p¾Lª`ú¹<¹ÕÓéëú¹ .5O‚ÐÊè¸i½¨h[¾ƒ-9çá’úӒB÷Ê>¡.l* tbh¯ ²Û‹¿/ðº5ÊÞá¤,âqìJÛ̒De‘ºq ®PöÍfNI¤6k5çMÖæÎÔ>ùyLyt¡*°ûàÒ,N×¢¼F
1395
+¾ª‚” ©KٚV¤„˜‡n‰Ç?ꛩ¸bÅ)q$pˈ"„)[ï¿J‘‰6¬‘ó˜:-ÿË¥„gýë7jӗVe*>_v”¥çæÄÈ%°­Ãóœ®þ?ˎ†Ï„³~FœAýÑ¡ðl/éØ$:„6ÅB·‰X1õ‡5CüzP;ªX²‰Û 1’„H¬š¼¯V¡*–@|Àä×hËÕ4”³$Њ@Rªùa{se^üäáØ?ëåÐqÓK>\BS5zû.ñ Ùéã-µØ¯¼Œ™Ð¸–Ü?Aðå)L«™ÇDÖҟ!6Œ´'÷/Æs ÉÏ×)mö+À7UœÅƛë3½ ¢°}–Åj‹“Žõ8v³£²r|—*Ú¥{*¿áðfMÄÔ¹B»«þáÍ&ÁºXÇÙ= (Ië Ù¶íÐSFí}"ÑMªÝI³Á¿Úæ/“Jpµ49/­î]
1396
+ŠºÅÃ+ê5 ¥ø‰¬dï?;‡é|¸¥ú÷ûÐÆ‚Ôrw÷5çšZÉ ÿ6LûÐð'ð8æô Ðª‹ÐÞ³Cã±5])»^mÎK°2çˆ`E¥Ë×kÒkèât&© B°åÕd“ÒÎôN†±ó-X LJñgâŠÝNo› 3Ûɕì(nSŸðI’Avhy—¥6'Måà_ò$ÏûS»á”,/K¨ÊÖ L~AÖ¤#6¿EBµD· gƤèµX:t8Ú_ æ D„9|¥Êށï‰ãÑö›>€–+Br|ò:k¿5¼ÄÓK>£i@p‡Œþ[ãC¹‘#Hÿž¯D#o±á˜ú~éjg:*mŸƒnBr¼›P–Ç9à1›2­“XËK,ÿÏ/†t’Øa{ÑUáúö¢s Yu—ذrba;܉éï‘ÒÿA{•Ãúa…ëç—"°žj €ÿ9¾B"O1aZ£Æmµv ‚lc¯ö
1397
+¿q¤Bº*f3 %ÄùÚK_…X|òjˆ7‹N5#5<̀,jïê#Æ-ôašMk
1398
+Ù¤¡C›¦R˜(´ŽbÓû¨¢&Tí‡ÁXäÞ΁4y=#õÝÌ«Ø3Zƒ]»Ð±ïÍà”½îõ@íq*Ͼ¦R_»‚º‡CǬ×WïÝ*œ¦ '/¿J¡4…2²‡³€¿ßnâøÒ’¿?!M+ÖÄ녮qñ€´
1399
+`ª¬q=À¨È$5Øçÿû‡JZ øˆCØMׇqü#» ØÎÛwøó´‡ó҇u£ŠÜ±JÄêüÖñ ÑɆðp[!ap<,l#"šçÆÙO…ñFlWßþŒŽJ¡*—¥{·NOB¿pÉüS±Ú­; ºЊ¦ØH…âÐøˆª"Àm2¼To—ô`!?Tè0H!9pâ£ÁZ,³Œ†2›:nŸtÿ÷;mza›Ÿ=Ë]úµÃ­˜pI-Õ;*û2¾6_)¨me("xÉôBµÓsߕÛÇ}co”\*”Oa‘€><)ŠnÃ~Ù" Ë5mæª ‘°PøëFá‰Â]¬ŽÚ„¤Ts ÿ'ÊëŒjⶤͷm5J Œ¹V@üs‰Ú=ä!VøJÖÖÊÿ§i,9Àªq5ô,à]€Â/(ápº û¾Ÿý“jÂi”S PñË2jPLX¬àB ù™9E—°¨þ„Aº.䮋×ðÙ\*òXïß LöPGã=†EâEœN/ ƒœYJs‘¤grÝâ(x¼ü]ëâÓ7{A ¢¬—é*Bƒ„î 4Wº¶30@pcñªÏ à|Îè{+„S-Iû՞ø.™áãÞ'\ž÷°ig?jéOH_áYÄuœ- ìhäó^8SƧØË
1400
+dú°~µo
1401
+°}a ­ꌱ]kvd.Ù>rÂÁ¢Ï´I)‹C9´õú2š1،ÔßjØ•!–Ž[î™±Yºœ!»$fÒSœ¶Ý2ßÕ·YкŸpL-ŒYü¼Lûá{¿¤/ ƒÎB$՝wQ•ÿ;±ÑÊòÔ¼1Rr]~»¤^⃨Ï{ñVûÓÿSbÜ·gß,46g¡¥ª-K‘‘É>ÙOp­$ƒüÇ8:x2‹˜™“®yíÉ;qX4ÿš(¼)»ç"§>†¢¢Š¬-r@mf,ŠŒ•ç%ÒÇhóôçñÚ0ê˛¸<x?o;§›÷ÚY„Ç ÒÙÇeb@²·_‘€´mñÛ>ù¡ç+Çÿ:åW•dé³$ìÀÑ† ¿ÊGû&UO§ßèž,})§WárD³ÍŒ´rWVDií¶ a^V^•ü±_š$ÃøÈ›N;šún÷0o‹1$´ÍQÏ?rˆR ;4
1402
+P~H±É`ú@ê…BŒUˆHh–k@ڙÙìüÖÀÛà •rvv¹L¹æ8‹­°Ä‰ü;=”ŒºÍǃú‚’Ÿ+œÏëÍ7!å´Æô¹XŽ\Í·‚¡BrÕt ÿ4«CÖ%ë͏La™à 懃炃ç‡ûý@E»BKýk ñD^nuX°ÈbªŽNI Èvl™ÙX¤8udzµ…&1vAÉPǰ `Ó:žEIotöùßôwÂñËÆaQ#67"cYÓr¿Üù¡UÓ6”oÊ~å°, s‰I߆yŠ>³‹­žŽÀ÷ ¥@+Ãc’å§&z,ìcþ®ásU¼b›ãGPn:*•­‰Y’—7
1403
+´WµÊ£ÎY<Û ¦vNÞÆC­¥¿7ÐÁ† KVØB9ŽÜt¬ÏX@l³™’¤ Ø„ë´OE‰Ôñÿwâì²FÓÙý‰ƒBóþâ³®Æûp„'X·M,æãȓ¤<²ŸàÈ´ê2‹CA“Lj¨¯Kˆ,Ÿ€<
1404
+‰JŒûA0Ì1|l*¸ä|0ŸY,}Ë· ÷Jô”h ÖÉcÞÌu‹@¥‹Wa”Kžyý4:§oFÂԖbr³‹Ãw”a~¾ÔnÒuÐéfÈáÿjÃøEYmJі:Nj/ûõ†a_©7/7³B™=úÆÖ‚±Ø@œhÊKõ\5‡BX¾ßÉÂç":ÃÖxmÏD>W9šž'DÄø$…$òfÞwGO$©¼Ø¹M5`¡³E";H®€úܾ¾‹Á>(Çô·^‰ô=㤒Iž”Z ¨êyvÅqñÃÚ2<O3y4;ncŒ‰ÈœíÆK&ô5e'žGÿƒsŏD
1405
+é»EŒàJÜ[ƒ/—ì\ú2ÉNÀX0vâýQ‹ãöwŠ É.ÑISLËVóª„4V›í5õ½=ÁA*3ÿþ_BFRl5 Lp˜&Í¿çë ã8ß3Ñ\@k æ›{:^ÑçukڐC±8ΚؓÁØ\‘b×ðšmCýٟŠˆ6›^†Ei( T%ÎÙ˘@)0èø_a“òaº¿sZ­ <œ¢˜ =¾j们׳öŠígÀ~Ÿl5Ê«tç­ÏIˆ#}0%]ÍIÜëTOxŒ¢jÔ â«’Ï7(lhƒ»*Kÿ#=ó¨úªL…§Æœ ùûP¹GF„_eŽŽ™^ZÄÂ-ÁG›Ä%]#Ûéa£‡j ÈWwØNBBVVcK§=²Ø:ֈX¾zêìSÒFÛwݖCøñAì!áäjóÿŒÔmDj¾1YëZ>Œ…à§³s>¦’7~õñks^¬9º3uÉ´—Zcãí9XJ êpëkö;þ;äc+(ñÄɛL½÷è‚ì³½8]=ø59¤C”°^Æk,õ¬ì6tœ©x-/Î,xÛòõ·fE-Cƒ)f˜þ™ lÝû’ÆIw«5©á‹}ŽgÓÂ×K¥ÿMEyDPýÜ
1406
+ܷ^p
1407
+Óà2ßW¼˜«‹x}¬ôā¯(9¶Kì®ÿ. ÿ*&~4ˆ¨þ>U{%'Á—Qs¯Tãf.–²ìw|]ðoý;Å)ޛDmµWï~}¼§*I€_z?¿ýºLô´_x7ñMbUې޹¸ñkàë'© æÉ¾Õé>³­×–ów-¼[û*í¢'ýtšÀ!bë&…—ƒGʯ{UÙÝÚKö;>:>ÛJ”
1408
+¿¸]W”$Žzá9\~Ftt½å›3ÔJ‘/Œ¢ÚÙ­°”`7W·^R¨vêϽCeøÊptè{“ƒ(Ÿ@ÂÍ#%r\tÉ_Yµ
1409
+“6xƒ¹'a-àÌqÍ:%vSæb'k@Eò“úk{<NÉaWÉߊõ5ѱlêÝ 1"X$Ðs&cGSwdÊÙà g¬ 0¯½’ñzKš‹Ðˆo*˜på ‰y[hxm± D{û·œ˜°jónÕÇ:ƒ®ÇX·‡ç ´$ûf€EFGâА¥ßwľU·h4œéª]¢ò¤ºÇNA¤tC²F¸N—Ýíçƒ<§Î!?(zé©wZ,ÁônUvÂ!òÅMÞÇMþëÙº‰ú_Ïû_O$ãˆîß}„~)¸†y¢‡©:’þߔ]`ߟ5Zяa0HÉíúûWÂÕVˆ”ïÇv]S$’¿FÓ±«»î«»îå+cÙ|¢Q݉FuwÀBúQÒÕÁ»f59%u€³†—)*ÔüD歖óÛ,¾ßLJ¿™T™l’Moû!È5ØŸö‚)ןӶM®Q ¬ß®ž‡èъ]¹dHûj³çZBⒼJ: %Ds®úäb·¦È5—÷÷g\rMPsPÈïƒÝªŒk\³ +Û°úrà`X}Ù$à +5öIšIŠG&*5ð½ožwqÎ7åW?°ï#¯—&+ìH‚»Ï¥Ò–¬7]\IÛÊp¦ ½œéApæ‰ùœ¹z)JcÆMŽs7 M:U&ý;›®ÌDÿÁ}²ƒª!ÉvD_ƒ¢¾hôÁ?ä™} ëý¨¤ô~FçýT IÅü~ÍÊ4£=œÍÒù¾gÚȉQ 6&nAé{y!/)áûT ͕R†±÷tJ’¹ä;UÃïJžk$U#UÃÑÃH!…‡H>‚ªáfß#hOa2×"dHöadxÈ>ÅŒÝqR D®qÍÓÈêª@aä‚9±\cç/JÒy_PV²™ØBŸÿÅ¥]á¬z@b!ÿ=XÊr1‡¦MXy¶[Ó.ˆÞH-Œ¯’`˜—IʍHóMÓä0˜Ëårñµª®UµÙ0«£l0îô?÷‘;‹Aæ»r Ò3Œv~=•6æRY¬ê yÿsAÎ4qYæ}ƒk\k!Z“yŒ•M©£s-! ýFÙH©š`$ï8´fÀ#Dò¢a™#Á‘0¾ÿq-€k)Ø]²Ýƒ†Ò ‹%|0apåZì2ýÒ¥IYAHš ¡ä7Ášjgî R:°£´f’þˆN}„Ü àL
1410
+«mk¸F xO®dqçíÒ¯à4º7¦0l„¥XuWô­:×$1›jSÿ‚”dèú­—^
1411
+m×3)ûy¼è¸¦Ùpkƒ•nXLÜX·IFø!”P‹‰[÷¸6¯0gNP•ßvŒ þ¯U€þÕShÕS®;lTJ{uš° " ½C\۸ƵӺZÍ;ƒ´±1H+ú²
1412
+ªRr-ÄR–þ€VUJþ]t(«á<d"®¡0¯wËY–Àȗ Æ¦Ð ®-›€«#+õƒ£(àB[-¥Ä0þ¦–~ۘ9K‰IBSö@DZ®µș³‚CÚËit…Ló2¸¦^i º½P4RŠG(%Âî¼\#´Ð¹mЬoAJV ã ßÑ” üU'›³•Ò¾X0H J@úÃ
1413
+3HË5GÂäL¯±qãFz0þâ¶ypãڈ²93B“•ÈêÞÀdP6€]5zŠžº²‚€¤lkƒ½—Mщk\KqM€r#„ ¤¼³ÁŠ,AZJš—SYò3—ÊbcSÈû®Â RVâFÊÛ²ý-˜@ý9±ÐœøÆµýÄͱRÃMÖýB¡tlٓ–ÂÆæ–üŠ¢þr·µf$aWJÊ;h|®aÚ±ñ.ٝ¸öê(¶;N߃žÙ“anÉñ3 ²ÉeþÀ/Œ2¨|c䀈1# ÈãrIý€8>V*($,$‹"‘X Ãâ€0 s4‰ÓâK2[åœKh§kq W}l ÷íFÁÛ)–ȝm¹BÞNã¤ëÞä¢qh'7Ð¥nÜòßÑ3¯žj|ˑ⤿¨Ÿ¨šÜXgêx¼˜j<”ñœnÝeÆܪñ »Xぷ²Ž"©!¬¦²7æ¼z¡DÀH#ñ¯j^¥‹$i$—E>7êÓ0`‚[Þêþˆö5›¹}æV¥Tw=w“ïü8ó¹²Nh-Ãý¼1j[”FŸhÄéæXÜ⍫¸IR{ I2Äïð"cxh ÷ù©‘òù ã®È¦t^-Ø×‹„:5-(ïXV—ÎòÁ2P.SØwB÷g÷v°ù§+Íí±¨çì$°ßHi[·+6V@fõÆMù½¢£›ßY#ùëÑÝÚl<5oÝzÜ2gQ¬À~hK³ëîçþ ¶\ìq×ÊøÄêöhòë‡$ßH&€©jÉöñÉ$4´ºގsMr®¢ŒŒÐêœÞ/ ¥$fën
1414
+ º$:•;ûÍ 3tw\vX\žŸTw˚S•zj±oºã <&ܞ)^Êb—­û$l»ó%ÏîÆˆ>±O&„õg¥Öv=¢åy²é™å~nÖVÛóúã|NoíöHÇÍbX¥à¦#Š\ËmçºW¢ÖºŒGÐAH¦´ŽsÈÛQ8ÃÄi$P’FöÇù¢@ÄGiOcÊ Pˆ}óÍðË#kã)uÍ3Ûi,·દxéuÚ×4MrD2‘/% ¶ß¸- ;üÚfÁD_ÏlßÈØE˜ ëáÈÏ[Årå%j‡ñv5ÈF¯¡Y”èëÎÊLFúèøß!glý`ÓÒÃ#k­Q¢é42tšž …ñˆMæßÇ
1415
+%¶…rY”BuF¥C£UˆF ÐAt¾Ã³c¬üÁ\ÎÎïdÀY¢Dãõ–Á¡xi¿†½3cPÂl™ÙG*±ËÛï%JOšÍhÒb Œ{<ùž'Éùq –½M]¦mýC~ø÷Í" ŸúÇr™G¦ 6_’¥@éôÌHqM4˽¶` ÂIúŠ[-Ä¿(¹ó  ]Ž2’‘eEFï³ßÀ.ˆ;VGjüF‡ñ²Z¨Å”*2 Á%ním礑”‰\=É A 5®ÑË$eÈ\ã§±‡¼±gé2¢&6–\’°…³°E‹2Éßz÷pBÕڔÂ[Gn>>{°b©þ™@h™"õ Xë÷kJ•Å媹q’ߣõÆô­ìl‘ɐÚôxHëxñK\?¢ÑûÛ$ê>ÛßÕê¬58¸”ªÙ­[µŽ èå ¶)|ŸRÙwBQþ»òE`uŒò¹ý‰äo¡ÉF¾*þ ]¾}î ʽîBˆ#Ú½ k’»”!åhV$Ù!c Ô4’m›Kézgo½½íR’ªV‡bóš^¤±¦«Bö`D¬i›0 Ç–)j¿©›kéáñ–=ޟ7Ú×\Wm‚6×=”l3ÃæšÙ óg9¾¼]ð0¿×~¢Ð”î¹ ðÎOÕ'­ôø-ךº‰]®Ûl”$y «µ[ó÷¼4Ûj€º1ï6-Ëø;ÉõlT'°4taŒÞ$œðy/t0Åôväòjæ%D‡•T%A–Ò£ívUgx.çÆÓÀÄÃ-y¸’Ìο©ê c+ò-ʕÐuT v1àøûOÀð}áÁÒNíqõõ1k;» Ù%Öÿ®Í…^äc3¦Všú
1416
+táEIóõÕ­”âeÀ®ÖÔ×\¡STaÚEëßnµ¨ßnõJŒF¯Ugö)؝Ü(¹†Í±×Œê¸¤‡y:´f$Տls×|}Hæêªø;»+¤t’OM7-u{?¤¾‚Ò¦Õ–Øí¨šèÚ8KË'oVp¦Fd.‰5~8³~kO~۝Úf÷&€Ý®÷ÙÜHìêÔagΕãêC"Vyu5x8ldÀ±',—Ÿvk*]?X,WŸ[c?¿Q‘¨é´µ•A#b²=Û³g°s;~#Û\ôOꏆ<´}JUd¨†ú> Á[¦Á[ø™ðíu«*Zb0ZF/=Y}¬BMT,æÎTq^š²ÑK­çž¿dæÿŽsKa"YýƒXÛµèÕd›°Ò‚áw‚2pcßÜt\fœû>Zʇaœqa¬i¬sâî’C4rD^\ÁˆÍÆ/¦J‘m¦g¨}˜NT%Ï~:=͐¥¡¤
1417
+¢A£.g¶3ÉŽvì½,m™#·$JG+ª£°ô¤5dß4¹Šyh¤hÐúhWÔ:•YQÃC³¨ _ìRƤAëå^h%W¾"‡~k›heÅqöNó:ìÏ×byw»Ëq)Ͻq¯ÁêáúׅgÉMT”o­¡ð“‹‚<êO‹[ý>R4næ7ÃD6d"Y*ß¿¬Ož:”.Jš0EMøçGðDçbÇuB¿Ž“î֗ &1š}` 
1418
+äRUº’kh¢I¿®<ñáY{t«tÓ1bë:µx§ªa0;“Hxÿ %‰>éŠÐx+™òÎW«_BN̄ Y¾‘¹¾„Ìç NDéßÃDv¥âˆbûÝT­Ôf@<~ ù¥kzÓ¹œqðr”H¾¦—²Ï²n7ê­¨D®íýF•ð×Rm\¶¡>HKˆ(­wlR¤4´qÖ£å=¤=œº*[œª
1419
+²¾ J  ])/ˆ„ᬠ":W²JùHÁ†5}”cîDÄî¥*œßjD¡)©âTE÷Bo„) ¦¹ß T¸BêaûöۆýÒ¸ðt´OV>rô5+—¢°(@ Ÿ_µ&2-<»:øSNš])åz ½D?UDˆ«¨Õ,E©ì›ÔƸ\‘kÆq­®ð·Öc'f"2UW ÿ\sx„ÃýL–d«® 4¡za@ú…>€ã/1Fºê='žeÁ•>é¹Y>¤ÓŎd¼s"vlÂ~ω@¯ xļ•.ö±ò‘iÉ]{Ó¥˜Ó¯ÞDÈ_´DÁJéÜ4ìÜ6“.=cˆbV[”™Œ"‘'
1420
+_©¯3y26Yl¦Ä¹'µôö…׉x|à¾CC2‰† Â7Æcìø ò§nžÉOæ•!9q׿οyZŒ‘ªšXˆo$€üæ0ħ“Šjâ¢Wozž_2ÇÜ0m0¤9(†¡¢³‡N¢#—©KZ†W'ȸ’aŠŠzЉBºÄ“ZD}ïK‡‰:ƒ…±uŽ`ˆ5_Ôùï%&g·Î«JqR;qnŸ,1ΐق:÷Ö¹ÙûPDï­Pˆ…·çÞψ™Wzä{­sÜVr¸=zu3 ø+Î'îõd§r.Q¼VQDsò8pÌÁH
1421
+“<#ýAÝ©,b#³ApŸ=‡ŒSÙåË]õ¨u‰Wý:)eçaŠE^bLƒ,ÁK Ḩ ½”$ š^ £ìèEZXì³ÉîAsoòÛB£Šfás ßzvV¤<_±ú”µÌ¦ÖTÑÎQÉ“t»ÂS
1422
+s<Èҙ0¬O9Ž÷=aÞ XDÒ{$/ÿ ² ¬[o<Š3Eò‚Rp€¹ª‰ä¥ŒfT¼õ&ª°s¸J˜ -ÀÂ|É×>`®–jhëw`N‡]8&Dµ„9Û ÊÒ^BáͺˆÉ)ªâᎺ7„égz -x=â~i*ÜæGb2ÞÔì[Œ}g½åˆ-P¦|Q/5´Ï° |̹Ç,Êǐ¨—JS1i8Kc„¢z…z¦—ô$)¿¢^º|ú “Q/ÅTØÝ '2½ÄÔןõqña¼/zēhm°Ó̧bb7ÝÝ4 ºÓa¦\¶/zÀÇMßÚ*pŒ¨;V¾è{n¬‡e5+üL Ð£èø¿„ñS…‘*‰½}C„Ö®?bÍK×îÜ£P–iEmË:wÿ¢”°½GÂ.åØåT4f%R;-픰)輟ؤÍ{‹~`Õ9‡fJØæ ÞÌ®ŒE‹¡ßq¸–ÓS“¢—eˆêMVöw*Açx“ ˆ˜|Ѩ{‹÷SPO¦ ÝX$эÈmÞ*Á$`é°öZvD- C·ÅËÁÕ ×Ò¬‘/
1423
+¬6©³ºN°é»æ¸½Èz|ÌfÁˆ|çi8yÕÆ†-A»Ðžó2܅>´|P·çƒ— F§N°´}]'­­gÜN°åUî%ÜO݅ÄB
1424
+ÛÔ?pŒãŽÖŠO.†óÅøÓÙÝô[„j£XYu‡ÿÎì!ÎjžØGEdR9ÏM@Ùÿ‹›i l{òOäõv¡Û•%è“{UCÁ64lú‰õ²>ã…nI
1425
+Ÿøóõ±¾ƒè]\Ƭö•û’„Ûk¬‘²¸WôV6ùþہ§ÿß[çIƜqŸ;3¸ö„é*b "ltô–£[dÍU‘Ñ[Œ¯ª"ڗ°ùew.þà£÷ú^1Õ¥Iœ•8W–Ñ,L›0àòÙ~¹„‰{Bç¢n @¯ãcšß[ø˜ñ}Iò*C aCm Á'ðA “^äìçÌ"„5ÖÕ×%“—«çWß¡S:b€—ù-(=«FЧE±V‰ÐÀ+Y:%*åƒyÛþ|%Béñ±‚xÒEʞiqŸ®ÙâÿŒêⳒa¼N¹OÙ*NåÂÐËî¼Ó^%bÃ.ÒG¶Pð°ç·x ÍÕ.ËýW"ŽR˜BH†ëÌoq”ŸÄíÊÌ/ÝLöƉ?h=^ð²þ$F¶Iúǎ¹Ñ½R ËOÌÊSiïԓäü1cž ãïó[<|[ǚz´¤Ú:rŸþmÍ´|K#²ž< ÎÄJ?lœ>PŒáJ¦Ø>º›É¾ZÛ4N›Ú…žJtŒ²±”6Û}º1‡È\/æ…[÷d‹DDæá9Ðàëø’Ã{…e3e¶!5ܕ,?1D“‚•CxFæ&±³e&†(Ho»$LæÝCTs¡Pg0QC¡Å—¼é¢{]5í.¤“ö°Qàޖ‹â–q,1„ÐdEýHZ AŸ/NAèèx¤Hõ;H™Ct|\”b…»2ý±à}„¦Éh.όy,I7&c ׊ðþß ¨K›¶òdñQßq‰!VhŒy-ÁÅ×_'u=QÔçÁþ¨k_i8FÔõ³“¢ú«='fÔ³"ÊðÙDq•Â&ʼn‹ïjï±*š' ïÌeªÉö(`u's^X9ÍBCT» Y€}&3)îæÅqúL­šb0-†9X•BõeÏó RÅaHS®‰!v$³À$˜¶™Hr^¯â¦é`ÙÒ{#oh(Ìr•ýÍYºp閩ØôËŸÄ[T€$˜Y áïfÂQr!Íþ~i'†Ð¶ ™¹âŒU·‰!êʾE-Æ;N A jË»¾þ6’B$xý«dKšÂ’$\¦Ê2‹!î³|‹N ÑËbrb¦èN atÆÝh€(F8“œ€§&£m’#Wç/|%±'†¨˜(Ɏ²™CˆÅCt;³¿Cԋ\+ÖτÄ#Jø¹ð¶züÃü"1D©63:n1D¸~¬Ô•vû4¥¡&"&à.NƒúQ}¬Œ#2S‘ti@£B](Ý;±,&†h+"a¿éG^˸ÆÄoŒldz¢²¢ÃÎRê‚Ó;e "§žÎ¤l¯¹¶‚­y1½ì´Ž¥.µRWBÁ1•S$1Dí&Ÿ{š 2ðáAó¹’1GÐ̵x©nEIbˆceæê°¶òäÄT¼˜+^¦˜ÅÅÍȅÄ-Þ<õ§{$ Ž%¸/°W²K÷&>èåb În‰µÆL‰!rh-¢²à¸SËmÁ¿ÛòÕgáõ{|l¨xU†bX´ÐÂÃ8‡ãCÏ ü‡ãØÇq-s’µ]”£z3À¥O5h5õúÏ ‹¶½Òç"3¢ÿÚ/?ýXU哯4IÔòúÅõóüwo¬xai„NV¢]ª[òj4̰>34|wBȶðÂÍ$(îŠkˆ¾Gá…²ý9W›¹‡†ª¯»nGÍp}7/èýìçm¾"˜&AbK³4í³ÒKX48Óۜ_2;n¶ñþ(»ÔX>/Þæ¶õõf/zm8jaáŒ$ËTùËâ‡wø<óÑ Q&â;^µ«c+•6{^os©äHó-—~ZOþ)oó!®CÕ¹Iüd.‰È‡„zpr9 y‰Éyùy&
1426
+Ši¾·ù>ëqܿſXoþ?yr7s™Ôš ®eјg<æUS)ñìIÑ^P¡íȜŽò]Сה$·¦© žj̲åK•,³†"ü_Gå3¬áfÒRqƘ…⩐eŒDÀÏ®ŸQK™r“ [,P6´Å_vZz…qàý\T1íð§šÐŠáûÕLý‡T 瀘O‘vçô‹ï^DPí5)›æá' Ê-Å!¾è"ûB/±£Vný@¬m“<G‚æ½×Д[:9ÚèWÊ­Å6an9/Ú£ØSn1Œñâ½â2·ìZåÖØH·
1427
+pR•[ï¼ZéV:”[ú‰ÚԔâ2·œÿ­˜ªÜ’2¾nÞZ?Ê­÷Å6è/Ì-K0Ýy•[JgÖ`˜gªÜÒzf­™–z¤ª%³•[6ŽÝ¶ýQPkå–<Çܒº•r #Ýó,cµý}êmvÌð
1428
+Âhþ6”1ÈD¡ê6«W*¯ÃÎùÃB PzI0q{¿ýžï©2ÞNžßIìá B\¯9f;I´p&X^­^»]’R‚@K¹W‘+ÒJœ¸ºôŽˆç|‰÷ñ$xKçæ!?lOéëAÚaåÍ |•К7CJÑff9 töh¯Ûúv@/¯c”UlÙn+ù5–1d9JãÖônö ¡§ææ:|'Úä·¼±ÏGîy Å ÏHKiŤyGî Ô0z¡N4±É•]clî6 °]‰^º ™ü»;–ÅÆc¡ ƒv‘’jx½ãé˜Tã¤Ï^Œ;†-//ä0Ì&c¦Ò]Df而‚D† 6NXT7ªY˜åcÎ
1429
+Zۉé+A`L …¾K‘ç#L]t}½Ä‰ŒGl‰#é<ÇÉDä¿p}“Éf‹È4d,ÓÛ̲3ªÏjo2s@qõ?QœŒ¥ðv¹æºo2ãSW EySU ‚YøôÛã+‡ÉZÅ Ô2 ßï Ù>¨0e2ën QźËèDã è1BuR-…r’ÿ•½m2"°ßîc~=¼ªÌ[lѼ»¯5ýÜaqz”IÔ]T…ñǧà¥‡­m!ir>ÚíX|ÁÐÈ$f dþá@kU‘ÞÝ÷‡PœèBÐ÷êF#8ÐAëË@ÐWï°¢_+š|ý#yz•—²ñôK"ä"V”CÐö(h.Àjà@_ûj7rJK™ì@Óö*ýðL;ÐP)dõº&4Œ yÛwµyÞ
1430
+Z÷–ÞX7[°4Ζj×âƒk‹‚h‡#ï–Í4‘€éÖ9/’IÊhÅÃ&¡ÄÅn‹Ÿ×"qÁcÈ‘$6‘7֜
1431
+;îÖ$ÞHÃM÷¾Ö–L¼±&•!@´ á˜ÿ©îÆï%C¢·¦´1Õ~½·‡eghS” …Ý97zZËêb>¹PÈx>éÿ!á;Û6cý=،579¹$£_ÍyêýÉ2‘Õó2+P‹51÷tÇÉÃÆ>Vœ+†°–<lŽ 8b#™,‡bÏ[ ö§Ø 6V)ö ážçœzd-gVàaãhðàc‘iDµJM,î…Ž3g‘©UlwÊO@€³~‘0å— ÒA€„ç<˄鿍dDïÿ)"¶‡)NüÏ|¸$îú(ᑰ'aÌљ •üm1/¿de{«ô©n2ˆÐðÏ'ä³ô܋*ájocÐ7Á'1鎼€èÞó&ü­GOËBÉʞç/Â$ÔùÍÖó©é-Z«EVª¤T`Êkâ+‚QЦì³M3Ï>K_R`‡ÝgnQK!Ò"r%¡‡0â8)תÁJÔ•/ºíoÇb«À¸÷èÝÿTçäVa, àÎ€È æÌ8Ëø¶²¿0ÞS‹¼áПð%G®¸ý†âΜH)·p1Œ^³y´#qÕ©9ØQsœgU´fc¾÷IüöŸÚ/:dÔYG{Ò¹eåCun¶rÒΑ‹ã>òR°$Æã#H´°aU–‡Âàþ8´»_ÓfÓ&¬Ù´™þ£˜¥º{IFdB: 3I(ñJƒŸ0ÛðbGÎöÃڛ#6iáõ²g\¿uŽ0BHL%“óAD;rÖjܗ#§8:Ú£Ñ\aŽ&£ÍÊØþ„m´ÿŸã,šõ X œ(ZZà3èe—*“8ÜË农Ð,êï(]¾J£è֢蚃ûj«…ÊãìñN€¢njrá¨ß úh°ö„mÍÒßÄnŸY­‰#GCð×ÚÍß6ªiâ'Ôg&:X¬AOã“<Á‘ŸÙû¹þ ͦ:¸šN;ޏ'l³
1432
+_9ö7ÿ3ïLŠ¡9E½ßLÏ`ŸyãGhV@MŠõ
1433
+Ùotz€ùK±M¦¢#PØæWvH 84#žh D†Lb›OK¨ïÚ~<ClS,
1434
+
1435
+ۄÍò™¯-šË͕Ùg¦NùŸÀ„æÙeN$ ˆ§CEwS•Ÿ˜çdY¿šIŸyT²L‡f`ƒäéúE?óo³×â …gü¯³¬y£Ã?j¬¡¯“7NË|gG•W–‚31LíxSÖ+w]L˜C|òB?PQZÐܙáŽ7ìÖïíBmÇ)[]5Ÿsš˜Óã0›=›õŽ7ÆOp—êAWEZ7¢ÉÊ ú äÇT":${Âö
1436
+X3‡+wßöÍ|Õ,éé ì–ÓÑbºÌº9Þ…­æøC¹¸'ý“ãÍ¥4ȨQxàxƒÐÌ­Õ¿ª£ÃdyÉñ&7Øm-£\òBÌ«¨ &ÇÀ2—kFßúb¨Ä BÄTàd#Ñ1°c PëDHä˜8Þ¤xÔÿÀÛ=Cބ&K_Ž77V2ƒ`Ø(î>LrHscÊcÅoJ-¤Ôܝ¼„ï sHӌ=7䞉iˆ¡S$™6=RÍL³#é $X¹ãêþ§*Ë§áyĂÌþùY鹦[B‡ Ó õ¥åxó‹PœÑ ˜EÍc9EŽ7Ã(Qî<?ÍõÔ º„$”ÎñƘ×_˪&8ÞÈÌodóBFÇÀBP
1437
+†‰zèß7
1438
+bÉÀ@»Iû,CgÂ9Þ ¨ÃäŽÖcž´í^FSÌv¼!OvÄiDi¹gý¿\E¿j™c³f´ž‹ƒˆýwêÇ\YÅX‡(çɹå•çÛñæ]?cÅp¸ºA°ã¬ z}ñÿð-R¼»Ÿ¢®%áx³£AiKÒq¼¹9ÑsÞûžLÏñæ1(ñz¡Ò£fËX’㍙å»3J:Þ` ©ÊÐb¥s?UFñXV†ùy`¡VÁ™ÉQ"3»×C¤[¬$t>ˆ=ëe؜–/¨2,îmn¤T4¹kä¨l ºxx!b…
1439
+‹ùÝdšœÎR9ùàÃz¾I< µYo2Ñ+VdhrØøn¸ZÚìe^ MÎhÿxÏ7箈ê8=k} Œ|Ìr(ÑÍ|A„—CÔê$&·œ:ã~aj.Øñ”H°¿yöè ÞWJ½†I×¹dŽh«¬'ȺÚ3ÕCs{ëÆJJ´PÅ29ˆ³³ðŽ¥êQ œ Ä9Þ^È DÄb Öù–àk»L—À è`!ñˆ ?W(p8ên°*A8¬®ÃÚ©iCD¹âïí´¹\õÀ,£ÝZÚß~@ü/;íùêhªìD 8ÍBó’'Ì«”¶ëÒ;ß!)ŽgÛÌÜOóZ\nj×ɧûoS-Òº„ÙlùÔ«¡Îâ*úª²thM7í,ð¯`f8Üô´û4~ÌÉ¢5½Ógˆf!/˜¥@ÃÉszʹ¬ ïª&˜C”¬›¶;Kü•šŒ¡‡^ ¶‰ÐIºPyý¸ó®gÎ;©ÄõНMÂL¨…ir&Vh…EE¶ð4ý¥q2gjS¨ùÑÌáxÝoXÜ2f¹>jP±ÄÍ9)•Ýñ¬;¶±­t”uÅ•¤¿1Äýg†½@’¤ßÏ%¸t›ô -#”‚¨ž{=‘#a’>cá ×ëqu4lÒ¿G¢l´mOz ÉRÄYiӋ1(õXèa–Iÿaznaï|6d,ĤÿOÄ|.Á÷b‘rF«üóÐßB“~V #'·w8äÊ 6Iß$&}é_m6>B=I_†&}/;’ôËb3éÿ¹® I”RLú`-I_|¶IŸ´M_ Ü‘ô‡Øì£lÒ/À¹'éÿ`Ò×Ò«¨ éË™£`šô®qm.IúĹĀ&ý_
1440
+:‹&éË*ü}¸Í1˜-«‹º°ä0*mÒ ëR5¦ø3jÕ(5-í #‡±ª§uÙÝÝݛ>µ ïmŽN«@\rh«VoLüoêÛ¸»8íbôðkñ’»ÿdŒÑs‡‹g‰›+ÏØmZ—‹I“-Ô&ãÁsgDóLê±pBhž?χ䂍ˆ‘ rDŒd0p.PqjÔ+P‘·h2 ŠƒL¢Ðd
1441
+Bˆ BJtÅ}Р!I¸`€TŠB^(ES¡
1442
+åDW&òB±$  R˜‹ãÁˆ0â,I†Ê…Â5#> AÂ9H,Œ¸µiù.ªÒrÈñ`A!s¡¤Jg Ed„„ȁœxñ`Iy¡¤„ñJ…¢.J”|Xh(ЀCã%¢Ê&ÀPàA¤¢£!2á€21a+³&œc¦ÄÇ`J|`fB0 '…ÔX *0¤£QA5pH H28,h€Aä(àBB‚ù¨`¤ågfKUÌ8.$ÌjœY8Êbáа@Nd©X ‡by¥Â¡9•‹IM,“  … EIj•ª@N¥B©|2ဠä˜`Ó â"J DpÀLF6BI‡‹(,th€ÁH#'6%òB¹Mɇ”a³l€ÈT%EGU .b’± ‘ypaÃKR|\B¦Á…‚"£A†’A¢2¡x€¡p@@Åa.X9#Ž *î&˜Áâ "!H¦*ä…br ç¢14˜TÐXЀ‡
1443
+6hب4 áÃE& ‚Q0’FmŒLJ\’É…Gè ñL†‚ ˜Æ &–`Pá‡ÆÆE—¸P¬<,Æ»ÚÉÖûº*³½Ö5-£G¯-Õ&^Öµ]&^Ô¼»»Ÿ™no÷6ö‘ï’+­]îZ^[Þ–ÍøÉ˜ù”¼z©²
1444
+Ùð+5/¶²]%î*ÜóòFÝî.ÓÌÒ±Êp/Sñmj÷9Y!›&»Õ³¦›•‰£nn'3+Gä1ļì~F}ËV÷WmH³6ÐÚ@hm Gdabaoç¯Ý‰ù¥ø2ÓÔëˆl@»ç´1÷xµèù³zõ¾½Ô|¼„ÅæÊš™Ž‘·/ù:•"ãÿ+L½=ÆkµuɜT÷YîëªV/&>&â/5fŸ|¯Ôóî¾=ÜÕMÚmלÛIñ…x‰Ü™õTùz¬ï2U¾™U9ñ¾žäÃê,íÃûâfݒÞj½¯Ç˜þ›Ö*#&í®ÍªÊèÑÜk§Û×»ìò«Oˆy•ö*MÇ×Sõs]íet,Eeîî|âÊ3ÌUëÆèÙTd6Î^ÜNu/Ç£°ŠW™s9qq+õ‘»7zw!6ç-U•ëËvWî<\4\»¥—Zé^&ž“2⦙ê:vÝ›mïtKw³ÏšÉ2ÓxÙ¶ïe]˜˜ç«êgu›lͬ­
1445
+ÙñxØ®ŒÏ™©w\̋ïåF»UÆç®bÈ¢ecz\ŸmÇÕ¶ZœÚ}«ªýÕº2ëT´ê܇<¦«Ç•
1446
+5zN¹ÊTw-=žÖbm4.>ÕºÿÝÅ÷s–•=¹Ú·Ìª­»ª…<ú³UB;Öanm¾KL|ïs•¾ž¬6½ë/-q¶]mns:¾ó•ñXM­.÷jÛ°Ñs ù†}W»EÕ6EÞFÕwÒÄê++ý¯Åë6nÇ£ÒTm“i?…ß³N­=W™©lß}2î‡+³SjFZ¿~†¼é×gf1^¿Ž›½õ÷~+ «®¹·¸yӖÝ9Q73mf¤Xܛ¶^×áS33zê͋güzÔÊ.7/£‡MͰŽÞkUsSímÙ}ßúñ튉‡ø³Ž AÎHǘH äù 1q¢äƒäùéXàãDÇóá@G ˆCòB¢ƒCi‘÷xÍ("ÁÑ<j?GDë’)[›.Û²–ÍÌéZœ{æNeMÎdµÛâ”vմԘöN»—#b6ÐÚ@hËXS¾£çJù?Ìka²]æ±Òru%óý©öÔ|û¬%ç‹5Ó¾°±û,ϽÑSû«{éÝÊ0ÙñÌ.-Wô`_׿ûwn?iÖ{֝ÈÖOÉüìŸ?UTÝZm.ìMÓ»KˆÕ[I7¥²£éNÅdkEM‡\l¦Ç¬…Wﶤ·…Æ_îM\ìˆ<Ì{ÆÚï~7ÐÚ@hm ÅísZ/_ÞâBP,Ä^ÓîôÆÈñ€ÐvæJNõíÛå–*r¤§)ñùî¾¶^ùÓÃTÑSx¶§·Ôè±²';;VÞ:îLÓrB<[%×úWô^·å-ì՗ƒ±—Vå3ëI+«oy]z<ÚMõh­·¤¹Ñ“¨ËŒˆv›ôööÎðVú;מÞVš©a±a®ƒ‹¨’kœSL!4C##-HÒâÄ0Œã`¢ÍR~@`jÄ0dˆ!BIšÈIRn“} uŸÌÝw—}9‘Â÷YRt¢`ú窶÷͈Ö"} sS2AÞ]]ÊSá@»‡„Î…Qt‡a ”åhj„¨ëŒ_-ü¿¬%NBÝ]®ò[l%)P)éǎÓ1´áƒˆ(Þēšó¦$
1447
+úY5 ÎκÅG˜äýA‘ìôv‘½¤Õeà ‚•¹bža͜FmTðϑdâJʶIå¶ql—$¹<Þ R±™nY5t>ö5%³’}½!}ÉeX`Ё•dŽ»|Hr¢]žHzÀŽG²^ãס‘gŒ¤Kš û¥Ë&‰Ïñªgc–ጺx㷎aGe>°º!Þª^7ÈsÁˆÊ+ÕºÍð]ŽVd#áþ¦¶pÈ[¥þ@s=ŠIK·Ì5Ìځb:¼µ•: ¥%ÕÃÆ LĄþÚcF³Fœ.ˆ×u*εOëÒy4„ðjåEô YÎ Œm½5hk͍89âÉT×Èw'ÑFŠÄÚYÅ>þA‹t~DI¡˜zÂCŽ?²®Ãé‹$NdÃweJ‡hˆƒ’ᆀ!§J©qWö¾£Še›Z3b!t¡ÂÍj1¡Ð¬Ä„¢T.I¸Õ[¤ ²¦˜ „/#Ҋð *ô—8˜ŒTÐ ¦ÅàÀต& YPG¡ }4´ Iðzà¦€è+䱯èEèàiü³Šz!àfڇM‹Sƒ èЁyC¶ŠËýª'Sî®o~»¡ÏäM`¡¤jv)žôȘÊe¡kR䙺™O2wÈ0ƒú®Û>fRˆ™÷Û ^)òïéN'f‰@”"ª«cMõzðºnˆ{çüنþg;£zß!̘"£4D^âQ&86H!-wŠøÄ;Lxκè|QfÆ­éHéù—´9@•b‰@qêÃnÉñ¯`1Œù**-ÃöRAÙL© [‰”šyYXF—· C|Kô.ØÝ–ÞáÃM%ÎϛßeÍJ5½)Ȇ«ü½ä /Ô*c1Ð2jŽ·©B–øùû ø°ŠÉ±IÓm \^Z‡Ü¸' ”xF[v&:a鈿uÂVEãæÝÉ®(cÑÁZúåþ2´ä˜ K2ÌP“'¼q€È².܅ ˆ‡!Íx¸YRŸÇç£犡Dâ|r`“²(U]øM]š/äö6¯([®C`/V’ÿòpeɽ Âx—
1448
+þ¬_Y;à Ué‹â„ˆÉHWc²UQˆ~iÄÄYM>k¬Æ¦¢’ƒ)]øPnÂ,*aàkUTêýŠÌÄø{ðJÆr¡?û®ö§1¾ßªgN‘jÇû‡Ç®'¢y´è±g²©”.ž¬|…Õ÷VÉj7p¬JîNÄí/åÚ!±MÂèê¢ÙoZù‘9Lõ!N†wß³ä6oýØfüò<3 "·Ž›)_ø…ìASÒ@ˆ£QìLŠØ.´ˆ;v¯çØ(|íFˆ¼8ö€H2ÊÇÑveÓ7Qe¯)™]z¤FÑK·Yƒڊ‡Uç×g­Û©MŽxJ± 8c¼¢Àß!ý%¹ˆ[fµn!üL¬9]<Q&Ä÷Kcjt{ØA‹.U32çÜìOa ]ƒ‘ðßx(
1449
+Œ¡¿à¸é‹œc/XÁJyE»×A×,€ Ý‰ÇŽì2&Bˆ‹~¢s¸°HK£Í$ô¹]ÝjÌbxzÌtHŒÇÌ]|˜hŒ2Ð®NÐÄP÷ZRó,{¨Ža~\Ü¡-c²sü¯j"Ûc'@*+-M™ôdB׃b—Ú¤nïzX!˜¥ÆehËþájðß*ðŽq¾¾ÿ¾&îÕÕÕb&³ÍÝa<G\a_HMY³aÓ}³²L@n/†U Cχ¼‘Ìqi˜ü(¹:àŽ×ª&: PgËä§lèëpYg—/ÃoÁWH§ÄÅ Ø¡‘ïþÒenÑíŠdGxþŽôlbbKƒ7–C†ÄGÉÊ=ªåK“D4u.œžw½ó SÉtä²Êw|©íÌw|”\#U0Ì×QþíyžôÓ³ê»m°lÑ¥.ªôÐPÕ¡‚JyîTâáS÷)Cñš¿ž3^|îʃí*bÝÁÈu(;ÏàŒxÜ𩤠ù_ex6‘Üã*‘ÊÇTúB^<ÂÍä,¢Ëõ;¨żæŠ\ ïÄj&¶î5FÙ[ {¾/L3ëjZ+ÑE)?A¾‰œžÙã\0$eò‰ÓË[OŒ#9G½`t1ptÜ¿ùõ8Ž|Çè 1vtА3-dt 1wtPÕ <R4FॣƒpÀ4äGCFçUGµyVƒÑA—&ptPdåÁË8:Ð=£ƒŠ‘£T8:¤7ª( ©½Xj ŽJ沚§gt.xWC&1¯HœIÚ×
1450
+¼N‡-åd¾ôž;Rà÷sãíøƒé4K›Ò4ígøëPL h~>]p‰Ô!ÝÒË~F×ÞQ¹uŠ*OÛ¨U›é6®”n­q©X%–ÝgsùØO”™(%Œò|äÙ03[¾èÛeĀõÅäpt¹`®r’½˜ýEe~£Rô 6Üáú{¤ðÏ*…ô45–‡(>³^d©ò×{=ZÐD…ìXHJÿFY¡8†¤P^êÓH@§fâœ+hýÍ0ˆ<¡ãþ#Õ/¥ ”òˆCôDTsa
1451
+2 óH€+µ°Gü™˜›ëÄ(£%[p Oⳗ]ýÒää—­·f$‡¢Ýx¥GtÎHŽ„Ûñ&¥_ÃWmÕo< ›„¼ë`‘ŸÁ^ pŽØ@3YO#RÙÓBJÀH/†XŠIEåZëY”’ðÌÒzdE¤c~’òôa-hÙcÙ¬” ‚qU¬\< Eô B']pÀ*}=‚~$yŽ‘ï)kpµ*™ç$ÁƔԥwÖlÌÏj¾{V›Ì =àE£à#ԟy¨ò³ú§žÕ­ z‹õ…¢†¬£ª8øOæà?NJ €F‘UUaà·dgv¤SV”Äú³?+L}†¬dP­N ˜­&µ9SS“ 7©YÖÔî'\žB6O L5•Hë(2u°Ò¤g
1452
+i}vRù<Ï:3‰"¹œ’¢X‡W®êwdÁ^¾&ëxMToé&Å'¼G¼Y˜§p1^ð}‘è/’¨½ ž>~ž?E£¦Í¢#îæPž½ôŸ` ŒºtƒVG*@ˆm`ÏÓ䛿Îâôÿäx5ÿÓ(æ˜ðb¾ÐªDÅ©Ìg~üÁâÔpÀO,N¥ãwN^Ñôãùƒù<FËûÌ߄¦«3ÓmùKnÂ3Ë3寀>kS6µÃãÔïfç"]Џs
1453
+[¼™$/«—ºÉýh4 ¸B©£ŠÍ¦ad~Y„(ÃHaÆ=—(U<]yUšeü Ó7d™œhQ‚G~ endstream endobj 29 0 obj [/Indexed/DeviceRGB 255 30 0 R] endobj 30 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 441>>stream
1454
+85$<f>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
1455
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
1456
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
1457
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
1458
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
1459
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
1460
+l[$6Nn+Z_Nq0]s7hs]`XX$6Ra!<<'!!!*'!!rrmPX()~> endstream endobj 27 0 obj <</AntiAlias false/ColorSpace 25 0 R/Coords[0.0 0.0 1.0 0.0]/Domain[0.0 1.0]/Extend[true true]/Function 31 0 R/ShadingType 2>> endobj 25 0 obj [/ICCBased 32 0 R] endobj 31 0 obj <</Bounds[0.000970521]/Domain[0.0 1.0]/Encode[0.0 1.0 0.0 1.0]/FunctionType 3/Functions[33 0 R 34 0 R]>> endobj 33 0 obj <</C0[0.0 0.0 1.0]/C1[0.0 0.0 1.0]/Domain[0.0 1.0]/FunctionType 2/N 1.0>> endobj 34 0 obj <</C0[0.0 0.0 1.0]/C1[0.0 0.780392 1.0]/Domain[0.0 1.0]/FunctionType 2/N 1.0>> endobj 32 0 obj <</Filter/FlateDecode/Length 2583/N 3>>stream
1461
+HKœ–yTSwÇoɞ•°Ãc [€°5la‘QIBHØADED„ª•2ÖmtFOE.®c­Ö}êÒõ0êè8´׎8GNg¦Óïï÷9÷wïïÝß½÷ó '¥ªµÕ0 Ö ÏJŒÅb¤ 
1462
+ 2y­.-;!à’ÆK°ZÜ ü‹ž^i½"LÊÀ0ðÿ‰-×é @8(”µrœ;q®ª7èLöœy¥•&†Qëñq¶4±jž½ç|æ9ÚÄ
1463
+V³)gB£0ñiœWו8#©8wÕ©•õ8_Å٥ʨQãüÜ«QÊj@é&»A)/ÇÙgº>'K‚óÈtÕ;\ú” Ó¥$ÕºF½ZUnÀÜå˜(4TŒ%)뫔ƒ0C&¯”阤Z£“i˜¿óœ8¦Úbx‘ƒE¡ÁÁBÑ;…ú¯›¿P¦ÞÎӓ̹žAü om?çW=
1464
+€x¯Íú·¶Ò-Œ¯Àòæ[›Ëû0ñ¾¾øÎ}ø¦y)7ta¾¾õõõ>j¥ÜÇTÐ7úŸ¿@ï¼ÏÇtܛò`qÊ2™±Ê€™ê&¯®ª6ê±ZL®Ä„?â_øóyxg)˔z¥ÈçL­UáíÖ*ÔuµSkÿSeØO4?׸¸c¯¯Ø°.òò· åÒR´ ߁Þô-•’2ð5ßáÞüÜÏ ú÷Sá>Ó£V­š‹“då`r£¾n~ÏôY &à+`œ;ÂA4ˆÉ 䀰ÈA9Ð=¨- t°lÃ`;»Á~pŒƒÁ ðGp| ®[`Lƒ‡`<¯ "A ˆ YA+äùCb(ЇR¡,¨*T2B-Ð
1465
+¨ꇆ¡Ðnè÷ÐQètº}MA ï —0Óal»Á¾°ށSàx ¬‚kà&¸^Á£ð>ø0|>_ƒ'á‡ð,ÂG!"F$H:Rˆ”!z¤éF‘Qd?r 9‹\A&‘GÈ ”ˆrQ ¢áhš‹ÊÑ´íE‡Ñ]èaô4zBgÐ×Á–àE#H ‹*B=¡‹0HØIøˆp†p0MxJ$ùD1„˜D, V›‰½Ä­ÄÄãÄKÄ»ÄY‰dEò"EÒI2’ÔEÚBÚGúŒt™4MzN¦‘Èþär!YKî ’÷?%_&ß#¿¢°(®”0J:EAi¤ôQÆ(Ç()ӔWT6U@ æP+¨íÔ!ê~êêmêæD ¥eÒÔ´å´!ÚïhŸÓ¦h/èº']B/¢éëèҏӿ¢?a0nŒhF!ÃÀXÇØÍ8Åøšñ܌kæc&5S˜µ™˜6»lö˜Iaº2c˜K™MÌAæ!æEæ#…僰d¬VÖë(ëk–Íe‹Øél »—½‡}Ž}ŸCâ¸qâ9
1466
+N'çÎ)Î].ÂuæJ¸rî
1467
+î÷ wšGä xR^¯‡÷[ÞoƜchžgÞ`>bþ‰ù$á»ñ¥ü*~ÿ ÿ:ÿ¥…EŒ…ÒbÅ~‹ËÏ,m,£-•–Ý–,¯Y¾´Â¬â­*­6X[ݱF­=­3­ë­·YŸ±~dó ·‘ÛtÛ´¹i ÛzÚfÙ6Û~`{ÁvÖÎÞ.ÑNg·Åî”Ý#{¾}´}…ý€ý§ö¸‘j‡‡ÏþŠ™c1X6„Æfm“Ž;'_9 œr:œ8Ýq¦:‹ËœœO:ϸ8¸¤¹´¸ìu¹éJq»–»nv=ëúÌMà–ï¶ÊmÜí¾ÀR 4 ö
1468
+n»3Ü£ÜkÜGݯz=Ä•[=¾ô„=ƒ<Ë=G</zÁ^Á^j¯­^—¼ Þ¡ÞZïQïBº0FX'Ü+œòáû¤útøŒû<öuñ-ôÝà{Ö÷µ__•ߘß-G”,ê}çïé/÷ñ¿ÀHh 8ðm W 2p[àŸƒ¸AiA«‚Ný#8$X¼?øAˆKHIÈ{!7Ä<q†¸Wüy(!46´-ôãÐaÁa†°ƒa†W†ï ¿¿@°@¹`lÁݧYψÉH,²$òýÈÉ(Ç(YÔhÔ7ÑÎъèÑ÷b<b*böÅ<Žõ‹ÕÇ~ûL&Y&9‡Ä%ÆuÇMÄsâsã‡ã¿NpJP%ìM˜I JlN<žDHJIڐtCj'•KwKg’C’—%ŸN¡§d§ §|“ꙪO=–§%§mL»½Ðu¡váx:H—¦oL¿“!È¨ÉøC&13#s$ó/Y¢¬–¬³ÙÜìâì=ÙOsbsúrnåºçsOæ1óŠòvç=ˏËïϟ\ä»hÙ¢óÖê‚#…¤Â¼Â…³‹ãoZ<]TÔUt}‰`IÒsK­—V-ý¤˜Y,+>TB(É/ÙSòƒ,]6*›-•–¾W:#—È7Ë*¢ŠÊe¿ò^YDYÙ}U„j£êAyTù`ù#µD=¬þ¶"©b{ųÊôÊ+¬Ê¯: !kJ4Gµm¥ötµ}uCõ%—®K7YV³©fFŸ¢ßY Õ.©=bàá?SŒîƕƩºÈº‘ºçõyõ‡Ø Ú† žkï5%4ý¦m–7Ÿlqlio™Z³lG+ÔZÚz²Í¹­³mzyâò]íÔöÊö?uøuôw|¿"űN»ÎåwW&®ÜÛe֥ﺱ*|ÕöÕèjõê‰5k¶¬yÝ­èþ¢Ç¯g°ç‡^yïkEk‡Öþ¸®lÝD_pß¶õÄõÚõ×7DmØÕÏîoê¿»1mãál {àûMśΠnßLÝlÜ<9”úO¤[þ˜¸™$™™üšhšÕ›B›¯œœ‰œ÷dÒž@ž®ŸŸ‹Ÿú i Ø¡G¡¶¢&¢–££v£æ¤V¤Ç¥8¥©¦¦‹¦ý§n§à¨R¨Ä©7©©ªª««u«é¬\¬Ð­D­¸®-®¡¯¯‹°°u°ê±`±Ö²K²Â³8³®´%´œµµŠ¶¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼›½½¾
1469
+¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûۀÜ܊ÝݖÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿÿÿÿÿ÷„óû endstream endobj 22 0 obj <</Intent 35 0 R/Name(Layer 1)/Type/OCG/Usage 36 0 R>> endobj 35 0 obj [/View/Design] endobj 36 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 30.2)/Subtype/Artwork>>>> endobj 26 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 23 0 obj [22 0 R] endobj 37 0 obj <</CreationDate(D:20260321161439+01'00')/Creator(Adobe Illustrator 30.2 \(Macintosh\))/CreatorVersion(21.0.0)/ModDate(D:20260321161439+01'00')/Producer(Adobe PDF library 18.00)/Title(PAILot)>> endobj xref
1470
+0 38
1471
+0000000004 65535 f
1472
+0000000016 00000 n
1473
+0000000147 00000 n
1474
+0000047892 00000 n
1475
+0000000000 00000 f
1476
+0000047943 00000 n
1477
+0000000000 00000 f
1478
+0000000000 00000 f
1479
+0000055322 00000 n
1480
+0000055394 00000 n
1481
+0000055589 00000 n
1482
+0000057197 00000 n
1483
+0000122785 00000 n
1484
+0000188373 00000 n
1485
+0000000000 00000 f
1486
+0000000000 00000 f
1487
+0000000000 00000 f
1488
+0000000000 00000 f
1489
+0000000000 00000 f
1490
+0000000000 00000 f
1491
+0000000000 00000 f
1492
+0000000000 00000 f
1493
+0000241877 00000 n
1494
+0000242177 00000 n
1495
+0000048360 00000 n
1496
+0000238879 00000 n
1497
+0000242064 00000 n
1498
+0000238736 00000 n
1499
+0000054301 00000 n
1500
+0000238162 00000 n
1501
+0000238210 00000 n
1502
+0000238914 00000 n
1503
+0000239220 00000 n
1504
+0000239035 00000 n
1505
+0000239125 00000 n
1506
+0000241948 00000 n
1507
+0000241979 00000 n
1508
+0000242202 00000 n
1509
+trailer <</Size 38/Root 1 0 R/Info 37 0 R/ID[<F328746D0849448481AA1F3681959721><3A8EF663527145998C6D2F26B50FA277>]>> startxref 242411 %%EOF
assets/PAILot.svg
....@@ -0,0 +1,53 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!-- Generator: Adobe Illustrator 30.2.1, SVG Export Plug-In . SVG Version: 9.03 Build 0) -->
3
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 519.2 519.3" style="enable-background:new 0 0 519.2 519.3;" xml:space="preserve">
5
+<style type="text/css">
6
+ .st0{fill:url(#SVGID_1_);}
7
+ .st1{fill:url(#SVGID_00000140010444917909177370000008693087742949585070_);}
8
+ .st2{fill:url(#SVGID_00000018934966357755650130000003082424866747500951_);}
9
+ .st3{fill:#FFFFFF;}
10
+</style>
11
+<g>
12
+ <g>
13
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="0" y1="108.723" x2="389.3739" y2="108.723">
14
+ <stop offset="9.705206e-04" style="stop-color:#0000FF"/>
15
+ <stop offset="1" style="stop-color:#00C7FF"/>
16
+ </linearGradient>
17
+ <path class="st0" d="M149.4,68.3l41.7,87.1l109.5-4.2c0.7,0,1.4-0.1,2.1-0.1c22.1,0,40.3,17.9,40.3,40.3c0,9.9-3.6,19-9.5,26
18
+ c33.3-24.3,55.8-63.6,55.8-107.9c0-40-17.6-84.7-45.4-109.2c-4-0.3-8.1-0.4-12.2-0.4H0v5.5c0,76.3,59.8,147.3,134.9,151.4
19
+ l-27.6-88.7H149.4z"/>
20
+ </g>
21
+ <g>
22
+
23
+ <linearGradient id="SVGID_00000026870600589613751090000010961466516538721174_" gradientUnits="userSpaceOnUse" x1="528.4339" y1="258.5626" x2="36.9606" y2="258.5626">
24
+ <stop offset="9.705206e-04" style="stop-color:#0000FF"/>
25
+ <stop offset="1" style="stop-color:#00C7FF"/>
26
+ </linearGradient>
27
+ <path style="fill:url(#SVGID_00000026870600589613751090000010961466516538721174_);" d="M518.9,175.6c-3-47-23.2-89.3-54.5-120.6
28
+ c-31.2-31.2-73.3-51.4-120-54.5c-0.1,0-0.2,0.1-0.1,0.2c27.7,24.5,45.2,69.1,45.2,108.9c0,42.3-25.1,85.5-55.8,107.9c0,0,0,0,0,0
29
+ c-5.8,6.8-13.8,11.7-22.8,13.5c0,0,0,0,0,0c-17,7.9-35.7,12.4-55,12.4c19,0,37.4-4.3,54.2-12c0.1-0.1,0.1-0.3-0.1-0.2
30
+ c-2.9,0.5-6,0.7-9.1,0.6l-109.4-4.2c0,0-0.1,0-0.1,0.1l-41.7,87c0,0-0.1,0.1-0.1,0.1h-41.9c-0.1,0-0.1-0.1-0.1-0.2l27.5-88.4
31
+ c0-0.1,0-0.2-0.1-0.2C59.7,230.2,0,283.6,0,359.9V375v141.6c0,0.1,0.2,0.2,0.2,0c29.4-87,111.7-141.9,208.7-141.9h89.3l0.2,0.3
32
+ h31.4C439.7,375,525.7,285.2,518.9,175.6z"/>
33
+ </g>
34
+ <g>
35
+
36
+ <linearGradient id="SVGID_00000059312317453721029260000015694281937446923931_" gradientUnits="userSpaceOnUse" x1="149.2106" y1="391.7388" x2="149.2106" y2="579.0612">
37
+ <stop offset="9.705206e-04" style="stop-color:#0000FF"/>
38
+ <stop offset="1" style="stop-color:#00C7FF"/>
39
+ </linearGradient>
40
+ <path style="fill:url(#SVGID_00000059312317453721029260000015694281937446923931_);" d="M208.9,374.5
41
+ C111.7,374.5,29.2,429.6,0,517v2.2h158.7l0.3-101.6c-0.2-23.7,19-43,42.7-43h96.7"/>
42
+ </g>
43
+ <g>
44
+ <path class="st3" d="M333.5,217.4c-7.1,5.2-14.8,9.7-22.8,13.5C319.8,229.1,327.8,224.3,333.5,217.4z"/>
45
+ </g>
46
+ <g>
47
+ <path class="st3" d="M134.9,225.7l-0.1,0.2"/>
48
+ </g>
49
+ <g>
50
+ <path class="st3" d="M134.9,156.9l0.1,0.2"/>
51
+ </g>
52
+</g>
53
+</svg>
assets/PAILot2.ai
....@@ -0,0 +1,483 @@
1
+%PDF-1.6 %âãÏÓ
2
+1 0 obj <</Metadata 2 0 R/OCProperties<</D<</OFF[18 0 R]/ON[19 0 R]/Order 20 0 R/RBGroups[]>>/OCGs[18 0 R 19 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 17777/Subtype/XML/Type/Metadata>>stream
3
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
4
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 10.0-c000 1.000000, 0000/00/00-00:00:00 ">
5
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
6
+ <rdf:Description rdf:about=""
7
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
8
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
9
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
10
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
11
+ xmlns:stMfs="http://ns.adobe.com/xap/1.0/sType/ManifestItem#"
12
+ xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
13
+ xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
14
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
15
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
16
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
17
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
18
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
19
+ <xmp:CreatorTool>Adobe Illustrator 30.2 (Macintosh)</xmp:CreatorTool>
20
+ <xmp:CreateDate>2026-03-21T14:55:40+01:00</xmp:CreateDate>
21
+ <xmp:ModifyDate>2026-03-21T14:55:41+01:00</xmp:ModifyDate>
22
+ <xmp:MetadataDate>2026-03-21T14:55:41+01:00</xmp:MetadataDate>
23
+ <xmp:Thumbnails>
24
+ <rdf:Alt>
25
+ <rdf:li rdf:parseType="Resource">
26
+ <xmpGImg:width>256</xmpGImg:width>
27
+ <xmpGImg:height>148</xmpGImg:height>
28
+ <xmpGImg:format>JPEG</xmpGImg:format>
29
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEAAAAAAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAAAAAAAAEA&#xA;AQAAAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAlAEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXkP5z6+l1ewaBGeUNoBPer1BlcVjUg/yIeXh8Q7jNt2bg5zPwdN2pqOUB7y8&#xA;z+qWn++Y/wDgR/TNtwh03Ee9kHkXWofL3mS2vaLFayH0L0qKD0ZCAWNP5DR/ozE1mATxmuYczQ6g&#xA;wyCzsdn0VnPPTOxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV&#xA;2KuxVA65q9to+k3WpXO8VrGX49CzdEQe7MQoyUIGRAHVhkmIRMjyD5uu7u4vLua7uW53FxI0szeL&#xA;uSzUHYVPTOoxwEIiI6PJZchnIyPVRybW7FXu/wCWPmH9L+WYopWreadS2mqdyqj905/1k2J/mBzn&#xA;NZh8OZHQvU6LP4mMHqNmXZiuW7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq8n/OXzEJJ7fQIGqsNLm9p/OQREh+SksR7rm17Nw7mZ+Dp+1c+wgPi8yzcOjTBN&#xA;B1J9Cl15R/uPguFtX2NeTrXnXsoJVPdmzHOoAycHk5Q0xOI5PNL8yHFZZ+WfmH9D+Z4o5X42eo0t&#xA;ZxWgDsf3Ln/Vc8fYMcwO0MPFCxzi7Hs3PwZOE8pPec0L0bsVdirsVdirsVdirsVdirsVdirsVdir&#xA;sVdirsVdirsVdirsVdirsVdirsVdirsVQmrana6XplzqN0aQWsZkenU06Ktf2mOw98lCJkQB1Yzm&#xA;Igk8g+btRv7nUb+4v7kg3F1I0slOgLH7Ir2UbD2zp8WMQiIjo8lmymczI9VGKKWaVIYUMk0rLHFG&#xA;vVnY8VUe5JpkpSEQSejCEDIgDmX0JZ+UrKLycnlqWhhNuYZpF/369WeVa9D6pLjwOczLMTPj629Z&#xA;HBEY+DpVPn68tLiyu57O5XjcW0jQzAdOaMVantUbZ0uOYnESHV5XLjMJGJ6KP+e22SItgDT6G8je&#xA;YP075atbx2rdIPQvPH1o9mY06cxR6dgc5nUYvDmYvWabN4kBJP8AKW92KuxV2KuxV2KuxV2KuxV2&#xA;KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV5d+c3mMgW/l+BvtUub6ncAkQxn/ZAuQfBTmz7&#xA;Nw2eM9HU9qZ6iIDrzeV5unQs5/KTQP0h5ibUJVrbaYokFehmkqsf/AgM3sQM1vaWao8I6u17Lw3I&#xA;zPR7Zmkd+8e/OTQPq2rQa1Ev7m/AhuT2E8S0Uk/5cQp/sM3HZubYwLpO1cO4mPcXnebV0zO/yi8w&#xA;fUNffTJmpbamvFK7BZ4wSnXpzWq+54jNZ2lhuIkOjtuy89SMD1e1ZpXfOxV2KuxV2KuxV2KuxV2K&#xA;uxV2KuxV2KvNP+V8eWYtUu7K7tLlIYJnhhvIeEsbqjFfUIJRlDUqKBsVZVpX5h+SdVoLPWbYuacY&#xA;pmMEhr4JMI2P0DFWQ4q7FXYq7FXYq7FXYq7FXYqh9QvrfT7G4vrluNvbRtLKe/FBU098MQSaCJSA&#xA;Fl83avqlzqup3WpXX9/dSGRhWoUdFQeyKAo+WdPhxCEBEPJZ8pyTMigyQASdgNyctanuXlxdO8j+&#xA;SIJtVb0JZj69ylCZHuJVqIlXuyooX/Y1NBU5zmUyz5TwvT4RHBiHFt+tJT+d9p9ZoNIl+q12kMyi&#xA;XjX/AH3xK1p29T6cyP5MnXMON/K0L5GmR6kdK88+TbpdOcSNIpMAaivFcx/Eiv8Ay77HxU9aHMWP&#xA;FhyC+YcyXDnxGuReCkEGhBBHUHYj550gNiw8qQQaK6GaWCaOeFzHNC6yRSDqroQysPcEVwTiJAg9&#xA;WUJmJBHMPpDy1rUWt6HZ6nGAPrCVkQdFkU8ZF/2LgjOXy4zCRiej1uLIJxEh1TLINjsVdirsVdir&#xA;sVdirsVdirsVdirsVedax+RPky85NYm40yUj4RFJ6kfLxZJubfQrDFWDaz+Qfmi15Npl1b6lEPso&#xA;a28xr/kuWj2/4yYqxl0/MbyfXl+kdJhQ0JBf6ryX3HKB/wAfuxVP9J/PjzlacVvo7bUo6gszp6Mp&#xA;9g0VEH/Is4qzXSPz/wDLFxxXU7O50+Qn4nQC4iUePJeMhp4CPFWa6P538paxxXTtWtppXNFgLiOY&#xA;n/jFJxk/4XFU7xV2KuxV2KuxV53+cmpagml2+m20ExtZ29W+uVjcxKsZHpxtIBxBZ/i6/s++Z/Z8&#xA;Y8dyPJ13aUpcFRB35vHlZWFVIIPQjN887TJfy80H9M+abWKReVpan61cg9CsRHFTXYhpCoI7rXML&#xA;X5uDHXUud2dh48lnlHdPvzqurhtfsbVifq8VoJY17c5ZHVz90S5j9lxFE9XK7XkbiOjzzNq6Z6D+&#xA;S1zcL5jvbVSfq8tm0si9ucUqKh+6Vs1XakRQPV3HZMjxSHRLvzS0A6X5nkuI1pa6nW5jPb1a/vl/&#xA;4I8/9llvZ2bihw9YtXaeHhnxDlL72H5sHWPSvya8wejeXOhTN+7uv9ItP+MqLSRf9kgBH+qfHNR2&#xA;lh5TDu+ys/OB94et5qXcuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ksa1n8t/JOr8mu9JhWVq/v&#xA;7cG3kqe5aIpyp/lVxVg2s/8AOPdg/J9G1WWA0qIbtFlUnwDx+mVHzVsVYNrX5O+e9N5n6guoQL1l&#xA;s3EtQfCNuEp96JiqT2Pmjzn5cn+rW9/eadLEamzlLBVPQ1t5gV+9cVZhpH5+earXiupWttqUY6sA&#xA;beU/7JOSf8k8VZrpH59eUbrimow3OmuftOyevEPCjRVkP/IvFWa6P5s8tazxGl6nbXUjAn0UkX1Q&#xA;B/NEaOv0jFU1xV2KpTqflPy1qhZr7TYJpXNWn4BJf+RqcX/HLIZZR5GmueGE/qAKzy55R0Xy99a/&#xA;RkboLtlMnNy5ASvFQW+Kg5HqSd8OXNLJXEeTHDghjvhFWl/nzyRH5ms42hdYNSta/VpXrwZWpySS&#xA;gJptse335ZpdScUr6NWr0ozRrqHlf/KsfPXren+ijxrT1fXtuPz/AL3l+Gbb+UMVdXTfyZmvkPm9&#xA;B/LjS/LuhzXWn/pW0u/MjtwvLeKRecYiFfTjRqOVWp5Nx3P+rtqtVqTll5B3Ok0owxrmSmP5meX/&#xA;ANL+V53iTld2H+lQUG5CA+onj8SV2/mAwaTN4eQHonW4fExkdejwXOkeVRGn39zp9/b39qaXFrIs&#xA;sVagEqa8TT9luh9sry4xOJierbhymExIdH0ppmo2upadb39q3K3uo1ljrSoDCtGArRh0I7HOYlEx&#xA;NF62MhIAjkUTkWTsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqGv9N07UIfQv7WG8grX0p4&#xA;1lSv+q4IxVhesfkl5F1AFreCbTZTWr2sh4k9vgl9RAB/kgYqwXWf+cftegBfSdQgvkAr6Uytbyf6&#xA;q09VG+ZK4qwbWvI/m3RuR1LSbiKNCCZ1X1YR4Eyxc0H0nFV2keffOOk8PqGsXKRp9iF39aIDwEcv&#xA;NB9AxVmuk/8AOQHmO34rqdhbXyDYvEWt5D7k/vU+5RirNNJ/PXyVecVvPrGmyEfEZo/Uj5eAaEyG&#xA;nuyjFWa6V5i0HV15aXqFve/DzKwyo7KP8pQeS0ruCNsVTDFULq2owaZpd5qM/wDc2cMk8grSqxqW&#xA;I3+WKvDvyNtp9U88ahrN0DJJDBJNLJvQXF1IPiJ/yl9Tr/DFXveKvGfMX5SeYIr+5m0iKG5sJJGa&#xA;2gWQJKiMahCJeCUWvEfGc3GDtCIiBLm6PUdmSMiYVRYbqWi6xpf/AB0bKe0Xcc5Y2VDTrR6cD9Bz&#xA;PhqMcuRDr8mlyQ5xL0z8mPMHq211oUrVa3rdWgrX907ASqPZXYH/AGWartHDUuIdXb9l5+KJgej0&#xA;zNa7V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVI9Z8jeUNaLPqWlW80rElp&#xA;1X0piT1rLHwf8cVYLrH/ADj7oc1X0jUZ7JzX93OFuI/YCnpuPmWbFWC6z+SvnrT+TwW8WpQqOXK1&#xA;kHID3SX02J9lBxVhl9p2o6dcCK/tZrO4U1VJ42ietOoDgHp3xVO9J/MfzvpQVbTWJzEoCiKci4QK&#xA;OigTB+IH+TTFU41/84/MeueXLjRL21th9Z4LJdw842Co4c/AS6ktxAPTvtiqcfkv5y8p+XrXUYtX&#xA;u2tLy8mTgxjd4zFGvw/Egah5O/2qDFXtWma7ouqoX0y/t71QAW9CVJKA+IUmn04qjsVdiqXReXNB&#xA;hv49Qg0+CG9j5cbiKNY3PMFTyKU5bH9rJccqq9mHhxu63THIs3Yq7FXYq7FXYq7FXYq7FXYq7FXY&#xA;q7FXYq7FXYq7FXYq7FXYq7FWL/mVd+Ybbylct5fink1R3iWJrVTJIihwzsFAYn4VK/Tirx2y/O38&#xA;wNPlMV60F467SJdQCOQfRD6FD8xirKdM/wCch7QlV1TRpIx0eS1lWUk+IjkEVN+3P78VZNb/AJs/&#xA;lrrNube9uVjSQ0e2v4G4Edix4vFT/ZYq8G84T6ZP5q1WTSo4YtO+sulqlqFEHCM+mGjCfDxfjy22&#xA;Na4qk+KuxVyScJQyNxlTdSDRh7im+Kso0r8zfPemUEGsTyx9DHckXIIHTeYOw+gjFWZ6V/zkLq0d&#xA;F1XSoLgf78tneAj/AGL+tX7xirM9J/O7yJfUWeafTpD0W6iNCe/xQmVR/siMVZnp2saTqcbSabe2&#xA;97GtOT20qSqK9KlC3WmKovFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXnGu/m7+&#xA;jPMN3p8Ngl5Z2reiZhKY39Vf7zqrghWqlNtxWubDDoDOAldW63N2lHHMxq6TLTfzd8o3dFuGnsHP&#xA;aeMspPejQmUf8FTK56HLHpfubcfaGKXWveyCex8seZbCOaaC01eycMIZisc6bHi3B/ioQy02NQRm&#xA;IQQaLmAgiwwzWvyI8n3gZ9Pe40uU/ZEb+tFXvySXk/3OMCXn/mT8kfNOkW095bTQajZ26PI5QmKb&#xA;ggLFvTf4eg6BycVed4q7FXYq9r/J/UPIo8pHS9WurFrye6luZbK9CChIES8fWAVyUjB+GuxxVlmp&#xA;/k/+X+oAuun/AFN3PISWcjRAA70WOpiA/wBh8sVYlqv/ADjxAeTaRrDoB9iG8jDknwMsRjp/yLP8&#xA;cVYhqn5KefbHkYrWHUI1HIvazLWg/wAmX0mJ9lB9sVYlf6Rrmjyq9/ZXOnyL9iSaKSH/AIFmC1+g&#xA;4qnelfmh5803aHWJ5k25JdUua0/ypg7j6GGKs10n/nIXUU+HV9Jhmr1ltHaGnj+7k9Wv/BjFWZ6V&#xA;+dfkK/2luZdPkNKJdxEf8PF6sY+lsVZjp+raXqURl068gvYhSslvIkqivTdCRiqKxV2KuxV2KuxV&#xA;2KuxV2KuxV2KuxV2KuxV2KpL5x14aF5du9QBHrqvp2qnvM/wpt3ofiPsDluHFxzEWnPlGOBl3PnU&#xA;liSzEsxNWYmpJPUk504AAoPJEkmyqW1tPdXEVtbp6lxO6xQp05O5CqK9qk5GcxGJJ6MscDOQiOr6&#xA;S0LSYNH0i00yA8o7WMJzpTm3V3IqaFmJbOXnMykSer12OAjERHRHZFm4gEEEVB2IOKvn/wDML8n9&#xA;V0u8lv8AQLd73SZSXFtCC81vU14cB8ToP2SKmnXxKrzRgVZkYUdDRlOxB8CMVTbyv5Y1TzLq8Wm6&#xA;chLMR68/EskMZO8knTYDoKjkdhvirNNR/IPzfbqz2dzaXqr0QO8UjfJXXh974qlcHlz83PKzgWVr&#xA;qNsoowSyJuYjToTHAZkPyZfoxVONI/PLzpZzx2mp2kGoyMwAWRTbTsSaU5IOA3/4qxV77iriAQQR&#xA;UHYg4qx3U/y68j6n/vVotty7yQp9Xc/N4TGx+k4qxDVP+cf/ACzOC2nX11YyE7K/CeID/VIR/wDk&#xA;pirEdU/IPzZbcmsLq11BF+ytWglYeysGQfTJirEtQ8j+d9FlM1xpN3A0O5uYFMqqOtfVgLqB/ssV&#xA;Rmlfmp590w8I9WkuEU/FFeAXG47F5AZR9DDFWaaV/wA5DXq0XV9Ijl8ZbSRo6DvSOT1K/wDBjFWZ&#xA;6V+dPkK/osl3Jp8h6JdxMv0l4/UjH0tirMbHUtO1CH17C6hu4a09WCRZFr1+0hIxVEYq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXjn5xa/wDW9Yh0aJqwaePUnA6GeRaiv+pGdv8AWObjs3DQMy6PtXPZEB7y89za&#xA;unZ/+T2gfXNbl1eVa2+mrxhJ6G4lBG3+pHWv+spzV9pZqAgOrt+ysFkzPR7Nmmd67FXYq8788+fN&#xA;Y8tebIIYFS50+SzjkltJPh+IyygskgHJWooG9R7Zn6XSDLA70Q67V6w4ZjawQpj8y/y/1Qxyazph&#xA;SZRxaS4to7kKNzRSnqOVr/k/RkZ9n5RyFsodpYjzNJz5R86eXNU1J9H0Oxa2gjge5Z/TSGMkOiUV&#xA;ENann1IGVZdNPGLk3YdXDJIiPRl+Y7kuxVTmt7ecIJoklEbrJGHUNxdDVWFehB6HFVTFXYq7FXYq&#xA;7FXYql+qeXdA1YH9J6dbXppxDTxJIwH+SzAke1MVYhqf5H+Q701giuNPY9TazE1+icTKPoGKsQ1P&#xA;/nHnUE+LS9XhmrX93dRtFTw+NDLX/gRirFL38rfzF0aX6zDYSuyGi3WnyB3qNwVCETDxB4j78Vbt&#xA;fzL/ADJ0CYW9zez8lO9rqUXNiR2YygTfcwxVl2kf85C3fJY9W0ZZixAMllIVah2osUtQT4VkGKva&#xA;sVdirsVdirsVdirsVQWtarb6TpN1qVx/dWsbSFa0LEfZQe7NRRkoQMiAOrCcxGJJ6Pmy6uri7upr&#xA;u5bncXEjSzP0Bd2LMQO256Z1GOAjEAdHksmQzkZHqpHp3PsBU/cMkTTACzT6I8k+X/0F5btLF1Au&#xA;ivq3hFD++k3cVHXj9gHwAzmc+XjmZPWafD4cBFPcpb3Yq7FXi/5z/wDKWW3/ADARf8nps3XZf0n3&#xA;ui7W+uPuYFmzdQz38mP+Usuf+YCX/k9Dms7U+ke92/ZP1y9z2jNK712KuxVZcCcwSC3KLcFG9FpA&#xA;WQPT4SwBUkV60OKvL7P857y2me21rSAJoXaO4a2fiysp4soik7gjvJmy/k4yFwOxdUO0xEmM40Qy&#xA;fTfzR8mX3ENemylbrHdoYgPnJvF/w+Y09HkjzDl49bilyLJ7W8tLuET2s8dxC3SWJg6mn+UpIzHI&#xA;pyQbVcCXYq7FXYq7FXYqpXNra3ULQXUKTwt9qKVQ6n5qwIxVj0v5aeRJL6G+/Q0EVxBIk0foc4U5&#xA;xkMpMcTJG243BWh74qybFXYq7FXYq7FXYq7FXl35z+YKLaaBC32qXd5T+UErCh9iwZiPZc2fZuG5&#xA;GZ6Op7Vz1EQHV5Xm6dCyz8s/L/6X80QvIvK00+l1PXoWU/ul79X39wpzA7QzcMKHOTsezcHHks8o&#xA;vec0L0bsVdirsVeL/nP/AMpZbf8AMBF/yemzddl/Sfe6Ltb64+5gWbN1DPfyY/5Sy5/5gJf+T0Oa&#xA;ztT6R73b9k/XL3PaM0rvXYq7FXYq8V/N3QPqGvpqUK0ttTXk9NgJ4wA+w/mXi3ueRzddm5riYno6&#xA;HtXBUhMdWCZs3Us6/KLXxp/mB9Nlbjb6ovFa7ATxglNz05LVfc8Rms7Sw3HiHR23ZeepGB6va80r&#xA;vnYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqp3VzBa2011cOI4IEaWaQ1oqIOTHbwAwgWgmnzZrerT&#xA;6vq93qc9Q91IXCE14p0RP9igC502DF4cBF5PU5vEmZIHLmh7r+VmgfovyxHcSrS61Ii5kr1EZH7l&#xA;f+A+KnYsc5zWZuPIe4PUaHD4eMd53ZhmK5jsVdirsVeL/nP/AMpZbf8AMBF/yemzddl/Sfe6Ltb6&#xA;4+5gWbN1DPfyY/5Sy5/5gJf+T0OaztT6R73b9k/XL3PaM0rvXYq7FXYqx/z35f8A055aurSNeV3E&#xA;PrFn4+rGCQo/11JT6cu0+Xw5iTRqcPiYzF89A1Fc6cF5Mil8UssMqTQuY5omWSKRequp5Kw9wRXI&#xA;yiJAg9UwmYkEcw+j/LWtRa3oVnqcdAbiOsqDosinjIv+xcEZy+XGYSMT0euxZBOIkOqZ5BsdirsV&#xA;dirsVdirsVdirsVdirsVdirsVeffnD5g+qaNFpEL0n1FuUwHUQRkE18Ob0HuOWZ/Z+HinZ5Rdd2l&#xA;n4MfCOcnjeb55xOfJ+gnXfMVpp5UtblvVu6doI93rTpy2SviwzF1ebgxk9S5eiw+JkA6Dd9GAAAA&#xA;CgGwAznHqXYq7FXYq7FXi/5z/wDKWW3/ADARf8nps3XZf0n3ui7W+uPuYFmzdQzz8mWH+Lrhe50+&#xA;Ugewmg/rms7T+ke923ZP1n3Pac0rvnYq7FXYq7FXgf5kaB+hvNFwI142l9W6tqdBzP7xNqD4XrsO&#xA;ikZv9Bm44V1i832jg4MljlJi2Zzr3pX5M+YPRvLnQpm/d3P+k2lf9+oKSL/skAI/1T45qO0sPKYd&#xA;32Vn5wPvD1vNS7l2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV5p+YH+BP8Qn9PfX/rvoR8fRp6fpVbjx&#xA;5f5XKtO9cz9L43D+75fB12s8Di/eXfxY3/yCT/tZ/wDCZlf4X+KcT/A/xbMvy2/wN9bvf0B6/wBc&#xA;9NPV+t05+nyP93Ttypy+j2zD1fjbeI52i8Hfw/x82e5hOc7FXYq7FXYq86/Mb/An6bg/T31v699W&#xA;Xh9Wpx9L1H41r35csztJ41Hw+XwdfrPAseJz+LFf+QSf9rP/AITMv/C/xTh/4H+LZP8Al1/gL/EM&#xA;v6B+ufpD6pJy+s04ej6sXOlO/LhmLqvG4R4nL4OXo/A4j4fOvN6RmA7F2KuxV2KuxVhv5lf4Q+qW&#xA;P+IfWr6j/Vfq3959kep124/Zr70zK0vicR8Pm4es8LhHicmBf8gk/wC1n/wmZ/8Ahf4p1/8Agf4t&#xA;MvLf/KtP0/p/6O/SX1/10+rcuPHn/lcd+NK8vauU5/zHAeP6fg3af8txjgvi+L13NY7Z2KuxV2Ku&#xA;xV2KuxV//9k=</xmpGImg:image>
30
+ </rdf:li>
31
+ </rdf:Alt>
32
+ </xmp:Thumbnails>
33
+ <dc:format>application/pdf</dc:format>
34
+ <dc:title>
35
+ <rdf:Alt>
36
+ <rdf:li xml:lang="x-default">PAILot</rdf:li>
37
+ </rdf:Alt>
38
+ </dc:title>
39
+ <xmpMM:DocumentID>xmp.did:b3cdfe6f-db41-4457-b701-9259963a3b0a</xmpMM:DocumentID>
40
+ <xmpMM:InstanceID>uuid:efceb3e1-aab0-d246-b60a-b06cca0e794b</xmpMM:InstanceID>
41
+ <xmpMM:OriginalDocumentID>xmp.did:b3cdfe6f-db41-4457-b701-9259963a3b0a</xmpMM:OriginalDocumentID>
42
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
43
+ <xmpMM:Manifest>
44
+ <rdf:Seq>
45
+ <rdf:li rdf:parseType="Resource">
46
+ <stMfs:linkForm>EmbedByReference</stMfs:linkForm>
47
+ <stMfs:reference rdf:parseType="Resource">
48
+ <stRef:filePath>/Users/i052341/Desktop/0724_AOPAapp.jpg</stRef:filePath>
49
+ <stRef:documentID>0</stRef:documentID>
50
+ <stRef:instanceID>0</stRef:instanceID>
51
+ </stMfs:reference>
52
+ </rdf:li>
53
+ </rdf:Seq>
54
+ </xmpMM:Manifest>
55
+ <xmpMM:Ingredients>
56
+ <rdf:Bag>
57
+ <rdf:li rdf:parseType="Resource">
58
+ <stRef:filePath>/Users/i052341/Desktop/0724_AOPAapp.jpg</stRef:filePath>
59
+ <stRef:documentID>0</stRef:documentID>
60
+ <stRef:instanceID>0</stRef:instanceID>
61
+ </rdf:li>
62
+ </rdf:Bag>
63
+ </xmpMM:Ingredients>
64
+ <xmpMM:DerivedFrom rdf:parseType="Resource"/>
65
+ <xmpMM:History>
66
+ <rdf:Seq>
67
+ <rdf:li rdf:parseType="Resource">
68
+ <stEvt:action>saved</stEvt:action>
69
+ <stEvt:instanceID>xmp.iid:b3cdfe6f-db41-4457-b701-9259963a3b0a</stEvt:instanceID>
70
+ <stEvt:when>2026-03-21T14:55:40+01:00</stEvt:when>
71
+ <stEvt:softwareAgent>Adobe Illustrator 30.2 (Macintosh)</stEvt:softwareAgent>
72
+ <stEvt:changed>/</stEvt:changed>
73
+ </rdf:li>
74
+ </rdf:Seq>
75
+ </xmpMM:History>
76
+ <xmpTPg:NPages>1</xmpTPg:NPages>
77
+ <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
78
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
79
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
80
+ <stDim:w>379.219775</stDim:w>
81
+ <stDim:h>219.720157</stDim:h>
82
+ <stDim:unit>Points</stDim:unit>
83
+ </xmpTPg:MaxPageSize>
84
+ <xmpTPg:PlateNames>
85
+ <rdf:Seq>
86
+ <rdf:li>Cyan</rdf:li>
87
+ <rdf:li>Magenta</rdf:li>
88
+ <rdf:li>Yellow</rdf:li>
89
+ <rdf:li>Black</rdf:li>
90
+ </rdf:Seq>
91
+ </xmpTPg:PlateNames>
92
+ <xmpTPg:SwatchGroups>
93
+ <rdf:Seq>
94
+ <rdf:li rdf:parseType="Resource">
95
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
96
+ <xmpG:groupType>0</xmpG:groupType>
97
+ </rdf:li>
98
+ </rdf:Seq>
99
+ </xmpTPg:SwatchGroups>
100
+ <illustrator:Type>Document</illustrator:Type>
101
+ <illustrator:IsFileSavedViaInstantSave>False</illustrator:IsFileSavedViaInstantSave>
102
+ <illustrator:CreatorSubTool>AIRobin</illustrator:CreatorSubTool>
103
+ <pdf:Producer>Adobe PDF library 18.00</pdf:Producer>
104
+ </rdf:Description>
105
+ </rdf:RDF>
106
+</x:xmpmeta>
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+<?xpacket end="w"?> endstream endobj 3 0 obj <</Count 1/Kids[5 0 R]/Type/Pages>> endobj 5 0 obj <</ArtBox[8.95956 4.50438 372.618 212.305]/BleedBox[0.0 0.0 379.22 219.72]/Contents 21 0 R/CropBox[0.0 0.0 379.22 219.72]/LastModified(D:20260321145540+01'00')/MediaBox[0.0 0.0 379.22 219.72]/Parent 3 0 R/Resources<</ExtGState<</GS0 22 0 R>>/ProcSet[/PDF/ImageC]/Properties<</MC0 18 0 R/MC1 19 0 R>>/XObject<</Im0 23 0 R>>>>/Thumb 24 0 R/TrimBox[0.0 0.0 379.22 219.72]/Type/Page/PieceInfo<</Illustrator 8 0 R>>>> endobj 21 0 obj <</Filter/FlateDecode/Length 694>>stream
129
+HKìVËn1 Ýç+üãkÇq[ZT±¨P邨hY´  Ô¿ç83ím{YV‹ÑŒØÇÇ9If÷þˆv§GBoŽ(Ý&!!kƒs¦¬ƒ[¦»Oé#}ÁÐîä\èê[*M)¦åê´¸ro¥Õf´hç^ªšº¸I»w7BÇ_ÓYz{ŠÔ»HW ³ µ!lxËs@@pÅÓéîêû–Vl%µÁêÖñQx¨ÕÀŒ¡›”•«ÔÆ.•®S©œk&v5Ø­± àœ68Tœ%wTP¹yx¼ñðN­r0›vw {Tòˆ¯„4*ƒ¾'¯\€»˜’uVís© ‰ŠM«*]$Øfëhs2ä“iKÏtŸ>§K´F&Å'I8;ý uÔ îç!‹=Ձ nÀ¾'Š®x¸!qK.ì^ÆÍê´!$C„°´h@7f‘ÅØBÊÏ6Áïç2ü!¥¬}.ôð`?<©­cA*†¶–¼¯®² :¬wvõV|à»Ía`·9Ú¡†‚Z ›݄Ç8ƒm°q¬4<c†.™§9*v~vˆ`Š®Oµ-Pg#8ÚTáݶ˜ hEtÈl› Øá%sCÏ@½ ósŽÓ=@אmt0èDgC´÷iñ(8ª*[U‹Ç\x¦“uöH®L8VËڃ9£ƒl CñӁ)¥RñIàzۛÿÿÛÿôxxv)<ß î=ÆÙÒ>ö[”–Ê=Šƒ±¬{ÎZ?x_LÆ9ª٘>Äo¦ÄÔí{Ù_dÜ'^‘7[¶(™™š¿“ÇÁé-òÂÒ®y”=Ãn‘ÌÒ×KˆqÆ%òp^ŠÔmÁ/_9ã¯ï™\qÔù2ïܵPA‹ë°OÍâ.“êcK}…”OkÿOgé'ÿÿÿÿü Þ÷ endstream endobj 24 0 obj <</BitsPerComponent 8/ColorSpace 25 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 27/Length 235/Width 47>>stream
130
+85#22!>:)/#XnD$*0%"GSJ'BoJWQ;^>Q:tf[^G64!;F$2!1iU%U,q/q,Q+.1b]i\!
131
+0ChIiP2@5mnPC9)L8Je`)eOO\j:ri/^?bCGV#SN$*nI^*JcD)nkCOP$6I=:17G"B'
132
+R7f+>[qEh@#9SRE/^oZXrgYo^R8tt=mCB\WV`h;'=B#XbKdH'pD0S^fE=JmIO9G6;
133
+8llidT8@QYH*^KJ"TSQ&rr<$!s8N0$j?a@@~> endstream endobj 8 0 obj <</LastModified(D:20260321145540+01'00')/Private 9 0 R>> endobj 9 0 obj <</AIMetaData 10 0 R/AIPrivateData1 11 0 R/ContainerVersion 12/CreatorVersion 30/RoundtripStreamType 2/RoundtripVersion 24>> endobj 10 0 obj <</Length 1569>>stream
134
+%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 30.2.1 %%For: (Nott, Matthias) () %%Title: (0724_AOPAapp.jpg) %%CreationDate: 21.03.2026 14:55 %%Canvassize: 16383 %%BoundingBox: 130 285 495 496 %%HiResBoundingBox: 130.834332728911 285.475029183524 494.492417551866 495.150708247466 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 1 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 121.874765873835 282.846135718833 501.094540419797 502.566292862191 %AI3_TemplateBox: 305.5 396.5 305.5 396.5 %AI3_TileBox: -91.5153468531844 113.206214290512 691.484653146816 672.206214290512 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 2 %AI17_Begin_Content_if_version_gt:24 4 %AI10_OpenToVie: -12.0634715853521 670.213357447419 2.29848638625588 0 8489.12398762921 8258.01054149585 2542 1383 18 0 0 9 51 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: -12.0634715853521 670.213357447419 2.29848638625588 2542 1383 18 0 0 9 51 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 72 %AI17_Begin_Content_if_version_gt:24 4 %AI17_Alternate_Content %AI17_End_Versioned_Content %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 11 0 obj <</Length 52841>>stream
135
+%AI24_ZStandard_Data(µ/ýXœäúû¾–(Dhõï1ú©fT¼Áã 3øÒ–/v,²”ìé‚
136
+D»g ¶ ûãÎÆOä" òÝÇpÅÃ0 Ã>½1.ö±“ÝcúÃRn;ÁqÄ0ýéw
137
+îS5Só4MӛägzҋôÝkŸŽdH~$÷ã¸GUDEӇ#?AŒƒL?ô3?Û\ݨƺîœÄÀžfØÉ®IõMžŠ¨E,Cñ?±ët Å/üvê1 ûæŸþÔûwrÓo‘«:=ÍU=ÆÍ ‚ÜÔ&7·©MÕkS=}êQ¦é½½‚]%·GO?~'5:¦¤8†WET<E/š")Žbø‰< Ï3GP%A7ù‘á÷©]iÇøÉÏ>¢=QTÅÒT« őIÕQUQCðë*ßêÖ*¦¦hz¦§éS2%G1 ÓL¿žò”«¨Š¦(–¢è‰š¤ˆ†ú¡å(G·FÕS=ÏÓ$ÏQ<{çÏPnŠš˜lnÉ&iÃ:&i˴ޙ³0ÛÏtòqo rü¶&;}›äæZ ÉO|“áÞ½ä&ŰÓ©C’Ô"7ÉOì4¦€Å&iË>Lë­¹îúÓ µ¨GMj¯M}jT§Z՘Þ{óÝ÷·Ánq›Ü~›ûÜèN·º5ߜóÎ?ò‹|ä$÷Üä'GyÊU®ûî¼÷þu°‡]ìØØÉî»Ùώö´«]ûã_ÿ¾üÂOüƏüüg~ç‡~é§~Ü ;ø ‚"8‚$èA<ALAÄt¸Cöð Á0 Åp ÉЇfx†h˜†j¨Å-r±‹ŸŠ¡(Š£HŠ^4ÅSDÅTTE=}üFp GqÄÆ‘ýhŽçˆŽé¨ŽšÜ$';ù‘ ’"9’$éI“<I”LI•Ô~{î»ÿ<èC/úѓÞ{ӟõ©W=¦Ímr³›Ÿ š¡)š£IšÞ4ÍÓDÍÔTM}ýüNð OñOòô§yž'z¦§zjt£í臂hˆŠ(6¢$êQ=QMQÕéNyÚÓ/Ó0Ó1%SŸšé™¢išª©V·ÊÕ®~*¨†ª¨Ž*©zÕTOUSUUÃL¿´§;թЦ(Šž¨‰z”DG4DAûЎnT£é‰žçižþ$Oñ Ïïä§>S5M“4E4»¹MÕ£Þô¤ýç¹×>%O’$E$;©Ét<GŒÅû¨ÇT<EREPìâÕ ͐ Å {¸CÕ`G¿3üÀ´ch7ê<¹ÈӍb^Ôá×ùÆF?ò­’)zŠà&u*b©ØCŽ~T?üú‡ñ/å(ÉǍqôô˜éMïýj¯’˜Š’'y’f'ÇqG,ܨˆ*˜‚(x‚' Ž ØÁôCù‡ù°ûäæøñÎyŠ™`ªQ~ºo­KLMÑÓÄLOŽ¢š!øu¾MmjÓ¦êUŸúÔ£õ¨?ýéMozÓ{ï½÷¤ýèE/zч>ô ýç?ß}÷Üs¿ýöÚ«dJ¦dJ¢$†’'i’žô$IŽäHŠdH‚$H~d'9ÉÉMjRÕ1ÑñÍя~GqÇpGpüÆ>ò‘{Ô£*¦"†Š§hŠ^$ÅQÅPÅOì"·¨E-ªa¢áš¡Ép Å0 ¿°‡<Ü¡SMЃ#8‚!‚ØAŒƒT¿ôC¿ó3?ÿŸø…ø}_ÿö§?µ§íg7;ÙÇ.ö°ƒýë½ó®»ÊSŽr“{î9ÉErcï|sÍ5W7ºÏ}nsûMîq‹;Üßî»o¾÷Ö[Õ©>µ©½&5©G-êPƒԟîšë­5&€)`(3ã™Î°†*CýÖêºF™ÝÏ¢Ö¸âšY‡@ÀNÖøðºêd(÷õ­÷ü3ûêdñG¹lj5¯›ÐüݵÝÌ.»fâÕ]Û€ÍÈ(÷·f¶
138
+ÀΧËñ?±+xUlÛ®çû9ö«yݸñ;³¨4s7²‰Í0²Fæ¾lʽd«Ó¼ðU¨4kß×Ó¾¯'[ɯØÌâ?ÏëéÏò€ÎoO쯛–̶¯©5 ¿íভøM}”‘5²¯­Ú€Ùµcd •ËžÖؓ1²Æ|ú &ƒ õ`ãw>}{Sî~½qÅeU¯vC 0•ËÎ.oÜ·€¿æßQ½ío¶ “g÷·Zï‰rÓmÃ:šNkÍIâÛýó¼¶*ÿöîP$INjNî­Çn̸ˆbã
139
+IŒ¸¬Š ¾jÝl"Ÿ¨OB¹)äÅo؟W7þsëIâÞ`FŽ;ëcßÿ@ž#H~ûõÖÝò1ۜä¡8’ïŽ¿1ÓÙ8‚ ÇŽßHòŽgäþÄïÁÞ7ï´f›ƒÁ-~=Ôߐ,òYÐëq?l@Òûâ7ìË>™U¤¤KšÝ?»ïIrYÕ7IâŽÿ€5ÓzŒó«}åϙ¿*^={mÕ9ö$°ý¨WCþv=u¾*^3¤gyfÝOüÛGëïë̱ÿî[Eøl€ÏÅ0 ÷~»ƒá7~Ý&ÌoP“üÛ<Ô¼ë{gß7îŽá×Á v›„´¬ìB²g`êþ絅[ßCnŽœäav\ƒ™HŠäþô~¤î¶³ÞÇq‹`ßá7v|äØÇ.Ž`(~âØm¾³ˆÌŠ×üƍ÷eYÕç(0t1+œmÃt‘U.;Ï¿óUkëB/~òÈW­ò‡Ô/~Ãv‰¿©õ*@µìË$ñ}ñ;›×Vüª¿eUxñÆ:­­™ð¶íeëì~ÕªÉÜuÀ™EäømßS–ÿé7³û[¯Ó‹n†ŸøñQ‹ÜH~YŽÅýqòë>òË>öq“\ƒâׁ#Ïö&G.òÞ¿>vò簖mÃBòË@òËÀ‘gºï,"à5U.‹r_¯¹mX{¸³È€•å5€»žÛ†`äÛYÈ5ïºî6Ï"^Q÷e*¸¡ƒáÕo <éã¢fd‘ßάgÛ°#kÈ+»šçU“=æù-`d‘øU· ÛïtÏ"îËÊñ‘Æ‹ß6LwÏFüÎk<˯¶½dY$~çõÇç¶a™î:ä›^”‡t6ÚëG‘AJ'»¥ÆkPÇ{ …yÇ6§rŸüm˜B«”Sۍ¡át>Os_ÆZ؜
140
+¡¤Ö¾ÔV¥7´WTÐÐTVÉi†ÕC£¤#ˆæ(hh݉Ó4*h³ÌãXÎÌc¦wŒÏ¨ãð§²;Š>3@E7 eÃXÉúQbDWài\ –Þª Å[(ÌÞÑ.(BFÃ¥/3þ(–ÜXKn‚)Y]þºÇè¢õœðƒU·xOZü‹ Õ #@-þ\Ìev4ĝûx-T{DjÚqâ´ Zü1‰cËÀÀ‚³Þ’ÓÈLï6L„"=´‡lah•?4é¡m݉Ó, «‡æòÀ O öóBpž¦¯á“QٝôRàÉ*Ø´5Àýa<v
141
+O|[ p¦‘¹ü4N ìój•dÅK¬÷V…“WêFJÆÃ,œ%Õàä+ogžé …@7LÔ©Þ*…“sÉ)¬¸ zI?)JKM@_˜û%jGáäÉÝGr/j°Hi!”ôŽ;Ř Š‚’9êN„”,Pöº ƒ;`É1Džæ ÑАæ¡u"/NëR¥†¶bWL(hh¬’Ó8 ¢ XzC[…œŽG>®á<Íɍ÷¨4ž  §üåëG¹@XŽw¸`V{ÃROIÑ ׇÂ-[dÊ pa ,9”î⫖  ­0!ûhö†„…,)J—%ƒÉÇBÁ’SY£t/4œ§=h‰%°ä6ì‘}Ô{ú(8^.gÇ{Y$Ûûâ=lð={_¼¤‚rW—͐Pl»‚Hñ©è†•_—Í^7#/þâ3î3vv}¨9™€ßÂl{v¶çM¹ӋiÛuw¦·¡mß*~¿ÿ?îLoC»®­ fYrgzTîÕÊ¢™Ïf—•t¦·Aþò«ý¨·…‚ᮝåv–a¸å†»†Iã¸E4u_µ¶Ø.†a=Æ0ÿlŒfLê»lê£t1 ¿«.†á.†aTgzL¼5³&yíLoƒ6½ q{Ò/·¬Óښº¸ÝÏÆÄï
142
+fÛÜ¡â“*~UñûÛuÿv=É-ìžNr‡ŠOs‡ŠO«¼¶ñðv¨ø4`–õÌΦ·á»l›ú(S|b¿j…ãŽÕR™´FýߚÚ9îR©·cµTð›ŠáÕÍnÊô’»ÙMµ?Ào;fM ¯ªïÎî{:í¶“áø£Ö•ÜÉðüåN†áw°€XÕÁæS `ÛS `gw}O_~¡à·ƒü™]¿äÐÁZÓêþ“ûJÉ®»vrŒŠYZ§ýg—íZ§·ÕµN<@Öm :ŒQ†úóúž™é#d]§û¬æ·k´éu6i*þ›ö `7š_<¼º(ÖÀ»ê¬æV}™¤rÙ¯æœUtÃÈ$¬çË®]¶?<ÀòQ-»º¦Ökåùó÷W@¾¾¬qå·¬gÀWB¿&ÿº¯üX÷eYñª‰?ïXñ ÀûÖ«•ËΫéO~¿Ú“{qß3~[¾ºì,4þlŠÝº Ü÷À`áõL]^ô·ÞxuzÝWÓÅÛ¾›ßZ .ü·í{Êñjn˜OòG;€×e¹¯LfSoöåWÖ®®«b叺—L^³Õé%g'¶…á5›_ÍÖÌe³™Íþimáì3ÔÿnözÄoö`3—]U*—YÔÏÜ7s×Î^ï€/˟¬Sэ»fòšý–Me\6À*gî_É*û«9ûñš}ù¯<Œ9ö0¼Æžú™xE¹ëÜá.›á¨>çM¹—¯Z7|dú³¼ª2+^5-6öløõìߚ§%©èæÛïy¿…Ù¹}i~€µsñº]OÖý-»B€W·3¿^æe’—WŽ<»¯:Ùôêh4že÷=åù˲ÿ­iãzó‰Ev^ÛÏ!™E½û7‚Ýñmÿî>f“#HºïéwbVðQîe^çŽÌ‚à×CŠæœú•Ë®dÖ]Asêg2ðůÛ[Qñ{úœYf3sìQ^c«ad™WÐÅ»¿2»l Ç?À ¿¬êǙ€ß­÷”Ál{jWSëÍêBëÅ¢¾F±’¿&›_ðü2Èȋ×~7ÙW­/•»f2”oV~7œ×Ó~ÇoXñª°¶°Ì¢èåóÙáÿBÔ¦4
143
+’ú: YM¨¢M$I}D…äf6ì1Š}‹ZìýëÀQÙ'j=~Ô{bݏ—5vÆÈ¬NkšI²ÔG‘6ÒFÚږU½ùôÛß)ðòů?öðŸRò¿ÕŒbùjÀòD¼õÎókú§øõvNl»Hɛ5Ì¿¯ß}]ÔgÞ6@DŽ×"\Òzgùu"É®‚á¶-ë¼¢¿…[« ™_&6žç5Fµìê$‘çßù­ieã5À^çµÎ¿µÆ±÷fr ÐZݏz]ÈG½nÛ€`|Ô[Ñ„Ú5cgw åÏzãYðçì»l;¿Þ,þ©LÇ–WNöÎ/Ÿ]<#“´ï‰%¯­Ž…Q"j…Öe¶]ªl~½¬Óë²ÚW‹•³øÃ+œ‘ñoMٟ×ö•Y”œ¡ØX• 8¹?^aÙ]ã9#/ޔñ‘Te;‹ßö=e¨x}Ms¼fäÅ_ü:³¨4›|OöÄ_þñ&Ûûâã¹Ó¶/Uå²ñÜñ²T¹þŸVõ;¹ë,³¨Êeø,hüܗ×ìö÷Ømr¤ ›]öÝì™u?+Ëù³€tNý ¸y§Gq?1ywÿ+ßæá«5çÔόä¢>gNýLÁð´Âsêg¾œJÄïÛª³ûzOpÀvÚöŸ}^©Øoqߨøµ´ëçx™?<ÀCB±q…Ïl˚Øy…[ï©¢•Ë¢þ7µÒÙ}Uí¾¬,ÿn½gû¾æêÄ®6iÃYcÀ'ø-›zã ê›Z©ÿù·ÖxÝ\<‹‘ÍîÅËô€xu_v>±‘Ì#mØ:¯(‰rSÒÇ?>ËlÆÜ`§ †2mþ<ÿvÝ ÜT’¥>êe˜ÄÃP¡lgã„2¡2½ i2½3²5d:ÃdÊ4æCœLckÈ Ó¿…[lÇÃÙo­^ÖX˜Ûךú¨‹d.¯Kàaòo̝9öc§³°ÓœÜbç;$·&?Pw: E’‡ãjñ#˜ÖbG`O0­C$ÑMΊñXd¢‡+yáÒÐXÉ ü2£Œ‰±¨>RÈ伜KîÀ¢ª¥\Nf‹j[,Xç4°è@ mÃ2‡u¿ÜTr)—2¤(ü¥ )Cš2ÀQ7ú2)íplªðŠ7ŒÁ1݉Ó6Œ²ÓXÑ ‘û ›ÚP&Û£ÓP¥ÀÛ4öj¿®’.8§MbQš¨ …B'#’Ò#’ÒŒHJoØ
144
+9:FäÁˆ¤4×Ö½aÚë4‡uŸàa§\#×È5ª@D%‡pØ)ÍvJ+t',ª” Ñ(Ý¥ûœ Fé>]‹¶Ž†‡s;n§âv*e§zQJ½~BZkS)[Œ’EŸ DÉ¢ÚAdBoŸI79˜`wX;ˆL^™è#¿&G°1-́`OÀKCc%/ðKCcÑH“Sså~éLòß0ÓÂ-°@£œI!ó ò<Jn{¸EeQ•s,ºF•ŠÛim*n‚Ä0“¹ä6¬òj*(FE~MydUPªºª|ŽR÷!’xǖxǖ¼TÁÁˆšGD¼c·›“ñP t –”ƒQÞ0ÅA€ŒðÃgÑgÅæ 8^ñ¤`”ÓƒJ–˜á {XVƒ,)U¨X» $Ñ0Ȓ
145
+߀ЅØkTD"ã€Ò3åkÄÅ꧋H¯ŒœóW9tP064•Èø D(Š+•0Q9”DŸ ä±6DØ)H©š·Ôƒ‚èC„Ü 4UÝ­êAôÁŠcöŠBAº#¥W|Ð*L¨18I6éCýyìC¬H pЇvrÐG×°zhž†ÕC‘ˆv²JNKI Dc袥  ‡F:p!چ©>® zÄ×YZÞ -…¶îú0p< Ì`Ú±kÔàžÂÂèGH å M0À…%1Ãy|F
146
+™üôº3¥eS¥Ìì 'jˆB"ÙTÙݙ’M²iÃ:F$“B!.ÁXpÄj`ÁOÍ4°à§¥›J.“BAp\#×È5rB
147
+„é°n¡Ãº]#רRr
148
+4¥û\¤4w-R®EJâ
149
+(Ä5Jð'Äm؁Á zA/¨ò‚^Ð'¤m¼cŸ–ñŽ}nØ aÉ_¿ ĹÇoøú7üßð5ã7|Íq@ÎÖ¦ÒÚT:¡y dÑç)YôéúJ}r¤õëƒÖ¦RlX¸}&];ˆL6‚í3éÖ àÈgÒ‘N#¸Ï¤ÀÞ ³‘”Æ´0Xw‘‰þÂì ·a˜¶1¾¾a˜VƒŠŒH¢cZ0™è2f3ʘ„\‹”~A•’»¤&ïXahÒŒyoؖ2&—††K^¸4TȲ1«ä…eLL•’³lÌ#…Lþ!­_cŠ ÛæÉ“Ù¢Ò&3*dr“³òt] ´Eõè|kÐÀ‚›œÕ‚aɪ 8”屮œ…Î#Km0»‚ªlØ÷®<®itӆyŸùkŠºH‡õA°Þ‹›T®rXæC&˜Üñ4Æ0evJoXÊP!KúWžUJ ‚ŽRŽ‚ ?ÐÐjъFIs™lDÔ Ì×OÍÀ‚/^$‹¾¬’Ka\*ºÍ×ñC”:ÊQªÐ©˜ÔI6¬"/¤ûU °ä¯ ßðõ†¡¦Ö;,2’DGC+Aʘ(ìÏc?öç±²új%·a[Z–Ü––ܲH¬U¨¥þ•·¡å™òkº(Þ±MÎêA1àrÛ@Œ69+¬Øl؁ãE²èMQ²èͧB–,T«”*¿fôŽÍy¤’;Ðô‹ž,øªåBó‰<½a›È‚&à¶^  ³Œ-TÂÙ°Œ$Iwñ¶eMåä!+'¬pЦ`%$Y"ðéf…³ÃÐÁÊ8’%‘S3ðl$ ¢2†ÂÜze|ÕQÞ0,1¥ .DH~Ifú,QÉqÇ,¿è‹cUgº,@¥GÔ*™$Z5¬ÁƱ,hÕHÄB1Á 4©j„BbPò†!4ÜÂ'DŒ4DØT\€;Ä$ÅE=ÈéÁ;vÃ4Àz‰Î'ÊôNÔøâøðôÂ5^[aq¦,¹EG”éüF¸ ƒ<6 žèˆ²w>O·Gà™çyêÌSÕ³GéÒT$N<ê¶'òi=ËFá>TïÁX€(m¥dÚ°ƒÝû›9ŒfØ0Ì®rp†„2Cȯ ’TOÃv*,Pút@΃î 21#  ¬Ñ(âÄ¡Œr¬ò†1 W<(-£jÂÙá‡o´7£|~҆}
150
+¯x¢ 8ÖLBÃBº)-,
151
+Ë({Ý䁘eŠ¥9Ö`ó<V~äø¡ Œ$Œž°Œa”c.ãXÃ(PÚb ¶°`dmÔ8Ö4¯kXÆPœÐÅžÔÊ(#pClBHtA˜)H0x*Ô$E:+ÒBÌÐA4ü,ÄÜ©ø:ƒd!NXy ¸ Èz!þ(½˜Á­#*#ƒ`lG1H–” ¼2*´OaŤVD$—Á~{Yð}¤¹?©n`¯зËÒ;¶ìâÅàá#Ž’ÎŒ¾ S1&ÿe(UV‹b`ذÐÇ`xlû)àR’ܰâp¥uA‡£/Ž7̑ZÐàÈÌx ‡Í°•<teA8㑂À¥W ´ÉÆ „ s˜sAКÊ|X=™@Иô Èa§ÜÆô‘@®‘Kü€$ʃ€dH ÒhÉj:Óé`€/ìÅc¦«Ž6QÕ C'x—YÐ/W¦£9…™uv´Cá»:‚ [=
152
+î-¿5èŸFoØxeÆ×á"&”{œg‹xÐÊh3áKMÞ±7,$@e´OHè:PYòVnˆQ¹PpÉè {A %‹
153
+”ְöHW tBD2ø‚gÙ°ÄAE͗Á,
154
+^ŠÐ*yÃ<žWÕ$ï;›M]XPõ†m$ÝMŒ U+ˆÈ”dL,›2%U½a[Ò™þ >õ ;0-6ÕÑ×PXG"ܰGʘt ©Û‰›Ö¦Rr¯±}ʗª@éEF„ìOéå­Š£1Pz•4ÍÁˆ”^ñùI½aŸV‰*R t[K.-VÆ
155
+”½B°'ÜkÌô.<X$Ü*ä Ä
156
+”Þ0 ³®ÒËC šÌ4¸¥1£ÌG´Í8ö¸¥/Á+Çv~’>Í'×Üùܔ,ÚäF¸Öš×ÕæZ;_¶È,)–NK°0ÊE¦±Ð6—-29£óy=!š?ذ™éÝ*ä Èp‰w-…Ù7ì‹BÀ?Ÿ-±ï'¿a ?|ÈDH¹îÌS@sUök4žvb=KÕØhí`´u‹æÒx ²×·Mࢠ(ÞjD(\*ìÇÞ0Á3;ƒ!HÀ*‡¶a송Δް•AXJ5ÏLR/ ÊÉCذW”’ ·aíq!‹™0,“ýi„ÂÉD6¦å-_·˜ÑèSZDœˆRò\.eÃXiiMIC²=’êésáÝ6,Fyü*åR±a VÉi°ë¡%>ðB3€ŒMr8ംîÄi°ë¡iF§aP¤‡¦~-§Q œV°ð 砏‹E åsë$КòèxÍHëxÙd}ß0Ï=0zÅO]) *I™!dòÓ9>© ã$ÕÓ©ƒô)½ƒÈd׌i·/US¼Jî@D&ehþŠE`¹É«*!íëšf8—¸Ò^ϊÉ/‘b‡ŽÜË<O±a ’êiHë´õ…çT‹}ß0“;:ã§CI«‘„⠝¸Þ0rTAT] l L•µ«ÙD݁åéÎ(ݱ»­<‹«S'”ãÕñ˜Pá‚2$O:•ÖԄž=²aX‘B^¬‰Á 刄8FÝmÃ䃚øPÏ¨ <Âò ©¢ØòR\¡ˆ+Tö¤¼”Q
157
+@”ã•¡‹…¡n˜$Ãåoƒ dÇ3çó4‹š»EU™m]Pïye³K:b8=ž„ž=2r¥J"ѐ|W¢>) b…<½(iíÇ ÍÒ<4T÷­ì¢8\@-R ÐÐ
158
+TþÐÌîą3BçÝP,Ö×½`òù&j¾ÇŽ×ò%Ó~Y‡×:-å-GÐf’„Zw¾C¹à ÌaeøQº½ÅèÛC”,Úc`hÒ+:Bƒ¤–½C”,:Œ˜¾[³§AšTU#‡ž"PI=øÀ’ûTEß0¾À’c ˆJN/€%§ ŠÞ-p -¡04ÈGºuZ®ÇDC‡ `ËÓ Zâ=eढ़ê/áDâ `Ʌ-IÊ¿Ž–Ü‹n°ä ¦’ÓXrÞy€ò ƒ œÄ Ê?Ogyz{+{R^ |{À’ÓTBÊ&^¯*?±™As sÐঀjips;3©ÓÆ;T]krfϤK"Ÿ„2ipXrÒà‰˜dÑ!€(¹þ98í°äÆËä´½°äöä§ý8K®ãT¦°ä:gbÙ¶»
159
+±ìúWž¦$,»}©%ס>Õ£ÀÄø8
160
+À’s¸ÌÊV°÷EȉËpëLnXƒ€´Z<öåba¨¯írÚ–žÚ §c…É §áËaÝô´+zÇflÐ[t §gXrcöt,Ë¢dÑ]»)¹·„@)GB@ ðræmùXËH( ¢O/D·] °äLZhñ£¨­”n&AÂÐ)醅 U Jö(Ù£PgAâTB_M@_ç–¿cn(ž‚G4–"« Ök–õ£l˜û½oòU0šÕ2;ñJ±( dM˜›ÆÚ$ B1tVö€FA~jjAp¬LƂ1—Ÿ@³Uô†©U—­jMeÁ¡MHЧ|¡ T…“wR}E&áð&-|ÊGC£Ñà¸Dƒû ³¡Wň¤šñj:ËeÌ)ˆ(.˨ã›×l(®HJã%$è†âš6” “ Ì_»FekgœÙVú¾°äP?¡7GõZ©àƒ/ £pFJ”†jöREþèý«WãrQHma…ÑZ¢Ç±bI®B¨ép\…E2‚¥ôr!:ji˜ Å;¶½Á'O’2 ø›p¿hø>w<JE§œge´'»WãmNž e‹<\ïQÙ̆¸2‡u/°±¹¨YåFéNGß²Xá8(ÕÃANÏaŒtJ‹ÒǪ»‰Ò“Blþbeˆ|3?m–¶yUŽ” #d…9òŠ/ŠWŽÃ/Ç HA7Jzã8Jڅ\H:ÔÍ š€e° QÓA'00H»v¤Wî¤Q¦†6'¤Ž’ŽÞ°Nvhô)A!£L1£9¯GE[TMIIUw¸ ՋÁ‡£Ä%gFZ §éD¸vÐyšª# íÝMcˆ>¥Éâøü$ ÁDH7ì¥Ð £D]6i2Ë –ÎpBjŸ[ ”cdXãuÊ{˜h<ÄtÁ‘F^à’1ùÒBãjÀRäu'ä°SÈa§ ®‚Ì9¬ ¨oǒûçú„¿aÿờJé 5<!O{£w:†ií kaÀ²ÁWò_4¤‹uJ[р§7lúãë|kd•ÜÈRהá1jxª2$ïØ¨ÄÁ9ª .6%‡¢
161
+/U¡•p•ð›XÈÚی²$¢ <4…þ ,£Ëˆ!Þ°­Œ&YBI¨bXùÌ®o¬Œ ²$=@°Ä «ŒÜ«Œ
162
+²¤­TF^€á 1Qd ÈzxeÄðӨѪ£ŒÐp™Ñ#‚Ðâ¸Ë\DŽ#º‚}¨ÕÏ(6 ~ýÉêAô•ЂoC„»A=$ˆ¾Ñ+t!4­j>PzʼnÎÇy5«Ÿ´Û¥Wj|'f+V ë(EVÈÓ ‰`ƒ"=´WC¡ž´¡QD%÷Yá¢p)ޝ4X¾F¬*ÞFõ«=IPœ¢š4¸ö˜´”׋y­*åêcà‰8Ùԝ)ݝ)ݝ§ÈëNHwvŒHLj¤B¡P(&1"©Dt؍¬=t”îs‘Ò°U@×"åp-Rü„œïØ'Kî/¨ú„ –ü5W ôy*PúD (PzÑ Òú¤õëÖ¦R6:¡NèíJ­Ð³gÒ1-™è˜†A°'˜.’è{‚Á´*dÙ]äåWär¶hnQq‹ÊRbà%¾xéÀÒV!Ó…L^AUPŒ
163
+ɪ $‹WP²¬Pä×äB ¬oÃԕsÓûuuUÕEGéÆà‡¥;eX,6DÔSþò—¿ŠÍ¡ƒ*6§wlt°li²Œ0žÐâ)±Ésò ‘8 lØùaèXÑxè¢ ~ÇÕ ‚¢ËFe "7Õòu5`¹aц‰]6ɦnêÎÔùXðs„€ø‡uŸßa§t?ì”>lרRž‹‡k‘z¸©‡k‘Ò°¨R‚B (t¥û„EXTáKþKþú}BŸÐ'¤89FCÜ>“®Dà¾uí 2aD&&@D&ó&2]d¢÷fO0d¢–[¨„”¶¹TSJ…Ð̌   &£ÑP×@6&HLB420& ÇâÀ8$‡rǁDQ$•CÝP†îUÈÅ']Ö¹,V:ëûúŒ­n¼cØ#Æ>ÓäÏ
164
+R7°lnéédîo_r”ë!¹¤²éú؝ò¥<*C±²¹Žp_¯7”c4”pÈ¢Zdüyâ<dk‰áââãÆDc€þ‰¼f¦ÕÉÉmOnÇý“øœ(JËÿôÁ.k ë6
165
+ÍсðÀÛÎ.~Æ’áùI˜e>€Üï5${ X²ò
166
+ÿ'Þ® ¿ òƒ–âñû#©AcëÙµX 2ÀýØ«Úur÷²
167
+™õL5~èI"Ö0Ěò•~„9ûî±¾|Vo#{ÔSºdՈ`z^"«4׍¿FöûûÑáJö ‹R#(5¨á\EºÒèHŠa‚ª¡’³'é*rzåqiŒg|Î%6Â!ÄtœÇ°ëYwÓZ›wµ·ßÁuÄÑ+VDG©:NìŠÂ5¤åɨyŽ.§«Q+ !} &ŠÎrFV<­i ä½äÆoրèXO‰º\ªk9ÝrêÌK&¦¦Ÿ{­­E‹vm’Ä.!ꮨ댦©?×Ë ¢æôӖåC58.᝿[úË?xvĄ”Ê(ԋ+’$Hºý&ÍÐèiÊw?uÿèf¢¤ËZ‰j[9¥*œâ—VÐ¥ ߢ%2VPW?ÈðÛω_Nº|?Ɵ–„sÿXÊo"XuÀ®·u—ïþÏݖòc—éúše,¦ó†Ã¤NlY{ ‘™“«©î·ücæ´X@…ÕZ:¨¡žÑ¸õ~Â*@ Ë‚cî]5ý†cn(ú4ˈgÂ"9ñ5D¸  âàcx–aš¥¸AòW0ï €‘zpÊ+Tu¿ºaÖbqe6sê´,læöB”-²]p×ZùÝfoã‰Õ¼bfHý"Ô ÖBF-‡é„$`Œ»È –Šæ¦bòlâp‚gbS<é5̶D*Ù¯KPüŸ¶*W„½S›´ðggßpœÒôŽ+3§ëᔸ·ÿFŸ¤Häf`Æ!²:¢ÙÙX K÷4ËMmbyá®ðtŸ„Jr¥kï9Rº{XVÚ ÃTdæ|™X$m»!2Ý._šbS%Ëk#^}4 •P§èüÂمýüÀyôÊv”IæW8D–E»:üç\‰­,€¯4C;£¾e&¥Á^SmÅ`œà&[Ðß2Õ­ù‡^£²ÛêqoD_'Ù·¬ûñ±M[ý^ߊá5èØêþž_Ey"ÉãªVÿhe¨¤‹Df­"†aŒ4c“3'”HßL¿ Z¤?MZÏ-þ÷[´>.csj{º©$µ¤oÄh2Âx°G:Ë2%žÓGz¨éÇÓ!7›®ÞpOBVÆÉJÓ«Õ8_áé§×·ÇtMkÇ 'Î=vÚ)÷ßÜysµ-¦J³pعÿòC™HqƒõCOÜõ85®ªß<1%¡é«µ’N ¥نÒÝ\ ypSHoÀÚÄ(ÙCÌ2ŒY6 ±«(½šBsß»ç¡GGõâ°(‰ôP@87qøü”v¯mWQ粞{ë.íK²–íÀ›n¤¯ôêY¨Ð_hÙℾ²Ñïóí²Xc—cë2HcŸ~ÚR×Iámô‚¸$ÌÇDh°—F&§!éä?õSšG›.¹D²iä®l2/Œ2-Üb1O+¾ü aŸé)?Ô —vtßs@«Qž´Ô|Œì9¹ƒ×X…=t\€,¼(é¡£Ia;œ„,ü² ú¨Ç£pë\üœéÊÒ ô¾¶vN8d/ìþЍ^o$B&ú -¢¾Ï’÷ž3TÚþù·iIBã8`~¾ëçA ²Å*ó<"ì.D¶^(úúkÞy³`}>…ã…¹#DƒR͘?£Ñ×dkf4pÆ}SB2ÔLj9Ã&8JaN Tq5Þ¯¤ÎˆmœLN9ô-â^iƒ7d¼«ÀƒíÅ6âÎI¼Á#ß&‹9¤blĽɍÔGáW #n=« N䫏t}ÿJÓÃ#ˆ¸‡Mõ±«øúÍ£DïãÛq“ï?#îm*Œð_øF'à ¿‚ù¡6u²ržºYžl+¨ÏÄj»˜¨™Ø’+ †-’2t&¶WR…Kô¹_ÖfÆÄÜ|;…£v&vxÉÿ›ÆB¤¥i&&WDaâÜr—tí”Í^©¿ÃŽþj.umò Z è@×fÝøÈ±€³©}]?Á³¬Naeæ ÃWò7£„9§ÅT¶Kêé)èüW0»Ë5úÝÈùS´OV÷)oA"ÛËei|r²„íë¡„ÑýP ±×é9½öCØé=Þ>’(`,XÀ w¿7ó¯(‰Ì“¦úR…%jٓL°vîhtxkK=™™s‚¹î‚øoíb0+
168
+SȘ—åœ6÷Î՛7fLµ3LFòA-Ö½LEn&˜ΝænßÛpY
169
+‚Ÿ=Я´œ`bÌl$LÌyÔme‚]…[¶R©Pà±}–LÆ ¯DÖ|¬Ø~úFÇêv2s:y—Üç Cô—Øf»Ëóš)% â´¹;²²ûUŒ^!sšZÒ2Ÿl`Jì#ÿä-è”òÝÇuz«p"}îËÀ£7™ådÉ­nGo°Û?öu¾+øè­Ïã(Ù
170
+‘¸B‹Oöü½ß k؋&¨þHåôuoÐëËöDop%^©¸£‹Þ÷ß»œýª<“iüâ3íHÏ«VØ£ ÑD猹šËñ!KŒÞŸeØï'¤s|_ËG¢'1PqWÌ£!ft™ù˜#Ù7c/cÇj¼M˜:¤Zs–ÆÝ[J™ ¦8ð=Ö_mNc=¸IÅ÷µ¸Ø&xžR²ex—ÁÜU®$~‰œG~Åp-’;Jw²Y•%¨åI§jkì狪_#ÂҍÿýqÐÆíOæ¦ès¡ 3 Ï d÷< )ÎÓCÎΰäíœWÉu•70Êڋ¿ØGá¥`ËéFÚæ¾
171
+$H«|t©òιw,}ÖM™vbçjXVÞ:l€í ‹©ÕŸ6S\W¢öþ,wÎM;*„ µÄ}&¬ó,±ífV%X8¨·Ÿ³#K¼@µïk­ºZÿB@œ¸±ÃæDDeýÌĎԆÞö Ïn ç«#û Žaûâ^REסDîõÈÜ <°†˜Î&_¦E.ßêS¯ÿö:@탡K‡³zP¯$vÿ²ª2Fo^5'@¸eNs•;…cɚïBJüçoÀš·î -d3„¦J<vB.•¾Ä~m­ë P'¢MyêXò+ŒQô‘èt8vxw6îî¦bÁ®Kî¶×f-wuʏVªç
172
+šO³VMú…Ýt!P§¹ð:•&¾Gsá𾆖OÕèµSÆd^ˆk5FªR«´Ë<ë…M±;·ò¹"~·ë ñÊGɓõhÓpþšI²?f[šðOÅ`5b$ã§˞ „î#8Hǂì
173
+ï¸èÂxÙñmr,@|ÎlYÛfòYãýû`FŸxD‹»”ª¨þ™é-üRNÕ¿Ý“"÷ñ ¤{´v'ÇJ–5æ){Ó6¸^ȯe,@l.ž¶‚âBkú"P3œ9¾nU­¸|ö|¥9k)œŒÉM)¶Ýl!øûcO¸h& kÊ µ¿ýÓ*h%6‰'‹ºÄ—D Ôõ@â
174
+v„³§Ãž^ìGP×B‡Q÷’êP*üHãY5”Å+¼¹¥ŠˆdÅրr*ÇMG’¦CÅSŸ&ËwÄ'ë¿ñM°hô
175
+}﬍õ¨*Çf\³I ƒ½0"ŽâB.ӈØD­¢¶QL7É f脠Xòë4 Ñ»RŠ‹s“Ëç Õjµ™Õ,I®«²ÝÎ7Ciˆ<Ñ?t’á?ÖoŒ°Æ± ¯³8N˜OWü%¯­Üu±<úEJù†§Æ¡r‹+ØxÔ¾’EiwýöòÉ#\S,_±ûåí;¢ôbV¾ýŸ‘VcÀüA=µF`^ð¦59Ø,ãdYÞeõe€éW«ò2ΌÇc¿úf¹<„Ãé¢-"_4õCÃ9p“ÈÙœøx±÷ímY%€LZY«µ'îuÄ¿bÔ^Nz1âqÐqÒŽƒ¤ÜöÔ.À˜=³üx÷ØDäŸp¹¥ÎdŠÎ•PUÆ/LžÃß}&-ä-fž‚•–ºÖ¶O¿‡¿´™ŒK]è¾W1¹!_£Kùêî.Yþ§Û¾ÔÕSWHAqJ]§Û¥Tµxë~oc³Ã²ÿ…R×ø rÔE¬¹…;¸>u½’¿”ºNV•ã6 ])éÐJ]lv0IîMe÷es£]µDÛ!ˆê GþàTÓ0ǧkûi.…a+ ”+%˜äÇTÚ4mA¨ÕЇ²ïB¢0ŸúZs¤@ã¾C°;‰Z¡êÔÚmŽåÜ£:ב oß'À…A+Dm°TäsbäÂs!?ºQ{°ښ6£V¦{0Ì×M`ŸëÝHÚ××þ~ÞŒÐï>µè!òõäéQÔ3Ú¬¦E𰌃­Ä-ûbÏ%æ*•8#X©_°ŠÑÔX­åaÊzÝÕ¸ÍòˆÎšBE{â` ³Y-o'×|ÃV•%gT±9ù’58!s²éaCâ<á7uH+5Äíä2/½~ö°. 0tÓpú#ú¥­ ç<@_©ÊD;ëNœm³‘0P¥
176
+P5ÏÈÁ.óÉȖÌ9Œ:\X͓EòÇ-é˜e‰o·¡]Q[P}+çÍvùE©¥ÍÖõµÅš
177
+Õ·˜3PjM’ÃÇAhCš8²W±\‹wØ*<;†Xü¸J<.›‹©õñÒè>»ðØá!žº†(i(ucé^ÒbUäxäbMè
178
+Î4èLøœ(û]¥w━k޽Ú}²ì/sÓ¨áYa7Åê2’ë¯~A랑4îa'ˆèÍe^›ê Üëù‹Òº´tâLM,<Ԟ@>êsP.c¸ž£yÿ/^Fa,÷ßûz.‘cN¬çø¥Q:«N‘\7ì.å(IÍ`£…ûª„‘8Kb¢Ž•
179
+ßVèö;üXr6›ì¡Â½wiE]€6³å'8æñ0Ð5mÕeÔS~gXÕdTžX…'‹í£*ÐGfWxËŽÉÒt÷oÝa@ÝøËz%½½ÄÌ?АÐb·axÊVò0¹V¼®žKŒqM»«Ô˜·¸ýí¼ yå…Ø†Êç-œÒN)jŠêÝîBVF’ŠTSÆ8Y»†]›úúhæöE"ì¹{‰ƒ‘ðYr<Ë0(vobj˜Ý°áÃJy–?–ÏÖa†7ÍÚÖ`× Ë”É4ë«zìËÕê¼WۑE†Qn u€ÆÉŸPpåV9Ì­’´R/QnUØksVWnÉqÂÜÚLŸ¹+· ʏ<§Ü9þsñ½˜[ó
180
+Šr‹ ]ÿçßàQ¸VØzU­P¹uûËjNkNròô«Pn5æÌë3· ÿ–€rk8—Å…]Ó¼U(·ªïÖL†å–@™h[™[תZ/JéŽ] 8kÞu.ëº5•[ “d¬‚ÞÚÛò‹ ]V´7sâo‹;&Œ¸)C¿U¤!.¦³Yp}¿ù݈Úfæ‘Èšñ@éH<ôŒè®ǚuýFEe¤«Ë]FÝü_\-‰J-/+5V~k{ðnAƒÚ¯†¬Ðv;Dì@È%3wíº¾ƒé³&¦r2~@ ís¥n¦gÂ-îʪ i™…œ@ŸN6€Ä°=xƦï]"éd] éÏ$ÓèŠÓiékï hF!}Ú#ºº6Ç<¬Æ ´^n#¢n…¥d„ÆÅ=XF7·%cF̟Íؐî57é.ˆÿ¥Ã¤‚u|å ³Ü^#T•02¹ë;ì ›mZÜQØxWtF¹\*e( Â;}ÃA[­¤´D–„éÔ¥@Ô@ÀpȹjožtÂ¼Â¶´ßð<q+BeDÜD¹qܘ÷l˜7ÆP}±<?¢Òý`›•©žç(gnuA®ø8Әg#böå´âЉN² Û`ŠÃ– lørP¬o¡¦–û}7–’'*~¹ðc8Å)/« /ãˆïÎ).š°›|­p'…wPk·výœg:î
181
+úQÞm¬OJ§ñEe­U¦”]…—>H iD”—‰tÎU…xÀ±8 ]Fé,Ìæ@-HH@–Bò”ºR@@ÂRö?©_qÙÂ[$—²ñÕ4uÇ&Tñ Dâb̲7ŒöŸïAP|fëèËäDoÖ́Ží ˆŽDcˆ?ú§k„þÕkÃ4¿›  e¦Øž¦”’ŠiÎØú¢¬.BA_ß\öÑràËt4—"·bGCÐs©àv¦‘hÉQÈÞ!ÕÈë@Ó¹«EK²ŒÍ4}ßd:ÐÞ *|@7?4F̬èËãYŽ– ñÎp3YÆšâS¤¬Còå«\áž9¿‰úÓn¹ôèíÜ.ì¦Æ¬DIÕÅÔç½û®º~Sœb·Îg-¼!å÷¸!ÛAðf~ª™ù(VoŸnúcpº’2$àÉ3Š,Qð÷&¬¢îƒ©*UT{á;5È<˜ÇNxJ¢~.ùE=œ\óZ½4=dÔoD€N©‚XٗD: ï%`”a¢€ö!κ[Í,÷’R6Ñ£më,˜&)35à B ÎñÔC  }Î £ŒX”ùqV¨Kz6žS:dåeÍNÛë#ûžÐs²wœöÅX\&öþÞ@R®gÝ$æ) â:҆' I^éc¢±"Åð,"ÊÒs_ãP )ìñb†ºÇÞ£è£{ê¢pŽ% ¸fÚWõ‰6C<jX‚â‚À¤ë"}/,pºÔa¢Õ¦hwÊí{u…À‚@ñ X²’«§Š’
182
+!>žsñ7EÎ5ô®&¥hV‹½Ò•àqßgL$¾Œ3QuáÏ\
183
+Î>08s06͂þà¡!ƒÁ{| ýZ2dfp{_ÞõGºFÎ>msL¨­Ì¦{“ÙóW/+§Ô”hÙ©‘›¬ôÍAûçß\|q‰:?À‘Î)ͱ{“„Š=Ԋ‚Èsì!¹Ñı˜DÊkóÑäEï…9ýóMQgŒOÝ鉄&föñÁ÷¢ÏZ݋ú}ZWUç ë5@ÉH#Y'Ætu¦5Ä©Ë<GíP\efÃêiÝ\ãuöçµð©%u~ù˜D]\¹®"J„s_5 “öÊ-ŽÉòׯ.;¯Í„ÄC2Øüå{lhúéÂ2~H±ì^!O¸ (ˆýZZj›«¯9î,sÔ cBŽ—Ôg&ˆÍ̅®*m÷pXŠžEÙ%¥ê ™k;$p¬Ô;¥Ø¸³¢D€“p|ƒ®‹°Õ¨thƃ$M³™®·ŒxÎÐÌoŸes­Í¼ª±ñ\Ì,ÿ̯n±p†fîî'Ù²rs ͯš2ڊ6¢|ó™…úÕD؞¿OÌ鼂 «yhNVG], ¦,°bMîOY[0Mr¼|ÎrùòW'4kŽL+¸ÁŸåˆsb(e¸±i†~q¶›Õ~7[3sFQ¶Ìàg~Ë|Yc$4ï·ÉX
184
+ú£5‡fm ПÙËBóUY¶ºÏÜ¿• 4×gؖ<¬~fÍ¡d{üÌÞ:'4ú̟U
185
+Ϳ䟙 ,~š%B˜*R>s„§²ÐÌ pØÏ,ÇÐ,E‚½l‡Ï¼|­Æ¡Ù‚ËMåšr?ó ̀õ´ýäËãg£Î{h¾eɏÅ:Ñg¶Yu-476×ǟ¾}ôÐ|_¾Ð[Æô3cÉÐ|µ¹‚ÅÐܣόÊõÐ|p‰0¤Gz¬Ï| àìj›B)¢ÁÐè ŠÄ¡yû|á}æ=>–—ŠL@hfªÝeß ø =~f”5¼PéŒ:†ÍgރGƒQh^MПÙq³ïJxVhö?aä>3o¢Iΐ‹‰æ3oH¥iÑái6ûóN“X«å¾Å èÇ`À_ä¤ö8üúùû·vä<H» ¨–Šñ¯5iâô
186
+pbJ^Ó ¶Æ{L¢ÅM\UÏ<jÖÓ}›š.AÅF8Ä#hC0¨”ê¤}2^j œò)(Uænìuz +`ŸU<¢ ×7™3?[Dä­QåPNª+g8ÜûÉõÆiÝL´H#Ú;BgýçñX"âë#àHµ‰Ö¥ƒReÈóÆˆ–L ú÷חˆŽÑÍ:~ªÃ>Ž*%;,ÏPuá(aAj„t+Xw¼ºŸª0-ÐêïžÞBˆ]\§¿bd}Ót;-¼T Hè(«¸nĽYW‘ã…x,^ã¤ãLÇâФ¨ËŒ&ºè·ðq˜½X\mBmñÊF×ʚü ’Öª£”o;ü…öd)£Uªíìª(öÒ4ǜv ͊Š¿TE¶iö†?E3ø¬„¬óò }¯b¯°tr[­SÞɋI˜Û‘.FÇ4ó½ †ü,¡dåÉ%ë&2¦YV-Y«I3x̦YþàÑØùÖ¹$ nš|=΃Ç|HóŸ"KÝÇ
187
+¤Yhb5؃H>ؑ“›QhŸGyÈî±_›×BN§°$B P ÏåaUìdÚK‚Žn•ßž¤¼:Á=¶Ý !7•F螊äp€r¥CE²ËéÈ1Z¢-…Ñ)°¢Ò˜²ì¥Z¢ôAˆ]‹ßd¨5qŦX ÏÀPu)ZÖåUؒŸžJ¤BÔ ý·)IȵÀ©q¦ >wSœcñG-Œ©WÈn*%îkµüè@…О$s3rpàñ/¤6Rá˜<º—ûù]l´–ÄÏñþç‚i¨û¥.·f‹ .Ý} w@b 91†ÊF>è\
188
+®ìÿ Ügœ“·œÀµ±ÌW›£ó51ºÖË,±#>øóK§ê‡æÛ™Ò¾¥ðo÷YZ8=¾‚cáLQø?Ùv+o¨UdPŒw@T €± õq~¢î3c5âàHi'\4rûg€øXî¦ÉËqËŤ^`ö¥Þ—ø¬r+šNhðŽ·ôîKk ù8tŠ`YºcpØP‡"¨¼}‰³‹J¯ÊÈö ùԌ¶¯f²•ñ—€£?e ‹È+µXrµdɳ¸‚dŠ“ŠŤƒI€ŸLYc1À—Ö'ÚXꞇs¤Œx”‹‘™¾ ^o`+®´¥QÃñÌ$f³Ž«ÍŒËPý£ç‚Ú|\¤fô¤†@ô†]‚+fS3‚ºÛãXðûòƒOÐ[ÇZ¬²RS/n.þ(0qÌ Q§[ΐi‰JðüßÁ7c†mùüXZ–Hêԙ1 x›B9˜Zùii¸ åOy âJ`˞à~øú/ü¸8Kœy51:3¹àú#¤#.écŠ!7©ZLx„ýa.µهl…/ÎýÜĤ[¿ˆHƛ|öÐå•ÄmœÉËë`ÍrÙ6ÇÛ>ËTÞ ü 5¿xþŸe`… É.¥Ç07†©i^-^âç!“E¡•áõÅrEŠ2[Ç«Soîo¾œ“d§I˜ w¦=Èþ²JÍ ‚í|'I>TK÷¤âÖæƒ>㸠Þï³ W[UìÐ?¦Ö±³Ú´ðÛèã'C°yoXôžb¸Ý²{QøÕÅ]¡ÉUßÎÍÆcÁÂa,ŽŒì;S~«ˆgÒ-ž‹Ñ
189
+Ÿ`nyˆ´=¬yU"Äï¥É~î wÇ:SµMÔ_Fhð˚闝¨.ùBÃðÆÐ9²}ÍYv
190
+sÎÚXȦÜrÜMбŒB;ž”÷ùåó+ PÃþHk ßk`¶ !r”Tó%& Ì+Ì+T×KŽÓYV^>ýPw£}½W#M ÂòSxK÷K]A,¹2™?°³¦ÀmíìÞ/v^ÁêVíŒxsIãÊ)㷓þyƍúÜHü‹{'GŸ…ÿ¼Ëšæ\*rü\姞ßo~̲U‡"|O‡ƒŽ6<‘
191
+2ŽíÕØ–Ű8Á.ÍUò9²0`Ë6ÀŽÐlc[)wZj _Áòž_5ZFÂUر¯½É(ôµÙóS­Ìï£4»ÄŒ®îMP@–PøÇíöÕNŽîøQœÃm“\=Ùë
192
+˜h8¹¸–G–ËŒ³yúo@gZǑXFž™[kwÍv¼ÞV“sYn‘ë/1Uáï‰fª7=˜Gwxc›¥Aí)ëèµøÑ%5Úfb’ŸØBO!Ð?¯¯þk=½
193
+‡øñW _=K¹ ÃS¬˜ ÝâéÞ|J™ÕÐ5Y@ X…>cä(˔×##6÷"ƒÂEâvè¤qÓh†·ÖìoZÒªh%׀£p€mHÑ8¥¾ûD_SkÁÔ?#¨ 7Ü)Èk—àø5/K.qË*˜D} ¢¾ëƒš%i}~Uý×ð‘ÿ@ó>8~kâ|†É‘Ãïè›éÃ[0‡‚Ï¢õsâû”H<ƒRàº]¨¬0vÂH=÷}˜F€È]Š4âšg“'WqH˜3,Ñ^ñ2ñ”2âü0]ˆKĆÞøB;ÇöáLf[~¸8ð‚ñQ†×ñQ’ÕÇs#ƒ_C‚çãu»e¦áE+BÊThê«×W&_'6V1ž®—9;|úÄs|ØÛ‹iSšYRwS¬Eßæ#©É&;¿¾÷¤úCm¿$±^~2™V°ð^Qgì[¡Œç†M¾€Y™ŸRþá´l÷P8¶œ=‰õýè€Ð28µ¤:£Tx{#E¶z<"3…é¢!>ßeܽúqeÂÛï0žB›Ô(ÓÔ~yh?J›„:22aeTs.‡Í<ÿ«1„üŸ³ŒŒj†n‰Ú¿;´ñ£ŒE*>ód½»U`ÜÃò‡òŸ '> ˜­[®„f«éÑàø eEþNó}‚„K™SHáà–“W(„hª¬=Ãc q/+ ºº­iÛ:Jø‚—E¿¶o©ûFɞIˆÉxV‘N$ߚÂú„C`Uñi“£.û¿WAWáRHØ^5P‘ýe…¹šó¿š+YŽãˆ·€d¼wΫX¾¦ 8 ØTÂ,°!ï|í=ÇoâÔe¡>k> ?
194
+IõKÏBiݏƧÕàõÏ»~f=üiû._§¿ÒÍª2ÿ|ò¾DÖڑsÌ ’t¼1°Õ¹îƒ{1?ó_¥,wX7$Yæo"¬ðoöG†I퐷åkV¶ò’à3Ô*‘Wš_Ø]ÈGð·NÛw ÐlÊÏԜê¿pÀá8Àsr BŸS¦Úô;DÐt­ÌÚ~°™Uæ5Ÿ—è!M
195
+S¯0Ӵдxye2Z¿ J£T¼›#s¥~Ã+#o>÷’ Þä±Ü%Ð0´>â|üôý´ð@~íÿͳ…a·"Ä¥æÛÃ,ïÔ -òêò~'Øõ¥=À3ÖæßqóÝU×Ü
196
+ó•Ïu5l[6aȏ8ãrÑÆÝ¦>Ü!ڝ`­¸ÂËhvZzM“¬­¯).?<$w‰‚½¶±ÄP/"áJz=ÉðáÌ{ò4ö SӒXëÃæ1EMëÅ™­*¸êH_’ËfdVŽ8oiàq$󄪐÷ÌèRZ °]&«ø¤C("zϛ ±!gWâŸå@p’¹öóuËÛ¡/x&[ãiU§€Ë€9ñ”½‰ò¦ÿXj£-€­ Ž×d7yº†eŸ“hÉŠv7äèÛª˜-:4+­Õiâ
197
+cCB‡f˜j–3D~ꗁ÷‹.­Ût3uÔd‹¹/'uf)re‚Êxþ™¥jçY¾ý‚¡t«µϱç¬'=(ÑÂí KrœêVuÇÇâ÷’Fȍðˆ\!‰’E¬eÓ¿c²çŒ–VÂssbú·!7Ñø™Tíô< ä‡@‡i‚0þÔ3g’¤t64 eÒëêzÁ°ª_³:"¨ïq'ígUž¬rʟŠꏓ6!þ燴ÿ¸BšrľÏj¯`–²³ùDUŗ~]÷‹qAuËïàö€7&Hzd¤cKD6|U`à³Ñ™5LS¯¤ÇË=~ÈLÔäÌÍn’ôed.œÞÊE†ÆìIÙ›È9;¬¡èÇbœ7Ëœ½y€ûê[ŽloµÏhë)óÉ»Û"üÐåÊ0¦×ó ©9¤C1S*ÐÅhN8 - …TªX†§x° €IááøÅ m—kVàù˜åê|Tõág<ôÅ u¹:O b[€ÑGôU^j®ÙªåÌÃ:ïÁ£[cÐ¥—h¢’ñË4*™x—¢¡‘"…¤Ùæ·™î¨Á9K„Y.¹¶ã‚³—„¡Ñ‰s*ö÷X#Ýi.&CUI2R¶dâšfíþp!x¢Mdk{úÓ ¿…2x²ƒ-…ˆÚ:dÇޏêì«z48|ڊlùΧ䥦°7“¨~àÐqüm¶í!‡Kï–Æ²Ùc²„Ø)ö6Á‰lu’~ù`Yj&ۗK'–fZ÷µ÷~Ïq²NÄz‰y©ŒËâö{Û¿h½†Æ#E.„=W°/N6º¿š¡à?«ÎÿŸޜ†CNü–µÔæ›È…X€ÕàՀ.Çê{¼±PÛÿ ”:é±®ý"­ö{.†ú8Jm‚Á)SO~w%Ü2 *ÿ·¾)mÄR
198
199
+­H4»Çým°ež”Wh~ƒ?èá²:õšÛRk¯ýÊEBô·r~ž%²Äã~ÉñázƏ ñ†ñËÈÊ­Ì4%¬“¬1ý„û2ñ8:3@MbgÇBâ<ƒ¡YÁðáÃ&hÕ—|<ª•d+@‚¸¨&ͨ¨”X¹‡%?_šµ–ü70”0k-jÀ’Bßakœ5 ‡C }ÕzóäðÑ7ú½¬{¥g‹­îBLø¦¶Û¯ôWKõhpVƅŽhܱÒ|le z_ö£a»i&‡çOL†~ùİEÌB´q.0¦e’TÔ~˜|!Ÿ'—:³
200
+{RˆÉBò¸§š8¦n(¸ôùt_f*å±)’Pð ”*¡‡7KÆmP¯R7ÞÛ?æÔ×+»‚7ôXÚ|³‡ôDx£X¾ q»D¼€]êü!+AÐNÝÇbÂ*Ã/Øaÿ?$ÐØ¢Ï5†S;X¸Ö
201
+ˆ ðß|ø±túOƒPÌ ƒåD¹¶›µý×îR|ü&F`FH¼¶Í\“#±°0R¯…>AO>|>܏'5 ýѓœò[æÊÙ Y4o 2­aÈ +å-yü4g¯$™•?´ðOõWN\ž.Ê ûš!ýق9ÔÂ6n˶!–†Š¢h»`®æ*tñm¼.­Ð\RxŠ”3†'Ë$22=9(¤˜ ×El}¿~`s<9èk5_'ÓæzuÍ:š»èlS´ ƒâTlr%a¢Ä¦È–1¡Á7©Æü„’Ë,H<Ë4‘‡X+áõöõ°åOŸ}b†Ç|á¬BýVž{ìó3Åf—D?@|Ø º±–¯ k{0h’võÿ¼lʀ°@‚"8išX0‡¢­^p">èi`Âòé ë8n{hûÊtóō•^±Ú$$¹+dîgñ6+š
202
+"¥užË»²ÿÛ%ÍRr‰‰%ÄCŸ÷¶‰sÌv¡Ž¶‡Â÷—7B;“HaG¤´äß+Žê‚˜(ÐIÀÄ%“cÅv2_z4XGÌù>—-ÓvìŸòk-yˆUûh°B$.¤<Ÿò‰ª
203
+f @ î¡Þ7]+öPç™rUïbáÇ&àʙºä—±ôü))ð ‘×Ä‚5".ØöÌnæ“/àý;ÊÚÔ&¾NÞ¯3Ú|‹Žfˆ
204
+ƒ½èÁ˪[zâ=¢q¿–%Ã7hŒÿv˜£Šwçp«R®`Òd΍ày—8-«Jy4¹†jJÝnGØk*G +*ó5Ó2ls.~w˜¨PM¾Í6ðý ú£øŽÌrvÈùjÔ[sèP"O9ÔÌÄWüÀù0÷²*¶È£bÖFH‰äÐCeaÕ©`)<qéÐèvyN™-£YJ>bô•¡ÅâZk«}ºúÓ ã¾fzï”,¸½úÉ{‡JN”<ðZ ãµðlæñ&k¹ŒªrÉ+õ_ ^Mʒ46Ù=èV”þ„¥tYsP+BÎ8#©[Å$Mv\ö>ÎdÂ$Ä{EtÏ wŠà’T3œ@†1ý ur»6ó9ZgK¹Áx‹9Ké[\0ES jÅNš´ó-HU‡]']gÉKZÄMŸ“Guƒ"F³é:<_‹Ïí¤ rÙOÿª›þäœF·WÆüô˜o¦Ð-ì'ێID¶°È´ŽÖº”ª$C¾C™4gõƒP‡Èeú­ØÝÅÆ„UqÉ6“·-/$ñʁ@dp6‡r´g£ý4ò"ìP°ìµ¾œ¢F
205
+ÌÊӘ.
206
+¿€OÔF*å&ʼnԢl‰ƒ›\v$˜©Ïkªþò'ïË^Ê,,zý_ -]§ƒF\¬—iZÍl˜U>cr“t‰sŸÙQâ$à h¼ÏÄtOáÔw°ô—¼dóT´‡qb`xà.A-§7;Ñ¢má b°´sdzxÝ5m.,uÇÂÆÅOœÚ´è"e³=ƒè$ k¾€õXWsè„mãV^7Ïل½è®Û?:^s?â±já¿À1F|²)—3óPãŸí Õ8ÞaÐ!°¨€âÛÚ¦¨DAô³•­‹”üªËU”?w›F‰Ž“)6ŒFÄãj4åã•ìz®€7}föÔU8R‰ü
207
+¤!Òöv0öç6£œ[X+"TfIn¬ÆÂ¾dv\†t*;i²d#áV¢B‰©" Áó܈‚s-ؑ>äCQjÛ͇‘9)´ÐÄ$¦l=YÉÛ¦ßæ+̳MP1Áí8Îç
208
+£÷mÈÐ vɨ¦å‡(ay›÷þ$˜UáôãÂõ«$ÂRy ]­#Ém-B®ö0Tz™®S+ ¾©†µÔÒ;_•ÑímÛ¡¬½ñ-c‰!’r[4ىðA†¤ðÎJ6zƄ0˜Ci/â
209
+v0:n«P?-b½>î  „”àÒٗŸtZñ–“»wE'â‰b8ºDÈÚ.V]¡lM´zÞÇéq>Ø©YÆ`Ó’¿ä>6ñ.6w¶©I´„èÌYZ æLq><´‹ÇaìÄ(€'+‹Èj™ƒ1ü‰ç¤Ñ>6æmmFVq2œMd@Íº/ú Ú¯ÆÃ+¿½æµã±#:)%\&9»½—Fªiæ@!çh¹1ó A¿›¯ RÀAveV=i›Áí¨þOÂæ{?©Jz°â¹¶Q0HU‘Õ(ïí<è“Ñ0ß¶ŠàdÔ÷Mۈ§8—CÕr]v±:–Ÿ¦OÇýÐXíäg7:Fì@ZÇÊ#[T ÖÚjÌs
210
+ ¯ýþZGù(M÷Ĕt»œÉ*%óUb蟘®R½ýÞÒPÃãœ5ùlèйÌJ+5ô‚gf›ž»§!eDñ^Ì…á\žg9/ÞÃte¶d#£É3Á[wººˆÔ-x¾ßüáã„Ûù„’'F ¹~3$ρêƒë1@œ ¯˜-¡"«oÀ0›™Æ™p½Ð&(ú±såPíÙúÒ3ĶíÒX]l aeÆÈ¬Vò3Ÿg šÑKð•yê Y[Y æ½xB˅BÐNßëý‹¬Y…@CL\¾LrÔ²žÓñF@{ñß/¬yØfړ íÿºFÉuZ¤Ü̳Bgÿ-«‰ge&pp~“ á¥Ëd`J”.ÁfH?‘¢MvixL~7Ü㗯¹Rˆû'G (~žº­L:tX%N/„äë‘°´X!ósLO /;ô‹1ìv‹öG,3Å Z¸ôQ- ™•Q‹&È3nÿq[£½Ÿ0&`h™´WŠÎpšS‚ý÷ù/@¨ÇåÄ~BY¡Á8$8T,œ(Óo(‚Qº¥ÎçnéSª¥L¤<:ùk ÈxP܆œE;¬:å=Õ>b±‡ž~ øÉ`âBéÎï<G(W÷a‹x“ù–Àéþá;é<dZŸß’‚IÕㅛ
211
+¸š<ŸŠc›Ž5êvÎÔyÐÙu=UÜ«À»® h_ªÐÓf:X†ámïÖ!/„/•.³À’…:W#0‡Õ«ž®›=xSµÖXêøSX#X’Ûœ'GÛh³š¨*.`$œ"©{`µöqr$qæÊÚâ-BÀQ辐 ˜~5…½PÄ®9ÃE•õy7:Ñvˆ\n}¡RÀp±U—À vµJ._‘=Ò³ži½™­¼Î7Jœ=€87¹Ñù1_=›Úêí©Λù»ñ Õ$[PaƆˆ¼²ŒR©¹ÔÖk
212
+Ø× Ò§ÂS N¿Ìšøù3KÇ <3 UTAaPhôoNq©nGB#DgDŽKä9ÅUÒI¬':>w£¼N!YfqaÈaäÅv~$Ô((Fóõ ”=‡µ˜HvˆŽ˜>>w4Wß(û–Q>rρË@3lÐp¼ŒHrš‹ÞAê«(k¸î™jk“·Ñ{+/V@Ku<Kþ£s^'y'_ã'ï5ìÉ{Jpò.COÞŒ÷ Ÿ¼s@¼ð}øÁ‡äð¯þé5 Weø ¹ð& ÿ6*{ÂßJø}„B¸ð_îàì°Áëü-8êÿàÓÀµøZÇx½€p àGúï»þ ±¿Eù{í~ãõ»h~ÿÇoäß÷•®Á¨ïôýÊ|Cܓ-ãû¾ßû³{cmï7ÍÞ'J9O¬˜r räÒcÈA2>2xJ92Êåöâë\œí®ñœÒä›uþ/“ë J€9µÁktí–óFÆ’ƒb ÌoØ8`!8X§,‡äæG.ÛÈkI³eA>ŽIï|ü :Ö8ÿF¿kú؊õûVýÈ Fe·»4u¤äw†$4…}4šJõL°¯1ٟAUs¹¼Äu>oë ¡5f̓#¬à=¯ö„«£Ê5ušB€ÊÀ•m4”ö_™ú—„€/}ýœ²ƒ:xÔxJú@Ý>Ë&}uŸÎxÐû_ˆŸëuøÿõ҉Ó×y#ÎîÕ?·ô÷!?èõläý¦M(ö昩5´M¿
213
+ƒFzöߞƳžwdß¾ùb×Üe¼†0zOcA öëgúúwZQØM2lì9÷*‹WŠá_µ/¨I?i™¦ƒNOmfëùô¥1¨h¿Oñϵâ1÷_îÊåE"¹­&7Ç@¹&×+7-åFúäê&wQc¼°\¾Ú£¢;)³õ·íñFݺ=lÖ^j[ÿFC÷=µÏÚ΃´Ï‹.׳ß#½\GJò=þìmvÂäìnö»P³¨8fEb—Ýh–¥(Ӈâ_"Gþпnwñ7nùäÇÇ¿ãûIáAƒÅsÙÛéîùC@@ü½Ñ‰Ñ¥ – þ³ ŠûY/Π‚ïúÛ¥·”îêÐr]ºtWàËW6³Ó¢ ¤šÖ›®6õÚ8Nç)‰Iï(xØ%Œþ”HÀjL©Q_~ G}XÖcàIH@‘_ñ! ÇU²€qŠ «ÆÚbXAÃæA „“‚Ê­Ö%,¤È‡‚ì„,à S
214
+ ¥¾΂Ã/l)ƒÚ'èSà92œÇÁÇ/Áé݃³:_ßh #sù®-?K–šËJü)¾îöxâØ& K&'¹æ#JÐH•çáb0\ďñ{|Ú!/:8d¡6þC®\|¨<µ¸CEAFÖ‹D*"\KÈ4Œ8} –yH …OB|X÷xíð>ÂO#•Ê¢k¿söaÿ¦,{ڟ@ˆJ# ƒÀ‹ŸÒ_åF€ÃÕR:CÑ0õ¢Ç¥—^$Ô/ ÷§Îϛʰ‡E;Úù™OÑ$ܧˆK¦J±Ô8†ìCNyh8é1íâJ2’Z‹—~Ǭ¯ê×(¨ëN_“Æ[‚<øUË Eç1õ‹óð" ŽŒ¦ž-׆*gˆÁ9JQ€Â®TˆÃAX£[oä¦ÿPóäîªck1LJKa=»6¿@_‚»ä¶Ã©>8gÍ0üoÈJÏà·ÝÈ8£¢ú‡~Vû³œÖLÈߥ/H(^]¼ '»°ëíÑÊŽW̼]¹‹{(ÇîNĦ§8Üæòë­_°a!›Tº™hÚ ÿ*ÿªA¿?þç£$¤ÞP:o›¡»ó"5šàdJ”–qé«Ò».@áà,b·"óàʧNðŸá=qá‚RÆ*Öæ0¯Íb_jq ýíï£ôü K÷ܧŽüß%þGüOg3ü”É*Á':@EtÃ0 Ã0 Ã0 Ã0Œq—[`«ÿ5 4¶Rí·¤ã¯?Ù1hBd0µ»„¤”ì’"Cu¼îÛ¾&hgZ"¬+ØúñD ª…ÜzS kì`F.}WPbÜb“.Q|Ú[ÞÍ&6<¬ªcB
215
+ªt'ÌñQúvY¿¶uC‚à>‚•}ξµiäymëPIéš×0 6!ÏÖÏÀV„é÷aL¾,C7–€5^”3b¥¾Ë@Qþ Åp/å@/c)rß$aé_FÉ7°Ú4àuà³zd³×8?cÊùWg4ÙR”åŒÄŽ 8›T€ÓœdùþY,#¤Ùà`|Á"E
216
+ƒf*Uyû
217
+HÍc e*UK€/“ L«”Ýš[Å$6…mÎ3@ºé֗ÅD¤‚ß’ƒ¥8H7EIÒMŒ¨Tœ²{œç3lZà)‰W…»" 8Õë_/ÌOW†Tç¹4€ÒO ÿ2MBj¹µGiçÈtÙðâ<šÜ'æÖ‹‚¨.£Äf—½ þe"_ö!ܖ¡#Ï̆žÁ… 1ˆF‰–¬zò2g¤á°Šòñ˜šôV§£•wÿTsM\[;Räö·­·Þzk‘Þ:áHí³’7@ä}kU[àš9ÚCc9’#ja„î\6<¦ØÚ9ïW°¤àԅÔª«Ko¡-ÜgÙUá JÆJ·^3ª4 8X)؍ïÁá…Q诹V#.{̱j˜ò”å­·~…ë&m»
218
+¬Jcë­0¿n]ÐēêE0ëq€àú=.wû[w¡oýœÖrgâwd„x&A¬á&"5¥90Xs40ØßR‚`2G/Sl=ŒN«ñrɑ†k3€Š`,hM”-/ŒÝ¹²\ ÑR̵ˆÍîƒ2?m¢/µbÁä4‡“V
219
+"Gx+ûl•në|á½rA5|ìÇEzçA¹­WÖæ¬†æ áè
220
+HÍC`e¦¡X:gǺ¨øÖr¯ŽYz*á˜*Ϊ€ˆT÷í‡õ‚@H·ò9dY…-'Êòübf –e(DöÍó8ŠÞ0ý2còe—OÅËTóOL‰ð:‚“?@`LÏ~®gY…Ä €äo’–÷­ ¤‚Éoj»]2‘|AZOÍÆÞ_“÷“‚üT—T·£0;NMŽGé&ï¢MarRšË¤X:g8‰t¥§a—8b¢ïê@ehâ'ºWb oîhvl÷— 3»„ #i"îßËäÀi Õe֗™+ՖmÎÍ˶vËX—MüË4eË>žŠ÷1(ð²+âZRáz˜ëä߂#îï{ýÁ¹ýuí0VG~hJß ;[Gº B’Lp‡=Jn…cĦ/¹•âOÑdëÂÖ“­~3€j`ˆ'"ñ`ÃZ®-DùI?Õ!»Rëa‰Í Ë}$"n~ÖaÐDºbÐÔo*œ»»ƒ®ºêõYZQ¥°±þ×A„ó脅[o­míi•)·µê©” I™iYKEn" •<ÝtRZmð"Á /ÔEºôöÀ¤€˜Ig \¸—`«ÂÝDyÕÆˆV²u •Yô·ö*Ggr[ϪË&±Ùe¢ ñe ê^ö{Y¦ÅºCMHRÛG¨‹†!"ܺ"sJ´!¶pw½£…oø,žÖo½u̵‹¨¼­SHÕÛÑù“ð…[Ÿ‹õpÆf—M‹õ­±Ùeÿ2ÑâØ2 =ˆPÓ蔨:ò”¾õúiÿp¢¾‰õ؉{TN¹kM[o½õÖ'„ë5‘Ôö9 ÐOWÒQú$F_l«Â)ž‡÷¬HŒ»¨ët)–Òç8VzrFÚ¿¨…¯ŠòL a.ÏwH16Lp—ü, lÒ`³’¶H†JêZH,|ÓJQ~ë·U(ÒR `Ò| ";†e¶•bqÚ#pÂb1.äb¡Ð&™CØeF³ûöèäÿKºÞÂߖ÷—æ‘øý4‹þǶŠ÷Ïb¥t9ÅmÁÂÛn–Éá[ŌC(Y“÷ÞrLVÊhv_÷z~ëPjñZYjZªƒ¢É{æÓ2Ì.9;n”Ï¥e˜ :òþ¹Þcä?Ð9w4;/žá®¹£Ù$lŠxΰ)ç¿oÀ#ÁÁVÁ·~¼DÂPrõ֚_m;é>=`}Ý·“¾(Op_ˆ
221
+*¶“ÞPc¸/|;éŒ3é[/ÄvÒ 1”ó 0ýFßâË>ŸŠ—y=¥m†í# sj}5?r•Då”÷¼«ëN{tòñêznÊß¿¤Ë~®WŽ\–®Öoý‰­ŽÚN㴅·õÛ Ò¾B9ÄHˆÛf/9|~뮺<ÿ ð¼bäùx]øU(´8LŸçx[{Ýëùn«žç`ŒÕ=¯$<¿uGG” "ó’Šï@×ÿØâٗ‰ä@‘KÙ [¡YÌbö`U8Q–Yqy ùè…(ŠŠPš`¦• аè„^ð!tÂH~‚WˆñGBW„´åC€´¥^¹n?„Nà®,žá•{1ücWñY†g×tÙuJèz€Áë”à5iëLNI°y¡$¬LN9iëHJèšõ6OÐôé%tB 0ŽŸ°øžÀPzŠÙ[§X’÷Ú$ ÝÚHìˆ Aþ!„Ÿ@ë)­w®‘.˜ãõ ß)’ØhRTaµ²¢zI:¡È´"ÂPŠœ¹HÛáÖ5ó”N[‹©Féƒ>[I#ýwEú h4;‘þèÍn$ø‘O2m‘¿õ(ûœÕ:^P뗀ÖïÍ|¸ë÷<q*¶ýÒÖ?@6´}-%R¤‘c’rƒÓ9f÷o¶7%¹ýÍhva< Â;6îC ÔÅEùþUfF³s5óó®S—ù/éún±Œf×KWûYPਵÞ¶<<OñN[åJ¬î¡£ž€gÑO>tìÊ1!޼' ‰çeâÝK¹¤ÿş­YðÅQŽ"^ó´¦Ê}jaˆxX' yœà­K…o' 4†{Ybå î}ÍZßÁTDZÿ­]þÿçý_2å­Ý^r;çܗ÷8/a8®RÚÂl ¿Wr{÷Jn¿œ&MË ¡çyž·y~+õ­”96·oۚ۶æ[·^êyàDYÎ>p”©Û)”CÝçŠ ˜WV'
222
+Ú–€‘fÑìBÒ,;Èç•Gâ{kÁä}¨¿†@ÄǭǪUµ)æóqG>à¾Y¶0·§Y(D΅ި#*UK[e„FD$M’áƒ@0  †ÅòtUëÀ@‰ÅQH‰£8ˆb †b ÂD TÎ0…D”Æ£ÚWèè„::)vt2üàC`‚»L¶Ó}\zËÓlüy^âK¡ûJxºCz+ÜcH”’¿Uh‘ÛôDW?¤çèÿy§ÆWAgxTOÓ£Hi*G`‹»ËÉì혷?‘eMŒY±+1낳6µÏž¢mYÌÚU«Q˪˜`ÖÌâ>ë©2X¿ß¤Ý©ûÿ,ŒŽ¢(»xÑ'.Æö-+£’gV²Qg#¸óo|¤ÞŠ,;i$Eƒ‰çõ ¬¾‚Ò¶ìÄ'·7åà@Â0Ã(t2°’#°R¨¬Ÿr×ä)¢…¦‡êz„/ûßuz®õ–Ç!{°Ù1‹éi g7º*Ž—›˜~@ub#
223
+-ÒØðÜÙR·ï¿làëD˜rÄÆ(cØu©¦D•K<’f„M‹Ï'-Bٚ↤”–@uˆlé61¸¡NL™V±ÄpâbQûuŽaì‘õLa *†êÁïž0‘8T¬BX%@6÷Íw¨`è¦~  ?ò‹ÛR(O—½ÂÖf¤woŸP. Ä4¥ª¨N@~ °¹s9ÅÌNI9åYjRŒÍr¤„S¢¨í­ ÿO•õj±¾´ÕÊOøztÄCÒO’‰š33xîÍÚìÚºr n>c4“Z%؁YNEÀrRùr¾ C%´¯1)éêKž®äg))›gͼ¥uÊV^AÔ93ä  R}TÚ®QZÙhò@%;ÔI^3KSž’pÆð"&hæ”4†„ò,<à`MÚåÖ¨O™ñÄùŒ‰‹ir¡ÔkÃWiÀö".0¾{70
224
+D€Û½eGDdû.$ýOR+pËThÕR¨q Õþj6˜N=gþc¡÷éòè L˜{Ø3X‹Ò_/%† `‰@xš]û]%ö ֍Ʒ+ˆ‹;Î×.ô€ÚDÏ0.Ö¬pWð F™ó)a}Û=T~B°¶÷‘.[;‘+Z)„ܹh;ÄßìE4¤ò&ãø¨MŨ:q½‹Å"V x`‡wÐâo/O·ÁÕÎ]H¸3Q û76x`P=†ûBFɔK¬ÿd6áëën mÌæŠ1¸Ö öP¡½ê@Äü8v*ßú96™$M»àºc¿öªbçŒ'áeêKÀ±þVGJì¿@zâÒK¬ÉnKO*jÆ9Ô³8«áöi~”nµèÎq{p¨:óÜËoSÓQYÑ {ÙT’Ž]ˆÞû«ß8$² &ˆI .EÆbõÓb‰…ãF;­¶J¹ 1Þ/ š‰Û-[ø²±i­͋[¶ð—-Ý „<¶øe o™p¼L8|a<r_¼M@añŠÊÑá„Qrh¢ÅÜå /œMbLãnÛóΡœnË SEÞð’]ipJVN!y‡Sà”9 þ?Häµñd' ä´ç2"/?àäàD9Õ[ä´ÙNâ'§uµk7ß~ ä ڕA‘wíQïåd$“K^Â"o`qi–Yæ¥hyÿ2K¯¥ß-ò–5Or Úఈ¼d,±È¥“—P,ò¦GÜvå&ò
225
+È;Ø÷%6™û‘ºœ#w¨,•àQåÍc1ä‚#GýÒ K­µ¦¬+J· –°Qk¯mÑi›"XeÁüe*'o’`õÐ;å}èêò•d‰X$›zåøêÇ…h7PJ葧SMû=üࢎ˜RÏׯ³“™E”þ±tܝP¹ õ¡à“î|Â2­‰M©dtéWèhWÄpd¸ÓfAô­Ôc/e4Kª-XÌ´™%¡ˆ%EÞ,¹öd·=w%–,ƒ0K–zJ&–\Ì³Y’ó V,©i˜%)ep],©µ'jkÑýC¹xWÀh—¼×Ax0ᘤ“ýóc2Hé“AޤœtǤãïÏEŽÉx¶¬Ã‘œ7I“EíýË8óð(¥_>Ÿ"¨ìÅSC2’E,ØÇåGÓ+䯞>î\AöǓ0ÔkBhm”?Üt&Áwò50UìLÔ×?3±Wƒïåyx!›ÉÒMárkåˆTÐ gO§Áý¸=\yä€B° 6l+p!ï$–ë‹ÛM:òÝ1±xÿE½â™—¥<jÁè˜s]K9áW ¸”&îŸëƒ*{åø® …tå ˜³åqÌ#±ÙП1áHäޟˆ&†U¤àËln ¤µ‰Ú{®N~(^‡iŠLTÉ*,Ä v\9aAë .÷øö‚Ì
226
+µòŠ$QÆ µ§¹$$« ð—ë.ÃË"àTö.Sõ@‚%³G$~ü;ô" Î~>õGŽò˜˜yyN¦ä̜Gèø¨P
227
+w!IÅÃþʤi‡Ë‘.’g(6q슻lIÙµ ¯!œ‰Ä„×@ã¬ÉÎMÌå…0ï ƒÞüÕÍ'8 6GZæÖmæð©Œ·TOx±™²¨å¨5-@À•ˆHªå5ìEÍ`vˆ’Ì&5 > „‰ëþ}Ÿšp[€U{uûpNÚÜUÔÚ¾p‡äޅ5£-êMhórÈ<ýÇ|ÆKó±Jš‹» ³Bix³ÂhÀ‹LB‘}.ŠÕ“á¶Þ#ºeaoj%·ÍMZ1ø2n7kD[…ºK‹¯FF·« š3Ķcûht &5†=¢w]:⬑cyKó˜Œ.ÐVÒvÕ/éö'(™â1„Z¸`ì¿åFIŹûB§Z°*ĹïÕ]H<ªo‰U²Ä  ÛçÁãO“Zs«¥þû `€R¡¨ŽD™Wí5 âÃJ
228
+Ó+TŠt„ÿ—ÎÓ2[ŸŒ6šæ Þ ÀªÌÆCxVàK£׌…)^6Ü@ÙZ-Ë9\´†;‰·4[Y•¦óá‹·EaÈ5E*©+M¸ eM"«ò.hŽ<Ã4EÉe‹I ]„Z–M™*ŠDêÊB®ïÞqü¬W ÈÍÁiø%E¶ÉÆeÙ>ŒJ"Â7MY¬ÂâÚ h^3k˄šû<«GåA,˜OèŸq3e%‰}Ê­´’pTúúþtE‡Û÷¤`®ï[wz-û'¯5·‹¤P=[t=xÒ·¡’¨ü5*çûÞ¦ÄM/7‹EŒ[^‹8˜©!¿íþaÂû^ù‘ä™ùíÓ2zÒ'ÇÔ5FÐ…»9¾ÌG‡¡W‹;ȯc*Y°PÏxëø“¦×P“ƳDC¨¹¦ÐþdßL„öIsñ KáäAÕ¹?TF‡A&©FßGўȑÞ`b†qÓ/ó°cDՇêÝ.z0I ïi]dE›øÏ&í,?¯-µ<E[¤–8Gcß¥gF·•X‚1ó–dˆÈþSd‹§ä„®ñ ¤Ï¸VÈK|ú€|¶—dŸ"›ëöúôÏ*²‹ n…#ñc¤sAPû„·u ïtDÙ§ U6éæ–ë‹€ÒLþî~?Nüóén·àý|Sûÿ¿Ç¯üÐM¿Ýí·?¼3r±Òø¬œÁ;½Ç{ùŒÔânèg›ý‰#¸; é€hɀXnVåòÚåO‚wO—EóH|ÔÝëØ%v'¼eE#ˆ‡+Z¨»¸ôüÙ*²Ë1wÿ÷?|$²»—û„ӓƧ¡
229
+»hh‹`zòÞ{GÓvjkp·?Ë¿%Q¨¨YUkY4M0: ~¼ö1€¶yÿ,F˜^陶'ÿÓ-™ëäÊ¬v<éý‘Z%í§mã8Ae¡;jháÈíãKNë¹×‹ˆßá¶
230
+h{³$Jz«d”ó6:©ójÇmöRÎrΦЉáY‰Ú^åö¦M^Ι¼Ç±“¯'ص‡ø›äU€åâGÙ wÅê®ïÑñ5û¿cwFÏ!<×ÌéaËþÁ ‰¬oâyê8Ä태èŽèAÒ"]™»^JDJ„¬êŸˑ¶*ÕV¢Ðþâ8‹ŽrI,#1ȒçÖ¡±÷ìœBìi-ø»ÆVZz„ë÷çÈzßUK…&>Örl¹¯íqÏZÁ¶„¡3¸Ù̖N +TÏ2?O®íjõWn' &ºŽ¢:O|•¬‡–]vÎË© izþѼÙˆDQ=„^Œz,×Ó`³_`
231
+Ùt1t—øŒÅXýŽ,;L#Ís2"á'½H¶Ëy¨ˆ¬‘!'×|#Е£%¢c»2„ÅáבëópCþñ¦- “É«‚ ªè¾{›WöÙ®d#q1ÓpÃÖJçü`&ÑÇ©.!J7x §«”Ø»º ÛûµÈrIá‰L,wL¿#±ç×l€U{ª”lٚ&¢rëÀŠwº¥[E˜,±¯á=våhðÆËæb;N›m«jž“¸°aÙÇùï}V8Š\}ùY)¾¯¢ùn–e³@-ï?sÚ. Š€Ö¤ó rüµ¸q yíúS,ÿ†Öõ’½jÒs‰2ü*YãfÌ%¸ôám²¾nHñfßÎH¸·!Ûù%ýxÔ5Äl22ú *éÒçšÖ1Ì×uŸÍZ֝ӨÂӛbãÄ3 =ÒìrÍÒ-ðFÉ·ýÊGžqûŒ³F5‹)aÙ,C^ߥïB¡ÝùŒÒ® VÑ¢Úd‹×µIáÔ é$Ç6”È̔æªvÒ®ùG…1º&‰Z›. +Àkjä7åæQQ³\ó™2œs—`‡:"ÏuëèÝ&i#¤4ٕqÂ9«QÜEpm’Ó]înזXaSF^\éÅ]ÃðÒ7"%TžÒia™d1YGé¥uqþÀÉÝVÛ§DþÀ ã[0n›F‚´r þËäzq¦ìÀvV€Véµ¶íô ŒŸk3ó0ÛF²œs2u1ؐIûú’ žüõ ÝרKyîÏh‰³EÌb©L»™±ñ·«hêbˆôøàõ‹’voMúŠÌP7“G[ƒMF^k–Kßhcp<££ïø¹¯Ùšæ"„!/mžÕèj/_à÷¹ÒWx–, ïÉ^7ŽÚ®0ÁÄ*¸Úm°ÚH>ÃËzŽÉüzFËþMpNŠ!´tN`ÃáýÀ`¡ä}†à¬šwœëÒ…DW´{Ê~l9`ð¦R¶Û¨É¬Ûì»ÍºÙ-¥”=ö±Y93­Õc“"UæÙJ ÈDX-2Ɍ›Ó¨¶Â$¹É$[¦x~`u< fýì­qŒàÊ;·íøÝ ÷Ø*ÃêâôN‰§[ê»Q³ý{ßémŔVôbût£Þ]ÑLcw†ÓqõšóDæ÷¯KK‹°:ž[LÝÆGÄoGÛ^ÆØ™‡™‚öê0]Ùÿ¿ý?~aÙø„ÀÔïíXøá2ýúÇíe ¦ ¥Mi 7©Éø¿ßw³dïP°wÚÒXVœ¼Ú!½7פ%9¤ÔmµTbê"¹ª†ì^V$N-«Óª_*s-õL§[
232
233
+Ò¦‡YªÝ…¨‡­Ž§‹ ëCêxæáô[« ̙ú-P‹ý¼,F9†<«_;Sy§;-¬ž)X«3ìòùt§dQIÃ3NÇ3·Ôo®ž©cê4™‡p ðht~^¢n‰t„Ày8Á\ÝV©_*/uKA[=Ë\+Ñ ß-Óþý¯ë°-^6ŠîDÉ|¢d»+šE¿DÉvW³'þÁhZëý{ë½Çÿñ·Öúÿ÷þÿß¿?˜º8A\=×^H¥ÿ5N|ïÅ:«/¿õÖ¼šíωpÊ;©[\\&ñNŒótsWãïß9+.–‚´ê¢´søl‹öë\&,!õ{)86“ë.Mÿ½²â ¸TZu+¹ 1ћW›ÁVǚ3;q Ð;<>;çI³¦ ä:‰©¸ºVU‘=î¯ÐÖ¸zh«´5v« -•wNÃYÒúÜÏõ(É­~'˜iÌR§Û*Á;sL««ßýøßúëþ«€KÝÊ×\KU¿ÙîJÅÙzK,ïÌíÄy«PŒ=ö^ÿöi°QS¹zHË0œ2S 
234
+Í¿ÖûÇßÎFèÅ¥ž§¯Lâ[ëcbÜemݧ2–J[=¬SÊ{ï—U—ÿ½Ç÷vo}F`êbõ[=י§‡UfQqøuuÒiÊ"Ri©[,ñŸN›ÞE)Êãڔu'V•áô Zê¶Î$¦ó Ìæè÷oIOpõKc·†3¿4fiÌʼËѽy6FxNƒ;]¤yæ–bÝåø=~aQYœ½2mù­µÖ!vRÇ2™+˜guÁDÕQːpÆh´‚Y~Nüzù_ÿ.¤²Ä¡ˆ¤â}¹ýÿû¯+7¶V*sWiôÖ¸FC2ŹNdôÞ»§µ(ŝàr« ý?ý»W[„ã0¸3¼2·¬ñù0~ÑþG­³sgØ£Qí½÷$'S¦+¿õûr¡Ä=®žoŠŠüom%æÉp§c7`¦ží”!©,„Ý*ýÿÞº«•\åœ=QÑÿÎmâr«ç‰Uýb؉Éïí»IªÕ‘`«‡2¬n©Ìô†3çšåõþÕl~HÌ8x"¢ƒ¤d‚¢›:£Ò »¬þ7¨5¸Îê·*!¿5/ ºp
235
+Ш‹¶N¯M]ô¸_ßɨ ÞÑìl=r-ò©ƒyÎØÅÓm~JüÎ6¾Æ²“çV¡¥ädêYT†4귆TZ](57F@î̯LÖ,õ]¨6úǽ¿·Eh¦ÒRpVÐÎØÍP×›'ÊS Bê¸Åó¶~ïÑ+ÔL=ç)« « š2 —‚¶Ê¤Õ*4ckÞÞãn‹R®3!W§v&ځ°ÓŠ4þwIz’ý‹Vç_k¯KU°¬2äz”ä·þQ/«
236
+ÏQp)8cv:£ ÿûG/R6=ò×æÝ 4î½oŽŠØ<• LD¤wŽ˜pÊÒª"¿ïݣ平C™ÌÂIjò; g ´SÇyÊÛ³ÿvG˜' >ܦý5Šbi1u bC0Fïõ×(z©c;%®3&-7D8¨î“ý³ b‘«ãZýœÐ¼¬ÿÇMësßÈ7¤ òRYó3â·»{Ôu
237
+RǼÓu¡Òüëçz„ÄV·µ¯MYôÿoM«L]†©Äªñã¨u˜ Ò•ó ¬Ž)žTz]œ¶&+—:U%)Tê*=Ù¯7ïv)Û©0eŽ«ò¿µÎªéáp©´à¥žå8ðÕý‰‰ 8N‚ßþ²òb§ã‹+Èå¨Èïß½¬Cyê@ž3©Ó¨¼]“ ì±§¥(¦Rɳ|nUBp©.øº¬~|íû»b“'xƒq¨¢ÓŒ1¦ÑL’¤12 0†a„ '´Ú€Ði)1C!B1„B !"""""3¢¤äÍf„cŽ€°¦hôÀ\3ÝrQ•1·2ë`VÓàr ¹ˆ_÷móÂfÀ|‚„wèÁ5=UÃG†YƒSÄ]*Ù;`‘)}‡;ÉHQÙŸVq
238
+~çaô(µ> ^ʍƁ¡°j9Ǩ h0÷¦ÂHÏT(–ØñNÞ׍ÓxeN¢RFp®Ú #ìÑT‡2<V xË#g1,Ú£¯¯»Wõ*ðFÔjÛúzǁH Vj¸Ëmæ$ò„ÖƯòõú4AÞB,|‘õrœ³™Ün¢×Ê?rħ'ϽݔÚYuÚõ¨—öÕrèÊÚ:.¬œ¨Ê‚lõ†²ëWaڑÊÇT³Ö£™›Ó›÷7 b#zŒ1ë¥+÷r,ÊYŸ´,e8ù›zŒBS^ù¶çÁ©J”w̓'wµ »û “DfË059Îy(OÉ2L-¨^ŽÌ$}éÜ1• ‹2ÚQ¸¸}ɽ]+,9Èo ñÃ)¨Çª vJWaZk-Tèfƒ¢…)wóŠK%¼äµ7‹Šï֐ԍ˜SúǗOHe¤Ðo¸Kp› OLL;ýÇ$4ì8ÜmœT¥ˆ#iÿÚ´úG)ىv?Øf¸°ŽeÜ)åsaûCð$+/Ûß+܌³úàÓ§Q¬Ã½Žî=¥ tel)hì€ ±«Ú lt¢— PO’u÷
239
+2;ð‰'ɍŠCAB¾÷QªòËh¶¶ýp›8!Ì0Çh¸Â¿µ:ä\ìç¹9çyñL¦£ Ã%ã™/%ÐT‚Dß ãt ® ¡š‡FÕ;03Üǀ)?Ý}k nñÙÙeãD€Zà ¯Õ4–¼ Ÿ1÷#h¶@¨˜áAÜËÒëþ¨W)¶\:c›OïÙ54Ñ f¤e„¹ÂŠ8’‹,¤þù1hü< ø£qã€ÃkËÒ=]Ü#¶;pà‹¸bGÖDd ù jÆ.~˜Ò)³6é5¦ÓËÖ4ÚäöaŽ…Ý³ô½3‚ùjßcÚš¢ÀËVßÙ2S”8~>¨m7f\©Läõð¹gÈ¢ÂÞrÖpÐ¥Ç !¡e&ìèâ•~ޖ3я­†—ÎöLJ˜½-_Á™¼¦ä”„€hB¼9Ô y(|"iøÕ;µð¢ˆ‚Ù »nÈ;ǦLaIJ„€*UèG£™ðTÇÑÇ«"ó™^÷ZKt
240
++â®_«@¸¿s·°„‰êbê/îv)ê•[äF'Œ•¢¸vnXDÀH⟛~»(=C?äÂc(±4ÊCð×zÉCjšWQ¬/7wÐ<É(©/±¹iZ ÷—械¿ÄØÓ’ðì‹4•›²¦ÌRDiìv+à_wH1V¤Q2.C¨Õ1E…}ye¸ÆìD©Ç9ÙÃMz”‹ ‚ðé/Ê«¡6–ä"o®^)˜qãa€EpnjŠÀ¢Ú´Ç–Œ­„”-S)ÒCÖº! ¤¦ùHod+¥uœ}‚7õ‚ÝŒ6e6õQ2‹Åˆ=it)U©Lçp¨F,ÞxeÕ27†‡"‰Ž <åÏš× — ç9‰åM|Q’Ä„ÿL0Î`v¨B2Œ¹hÁ, lW\&—8da‰KØFZ ´(S ‚F¶½EP3R©ŒCt]P.,D×~É ‡s¿¸–”VèZ8º¾ÂvŠÂ;?¿êAÖÀ¤SF[œ9.LzÝxLn˜mô¦rĦu¡Ÿ× i®ü|?àH!Pºr*îÏé¥;ñ?]Á–oú¡¯åZ±@å‰l¯Ue(5
241
+¨Ì'„H]ӟz¶Ã»at ø%B†ò& ‡VÈà9äÇJtA·q[úŽ;Ïp 4ÎÅ`Ö;]¥ƒ˜ÌZ*ð‡Ô ¸ŽÔì.ˆÜà«Æõb@ÁSµúⷼތ’ÀÜÅ]c­éy*ªñX!ísATáÆ…Ï±- ¼0G¦X«¶Ê‹ø$ Þ&÷"óŽ óS”¤¦B™š—TÂïZæä`ï3¥»×ä&ó.ñy¸p\
242
+Œ Ë<Äõ¦(Œû¦Jòðñ…–Dkrפõ5±‚ÍÃ’JÒøŒ‚™Nþ]£ir«¬Å<\8ÿY^bçkR!y•œ30Ê&c¯§PørWՉN"ÀÕN˜íöm7‰á¥sÝl‹‘WØ¿?ìª
243
+k‹Â.ÒÉ%ÿÕ Ÿ‘Ä8£Æ®·—‹SçšA<}¤Oî#¾™Dù°ÂWLˆ5‚ ßh˜t²h`܌_ƒMê–Ö²æÙÈÔ×åòHc*DSb­ÇmޝkⲎÇ䅁H7 EÃäÆÍÆe.zÁ눆¢‡¾ Ь+_¾ä¥LLÈԜ¬öôNæŠ%º‹'mä}'º-‡Ó'h(â°ïd¬6„˜÷ž¦5w@CŸJ £ˆ¥&Wôæqb–òԛðUwðI‘†,‘'êÎÝ“ÜÇÉkKþ«mÌjê=›z#ÇocáÁ öIÅ¿
244
+;ʏÊ%œ´Áï‹K„Œb‘ø)@¡ïø p ïÆw: 'PX¤'%o‹å+οb 9ÌÙx‚)'æØÐÓø~>aÞVv—Æ5Ս¤:AD´¼î†)ˆ®ùÂ7x½‰9,RØÜBC|–›@p ñAÕÀßå
245
+#ŒÇm6ü‡A³î€…|ÁÞ'ãu©{(žÅLòW'Ÿ —(ðS·À]LÛ1¬Ú:xË,fº"Ñ06ÖWc
246
+_–Wí%ò¥fWH³Gïs·ò阕ŽQ²ˆ
247
+‹©z…%ۛc¨uaJw¬èŽDD8CŽñya»qç ¹Í1sh –¼l}ƒ•W1Bz¦™À|Òåêœ# E<sYÖkY‚Öh³b´6ƒ- ¸©†+¦Žë—¡Ð~™ Ã2Î5hֆÑò•Ƴ¤‹ƒI ãœ
248
+v‹êÍÚEå“bE&uï»@Ï=9ébK‹‚CEI‡§3ðs™eá\ÔÊ!²£ÀXò(ñgӉ6˜‡°Dћ[eDE¶­V×ÔDÊ"õBQPŽŒ«Q癴½l¤ª;‹•C•ä:¼ ´JÊ
249
+Ëû–Zq—ª.ÉA]he|EK“¥¥m“)%eâÑãã í CŸ9D8¨€Ô0þƎKè%À"&R8B&Š Fã^YËìÿ·2_þÉsM¸z½zi:|r]¿«ÿ÷ÞÏnmmVUU2d0!)éz¿›s­»Þ{k ßZohhon’É$ ¸\îÿ[:±)²Ñ8ø-~àïɟûÿ÷qKéQ¦E )´h¬:iÀÎC6„ΖNì{.÷ÏårC„Ñ¡C‡Ÿ’ øÞ\ë—o
250
+)(E¢!/ßEµnBÿûh1Zmz@×„¶­¨ÅÒýÏÝn·kjjSJ¥OO„#]k໡¡C$&“I55µn·ËG­¢ @
251
+KÐY­`îj}×óݝÑ1I@޵R'ŸÍfA€uá ìwëwkÍõ¦€’™^^sssw]{
252
+ÇU-\Òÿ~öÞÏÆkÂDaD‹D¿i±jՂÇb±gggOOO<:;BDøîààÀ!£¢¢ÖÖÖæyÖ>“¤ÒXB&’°ëâÿWí” ˆ©q„Þs#šç¼<§Óéä䔓“óññÑù»u×|……†¿<0ëèè|·‹Òâ/`Kµòó÷~ ƒ´(-J#àà_]U f¾»ÿg®ÏËË+++cbb"ÞÜ|txp½ûÞïnðòÝ·þèàØÉщŠŠbcc›çùcÛ|äâ/W¡pXÈ÷]?cë®X0…e#DÎ÷þ×ëulll鈴©©éààè[ûæzs½¹Þ0`ð[lœUjrqIÛ+Y×cŸG™(BZç 8ÀÕëÀ[­Ö111¤Ò‘Æ‚… —ó®7×ÀÎuß[©Tæ¥ÅÈDQ¬™Ëü纭w
253
+Çye*žŽŽ , I&&&ã£ï½»Þ\ù¾\wÝ·VSS뻪Q,PÊE »'_M‘ ÿhQBŽ‹±/9€¯ŽÌËÉɁ}}!ÉÀÀ\ +úÞ}뮁ïÖ}G <Ðb³o¬d
254
+ÿ¢2րª§æó}×_Á@¤Æ¢Røw'ö±··÷ALÌÃ(&&}ï½7‘HôrÌjÒäøÿ¢E¢ß4–é¬Tà¹|ÿÏ]®u¬z|õÛjÖü¿Ïf³bbbiiiþú…1-±pÈÿçÙΌej”¯^<+•¢-þ¤²D5þY»º÷Ѻ¨LáøGÅ>—¼ÿÖ-PR ¨FØVµðÔzˆ~SXbËßwýßëàH*G#¬a"ž«7WuhQ‚
255
+KýôÚ6ø?sóæ¨T0#d8"*Ç¿©,ÇTÙ®ùýÿÙ§ÑžS’ «•û¢GJâ5_¾·[n@…¡wh6ÿ÷éÉrQ! Â?)Rܬüý—§dcä8§ lñØþ÷xf/²Ôø›«1†yæú®S˜!óÊN¾ïÎ?wËå†á–
256
++ ×ÀεȆ <T¦ÞÞÜü5 nZuª€ÝòÕAÔÆq}îÞßÛÛÓÈÀØÀ úÖ@4D£Q®­eqˆhEE%Ø{ßûå\ ƒoK ‹‘Q‘˜XØÝÝ]ܒz¤€iQB®>aÀÊ5±"‡OÎËw³]ÿgÏÆÆÖ÷ÖÖ\VVVPP…””¾yïDD0ôôTQQ½½½Ù1-¨° ÿ¨E é\2W¯áÞZwî‹kkÙ±±×A\]] mB19áz¿]|_Z\ŽŽŽ>|ø€‡‡÷¹rDáßÔ­Ó8JILãˆhܺ]­OJâ/ŽŽ›››U '&%|k¾¹†ðà†žžªªªçó9ãiÍ`*¥r4oç{¾µ¦¢¢êv»mmm$}sÜ Ø7§
257
+_Z\”’’ÆÆÆôôô¼÷_¯ †‹+JHሩ4ŽÆtT)øÝ<%%% #ºÞÛjµÊ²lUU…C$ZT ;ß[+(&xtr´²²®vvsßµ®ƒ ¦EY–fߐþ÷ZlöCX˜2*ÊÃÁ=§¦¤ˆÄŒ ‹Î5ßZ¿Z%%嘤´¶¶Öív?QKH£TXƒë–žÑÐОžžvvvˆ„ô­ß>B†¬++(ª÷Œ{ÚþA‹Õ"de*§Ó™trÒÁÉyû‚B&&æx<’‘‘íííå5W¦Qé5ÌÃ7›M&&&"‘øáÁѹæ@Ý÷&‘ AÃÏO–ç™¯ÎlŠ|€ ÿäŽÐ֑ÝÝݑ‘‘-!‘756}[ ),ÈÈ •”œÍ&‹ç<°é]“åog7öáÃ1I©f†f#£¿|O‘”AƒVV–T*ÅR±¦Gƒò@ ­« SBJš‘‘ÑÀÈè{÷ ß32Hd³ÙÌf³ÞŽK(ÃÑ*VgnnŽ8@::’‰‰¹°¨Ø›—L˜´aƒVVÖt:ýÿC‘RºªôU©_LFŒ1/.CŠ~QaA33ô´ät:³ÙìÕ ¢0޳Ï#ߥR©^^^q³°° '„|k^BB´aÃrk‹:•Ù6P‰"dXÂʵýÿ³—J¥\\\p±ÈR¡ÂD0ȁ}yÍÌLÚÙŸ÷~Ž©ÑißõÌ÷Ý9µs_ßs¿ÿ~öP(tkkkhhHEE%ØùË÷6))âZ.eYÖKˉÑ8âî ãû?8øg4€:«èû¬e¿û»öÏç3++K((H%…Bß»k``ÜØØ011¡¡¡m·Û>=¶jR2‘UB®#à¯cÝïµpLUø'-R*`åÒ{i7Ù¸­¿ÝþÿÿŸýÛÛÖÕUPÊÉIßzw½ûæ\o¾÷I‰‰——WµZÕ+ 1 ƒÝÝÝa]]]ØÙùèèàZw®7G1)
258
+
259
+ÚÚÚ¢R©Æ8î›óW5¯1`ÀÐÕÕ¥Õj¯®¬x.ìttppÎ÷E…ÅMMÇÆ×À7ø¾211VTTÖº:))©Š½tDÆ–
260
+Šaß»ߓ’’¥#njjŠH$^XXô 켂b8ϳ÷¾««kB(ä/°ƒ|x‰†ÎÎκݮ÷þ)™¬™™Ùï»;ÍÌL·û|>·´´ˆ††(   ƒÂwïápˆÅbõôôšrpˆ"! }ëÎwïOOOÞ{==½µµ5++«b±(Ó±±rR2Ï3^³Ì̉‰ ç†âáÁõæïÙٙ^^žZZÚU•UqHæÅeC#C…‚€ÒÒҖG˜Š !çÃá<Ï}}oooU¨6h:11 ¾/כk®åև}ï ;;hhhTTTBAA-,,Á·?ŸÏf³™td´¢BAì}ëžL&ážÏªTA@@D"ÑÌÌ É訂ÊJ°÷WoäñøõõUTTsQañnŽqqAca&ÙÔÔl6·Û-“Éä`4¾´´XP »&!!
261
+
262
+Z.—T*õÿ/Ë2—Ñ»°T 7ç654MMKhhgÛ-ßr‹TT„ïÛ÷Û·–˜ qq-«Õ*“É
263
+ñðxùî¯ð ¼¼<%“Ñhô¨Èˆ¿)''CCC]]]qqq4fúÖ䣣ƒc£óÝ;‡qyJ&¥Ñ¨÷¾ƒƒƒ/—K,,,ž ¾wßüåûÝüÃÃc˜V«‹‹{yçR©ôÿ¯ÕjÕÔԔJå… <F ð­9çØÐÈÁ!F=A…PS›¹]333¾÷«onl²Z,ZÚÔӅDºÖ0Qуsss󧚚ÒPPPɤNN΃wó׃cc'G õä½/
264
+ õ½õìo[[[SNÈÇNJŠ
265
+ Ã___tttóü-ÄÈô½ù†qyYZ"ÚØ|txpàÞ:89RJ%ÛZï½áZÇ±±ãñXCCñ±Ñ70Èß½¢¢Â!Ž¿˜L«ÕêûÞÛét†……%%%ÕÌXÐÈÀèÄÃcGGGJ©lkk›¹rayf-|T,ß壐’ÂÇÇwdd¤õrÞµî{WPY1```V«UN‰Sã/j €õêwΙíów½““S Ãqqq_L¦‡"˜‹Š!ßúÕ/ß@r‡gJ)åææ†ç|Å¿9dè¶b€w&Ó'[}¾«ÿùù óÞjUöòÐa—–
266
+Љ–
267
+FEÂÂÂììì®Î9¦ Hc¹ø“c¢€Ýrƒ»4šluë÷áýÿçÙW¨°Â·„#wwYY:89FF,†|o®=<<ˆDbSS“˜˜Øõz5S‘¡ÅßÔ(‹
268
+ G­âZ.3øüˆ„„pbr"ĵ\B¡PŽŽ¾· MÍQII¬º““ÓRa%Ùä$W­rí>dß8ì5a®LŒº*T‘ÊÅ_] –ËåÏϏHHÈ{aQ13c‰<š5˲٬÷~…v›%¥$±%$Rø¾ï¢˜˜,·¶æyö~{M㓕Ø6 ×2«‡a
269
+ªM+À–ÐÂ!}ÿçnõêʊ‡g‡ƒc£oÍMHH6ieeE£ÑRRzod`ÜÔØ(ÙY­534\k¥TTwû¿ïj·×|S©lŸ«Ø„º­Ô)?@EZ€Ü“f66¶ªT?>>$&쐐"‘ˆD"êժυž¾w"‘¨¤¤Äd2áàà¼÷2dàz÷·¦†¦¬Œl¾Ú%DÉðósuuõ|>±¬¬fdd„ïÛ¹FƍÍ1)iLLÌjµöÍ7…0xuu5s}©)œ"†…ç{ƒ—o »EÅP&樤TFFÖÕÕų³c1r {ß[JJJJJÊÆÆ¦b8ä{w>adäÇLJŠŠ
270
+nv:BBB À¨«ªª¼÷OɤN΃šš$$$&“)˲÷žÏÙl“’b^`„ýò—ïÎ;88ÆÆÆ¸Édrff¦b8ì;B·ÛU*•100ÁÞùI‰ כ••5--áÜÜ|tt¼544GGG<xJ¥Þûétª……õããó D„ïÎù×חGC.]^Z(&„Z䣇g‡jJª33³  Ž `ïá¹àëêêÄÄĔ’’hff6224çÐØ ±0Sāƒ——
271
+UJJriiy9ç[oй~ùæ"Œôõõ9Í̐ŽŽøNÎÔÔ[__Ÿ2*Š¥BáÜZËÉÉiµÚ¦™’‘””¾7n>.—Ë›››ŠáÍyV­V™LfQQÑËˋۂëÝõÖڄ¤¤§§
272
+
273
+ªÙlÚÙÙ¹°´ldhäq¤¼÷ŒF—–Љ‰¾9pë ™˜Fãr¹|>Ÿó<O§Bá
274
+ƒ///H$Òétn·Û8ŽWVV(„»dIÏS2iVVfgg×ÅÅÕ÷Þ)((Æ8怮×ërk &"Z¡ "|_ÎuÆFÌ Œ1޵´´ÞÞÞºÝ.‡8îz÷>B† ´´´¨Tª–V–PP
275
+”Î7ßw‚„‘ž§&&²²1«µ®………C##‡HT*•nnnÏç +hCÊ Jßû½¸°xyq!"ÂÂÂrssãr¹Ã
276
+=Æ8Î¾¾¾ÿÿ•• (&&øöÍ7ç"DØÉÉqbb"ûðNn®««kõË÷«’’‰¨ä•‡<J²ä‘Ȩº…#`‘H
277
+ ¡ó¸`_ö€Fb"ˆš2Ðá )
278
+b8À€d B‚8ˆ)Õ>Vñ /ù…Œ/®2 Íÿ<º,4 MƒïŸ‘L瓵¿ "U‘ºµÝ‘Dç~œjá§L·ÈÈ-¨œ¦‘ø‰µSŒãëËþ<¼|$¸}»ó}ºAð·PÍ»á©d»~¸‘Ofê§ð@3‘‡9þVW°SRû}ØÜm¬!“hÑTÑµM³OTIqåüæ±Pù–vYgŸpj탠£ê%S¯R‰©s!Õ]>¬‘öj¨¹¹6‡hœ ×
279
+íI¬Ö´ÿe­_àÓ¤ a𢵨ûîxã<üæ\<¨#rö SùÒ[?;ö%@å€ÔVWT ¸Y™¯¶B'u¸€óœ{$‹Á…6Oþ5©Ôß砞.›÷êÿƒRFòÃeõV– ±D( jAP ]ôOŸ+öºh3…ƒoÄÕßTlS¢oz%HpÜ˨_û²‰J£ÎïØ’žo¦ã’ämo1ÞGŞ$𠫋ܛ’ItSÝY¸+4j=®²y[o](>ÄÇê?‹H¨Éö)ƒŸ _"œqœK™ædæ­/–¨RŸ4TeH Õ«”ö#ùøö¤gk‹NОò­Šž…úÈ4²ñ6&†U…¥‚Àif—XÛj˜’§vßý`߁VB–@±§ü]—RÊæŸÛce§¾q~Ñyê"w:-L.˜1vOr
280
+ nÈ<¨„¦‘ŒÚp߸¢ŒÅrîeDÓ~õU¾˜„ÎPðÚ&+ðY^D6"ÓÈb© S§Œ}NKyCA¨Êí“€Pcã#ë®pCW…,RuunìDK1 Gsú+f7åª\V;I3¶¶70Šmˆ¸¢B9nEWñéye?"ÖÖsï ;›E««t¬®ŸãÕ êBóC3¸d‚2p‰3€Úæ‹SOÖ_ÆE‰\p°‡" ¤˜£q^å ÕCyÊMV…:…ÀތÅÿŽª–ŒèèƒH\B‰XþÏùœ©ÛÚj›,™{T”¶5’1}=òŒÓRB gæh}õTö̲ö’Ø: -xrþ=Z!/‰3â5 ¬Ì®@@¥¾¦©$Ýüïr8’)`—ÆÚÊš·j¸hÖBsGVf<I‰qÕź—í|(Õ$7“PÖP"4Sê¶Û~qv!ƒ¥Êí(GÞÒ4㏜~¾ 2h.•æèÁÈ
281
+“¬¤.ܻ٤p© *MG]Z_+ÎÀòL¤37ˆ#PÄj›‘g”RU \Ò¢¤Ad
282
+ˆ«†¡ÃÝ@Z6˜eu :,±–:ʐóæÙ:ú̈́$Ø($þga!ŽÑOmœêj´ø,v˜œ‘µ«Z%¯N¬ Îð7ㆯOÍ, ­’[÷_†dd³¬‚/Ä^Èï²®«wUóÚb¹û#ŸQMNY´ð—,˜ŠóÊåEè"s:&GÔ:FF7Ê>iVey¨ðâZ“¢òš®+«¬jí/±ÑÑðȯÔÓÁxË(€µžûÉQ™—ocøa"^ÍînE½…“ bB~‡q¹þúŽ€,LñÚÕ²!7ǫ̈Å
283
+#«ÆáéÐ3ÙÚì훔œ^¿_7?1Qq{²µ#ÐÅ6ù«Xž;€ÝÈëç}Ú0±ÔL±„iwRÔô:еjˆ"2I¤ZX>Â=™ÓæâMñÃL¨šíÐ÷׃>eIÁz‰yúX|Ò'ìæ‹ÖÿK©Ï©ÁÝ"°Þà+¾õsk¹Öæs Ç66E%švg¥›D-žº‘:¼
284
+SÈKb×(HûÌõtËðJJ¶˜´—2$ ð‡nbosŒ‰ÔØÌ« £ÉÊ3þ1àyršRÂ]¨" ö{õ Ba¼Í´!@^ãiÝÓ !\sɲMÓP?3Ë_a„À1S-¤õ/¯zøÛe ¿LXLÆ)3–JÑÌë™D_HAHCÓޖ™É ˜†2QëK ,÷\—ÑkšYdk±¨§£¨—ìi‰«Gÿ¸ l™kJ0Vù%
285
+¨CˆÕƒÛxÒ:á.’š“#¬bhšeʒÛì…°!ÑÒ¡Ž¢`ß«ÙÜÞ«¥>ö $CÂt[Ù[a”08`ú½ÏñíC%²vo~¼¨‡\ì
286
+ÓÇx>!õÓ#J-/ÉÂÈRoœ_ÊBøØZHÍEÛûÒCœã>)ÿØ
287
+ì}držÅm9Çcf×8)A©N?㋫9ª®q—YU|Õ;›²QAvXùQ”Ý”/øFeù#?옔D€pþÓí’Ò'¥¸vñÃ*ö7âòÈ`À¤­=í(õÅóZ×%‹îŲ
288
+M Êy±UäÞÎJ¼{¶@̂wöÔ¾iY
289
+ùêôxÚme,°°sêpúmÖ=ì\h:é¾ÐÓ‡Pz›×ƒ’¿#¦ ÇpnÊPåt
290
+Ö^»ë“|Pu'æ€Úׁ¼L%ú;}®7ê}ú›eTêOÄå̉ Yq‚shLçcnZèrìsH&;ÛØAí\ÔOºØ*Õ<¼?”A,ÕÜX¸î.I¯…zJ~z}foŠOIÕ+$ÿ7Œßj}iÿeå?vôºÿšN:²8Ê-ù™R£‚k>
291
+Ÿíb””®EÿϚAŸ¿&‘Ív@Ztu§_{‘‰ªRƒ>¨õíþJ›×Kä ò£ÆºŠm£ßû
292
+`_gÃG™UAKo-"ÍB‡ƒ Òn•¿†|íázcmqKÒ;±x§ˆÌõ_v½fëØxµ
293
+[êcøço.œù:J8¸ÿ#Ú;^mòD£á¹:q·í¬ÙžöÎ&ˆ<^zªdÈ´°ñöVä?b{CGÃÇc. &ªx@,‰¼¦Áà$îœ f1îŸ9î ä ûKaƒûbì
294
+öÞXiSq–ðø™º·¸œ2NYW„ÆkBwAdù}àHõñRc!5#­+µìeMC1‚åÌ#v†ÈƜè԰ۏªWž.„Uzç{½N•6€ØŠåÇCþqY™Œ”¨×Oꈦc>QÕݜ΁!z¶…/ä¶ã˧è­à“èÕLÀ¤Oë¦Þ
295
+Bs ¨©SŠaí´_Ó«eâÕC8šRM
296
+»Ù~Ê?ÍÑè,”ŠCNçïȏ£‡]ošü3A ª`8£T¦ ¬Iø ^¦Ò¡ôâoæ¼ø9Ïdn&ÇDùÇ@}à_NŠ*¸=Ö¢E "Z‰æ¹¤5‹`¸4²ØaÿS] u1 Ì9VÄøZ¬é`þ\ЍoŠ‹OaŸåÍDÜÚÉBÚ²³€&?Cß*v5:Ømæù%°'Št( PQµ¡G¡
297
+DF×vËޘ‹Âø¹ù ^部´«âá99yƒ7®.v֝e]Ò¯EÃяêmgBª‰EFfþê‡Y¨£8ÄÆ m± –ÈD!®ëéz¶½Ãî4
298
+üþ;jDjÐã4BB+­Â¬Ži:œ¶îº`áі)”­©>⧕1i‘ù‹q‘½F¤!ZõÝQ< —œÂ>rSžJ |mš bròïDPví¿X³|WNxCN­Ô…1cøŠñÔܜd¨*…-é—Ê>ö¥ $Pr WÎKÍ qä®fzöxÒÔñê{†k0ÀÆf@H”+C=½½òpú‡é”V/Vø7»AàëS›Œ>(B„l5t¤Ø4fEÕõ;x'-ËÇä¯d×´©\–p‘ý q ùø!Á¼sƒ+ÔÔÑÑÖ´77dK³Ÿúßú¤ŒöÓَ‡n((qïÆ õbˆxM4^|õÉ
299
+ǒ•$ä/µÏ¼F±û̈́é¸ci¨w⊉-Ãn ¸§“퍅²_êjÀ†ø"`ø ~ÿ­Üg»*Ez´°ŸÞ !YÞv±4‡¤Õ!í6ƒ±;î k W–ø{^ò¹ÛÅH“³'§„ˆÌ<é?š¿^‚Ω• Éúá:€\W;yU%օ<ULxН7j&×…·ß”8g]’c¶UŠÅx8Æe7u”¿F¸®˜ÖßnÈ IuõFu_ÖE¹j,¦ÕOöµÓƍ=¿¦å6Çþ–ꥹÞTÛ³Ð6N³m:\rÜ !¶œ¶ù·ñŸTÀžÓ¢¶¡ô$}a(ðžùo +½ˆÆs b L„¬¶“¶‚ü»,ÁA!Ë„)=ӟßÿ¾¤Í{zдØ\Ìwz¼ >ÙsC{׏ª:3—öŠx`mö®9S³*l–¬K¸ÑøÉ÷Ï m­"z^ࣲ˜IébJŒ0µ
300
+Ö5t‹”„îꡂ/ÚμÓÛdî®Æ1®(é«x%a¤/´´ðÏ"ãú<þ±7×o:
301
+òøßpÑùc´Úêfæ[ZyUž õêdž7/âx쫏 .óÛê-å2&Ç Ì hŽÝºbA$žØŒ²6øB">b§B¦£é°¾’˜–797ý‘¼ÂµÑ¤ävÜ%Y
302
+òñÙȍ0îÄ'OÝÿòö äó6ÌÄb õ“.Wø‚ò ”¬»j¤~-Ô9f´³ö×ç? *N8¢ çVPÎJ1l¢UÄÇ#La9Æ™í¡ºÑT¸E^¾ "ä¨}\œ‰NAIºlŠáê¢J#vۂc€ª…µYàôÁš~Ҝ¬²*T—Aʗa
303
+˜û%ӹŠêTã¶I}*ÑÒÆqÊÜè6jÊz%<)`}_ð3ׁ…TþM®i=‰Ï&[ïv˜®V€dÚx´¿LPÿepl€ŸƒH¥álŸ³:Óë ^A®ÞHsE®Ž"žÊd–75÷Û̓õQŒøU—ša]÷Q~Œ  ™>®@T®²S:iR¨çÈÈ>«ˆ—1a½QõÒ·˜,çM£ù+êc‘ä8hÚx+h¢ƒnq·tþ_L˜WVx€Äh¶ü›Á€l}eë$žãüwfè`?¦g:½¶ßÀ ÷áw—Z2¤\8õ!ˆ›)ǍNGxÙr»ßd£, Ïà“¤ÓîåÁ&ÈS;ç'QŠ‚<&s¡¢‚w÷ï÷‘ïK@0Çôúþ÷(lÅ,Ð};fŸüb"ý]LнÿÀú&g@×4”'“îÂÓ¿¥˜ò1{Bd¥)•KvY¦êvyó؜y[ˆM–2ن±]#•Øá†uxÌc¼;»õOÒ|eƒ>dO¿lë4`Ù#†é¹M©A,y (Ï^8únÈօpþ°žÀ»#íEg®OO@bàAš>DöÖ„/l˜·uë´ü5h†ÏFBR×D¼Þºô jʕ¦W¾‘„ù|÷«?rrÏq"–]“¬!îsSõE™m,d;ښW¤¡{ºâ‚w$õÆ`lž–/ªïx/ÙJüsY«'<™ãDâÌÚ,þJÈÁªgAfhÏbm¥5ÞÂ#, owS1Næ³áÛ΢± úšìØáŠL•´g¿œº?ƒÑL‰»q$«t¢â[OoÅ^Ìï±eTkÖøàˆY܎Á·Íã['
304
+Ü#ý,Y0è›yf²×†!$8]-3¿]¦jèá1Þkb~ÑAÖð\£3°]éÐlcE½¡;ÕX–b°iÛ֍L£1+s’zÈ\—y¹õ¾, ՝ÂA¥ lå2í…ëŒQZÞ\µæB!áSƒ(öwòÍÞ¾5.w{¤ÚÙ]€vLùÖM·DùŸéE„MڜQCÁW2â/ Gyµ‚¿­ƒ æÛG• ÆÒ‡üÙðÆs+˜Ûv hpú¦{bvÒÎÞ Ìz4Øp#>÷Qaù9  "Þz™ Úy{µ¾(çë^WH`!.•Ú2ø/6£&…+1B =„+áèÆ… C§n%Ëy’¹>қJ=v‹<ŠŒ×»%‹Æ{شª¾¥ª…Êbñ‡g¬“g
305
+¬=XÐZ"[Ž,¬âtÁi¡Ùˆ'¦÷èWÇbq͍'®Çäê›Uõ^¢êÌHc½*#jIU5¸kî"«|eq ™ÇŒœ²yx¡ÀÇXUåEÊRÏéw qk4;ßIMŽ“˜¥+͊H\šN ÞNPþHƒrä™qÃ.r’W‰3âì ºZ ²˜½kÐZ·‰±A ÁDX'ÿ)¸ åçù‡^熛֞·ºb?œj‡A£Á6áEf»ªëó|Då;–, xla4±ãm"ûÏ9¶gÛJDÃ5’Ñå҅¬IcRrÃòK¿JEvͧ‹³'oDPù΀Ë!’V–=ljž3EQ@D©¼‡ØÀ»/ɦÑ"?éÍYAk˜×‹ öÎ6«F+ D‘¶
306
+ÓðjD+L’¾¦þ¨Öø´LÒø¢·sH6F·k^°!ó‹ë¶ƒ¬ÏýùÄØ×ª‹Ùæìe(5À„çåLO[±Ë¯ƒ`g5: M(”ß"çAÞPŒ4Ÿ%xê%tƌ£Ð·ûÑ2JUn1¨äòƒ[ÑwâO¤“H㦠;(ށ2e´Ï¶žW\d]£˜¹»$!CG!=uc\:
307
+ìñÉ{Ïo¼æÿw‘&@)֣ʅ¦±Iå7K‹‹[å›äúpõ‰U×a‡Ð•'8%[·,¼¦Y>1ç\òb-LÑ<e&¤ð5a©
308
+.H|a~€šL'‘óë¦põ¸ã‡­tëÀwlŸzŠ%YÖwšÞ"Ë ÷GÃúÈ´µsîŠA¶ øÆ0vè̘ÈX†Åfwaâ )pÌfÉíɳFßlç˜äôö'´?ÐlÛ\Ãê‡Êl8'Šv~èãðâd5T¶ç°´°-§ ²Sé2;ê¼*žª4Ë µëÌBoC¯±CĪ‘K¥ý­<XÌ_.Í–ÿm¡¶öÜóU?&*š“_ð'®ÎÔRyvÕâ' 3¾  ©Þå-¶Ð*,8œÁ‘á£ÓJÊ
309
+
310
+scͰ3‹E VLƱؼtArõñMvKÞJ+¤í¨æ8TˆÒH€(ƒvÙ‹tzͬÁ4âaÄ´æ*‘5ÀþîUpbê(A kJ#L§íqWDY6P4+Óñᒠë£)–èÂÅâcP\½/‚’ Ûc½œ f1ê™Ë¾6Äæ!’œ®Ü@Ë鍚Vn–äíÊçïð i,Žnaý)Êu |.w1¹é» í7b0“]%{áFö¿Rv}ˆ$÷?úõÇ@V†’‰,ˆí®öԞPäò1¼ñ¨-c¦é,¥”ÒVé#ԏIw¹´’—ta·zƒpKvJä4úè>ÞHïnBÄ7~-o$ÿ/ÙÙV¥œŒv(¼ñh°ÞQo~s0­øi[µ,O©
311
+ yÝl0©Íðe,uÁÍÑÈF„iª¹IÜÛÒí-”XUf‚Š"£Ï&' PÇ
312
+Š2ú;¾èùÚL’|ˆåv._ˆé² -~é6C™ÇÑNdÌ(ƒu©ÐÑ"ÛØMß½ƒ¢2ªàE¹FÐ+
313
+ŒÝo@4žì^Ügõt=R¶ÔŒ±õ-Y¥ 4mâ§kì …˜®¢Å+é{ÕM‹¨ åVëÑýcó‰à K„Â’\´ÊLNƲþ,Œ;jZÙV£/ZǝÌ
314
+‡ªŠ™SˆìD. ¤Ã›êu‘Ù–-hòõFä¯fÿLi÷/ÃT^›àsøˆ•P$Y@Œ­úRº&ý»v›9˜QèqGÂ×s;¼Y–7ÞÚ d³¡U5ìôò²†ðS±ƒ¥Ó2;£i3ÌW= ¯x!+_ºMµÝU, ¶ƒ 6Ý+ *ÕÅLðÔø)̝ÝjÔ ÀõŒ%?éÅèŀ·Bʉ¿mm d“%D¯»‘Ü¡ðui¸»j®‰Ç$û¢áÚêŽÜ÷»¶ÞÊ­Ç
315
+›S.û(¯+~§Ÿ5VJ&‚^‘:¯†–~iF>X%thÜ¿×{{'Â=Û|]žã…¤#Šr(\ª¼“Œ?Ì”¥
316
+z”CPèÕÉ.AŒlwÉv—¤I™’ȝÏmqÐ͎C'>þˆ$IÄàÅQX²£ž\#oŽÒþŠÊF©‘b+Ðó"eÇ©—ED]¸p©RSÊB.»¾Sâ÷KúãØI“%GFEQ <AsÆ —9}ÚږË%8kչGöú÷Þ¿½½ 2¤Ë–-RQQeeemÛ~7È®;ëž?,ŸÏÇC‡¢#FŠˆ#¦««+..
317
+…F|¸õaçÍãî«w:c،ï§Éãq ¬««/]¼ ¤ˆ¨È![²h‘ŠŠ"##ûÌ?O[óv[«M@j¼÷WVl¸h!*ZZZ*S¦ 8pØØØHäôIkáf6»[çf•Èe¢ÇB/LKC›¢’Ê¢¥ Hҏ!¢,LMQš×“““ë½ûç *7ëÌìãíìŒJJ*KSSÒGCKNœ899½y󆍍­{C›Õí¬Ý¬
318
+ßhðI@S333Ç„K<Іˆˆ„ÒĄE³Y*•F_0.e`ï<Rº²2žÖWªTá±CGÑP££&L˜8‘!ãFK <D"1™fdk•»Yeó ¢}ŸÏÕdɒ!"¤£#(Ožì½F£÷^(G¨q Ί°º˜ÕeZ‘ÿ»Gó­Q¥DI驈)éÇ0^žÏ§““«$)'v^¹p Ä´ ìη1®æo³m‹t.š­Õ×Í<¨Õ$Ÿ*þÇéкšÈEbú öߍuh¸;«71kÂ´Øæ›lV~Yh j¸SßfÔÿÝ?Ý6ëVÞQ‚"õ±$ü²×;ûÁd|4ëñ¼)q°÷ï(Ñ/´ÕšÆB² • ÿñÔ]Öã?†í©Awå¹h§Ç÷©Ö$»Yߛñæ¨Õ—Í;¯®VƒU
319
+¢Ãòm¨eÁÕª T×bX ¦Üó­Lr­I1ŒÆp‹Ã[…ÀåÊ4¥fŸ&wå©NAkºŸö.m¡ÂžsÐT³MËíHl¼µ[%àÃ6¦I?C9$Z½î¬ò•è…¢GÝûî§Ð¤4 ÷ä^Í8¨¥ž)G;;†sVµ*쨜UÉ¶.Ðì¬Û™Uº…éÝOQ䟨…ã|{J®)Aª)I…`1^V·wj»•Aڔë¾ÿ©ï?,Ϊ-_²Qùÿ{&&&***555&“™,Cz[ cAÕ¾÷R¯.®"$#£)Q¤¤9ƒ¦‹‹ËÍÍm¹\ÃøÔÝnÙÉ÷~êϘy:
320
+º³ºµpëƒwr`V·Ž»^ÿ÷þ“gI몗€žzŸ{¹‚Q^]‹$ÃÑûÓÝjYîNÝ<>•ш´ëæNAV7¶»[Û'°JJ¼¼‚°µ.‚µðÒæ÷¿3ñ¸Vùʳ.–!uÿ½Oê™Ò
321
+ÁK?gþ—2‡sV¼RbìÿߥË@ðÖ÷ͼ('„´ÉÿÓϓRMé÷ïì#fgÕm_ä“åÿß}8ÜѲª gUˆÛ¾÷É¢W
322
+βªðîÔ¡›
323
+Pd۞&žÕ3ù`ùß;ãx®Öe~\sÒ£Ç=ì nàæaRgÐÿé/ŠÙØZÝZÎkûZ-ˆƒv’kJ<çõ]Ÿpj~¼ãu€ífþ¾¬jô%ýÿƒcÂ*ïú3‚ÁøSiGž%möd5€¹ýæoôùpuüÓêQ(ñ ¶bð²*0 ½Ymb7€[.om3gõÑl‡²ê@QŸ(Vƒ¯zm§Dƒ½þ{ïK¸× þ~­ð1óhÇ
324
+-éÿwïÛÀpVÇ[þ£z©àš»p
325
+jQèÈ7?‹B¯ßûiïÝ÷ï½ïßOPÞ{¾½(,Ç sÑ·%šyï}*ýÄpoîíAá±¹w ‹ß±'<…{SgPé»±Ôê›u\jô3õ¿;¹0Nˆ|õ jTëʵ¥D3ò}÷Ý;áž\WŸñ?¢ «± ÄÇ<ß{i<kñî÷m«ÄüˏDû±YÕÝé”lV¼R½Z·‹cF~ns½QÞ¬¹Žßl¿÷ÄÞÐæ©ÎßÕÔHvgý<ùÿ£/u Õº «òºµ[ {ÑýœSnÊÕêÖÃ/_ßûÿÈ4$<«0ûê¬jµù'Íÿ¿9ürár=7ˆÊÏÙx„7«0»³VupV]%ºsøýïL¸'M$#ú>ºÜC¥ÕëÊõ²íËTg„»ÓÁ¬
326
+g¡vÊÀ\´é·<´Zmá<ts!º„SöiÚ¬ çW«?V]ž%ñK·'W«Ë<Kß#Û`­
327
+¬¾Z»o¨‘­eñkÏ+1ч\cÒ²+לɇÉ3ImVåyoÒ7¤÷hÐW-pم ¨ªJ’9¨¨F’$Ë#`q(¢¡ X.’ÅBËÁú0BÅ0‚0 b 1„B1„ Q†‚8Ï'®šâ$ùd~?;1­Ë°åDæ ¤êdÕÃÇÄ'Š…«Ë"A;-ß6 rd#}BKƒ‡³\P0P¿§Œš "w@rœ–UaLš³ÓõŸgA‰ ` âçêÒ`'ÿçY)P‡˜)G¸ÙQÁ¹¿Òœú9´]YW°ÂŒ8ÔÎüõ“¾`-ZODQõ.•”t²O$ ö2°ÁCŽ@@—hd;“QFLùeì¶(ݾíyS Ly F½x© ìh˜PÚ}QÈbš‰Ÿ±X]„`ŽÞ×'¬Çï~9•'ÒAhîFq…Eû´½
328
+"ÃræP¤-ô– Z‰³ÅÓßxÎd H넆~s1èùå²pÏòÇ„¾>¥-Ã2‘o­6ŽBÚ×ïפ÷ µ¨ÌôÞ¼ˆÃóˆÎ¸ qâխ†úÛüš™ÿÏø¥¤úîkõ@Ë3f©+§ß_sý†«ÿÕ¨„b xÇÁ&ÃjÂÙ7<&{þˆ 3ƒÞêBÂTwo±ø:õ2°ñï²TfÑHaš6ó$„ ždnh²­V€G’|<À·Å‚™TaPðQV}-*Œ%‰‹ê ¼^¹U˜,þM:b.©†ùÔo¾ðuo“7Â0Ä÷­ê‹rÅ ¤i⼤‰ÅLxTb€’öIƒ *ߚ^Vîkõ”QJôŠ‚H,¬$’†f_ÎÔ!ᰞŸæƲ¡çÉDl8ÄXXuTÈS*‰;ÎÖ§cõ² möä@ï¯exˆ½á\XÉÆTêE)[˜y>Ý;¿àUûÙ7=tb€aÏ<˜Z.„LXø{ÙC–ä£8yóèO Y?Å%kÈ«N’dÆ,7<]ÓE°3CÓ
329
+k
330
+y<¶sJܾõˆjM…€ˆ‚SBS‚<Iø±°È Dȱ"˜M'˜V‚„ŒÜV
331
+2ºWB³Þ#dǫ߆s;&Òí[ÏVu –îkÝ0Ïy'÷¦ÈnNöYPïzOÒ8ÂZ‡U@9gdN‰õ¼#+}Oàrÿh‡n_°ÂÕÿ«¥NÍÈ3ô¼ºQóx0hcºT\ù?~¬DŠËV¹¬ã>НSeXñÍ ~1š4V‚‡1æöDÊ¼ÆÆÏnÍ©s} 3³=4Î3ˆ”EEÙë“ÇìÜۜ‡y íQ¾ .6¶+7"ßoe%°]ÑÀ*÷ÿ¦‰Ô}U¿+â¬XýΖ£Üº&Qq¶aU0Ašd™°ãR Õpq ùsÅöÌCŽ/›Ëº$ZÃá fHæeÁôZ±‚Ou"ú¾%ÃRë\Í܂ „žrœwÐhX4V3 +ÄæâÀÀ?˜Ú÷fý§¹Ü ÀÕW;…·©TÓäºOb-!ÜȨ®}íçè¯hçZò&fÜîV /ÿ[\T\.J‘æÐ¸w¸Ã!ÂQkIc#Äúz—XVĿś«æÜðŒÒw}BüoòՁÑÚ:ø÷žSœ<³®AïâT®S̑"gðÛX
332
+6@Ål(˜}Ÿ8¡
333
+·odÖ?ÿéÿ1ÏÍó~¿LÐ
334
+ü4-¦Ò=¿üږݛì¿Ù¯Ò;Íޘ*=èòµZLijÞ‡”Ï~)ùN+8 ŽkM=»o+<w¬–÷ådNû³±È`ž[|l'µ*TnVrtâ7á®#<w§…Üh¤uË ò~ñè_¦pCæ’óÎ$ ¼Ôå7}ò:ýG‰ŒÚ«i¥Œ'  P>[Ÿš—Ÿ¯ÐiBcîh8±ú® â XùÑ¥6åÉÌõBᏜ0¡ç–mŠàpYUŌvÕ̟;C÷V…3‹ÙÁÖ¼Wáýe¿c"Œ‡¿âN4ñðw
335
+ì–«ÀK=ëÛ\GöL[©Ð`~/—JŚÊ÷®%­t˺,>¾œ¹Bό¸®¸¹î4Q¬­Â3‰‘å¯5§HÔMÙz±27õÎ&3s#K¯ƒÖуè²õ`[¬Uõ*âíYî—ù®‚`·Òµýfq­$Bö [¢xÓ;JÊwŠñàЊìØ%KÈ\ó'-06¹Ó„¯çÀK±3¾»!dqSY8ÂÙþï
336
+# iŠçXuâ£/FIÄâÿ¹@ë·ìž‰» ÉM‰˜§ÕöԈ]Ïé-â/ …Ähz~ ¸TYKÅÉMƛã‚nÃ$Ø«®Æ3"wù¬a' DßR1Yàj½{«A9rÎ6rú3¿¶¾'Rf¡áŸ
337
+3®,à~xÂ,Y[x„;éÿÈÝd8“‡tC™:Š„Ã”FaW±´®Y±`aœ\Êw6c@­ø[ÓúÍð¦¨÷ä:mï%‹Z`Iè“9íö´‡jö截˜‡±Õ£Rh”ÅßÃÝOW•–‡­Äès:ª ΀;bm؛'£Ûá_Àzwcú–Ø(%ÿ²*Ì:ÊgÒÙщÃ[f"(ñj쵤•†“ZNìË"5Âè¯pÕ­Ï˓nƆVDÙ¯NÁ±v{«ƒñ>AìC’¨".
338
+Ó]DuL8±šúá¡ £-®ƒR¸¾ï£}wI­ÚBC”‰Ž^”ñ$ÁEÁŊsYîh ޾‹tÄl/iMà€ôV´z58#^8›õš~D+Ädn?4øhž|šZ]³Ì%¶Á²¶”‹^¸6ruôTM­ ¼4~c³‘!Áø d«â £ƒÏåíE*²ë4¬4õ+•SåAçÿÞpn?˜"óV¦Í/I›ÛÒ>rÝғEGC0;>CB—A+Äzk€6Î|õlrT£dN!éªQnfmøªÐ¶Èµb`iÙ&«Qyhxˆg†ïãï“êmLP¡/°0 nëÑk~†Àä`ÑŠ,’0íDêuGôkæy­ ô’+ÏE…wb½í¬
339
+©ËÄ幀ñ`TÝó9SM²û£¤ì:Óc”¿<Õe@ìÒFnϸ¦Á–ÏɳÀÏÓ¥O•˜èÇÄ'‘ý¼AšÀ\T±^H[ê”Èː1Ó¢[|a‚ú„ ߊ±u—´×žpMBü6*>š<®°>©0jfd`ìS• ñ< å1“Žþ{¶t»Ü%£Z+¸>¸¯ê1èü6¡"#»›5Ø–³/E³F"…³'ʃ+“6¹¨ ‰'(Ø÷ÇG%6…'_ù‚;vM2oÁ¡Þù=Ӄ߁u¸§é#/©üÃ]e$ò ÞV¼É%å"AÉ •8㤊‘]À5¹­Ä7߆{X0¯¤’ÕJyîueìE°Nƞ³Þ\–ê|‰zù™c…'ÿ©Åb°dt`3ÄÈö]…÷
340
+`çhyaG HQ ]M!¨ßÑ7!W0
341
+Ñy·w…E]Hhs6͑wàl DIë:i¸Cu±ó¾ùŠYf÷1šx_è˜Pg¹¯ÅúíŠÈ8ÊÐù? ÓK8¸‘V’ìVQ½o$¥GØÄšpFG‡õ?Ed ð÷!=Ïë…Ç7Îm,)[vËz4xHü¯{[¸…>[°sÞ±QD¾š½îÅö˜Y.§,!¼öK² <4äü›Ù Sjk“WÛ[Œ‚ãßÅÝÚ^fžãR\„h"© ÊÏ͘DÚ/tš†nÍßÄ~0©™oΞÃDö֐V ƒ!<.¾ÜùôúlFx̄º²¸sF¹þiI`Ô Ö ÕjXÒ<`“?³òʤ¡Œ®
342
+½^†Eëkcò
343
+Æ­OŽ/;Rï1ò(‰Á:%ʄ;qÛ9X…÷h3jY+âáçoh~?Œ-Òû‚œ!Xà¢tz°wÅПx
344
+ùߤåY°Ðã0císW¸­+üôs–êáÂôÛHã< 6 Þ;Ö<sõ¡!ø*Ç^!rC%«Ãí¾ä~p<PÔ<>ÛZ‘¥h‘Ámó\–Í“. ½2/ðfÑ#Ì¡¯©ßáSžÔ,ŒÛ®ÑIBÅ¥ÆÏ®2`)To•ðohÑ÷[ùGyj<'6“+Ù2X¡ÔÓ¯×LŽƌ´Ó±†øÊ¥Æ]á#‹vÝÿ•ÀŸõíôËfs
345
+5À9"ÆÂô9ˆó@ëÿŠIÃj\"¦r«øL­ *heZ?G¾IáX€¤›"ëÖiÒ¨—lof4¹eÒ&Ô8D—¨‡W3Ƒ%lFf|Á8p?ÈSˆ°fã`15~ÍþÉݧ^ÏMÜ&öèIw6Äsö4 ‚}dËÇÙVŒ¿(Š¿ÉÚmÍÉN³¾Ñ\ŸVü…p¥‘Ü€Á7MYs+”L74;"ŸúBÜ2ë|ÿë))!È5Ä2=2`­’j+…$l4ºµ¿}Æ «1Ó¸¨ÈÁ83ÅñüßnĶýU2—¨™‚À“‰õ¾í„‡ÐÓÃÉ8d5¡@ _Žò^Ø&6ŸÏAÖ¼¥ó|† ØµL/Á¾K² ¬Ïޒ dȅ,”«kÕËsï3'ÀaÀ{&ë²ábØDI°1 Òiq-“ä$™zý%«õ‰iô¯uÓVlƒÀìØ1ý1¸xÍøÝÈÂüØd4meçeH¯lá¦ü©~TººŒ µ]*µä@@…j:Ã0 Ã0 Ã0 Ã0Œñ­¹Vk™ad=Ë‘ÅiÔÚæ˜øÜ¾›D$¶¥”RJ)%El§82xÌij\‚»ƒ‹ã¢3’™ÀhT|„*<!‹•‡gz•”)ã |¤€É‚Dd4 Ÿ‹ @Á)@1q°©Ð0µ|T8ˆ8÷ Â%ôÑQ0¡ÉP0‚€ä@¦‡ I¥ãÄ>3‚aB0 å#Tá¹HB Ç,R‘AäcÒÁ9YQ ¶¡&ð‰‚X`Ã<Z8J8Yró“
346
+$ðЌ(``QD`q‘ d €BR 0ꨇ„…|"ãȐ‘ÁY±h“І¿è ££„ã Ó Ï‹‘‹Þt@èIÅG%Ä?*+˜‹´kCd>iÁ¢¹O q2EÂOÃr ’>ƒ‚ÂG…ŽÆT¢1á-OF““f¢èŒŽ‘ކGcĉ-$p‚ŽÏfŠÐxB<x˜€‘Ng$l£ 7yq±VA²¡ò¡CæƒÁÁåÁ*\p:ž— › <íD>-£Ž¢‚€‘ŽIÈ#ãaÀIæ"i„<"0",lóàƒa( #a¼>†àÃÂxmˆLÁ}0L„"2y˜0á#cS¢ Bƒé 
347
+Œ…•ß8 |XTl8D>(ˆ Oxtl$\Ðdp.’Ÿâx"0 ZÀMGtñ`F%GDC"”-œ +j@ÄO"XñhÑD` %2îÉ`!,’™ ú– z™LÈê( `).Ÿ¨áAFc &”âd²2mZ½GZݗCŽrx.Q‡3W‡U¼’C’ÐÄAAd”r¡/6›%ü ‘|ÆuÐ9ˆ4ՁsDDžæ î ÷êžùßíªþ»5•õWñy©¦:fdß×Pûx­«•›Zúãêm{ÿî/ÓT·¨ÎÉm‰-µ!*9­ÏOÝvï7õ£r~µ×|M÷T_{æ\þ(‘(v}7t7üä·ç¾ë_þ¨uß՜ï÷t‘_Yoý£Âgkû^û?ì³wGÕ՗Òj‘Ó9õž]w͙SQ—_*fåãd3ìk¿»Þo×hÿÌdDö_~©ŠÍÌ{¼¶˜÷YsíRmù§úï¼ÕC]ž)MêxY¿Ï²q9«rë4÷k{\m)Mj³ÿTsqá©RãtK;T^è(¥(DÌýÖþíÕ§Šýïwym£Ô²Q?2¡í²*/7/}”&řþí×h¶î3Ō¹ÍÙ2uýeËF)~«ï; éDР^BŠ$$
348
+Š5Ôˆe£6€¨ˆ4m(”P`BĪ40ÑÌ‹F‚CŠ…pà"i0óÞÏ\$ ¾H¬YFÁ jÐøø,à\XQ×xéÇö)`•p–aLMƒŽÍEº€êÍÂc"B :J8:ÀEoB0a!ê”_E+û–‡kªÿËò¤Ii¿­öúN•Íùÿií¸²ùy]§º7´ö¼G¿æ[ôÿå
349
+óó՘¹{å¢4©Þ_Í7f텝ê¶ 3wᢔ€ÚÏÕUïüß5<LüM[靖Û̹9×mªÛíÛnýìõŽÒÊ_Sûßuµb.oûŸÙ/fãý§ßúëÊMÅÿÊÚ몶1ùQýýkªd¿LcÎÝÅ«gvèŽ÷ºpS±Z»š¯Þu<~ÅÖËuœÊûU‘]us12Ÿyº±ö²NåÛ~։ü¸Yý9qe¦jäÔìÏ÷]øç»iæþ讽þ™K_¥Iu¶Z:úÿ/õT{–Û閏‹ÙX×ül·—š*LTÝe˜Ò¤Þûom±©zvó7t|\û¿{îhۋ=•ÿ·¦*ÞãzK ¢Ë[ß¾žõã.Séinš×mݹ‡ëh~·Ë”§wûêÝuÿ.»Ž 6›Œ
350
+.*Xtl6Pîüûÿ–¹«3ë벯E¼Ël´þ\Ÿ©Ü_Õõ[ª’çAçr¹\$‘Ð
351
+*&-JÄ¢2j±XP"  Ñ¤D€Z,H,¢éÄÒ1i›ï³­³­<•¦Ie:c[›§ZÕÔ½öÖ^Î)¥tkk¦^.÷œWï~1¹J“Zí»ÝÍÝW[îÏÕùŒŸxyÈ»~S¡Ýj>Þ#/_”Rތ•—÷¹#ö§£^Ÿ)®ÔTkÌ‹ÏÆ¸ëö|¿×táõ[.ö¯ÅÄlUãFËÿ_Ý©O;ßûI)Šw³=_UoÙqÝ#ª†Ò]ãK5æ[è©´óý²µ—™J)êUSùWq)§J[Ônít[ך)H!¥(l¶UU\×¥˜JYq×N/ÿI+e,¢)„d‘ɈV@&Dœh@„0t@òÏA,!èdt‚áâã•©"„E4 ªàg³ÌÝÎå|>b"ˆN6Ðí8my{)f2¢–•“iêd2' ‰S¹£>³·±.F’ÝçåW?\f)‘ ŸëÚjKÕÙí·‡¬¸ÚTÝöoÞ½¯¼Të}­çÞ O;-ÿ™U‘ן®lÔñî¯÷áÙÂT…¨¶Êÿª¸’}Ó]Mq-ª
352
+Â¨š!"""""""mÒÁ„¥¢‘â`A ‚b(„AA †c!ƃsÛ9Hq‚Z?E˪H“ðኒ`Z¸wªÿ ƒý§—°Ö:\¡‰$ðk‡~yÉ8oÓ3Õ¿XÎc)ˆ(ÅrcÞQ’ +™Iæð†š'i‘ïk¦¹‚6ÅkPÊÐ×<@úδ°šè1£Èƒ´ˆENä‰ ìjY°×Ò,:Áƒô‹4Ĺ?,_½Fö)íã³—øU,ÿwë ³-Øü¿ü¤/#£˜=UЄoäÛ‹7ýÐ g}³i¾cIÑݑ>w.Pþ^„%‚A}OàK4ëŒNµ~Ëû;U°žˆMB›.=ÚG´xGÖLxehòl¶ PE yÛè¹eœ8^*¤ÀbLØN«)Ǩ¡ê­i`R ¥3|CLÂ\áK˜ 8›Ä\ø™Cs–ÔØ¥$jw½Tíÿ€i+¥o,«ˆw(–Øt„Ž<cËåÒÚpJóóD¾Qè-åÒé$Ïúâõ՗Ãu0ñä^õt¹šôžl³˜O‘ÒùiøOšz<IÍ;ï2š ˜n†iõÎú¹ïŠéµû¡ÉJÃG2gŠa:käE¬†è\û{t(A”=j´uÔ ©/ÐA}×óœ8£ÈQٕH”ç.Á ÀeØã¶ñ–9ð²°ŒËÆTÅ«?්zÊWçø×ù(dgðVS~œvò«y‡ADù%Æ'¿rà×+Ò•Ö+1 x>ȏ<«Ù€ÏPüØ9зm<I_IÀ§!)*MIü=ÏH˜V¾ÝLP}:t–òýy°¡š(C™Ÿ°ïÁÓ*¬áTPÜ:˜Tٜ7e ÖALèE#‹ Âl
353
+g9ɋ¶u¿RCÉè™c™ BC½K8Pvs©X|=#Gg·×C3J<*ä'"*= +î—ÉÙ-6™’QpCp@¡ €ŽPÉ@Ì0BÆO°¤üÌ –•_œ <ƒsv7pή#°üFÅd)e&(°Ÿ©H¾ð¡Š¤á˜Á±«30dÚÓ°<RG8VQˆÒÀ/ÁÊuÛf€¨HÍ%8±+†%Q_<C]
354
+;‚®½S]¤D‘*!æ`äƒØ@‡‹7lôÂްHIVHð”•Þ ¬ö ŸœiÈ:+3~•S%1Úߢ^øï­Q¢^$„†?á9TvzOÉ¥qþñ¤¡™ó »ƒr~pnuzl©@¿gü‚"¡3V"ˆàHîYxKUN˜¨…`´²å÷Š™W&ñ®Ü7¶íÝÖ»c™ç¹Þ¤„rŽÄ· endstream endobj 25 0 obj [/Indexed/DeviceRGB 255 26 0 R] endobj 26 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 441>>stream
355
+85$<f>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
356
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
357
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
358
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
359
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
360
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
361
+l[$6Nn+Z_Nq0]s7hs]`XX$6Ra!<<'!!!*'!!rrmPX()~> endstream endobj 23 0 obj <</BitsPerComponent 8/ColorSpace/DeviceRGB/DecodeParms<</BitsPerComponent 4/Colors 3/Columns 471>>/Filter/FlateDecode/Height 265/Intent/RelativeColorimetric/Length 20303/Name/X/Subtype/Image/Type/XObject/Width 471>>stream
362
+HKìÖ]ˆ\gÇñ眱ˆ¶ZŠ¢ZhA¼S¯Ä‚"B/ªˆ
363
+¾!x!HDô®J/¼ðåBQì<盘6 Á4!1­i^¬5±©1!µy!™óº»ÙÙ×ì̾œóÿÿÿsÎîv&̲a“Ýß''ggvfÎÌîÅwe [™•|Љυ|»è÷ü¢zU^òáîØê›–u·‹úÉöŽ|h€­BrÉõ-¤Æí¹üP6¯/w›Wn®yWf~t±y¥\;’öÆ
364
+¹Àro¹ÅRf4àv(½â\gññWn¨fªLä‘
365
+â5Ï=G™ÔסjÅo3á¯t®L»àænY/·nÖϷ{<ªf[‰
366
+¨Ã©ÜXó Gª•(6´»Ûö‚‘wîŒ'=¹˜T]ÎX·u žûÀ £>·7”•ÛVý—°Ò4†©ÀÑJ“û~úèþôäw˜Ú+K¸¨1ôe?{¸Ãë—÷mê7%ª¦ß NøQòB_»ï„>¥›n›è«Ç¦
367
+7icÜξhAé¶oRŸ"¬ÝÜ­'nŸ£ÁíåhÓ«<^Âmʯ<>´3;žÒ¶UŠ` ošô«k¦‚6ïa·Q¿{n óÓd<ó3%ÅA(OHxfR.̶XÃÎJ [ßýûhïþ]# î§T·ZÂQuw¨ƒ_›R“?¸7:ÛY,Q`€U(ˆE¹:Åt+ÿљ .°nÜ5Ž6Oè òƒä©³Ó›÷ƒÜ­¸À9ó²ÈËòÜÄÒÃ{²jôšD{rVÕy¨#á%,7>z`ìúÍ\Þ®ØìŸàî`W¯à%úÿäfoMh²ª½ëˆ0màT:ªVôë‹ÓåêÝ TE[ÛÝ¥ãØêøÖðF댰‰•Žøj:Q&üܑSK˜Á[2L]…Ëß¼9ÃÃÕT±õV
368
+qN‡žÁ1_J‡ßÎ(ō .w1…jEn]‡ËÙEûØßF%¼ízú®´ë(°Œgß]ÊD>]ÙÄOë¨0€°2ƒéLÿZW»Ü^MNê'õ±zsèÄÓ¡2©ÜΔ =ý5œßìŸàî!ËԖ_>>®‚P­£´·épJ핆‡\x“|÷ü¶VÞÚý—»Åæý
369
+6‡­âw0Z¸¯E…Ìd od„ý S.¿t×P“ã÷ìNNŽõ$Â+`{*ʜø½W§T3jtĪnX„¹ºu~ù; _ß$?>=½üd†»Œ- ۏ-_[xïó‰×ª÷j°qcØD*ˆ|ò™îÒ zæú#{GÎO.ØúØc¶¯Ÿþ{Jé¶Ò¼Q)’V`wü9ñ›‰äƒì™‹ü/þ;Ëïm9Á¼€aؖ.N-}x߈gbî¤ y¬r'7¨À:RÆMâ”o˜Ðçs‡?þb'žË­µTà¼Ìù+: Û eï™ 7yÔÞPÆj*w7îбG—¥3G>æ· ÔšÄÑoÿ7[…—KL=F…`{鿟zq´«Zö*§x#Lá$¼´„¯û†–pâñގ;:Ö]ÊÝ'É%Ä[’u‰+–ïV÷~ÿ֜¤ç7‘L)åö€®†ž µ[¶ÕŠ>Ît“î¼:—¯ú”[SQΖ‹ÕÝ¢œÏíç_¯Çj*{u¹kÇÓ×RiÊ/=_»§…U½‡;"Պýfú•ããü©,ýÀ€-M:,-¶î¼ëZ×ã)K=¤¦¾ÀFJÛ7ž)ÍW©ô5™ÁQƒ_2ü¦÷jrºßn²CñMù`* [•µ¶¾%‹Ór¿~¢£LæQ©Ã|ȦÚ?žž¡œòrÖ­Ùïa)ó°¦íjoâïÿs’ÿ,Øê/ÀÖųyÉkÓíÍâìÄåÔ×ÕØ \WÝF¥sÔ/ž.›* åҊnЫ>¿Ì%û”t“Üg¢ð&}¸|“GwŽ-W¦¦¬âÁ[´ªb"ëÔ6U³\czZò«‹3ìzó{¥¾®ßZG;NOoî¯à޲²3ój—I·xG+áõK ¤®š„nc$+7éÏ–Ëæuzíûvöl±ãµIoæÎ·åM#zù»wL/ØMý ÜaÅråòŸ½1+õK<ª®‰={^º›ªV›fj¿xú|¸GçÎÍ¥=1¶øÐîþÑîa®Ãs:S¦íÑÓf6ó—pGYî—gòìçìX¼ƒ,u;ùÐÞìÜD•õoŸš ‡<~ˆzN;™«.Opý¤žß¡,ððӇÆF{|Aú¤tæÉn ÷µÄF€{^áRFûå…Yn ^GcÉ&'tÇé KגNî çÏZz4¥'ø:ãQmBO‡ý¯Ó–DG´½}þ­ëäw—¦åCÒ5s[§—ÎùfþÞ6Ž-Ç{åg**ãfí:">¸3}9ëɺ–åZ”_z¹ÓБoè‚m¥#®qù:´„ÝN¦ 6i“G^|ñèø¼›ëÖõúÍËjÜ»Š*dş.ueÒF¥œa¯«Vü“—EË˚¿þáÒ,çTK] 5”\÷<ÿ hû<žC/Q-z-}˜ô/׸íe½ƒmuùMú­l ™¬¿4®x¯FJ§žÛ¢Cўë]ÆÂº5œuËOS:áC.ÛЙÜîsúA*OP÷ç ùډÉz÷æõüÅ €­Áîiw¹À:ñMÊõ3ë(pü…£oQÚÜJ"å\<s~š®é»®Ò•iٚKXª«#_–³<9£m|ÿsñ‘´GW«Ëk1ƒ`‹°å7Ou( Þ«RË‘ìÏäoÍÝÒH+ »,/Lî“éے1lÎlS]M=K7è/B&Ÿ‡_òƒ×f,Þ]U` À½ïXÖ{×®z¦  ØÉµŽO[’éË'Y©U"éöOÎLªVèéÔ­\NqßK¥’Ð ä#±§e›èý/Œžî,J‚ù-ŠêÚ÷®G+ç;¼S«oìø×”
370
+ÚÔ^¿)mäå™ö‹¤$‘ŽëRÈÄ£¢RZMüôù^¾ò…ûZ’¾ÏæÜMuu+·ïÅ:öLúóק쪟àžaW–#ÒVw^ï,<¼/£I•なÛ*9­ý—*þ³q½fé%ñ#û³ IïÿÙ-›Ø6Š({·œP‚;p@*8pªT'.ÐH)ê®@…8p@¸ UHH*!<ž@[
371
+”¶¢ü4Uii¡UÕB- xÿ'µ“Ø&qìÞ{³»ÐÝ` H,½O›õƙ™\¾ù¬ˆ3[ÙSï<ÞÀÁ``á;E%|ã˅uE°å³ÚÕVÏ$ªçffŒP
372
+Åe2ÍHm^½ÐÆÈDµ‚!=2^ô³D…RÖzøŠô_8;Ÿ„¶ àTõ³;¦ïõdµ›HÛ¾5t {õðîKíUîåff¼ÐY>‚«ø¾ƒu¬[0†AœE2”©¢afmpÛ¾ð›zWSîfüIŽôKߨG¿¾îˆ<<t “ù}Wێ\Ÿëêä4áffŒÐƒ»F‰©·¯´(JÒðÈ®Þå1LÒø*¼òô·Mœ“¤¨²…ôàA›Øþqϵ–ccX®1ÿ.»1Üá{×:†êš;˜a˜q¡Ÿ‰’ô·VÏ<øe“¢´V²n´z×É’®EèVh˜ô'½%4n¥4;¹wЩV˜Q·¿õð ¼KæNÂ.”0IxۏÎÅ87;˜a˜±DH^´ò—ß]HY8V­"rñâ…BÎñ¡Œœ2ü5B ûԜY™˜Òù1µãdY=°ñ?, ´Ã–°ˆÒÁ»þätÇ®Ä0 3.¨ÄY‰-Ÿ8Ö(I”­SJÓ(7LMŸ¾ôó}è—&`dëTDï^[1¦§W-¢L¦b•¶pœ~c.-ô–vþ•õ³ wœl$ÿÃ0Ì8€Tgô—íh2´å\ ·}>7×EÁÆF¯±pú¼xvD
373
+&¯¡ÒÑüÔº2_þ‹ÝðkxËÞhj¦û—eíã~XÎ Ãl4ÈKÖZÚì<5Á{£ßõß¼Ô±•«u¾„h»úT½¿yŸ'tÎã
374
+Ÿ; Áæ]!]¾Cwxå¹ï›Yu'Ц¯UÁÀ0 ³~dÆ2'ê½Û÷£~]ڐ–`N0apïúÏ-¥Rµ®ªñ#Ѥ‚Ï'›%IÝ+<4*l£ ‡E­xé$ÝñÝùqt¾±g©M L
375
+VÿìP`†ùŸÑ¤+½ë\Û¢«ÃJØMb5|é\+D¨
376
+×Ml5iÌäôXz«¼Š}‹³®ƒµL=Œm>xå¢ÉÒ7•1—0Ã0LE¥./tàaibøûIïŽýÁw³+TÁJY±/­†§86}Õt*!)Žƒ²yMùS‹È¾uÿ¡¹jûoK˜a˜>Õk;¤»:y,^ÂP°þ3§ç5MŠv-”ž†NNܛÈRѵçj»$@­‰NÉ®^A ӀH:>à-¼{o]i»¡…¬‚Yà Ãl4ÈM:Xê?p¸îTGønÅs݆+ºéýàPµ›Í¬ÌÖÃ
377
+ÖI “´Á–*ZV[SK+á°$|Òl¾ü+dlIƒ+¾2zø‹Ùù»|mÌþefCBTïüÔF•Ißµ1it¸Ë{üX՛¥mq ëäž 7ø2>¿þc;Ùn΅„œ³î @Wƒ·C8Dœ$†ƒÊ¯•2é’ìb†a֝ü é(S¥¨YîŏEqÉpU‚æúÖÅ;zÏI†÷𐞕Ü@uÃ;6v±Ù»ëˆÛ`Ô¨4J™{O5ì2«¢•†aþ[¬‹ÒL8éƒénIøÔœ5¤‡Uœ'·¨ƒD’$䇎Ì6Wì
378
+q"¾‘«S›çÏ4KJxÆ){d{ox ‡›&‚O«]A®²™†a֋Õ}ª©VíýÉã T«¬’]4^qyŠLÂ4¸9ÂÛ}¹‚§%b»ˆ6£”§Mõcµ•Í{áD¨áB²(Ëó < vžj˜äéÔa 3 ³Nhk#Eøh y$Xºy"r%¦£‹lWXžÍ0R†ØX€º£-f[Œùþ;›5O˜‡…6 ßùY^´ÉÈ­·~žœé®úÿ†aÖeõ¨mÇ…‡ÏžFׁu¡T+(X4ßo.)3^${¿|~1[ $=•Þ?ªv܊?Š~“M†¥2<D»Î,Ja áQÚ||ùÿÿÿÿì—{l[WÇïu‘Æ‚BLL ¡I Tø!!þcÿ!¤Åv"Óº®¥{”1úÖnbmhGŒÑâëõEÛ4풭ôµŽv-Y–¥Ï¤Ï¥ñõ½Nâ$ÎËv]ßs.¿ßïÜë¸NíÕYê¤éùæäúøúúœß=q>çcǑ‘‘™>áÜa§ìæxêË»bŠføÂ¦Š*aC©3ÝP–Ži&5CÑàQtë«;­ûR6LÀ9ÎÀ±1œ¬p¾Û.iÆ;ÇbtC +¦dÓá¾¢ßØcId¸–M´$™OFh³±ÇÅ›;Kچ-ê"X§G<‚u‡›Ðüª€bÄutÞÿpXU`úYw Uê6\Aàë1¤}¹†û‚ E‹B/ŸâV6ÁŠdddd&#<ïri(óí†ntZÝÓZTܜî‡0ÚiTÐû¾:ó3G7ì1A`|°'P'ÖÎ3•ýAS]Ÿˆ «ZTXý÷{̑0 „°ŒŒÌԅôV, Û­‹‡|{ü½GØïdWÉàÜyùôl*Š·ár•öU³”:(#Vr³ˆÒ»Àóõ“y Àrs±‰»ŒŒŒL9Ad9îIÛ?jê%.“À®^’?‡£[;S4ú¤q˜‰
379
+¹Û9=ÀªïQ¹°_è¤Äº©BiQu«h¨÷±õè#ÿéΊe°Ý)˜»(2235œËÏ÷tŠ azpø?/(!S€´¼¦#¾°åÓº~r w$‹,›dÆóÆäÏ}ÐuúpvC¨»&kâL±R#X*^o¢kƶGó¾ 
380
+3—ö2234‚Ã4–pž’€æú6w;Ü뛀C Ü´ô×w Mú_s ŽŽûáy7–ùüVk–êªaKuñû M“a ¬ÔY¿8Úï89óebÎÝi&÷.dd¦[rÿª’ÀSݝIQ:EÊ7a’Ìpô»}‘^0üdÊ!óÏTŽùt©&|Øôô¸HÓ,ÅB¡µÈ}uÖÛF
381
+†c.éǯŽŒÌ̏„ðT…ÖÝõ¾àñ@LÕL_¸|ֈiuÑ?žY´É*—»}×µ$ °¡èÀˇ*ŽeøJ(1𳉥Rµ*U>çd‚{έ‰üLÊ̸xïùóç[ZZR©”xš”©l˜Gb™/lC¥$.߄iºõÀÎXkƳéÏhO^‰ CâØÌ†3׳ü‘ƒqa¿¤Á
382
+¹.v„âÆ¢ËHƒ½[ÑÍ/툝豉ðÜ+›q)Â23=µµµLõâÅKÃẖ–GGG§º¨{.\H%w´ —fi$–uåØåð3Í •ᨮ_OVXž¦:.)¹³±cñŠºv·ƒEZ³Â]$æÏUbÜqµ¹u‹²9£§w@æed¦GRÉôó _¨
383
+Tû5U~8VŸøõ“+V¼²uËö“'›{zzò¯/0ä©–¹­¸KÅÜßÜÇù¨ïú×vǐQÀ%]Щ¸IŠ# §ŠÄƒëcæýÛ£‡Ì´À:¾ó1Gíٍ=DànáÔãѸŒöÍ«#qƒ;ùU3b™™ŽŽ?˜Z°¦*¬ò~D±hsž|jåÊW¶oßÑÜ܏ÇK %9|[Éi)Ï{î­ÜKmÃ> ˜nÁ€Ã‘¢¼òøìÃ2p¡Ws´OŒÆxÎYï8Ä@Vÿ|*éUb¨‚Æ¥LøÖM ™+Ï»+" Xf†&Ÿ–MMM„‘ÃÕaÑw9ì¯k–ç>õô«¯þeç¿wµ´´ö÷÷³ôIc{øÅ%Êb}<’ýÎ[½JØRÂ]䐖Z‚W€\ÄuŽÃ¦‚£ÛٙD{3U*öG‰Ìƒ»-¬DÛí#eBÞû÷û»“px’x&9,3³³aƪo0@ ®¢398<…6oÞü×^[µkçîÖÖÖD"áHäÞn‘=áL<®i'“ F®Zd’Fq^™>-ªÔ™mð‹ÜŽ>z¨/ɈÀÜ&‘¬Ã8óÙ©¶.‚pl"†7jæÆËIoÄ÷Ib™™LÆØ¥K—×®y}Þü˜Í
384
+ýÇ«¤Êp²¦Ê†,ôþ›ù V¯®­¯¯okkƒçe
385
+C«’EFüb¯³èSÂ×T­K!¸(Ä|½
386
+Gä“ÌSՌ FÝñù¹X% óñƒVæs[`wlúÂ%6‘6=ܗ½!¾)TRæed*”|0æúñx߉÷O†Ãúòå@´ŽÑ8 L8߇I›á¥|h ÑÕ ,X³fMCCÙ3gÈSt‹Ó7DCÀ ˜£K`‚ ]%d¶š-(1¶¬ EФÁ¢cÎnˆ%Åޗ›§bC_…YƒÇ|!Ӈåu)€0~ À hGgZ HCەº ™Ê¥Ø¿'èñ… @kkÿ:oÞü@Ðå°èØr0û«Ɵ{öù××þmß¾}gϞM&“ҍ݈à9#a~þn?â!#³zO‹À
387
+^ ETìH--ò™pdÅé!^Î YîBî|̳ãZšÊ‹©Å5¾¤ GÅÇÅöTÁúed¦]z{{?¡…Â˖.€{€õûoâ°ðdÆp¬ Œ“ä… ®[·ØÞÞޞJ¥œ{™ÆÜÉzÞ( Ó`¤>>ôFSuYëß–‹hða ©õ`}üìàu1¾w°s½ŠÜn+i›ýô`|"øuoÜôi&,Åg·X¬ë÷êGDF¦0¶mwttìÝ»ôxîܧ=´æ‹qM®U݌hž*®ã/üöwë×oljz§£ãB&“)1ïxPÏ(t…³ŽO¦µËé_ï{`h°PÁ5]•àìÓȐQz~ ÑZ^¬#„ŸiNLå½pqCø°ùJZu‹/»a‚·«ºõ«c‰›F—‘¹·#èGÒããÿ
388
+iK—-–+L˜:ÕB‰©Ss3œó8ŒFôc'øâ‹‹6nüûþýû/^¼˜Íf'½àéN†øÉr§%žY{1ùÄû7u-lD©3É ¢®! |öÁpÔ¢_Üf¼×]j;«Äm8Y<0Çu¾×؃GÈ,›Ãл®G¾²+
389
+«‚}wü!edîprLËu€™ííí Ç«W×¢£ Ì\ ¶Áœ×æ, -P b 4j ³è÷‹ßxã¼|ù
390
+clêñV-’S>ÉÒ¶s¬çúÚó#5ÇßÚӋ(&㝮ˆì5 ÅQ¡Ç5'úΦP¹ÐzÎ3ÿÔ6Uê& ÃÝ©¥†@õÅm#8ì=òY‘ù‰Åb Ç›7o^¼h 8€\ÆV º<緜?¼—y×,Y²ìÍ77:tøêÕ«ã§»[,w|ò+ë!dlF§àæ¾FP¥‹2çhwjõùQÿûj°„“ UÇꯥéÚÉü*QfÈWiáŽÝšà_ß#­-ºé…†» [ Òï]¹1u7%#3írCnEÂL&sîܹúúúU«Vϙ3—t›`l¼Â“…${¶ìÉs€<™Þ a^¾ì¥M›69r¤³³süìwK×êº,¢˜š™PLN†LØðÓÖ£öìÈÏöÝ¿µ[ _›ýVï']™ð±Îœ“ƒ°;”oÂQÕÛ_Ð¥µÈÿÙ/·§&²<Ž'ña«¶jŸöaßv¶vçak¶jÿƒÝ‡yÛ§­ZIw¹:«Œwq–A@Dw‘qdðF§Q‹,㎣ b`…ˆÖ×réQÂ=dHÒ½¿sN§ÓI¸$ˆKÏ·~u8}út眤øô§O2ìßÈMÑÐ$d¢Ñ="Bgg×¥K—ssKõ Çl2á*nÅKU2.ƒ^…n֐’ŸŸùòe“ÉdµZ¥
391
+‰²ÄU—|À`+—ˆFH5ýø¬O”¸,S‹x’/ð¶V½zä‰yZÀá“ÉE oß„AFÖq¶÷›]‹›à‡¥¡y[Y3ÙÔ¦êõzŸ<=þWiéɬ¬lhŒ\—UPœ„Š%2¬g/gŐSR¶rœ±««Ën·G|nÂyم‰ŠE‚ýŠA#Æj ЕDµKD *ï”ÂŽ7"Ð‘¬Hdº&â†0ìÐmµù00Ùè¼ðbf#wFC³ù£&àpšL.\<|8wI3l$U#É!IFèfS·¥ò<ßÝÝít:7p§±DÄ_‡dDYIQY|ÂD±2ƒ ú±¤¾JÚP
392
+Ÿ! × {ÖbÂȁ­ZÞ -êÛþÜ>±‘£¡ùхÀÇãñX,–ëכA33¶«€bl¶eu 'é Ñ &•–žyìxq͕Úoï?pŽŽoô^ß݋½¾ÅÚ^éŒv *°\l¶ÕvLÚøªÉº ~îÐÐÐě0ë‹:t8÷@Êe¥zV-À2õ¨™™P+3ù°<9)x-TFæöâⒺºk===.—ëÿ»ãw="æpÅç58í¨†Û tà·\ÜNír+7Ưa/444±„€7¿=îïïojj:QR
393
+z¬gXÅx6EÍ^u_/1drHZ™ÞŒ!;kGIIiýµsïÃׯ—}½U//z©+/ž&:Öyÿþ=2¬ðrАLãø ü³:Ç]ç<þöƒ ý)hhâIìøRfÚívÐãª/Ï<pˆ co˜'ãJÖGY]„ÌÐâ2deï<Yzª¡¾±¯ï‘ÛíŽq=4k|w…ýS#f/ïcÛㅰ†sìî ²)°_’¨ ÓЬ91’L›ŸŸïï·444•”œHKÏT‰n2)à(äªGB‡!€ë ,“ lÿp箞ú´©éúãǏ§¦¦Ôº®,re=¦Y9_/¼×8®áG0N­^Ðrq•ðË&Çw¯½»€äÃ÷¦¦¡YK–„Ûª“IlVûÝ»••UFzœÄB˄{/F®ÊI'¤Í!2Ë.Íb¤³†wí.++knnîï™!Ÿ×ji–ЏË<‰Aj×r Á6-ã8!ÌŎ£ýH†áw@ðé/BCóFYó¹pnnܵ±±±¸¸$--a«,nÕÔ7¿2„±0³¡4Ù@žœ“³çôgå--_Y,ø,õGÓÿý8XJ­‚ç§WG5ÕvÑ©3B+Ä aÎ
394
+×þþÆØð,Â/±(Q¦¡Y[ÖÅ-Õ<´Z­wÚürßþjGé1ƲÞ='4Y¶è°iíÙ{æÌ™7n<}úÔãñDo„f…`o èM“[@€‘ЄmqCqÛ®ãíeϦñ]~rošDŠßïþüyC}c^^¾^Ï2A¢*¢«p•Æ2¼”$‡lYF± djCæö¬OËʾ¹ukxd$F¬Àê͂ñ¯¿¾i6÷yæÖ¶\¸êڐGà ÎÖA @F4¶c, *Ғ68ȃÛµÐçíäò?Þ~=¹‰oŽ/†æÛ=ÙÑqïtyŶ´ l¬¹LP fá,õŠL&"Íâ–aXCzFfYÙgmmwA ºY W&&&`·ðÁCmÿƒ bÙõŒ_ú õ•ÌU¬µZ^ÐÂ!gÓ: 1g#ãކŠ Z.‡4˜ÓG5ÆãÀ,¯H›††&!²`|vvöÑ£Gõõ NJާ¦¦±2¥!®¢Ž!ek‹t—Ho·Ùh+0gôP‡åž;Wyûö큁òˆõlF8“5CÛÚÚJ^+È÷V^^ÏM”žTñ|„VgÆ
395
+Z¤µŠ ;0“˜·N-‡ì¤w Ø2 ‚æñ|Îñ×{ÓQ¤ü¥¡Iü(èS:ÃÃÃmmmgÏ~±wï>=kH"°…– ¡5Ya¯Âg54@˜” de&`*÷ÈÇUUçÛZï ®ðtX²Ÿ€)/¯ gÐ[ 3õٕ/’ hJ`Áïïúb,¢® ¨««vè8™½¨x¬ÁVeäÃ@ãQ·P£ñtmϸݖ‚˜†&‘ʦ§§ûúúêêê@“SR<YC„îF—ìÌ2 ª6›p[5SÏ~|äï/\jooùòeÄ:œ½$ccc;wþl“ÁÛì4uEÌYa#~)x
396
+‰©ùÀå;û|.½{òw_¹WkŠuA±M ¤Eå@nŒ”³ ¹Z@
397
+hì̼ï–oOCC“`‰‹ldòÐÐPk+Òã={öFW†ª93ȰBcƒÊ–£pMŒ÷ñ4t-Ëòò>¹xñbGGÇÈÈÈ:îâ­Æd21Á—l†/^¨'¬²ÔàÙ¦1LFö
398
+è÷øÅîqïégsÛº&~{c;°€PLT™°úÚu˜ÉˆÒ¼ƒÐÎþ¼ÎÙ9öC¢|G444딩©)óÇWkk ‹Š³Hh l¹]V’ƒθXè«®BwÃãCJ~þÑêËX¥ÍfS@€–Pª\UuV¾5‰!ûÊÊÞ177×Â0uq¡® q0"º:?瓺ÆʞÍ&wºßoÌnáF1¼üÂ2gÓð£D’5Fë>󤄉NCCóc
399
+¡ˆÚàÐЭۭŸ±;gÏ
400
+ìŖÑÁä-*5½‘L&+‚ XNIM;ZPd4;;;A­$ O¥ûª7{´ @9ã
401
+ñ¤@hºHF`( œL/J¦QÏÉï§¶vºÓ<ŽØËas€_àcÙþëf—erq6ICC“Øq»Ýf³ùÊÕڂÂ"Ŋ±ëÊ ]µd7V]»\mKË(,:f¬áÿóm·0êŒ`Üza9VxŠ¢¹÷!^yè)SYYù–ŸXœÔÈrÅI¯tGX,y2ýÓ«_5¹4¼M @F†,hª­Ç-Ó²
402
+‹!–¤xÑÐм¥ ~sóVEÅç99é“6予É`¿,jѱ\ýòàM҇›31“MÏÈ<vüW¯ÔÞ¿ÿ`lllUô½ù„è|hÁ ÚNKKK¼7‰+¢ÜDåX1g¿tßõC©eêOí?©±ij¿h÷øü‘wH€7š7ò¿¼ä?õÄÄDoooMMÍÑü@.‹9L̲)Œ>9¿Dƒ“v9&+Ó Ô|Æx7dmÏ...©­­ëééq¹\kXðâõzóò>!ëQV»^—›Ç`1|ˆˆ®×/Þuz‹¾›1û2K>¹@‚£Å0 Íæš`+`M=200póæ7åågvíÊ Z±€K‘^…«êþÒV¬W¬ÚH&Ceeï8Qzª¾¾Þl6ó ®Å‹Å†5àÇìËf³­ín1G ýI£>é 0!~äÍä¤èހR˜æ엉SÉÇÿË7Ó=“@èêîz€ §‚]«Ã<Þ+ <ô±Àƒ­òÀ %û”
403
+Âo'‹¾>f:“k˜p•°¿O5S===3ÝMåÓß¶V &ú%ŽŒŒz<犋KŽV+ É\ª±ÖÕ
404
+6z›õюÛbúS%’ÎHÉÉÉ­©9ÒÞÞ~çÎ+BNiâä±²–ùî€
405
+vÎÏϧº>©½W;,ÆØ˜ ™½Q;ê=5dzæ£àGÀúO›ôücâ$×Õw:óHžäñÉJœ{#EX¯¨z$VŒê–x { #F
406
+¦§8ϙô¨ëòåËwïÞ ‡Ã«ŸoEy%м:ÿPÕá”Öaů.h^ԅ,,‰¹‹†ã’.cð/ü 1ñÒ«W¯FGG[[[i<Nnà$Ž­-ó\J%L=L¶–Š5Ï33çç鶴­ëèè >|XÁŒ?~¬*6öjúvL2<Rš[V±H«Ew2ù[B`«bž÷’]5¹kaaabb¢«»§¶®>'7Ox•çÛøBÚ£õ›´§ð³8J4!«˜9yǎŸêêŽ{½^"äOŸ>Ymww·¶epç³ríZïr˶Æ,颍 •6-ê×cÒ¯¸ :$àå˗7nÜhin-**¦9–‰NŠò­""¨ÌB/9²: ½*ëO„L-½œ™£âôΟv¯?ÙÕÝ=þðÁç¹/FsË ×=vŒ¾kƒ!·#„ÇÆÆŒ6; ß=ú£»ë߮ںìœÜdþ䔘 íÖC2ï êњ
407
+|×Ï»Oœ<ÙÓÓóèÑ£¹¹¹ïµÎÌÌdmÛÎ Œõ`«ÏŸ?ÿ§k€­1á­[·Îæååc¢JcªÍ( SS—Fb°ÞB²´‰ŠU–®ã O ÎÌ̪¯?100
408
+…ÈH|>½Ši‘´ˆŽssb¨FƒØDXQé3==ãõvW”WbEåÁÕ¨b™åaá^acÓ¢S´îd5ÖÉXÉÉu:ó ˜ÒY~Ö³R}¸&¥©œøÁš2ñÕóçχ‡‡›ššöï/Â$ ñ²øãO„cujR„½e-åªÑ·ã„‰úÂù‹ G ²`3bÅÀ1LOO{½]•6Õ.tjP«U Džg­N…ŒY‰“0韗WÐèn ‡Ãñ³Hi"?&KŒe»={öÌç÷»›÷ìÛ+ÉÈZúÕ,Ÿ™E0¦*æƑ¤Í‰¥žÀIQU{qñÁ–Ï矙™ùú`³±zk-±ò×üüøƒ—;;kŽÍږmêaUDå³S¬»—™©uy7Ìú 1³‡¨â 6{úÁÒòÖ¶6¿ß
409
+…ÀÆl:ŠËŠÍxÑsvvÖçó¹Ýî={ö Q®¨¬o‘GzfYYE[Û¹‘‘2˜5\ ëk`sý®Ø9óóó÷ïßïìôV®ÉÊÚ¶&QY¦#U–0 ̙Y•••çϟ}ñâÅjÖÁb;@2â½a¥Å¼}Ùwñʗ/_ÚÛ/¡°ŠJU̅,ŽHQ[IñÁ‹þ966FÆ?Hëë1¶q¹\ îÞÿü N‘¼šÒRêclñz½ a™d`Y‘dŒ°j8e~Æ*k§uÅf?P\ráâ¿HVŸ››³8Á”VÀˆðF0TTɇ˜%ÆmÛ²KKËÜîÆÞÞÞ„Ãa£aÖÐ6õõ'‘¼î&š5»DͬJÆäŒ”ììܚš#$¨ß¾}û͛7ñsO¸àaVƐÏOý#ÿP k…舤D")Õ¶oßþ†3gINžœœüúõ뚼tqqÑáÈXÿíal­Œ §‘«ª¸Ëž–^^QÙ~éòÇ“ÍÝ\Î1pWc4¸%Ä ¬KX6¨Øè1„•íÙ9DJM-}¿÷?|øèǏɞoÞ2>>.Ógª©u…ûVB<÷Ædc,&¨ã¨Eg²å帎Õvt\»wÿýû÷ ç$‘îÝ_(ŇFóH‰XTFJN޳ªêPKKK__ßÄÄÄǏM¼´Äà•®®.dM¡«.«ªÄO£ò0-Æ ’QaºñomšdWŠÙ/
410
+vìtÕÖu^ñ2ë ü°¥øüù³Ãá@izáÙO„$
411
+òxL$k‘’uS$vÔÍLî¢}ì6Gaၦ¦æÁÁ¡`0¸°°ì½ÕÕ5(Îl뛇õ òñÝkÔu¢v³q’Y8Ò3««x½]“““ù¿` @B)QåøøxSsK^~‚8V2BȒ^ç&%¡5a*&ÙÛíi¥¥¥gxxxzzZ¼‘ÄoGz†ñëè^±¡ÈtT&FÕs¾ñ[Àì»@̚¾BÂ<?gff¹\®k×®MMM‰ùÆ,¸Éiü'æÔ¼?›…d?g¢ŽKí—÷îݏXtDLMHORŒÄ¸‡åÄ֒"-TìäQD¼¥¥emmm䤑Gèõ–°$ó<O%ŒEªçƒ'cKœ{S~¾¾X7R222]®Ú«W¯>}úô»Á¨VDß'¥Ûø‘Iø+æâÒë×oz{ûªª©ªMW«fcš`EÍÁkG9ʁØZÂ\«Bò6ÎÉq=r,3#‹Gt2 ¾¹h‘>Ò3jül›Xf¨Zž§‹Àog•Ø•Á¹NgýÉ}ýý¡P(U‹¦žØbÌÍÍ Ÿ:uÊáÈÐÄE½J"ŸÊT¦È¬èÂQy8c¢Ã´ÈÑúÒÒõº'a"@Œ§í;Ó×ìììÐАÛíÞ»¯ï2 ~…ã‘¢]-iâô[@’ݏdìtæ×ןìy֍Ù%ØÔ¬à·‡oݺÕÚê)**F4O*ˆç[Ìó­0°&j#•è0¥8Íçë,a*X ‘}$^b/_¼º}ûnGǕººúÝ»!“´¿¦î˜8½Ì‹ø”‘ž«±ª˜Æc¾!…ö!Ÿ²DW¾KÆûöž9ÓÐ××ÿäɓdÿ/l1¬|Þ&Lhœ¯_¿öööªª*»-D;ÌD²±,Gُ 9’ Ê%Þæeý“°’žæ ™Ó|)¾}ûF4800ÐÔÜ\^Q‘™•Etª ÙTò¬DMMYÒÍ,.E¾"q#yHáþ¢³ n2†`0˜ð6€­Ê²NWOOËU·=;W3O$Š)<Œ©xuqñúH¸´´Ìúì–XyýæÍ{w;:¯ÔŸøíç_~5“°¬’Ý%ˆÊƜµ<KQ—9²\dçR
412
+¹ÿ;8855•ꀿ!³³³ƒƒƒ§OŸÞµëgáXÍE´D¼„´|•ׯax<çV3µ………ÉÉI2;§­²¢j[Öv9’ðãÝݨgi}²XœZœ¾ªÚ‹”47· ù¦§§cÆ&¶+É‚4laÄüÝ»w7oÞ$¾*,,B(¢áÞ .d;ðû‡Õ¤%á%^ûöí½{c^o׉¿íùu/õ*æv5›Ÿ>9ÒðO*HÁÄÕ2Æ4E‹ +é½´ƒŒÒìé%%%Çï÷‡B!s©&ô°ÅY°Y0ù!ÏÏρK—.UTTØìvª¬)Eèe´l·§ÿùgÈdØÉêV¦¼¸¸ }>_[Û¹ªªCÙÛs„ccfÊâ±Ê7…(ËÔÀ(ù‚0{“ví*¿#%--½¬¬œ¼÷úõëä3$áà“µ€~`‹!~ÔKŒø«Ož<éé¹Zûö˵©©#ŒãŒ¯úú ú¢ïۏà«~šœÍ
413
+ˆrT¤¶ˆ(Ú@ R°¶ÎHG„„0• ˆ·Qãhª\ª/„± C"uD@ÂIúìî9'{Î !AÃmöÏβçºû<9ûÛÿ֜ƘReÀTJJùÑcɆÿdI¸zõj}}ý¡â𮄴2f)o)K©+¦X¦ˆ^¿H3á3Xb%cÌ;QfF¬tÍÍ͏Çï÷'2T..®M©8Ô¢gþ|† cSî„322«««Á¬¾ÿ~©'â! œmƒÁG555•–I·n'4FÀB͘d¶,µG0AƐj­1œVËrûãáŸ.]jí›[*n†¹¸6±âLð@  Bxuœ0tvL©UL/+;zíZçäädüÑ&¨˜ž?²A CCC]]]§N׿ìaK(ªIHÔîÊë½YÁ/"(&èVŸUApҌkˆZÓKKËZZȃ³³³ËÅÅŵ•”§í/:€¸
414
+øe)àÚf¨i„ÞËˏ9Nâ痍+¥cÆ.IÒ²yxõêÕýû÷/^l¶ý\™³;i€¬ñÀªÑ«:3 ë‹6LCàêÛvíʱÙ*!j¯×;55•èÆÅŵy„ÑÔ:SWVͬEMêŠI)` qM,"` ÆuNNÞ¹sô÷÷Ãê`qRëK²¨w...¾|ù¯»«»¶®¾`Ï^Kñ8©³…(ÌQüª!˜•È!ûlÔ`Ë©Prž¾}Gùñcmí®gÏŸÇ œ‹‹Ë¨ÅH8‚gm(Bþ1›^Í¿õ¯‡‚£#ŽÔ*D)bâ"9Þ&öÜÆ‚ÓL@{ ÷544Þ¼yÛçóé@º¯XÐ×øøøƒZZZ*+íùyÚäˆ
415
+Z‰=&« Â4VÑål°mxÎi´óò
416
+ª«Oµ·_îëë÷î]‚ƒLu¸¸Ö£ÂØJ2߈r7¬¹ec°¸äÐaGŠ4ÎMˆ’‰X}Jn˜)µôÔ5r[%F™Åb­¨8ÑÙÙèhW9ƎÀ$ŒŒôôôÔ×ÿºo_ɘì)™õP%‡J͞a·ȤP7辀”ŒŒL›ÍÖÑÑ1<< ]Çmèã„Àŵ‰‚/\ \)–”¢(¼XüäɓÜÜ<AÃClð(*u`I¶Ð—з!AŒXá°)Ú£¾€ævé¢hI¯8~ÂáhœŸÿhŒb•ÝMLLx<žÖÖV»Ýž_°G1Ɉ „Y†ht‹܏”EJ ™Ñ¥ß/„­ÁéS¿tt\œ™™‰xÌ Ä¿Êŵ‘E?iÊ[)̞6|ìáõMa˜žàîìE VÊÌOa¯
417
+A Y N—vΔ߬ƒ=™—¿çüù󀣅……ÔådÙ«ì=’$ŽŽvww744îßP]>T{oÖ®h¸Öm~}VYˆñFà«ªªÜn7ôøƒââÚ°’à|Ü҆þÈaR ‚†º‚Ž+*à~‹5;{7c¶UKÌÇbFúCõ$ë!M2GYµµu÷îÝûðáÃ:I>ŒçéÓ>§³­âÄɌÌ,Å$[ØuÍdÖ¸e¦ qÅ4EÛð#8Q»À~[€:++»¦úT—ûúÈÈHĀYöpä‡‹ës‰|С°ê|ÌVŒ/ù쥵á
418
+ÔÛÛkMß¡ÌtÄsÅNÛ`Áâp8áýÁ`Ðë}âp´UUUïÊލ½7ôEk³lü¢ÞOk±QDº÷‹*™E1ýäIۍ7W!KF¬;cÄrÛØxvѯI@šèd&‹:ÿ­b3?ä vR‹YY;kjj £‰‰‰8ãäâÚ<
419
+GîJá(z7˜tói__¥ÝŽg7úD3¬ðČΞ=;==mìwttÔãñ8N@G‘B'!Jê„Qì1 L`ÙK“§ ÔŸiX½Ä)QèÆCÝ%¿ßÿøñc—ËQ
420
+$Ex¿€ìiW%¼)Pí±1-,´¡<PÜÐÐØ}½ghh(
421
+­B*¸¸ÖHØè†•iö͕À—­¯¿íœúþÎÔAïtËY·oþÅôǹÅuÍg 1"‘¡…kîÎܼ|‚b2ÓÍICXö¨fTi³ÏÍÍ%2Œ`ð-ñÉÎ*{uö®œ8„Qùƒ©eB_À1·ûzʒ´¼ñ™Æ{ÆÆÆnݺ}îÜïÅÅ%f aÅAÄú’¡VƒÅmæwYb¹ÄËÉÍ­­«»ÑÛ럜LMè\\k¥E
422
+a\‡#­£siMciM¾hùӗva|K“ï‹æÀחý[oLe<–öMÿ6ü¡sbþùôÇÿB„áôeò?iðZ’¤;w&_Ô Õ
423
+Ū‘Kø*<"Šé.W;¼G}g"˜R ½^¯Ã鬴W阬ëT@VŠ Wc¾db•əíèos¹~¶Ù2³v²{
424
+S”·¢x¬B]§´[Q=_X¸·±±ñîÝ»oÞ¼‰3’dGþÉÑsq%­°j€Ã˜ÅP¾ë™Ša¨/ø¶àÃ×iMÐÆ¸=žÖ4þ•Ë¿µg*Û3]10sñåìßoC†ZkšvNùý¿.w)+Wí¨€4Ó\ïÁþÿÿÿÿì—[lÙÇg¼}©Vªv÷µj+­ªªR/ªú´•úPõ©ênßb Jv·ì¶´$Ü˦T”ñ÷(—®¸l $‚ ¤elì¹8v.6IÈ&±çL¿ïœñØ¹ØØ„ÄirþùrüyæÌ帜ó;ÿãñº=ÞÊÊ]¡Pز,BˆSNF½½½--­ÇŽß¾mÇҒeDà ávc²ü÷¥ÖdR`ù•@}ýµêêëÖ®÷HÞ"·?¬G*†²Èm'4— ØWç ûM0ÜÞTâä҇þaßÞýðˆH$’ï»qqÍV˜Ÿý¯4DŸ.ø´ BVŸŠ‰b``8eˆ²&ø¡B@”á¸þÇ»O­™4àÓß$¶¶¶ÖÕÕíܹ³´´Ô ó\’<nC齅‹>úhUå§»råj4y¾Ë®žžx™£G9L®ªªÊëY3JÏmøàà`[[Û©S§vlÿë¢E‹¥$f”½€e·§˜Ây„ä)†
425
+´‹ŠÓÙ uÜÈP!uÐ-••­¨þìÀ¦›°ØeyŸ™32¹¸€¼À^“¦P.oî
426
+~c4~x“áÓ¹¾´¯XÇ@D+º ¾{2t»gؾ㠐i>ÿ=`ΆÃá¾¾>öՙ¤/e¶æx¨LÎÅÎý_(—VkšV___]]½víºââyŽ×E´¢ã-v¼q2€É^jöµ(ùÕ6Հk¼Á¾rå*¸sSS,»Ö¸½Ì„¯ÇáÌU(ÑÑi݌ }ûõ·ˆÓ‰œ0šaÆdŠe4Ìè{‘½p0äZisÌ"ȽDa•Ï„J¯<fžª~‡\®MçÃlâ@–¶Œ?ÕÕÕuëÖ­ººìÚU›Év¼Ì$K)CI±ìÀ9™¤—@f‰žÂdþ» 6lø‹¢ø®ëºžûKrqM‹LöCñã÷KE„ª:1mðŽN”$–e®}õ~É™!ØÊJ×ìÇÇÏ͗5[çˆ{n3³49?~üøêÕ«²OÙX^±¤d©Û#NZ݌ÏfG¡Ø6Æ£ý3V¦[Z°`áÆå~¿¿±±Ñ0 特l—¸¸¦B À%
427
+_ÆÈO‡ÑûõÌÖ(ŸÕQìu˜,k.Ÿæ®ï1Sž;;ß&sv2Ê´"̍wõ™µç®’÷ôôܹsçôéÓUUU«W¯ñ QYØ(¦n™ÁøœŽ_¤1Ųj‰•ï-Z\Q±éСÚ7n†Ãá©û5¸¸²ÉÆ$ÙÞ֏€…u—œÆae4„Ù)›À: z•/((0¼ö«A+ vk&Ñ兡—£y{)š•@~¹Ëúäɓ/¾¨÷++Ê7--YæIs¼ˆb¯vS,'! 4¦LF¥ûd´hñ’ŠÍ›Õ¾ÙÜŽD
428
+ÝJ®Y)bdüa3<dþâ| ÔåW©¡52:a´ÊªŠeM”±²‹ùõ¥®Á„I¬™…_®Y¬h4
429
+&ù̙3»wï^³f #ª;銙F?ìð9j ¢(i¤©=¶¯]R²tËæ­ÇŽoiine]ùºÉ•»º^‚ÿôÉ´LEŸ}9€Dõë6ZÁÖf€° |oMÒ ×@ejŒýHDEÛó°ßñ›ÞÙ,Xk¹æž`$wtt\»víàÁC›7mY¶l¹íŠmKIÒ2W,¹G›á1«KJ–nß¶ãøñ·nÝîíYíŒ8‡¹r³§ˆFöݤŸX$ˆõöå U
430
+
431
+ØZQœÉ cèB ÔK øÕÄà°á’µŸŸèÏFÞŽñæâšF¥SqxxøÑ£G.\¨¬¬\^ú>¯ÇÁ,$‡‹(“ÓO1ÿœB4œõxçÏ_ÐÔÔ4Ṹž/ꃁSN˜–':%@é
432
+V]Ù ,ë`ƒ¹èÚ²&ú:ÑËjù½~çž ‹{`®ÂhŒ;u’`0ØÐÐ&y˖m`’«’§¸ÈC9Lñk39 ç"–c™rÎíííãÁŕ£HÒ ǔbŠyõQÁü¢Å tÍ aÙk×üY!·}ož ݋Ž˜dÔ³¸¸f¦úúúîßo;wîüÞ}û×®[/y¼FZ
433
+Ûât«Œ>X-yW®Z=44ÄîN`Nc®\…#Ådø¥08þ¹1ô­ÃhnÅ}ê+ÈU ›‘À\vpmà…Ho£¬5–é‘\\Ó¦ñ<̅ªª666ÖÖÙºu[iéä»½¤1F‘™¼gï¾|ïÌÅ5F&û ”À$ƒèƒæ˜à ¾ ë¢/èº"WŒf6k‚Ö\àœe 0~¹óëQO¢À'VbúÛÈŕ¯NY &ùÁƒçÏ_Ø¿ïï¯ÿÄëçv3&Kç/\´8{¹&+“‡¡ÔÚÿΉÈèªè”®:u¶jF+AaA6hŽç5PLRã“XÜsÍPåEÑþþþÖÖÖÚÚÚòòr]×§î­¸f¿löâ$I>þéN_FØf¢Ûddò‰Žá¶lމv#I »Hg§ã¬ÄJUu‚*ÁΤ3-..®)N6“˜šOâ?:ÊÂèÕNj€ÉÆo.…‡ÌD¡7gä,¦V¼¬5ºâvlOû³3êÐÃèÈ3èb¦ù<Ó©o޳fòntXÐî#&G0×TŠá×´lYŸ>xê’õ¼!¬„DEdšËšKÖö?(pËæ–°ûØnfÛý˜ i'`?ò̓Ú÷ë:õ¯È»×{?¹ÛWýhà¢>øßX<6l“ÖîxBì›X¦éa“ðu”‹kʕ²Bfψùˋ]â‹@ÀÒ§‰Jð­s‘ί ؤ9)ÛӒÿÄ?<èK\uQ¡›šcÈÚëGõŸœ ½}©ûý›}›ïþêY}x807aÿBR£?9‰¹¸¦ZĤsÍ<ðø™à×Kó
434
+ÑÇfwˆ~U+Ú¨—âÙé#0±ñ²æ§ˆ\„­JŠ_™rØG Z²`=HsEdýµ#ÆOÏF޹ܽêvlwûà“þxAÆÅ5ËE¬8ó<lòþîr·8jnæ`ƒ5—Œùu‘öhÜ´Ò=6×Ô
435
+­+a}ˆ®µ>2òƑNè À[ûƒcÕ^^å óÉtËcЃé¡!ñx@” £m׬±÷žÄ:©Qüv
436
+rÞN˜š(ðÃxáªÖ> ©Îmð´‹q˜öæÂëÝ´k‚¸µAðê.àªÌ6,F¶¶í½Œê>ãÐ?µÐŠþúaírx¨Ð ã⚵"Ãp’… ½öÜôwäï„aއÀ¿q´óÌY‚7å.ˆè$Q¦ýbÐőínÔ4ðj)ßëӒgu<«¨.Û-Sh+úŠ–X¡ÛÄÅ5ûUß9ôÚa܁
437
+þøNØžÅÆÂÆ^»Mw®éú_B’©i뷗ºí~Aœ]>‡«û÷2
438
+^⪁¯! ð+rÇ÷Ntߍ³=“sû“‹‹kÒ2é\*kyjÏD0N™'iƐ©éRÔSê ÅŸ¡PúO”¬~4à’ ì—š€ t&×J€p0+„±š(«Ì ¾ pøÏwèÖÆ´ØŸd&
439
+ÕN.®Ù$:oïw'Þ<م»QÛò†0ìakÔw®ô$M’E?ù4F‘16;o‡n ÐU5€tUÔгxf²&2+úÏþêL ÕvžAxçrq½,‘ ÷b‚ü*å°êʗÀ>fƒÿÇ~ùŸqUaÜ3©¨!”/<”ª @¡¨â ¤€@!A@üQUDÅBŠx‰>¬„P<3N҄%°¡¤Û ìš¢4$Û6)¤t=ã™ñzÿ{×k¯=÷^Î9÷Ží¤µ“q£¬=?¼³‘}'Þs¾ï|§ôôõº¶©Zœ„ï:7üÅufýÕÌ:Vªƒ&b}ÝÐê7LÛ÷8¶evœºâ©Wj
440
+-X¤F,Þô?Á0LVŠëÉCs9Ç×
441
+¥f5aˆLŸ:9·ÐÀt¤™d¾»HÕ¶áΟþ•eñÀ±ò˜Ў¢¢¯ú½K©Cr˜ú0TvÌß99·Úì<€ËË0wЧ^­æòeµ Äà’톿™Y5'R^œÄB½Ëà#pRá§xüÂ
442
+h ëëƒõz—ÒIßc|Ø'[0{AþúFúÕõ†ag­!÷LÎi‰åÜÙTž™“ðGŽGתIgE5öË2½Ûܘ…aŠéróÝuM}Ë ú9°^jnڃ<ÝxÂNÏ+ã¾4d¹¾ ó–Ù}ƒ„æ“C
443
+aýLwÒ ×/VÓ#¥v©Ssw0iÑmÂ"½ÿÆ KTÓ0ÁQïR†i6vm¹¡¥?脹B0Q¬§†óªÃ0™Ð’!¦:Ú{zÑBé6,žN4†V rëiÂcÚ¢½H+Úr‹ è÷ŽÏÍo҉Magû"ŽÍ6hÂh¿P;'ó¦CYnðͳ‹èîRq&²ë§Lô¯*ÕwPú¥}3ÈÀZ‹po»}DRŽšµM¬ÂLµïÜ2©WT:ŸÒЀV)[‰úü©E¬,Úﬕ}Ó¡ºû¶½çÐÜT¹®¸Â “‰»£Lp¢ÿqßÙEŒ7žO*‹,Ǭ«–Ó[Œ¦¼˜¶T³º¾Í+ž(5Ú¸ãöR²T‡œŒp=}mÃ0¥Ùœg7ahßÂu)|ìâŠÒëO[†¹md—^´[þ£Ü¸ÿp„²r}ˉÇ@¡èÆxr^ï$ŒBÖoƒX…¿~ñô‚>“20Ü$ún%‹t "”k­Ÿ¨äLî³éôº܀œ`‡|ðhåòRs«¿Ì$䊰žbþÑÅ%•Ñ7¢-•¼×i[qÏ$l»%[ >å…ÿÖÒ ¬Ýר^(ÅIxë1%ðóçWÖr(\ŒëLVvŠÐ':Cݟ¼¼Öu8Ã0·æ¦\:³¼¹ûx%—v —‚ý”~Q_䮽ňï1†Ú‡?}ra¥¡íV´Ÿd~JÉ"Ýr¤‚+t…f–š»‚—¬Ì1¸„EGë.ZЮÿÐD¥¸žlõ—c˜‘¢ã‡¨È_^YÁr‘G›&úªØ+Y}c’ os|›6Sóo_ªÑá-ót^”¼6|Á.<Hª¹±zìÂ*ŽQ§÷¦Óó¢Ñ\€>)â°öJãW7¸¾ sûà:ª¤N«ázëá¿, ‹‚낸À‡u:m:m¬Q¿D1ØÁHüщøzµ%»…(Ó,ف‡*‚P-]ŒSqã¾½‹Ûç2£9ÂAC÷<WYkq‰æ¶¡dª5ó»«Uʽñ˜SÌ®G£àòòï©#/kqXѕ1“g¤øúßaþÆP}êX áëáH…âZnŸ~qEÂغ¼°ðښIØÆê•ØÂ¯Ê0#†Óõ–|äԂÉ3^Ù„½ÀrAÂ¥]GÊÿšo)’ »ðÐ"Û¾(I*nÀµÑKq’ZyØkچÊþKßù«Û1³wjQŸŒ—0w’˜aÞ!(~­†aƁ`¢ 2š°å•,nüïœ_Rœ|†Ù1býÚJÔ£“ è¨k=íºí×>&Ü5²)BçòÁÛ]"Ø© Óã¸#¦?âËg–sà¢_¡ÌI؁DïÜ_~6ª Ür ÂCMêÁRJŒÿ§
444
+IÛ.ÏGS¥§ßfDé—æo˜sð³zx´ï܊6^}º4b+f˜7‚IødÐØ¹?ʹ1Ú/H o2š0n£Å/M/Й‰R©î˜áEêáÈ${ kòcsch§TмOÖö3a—Û ÒÀς“ß(>[n&æÜ Óñí³«6
445
+ª½W„15x}MéÌQxDH+dææ/®¬‘Fh¿n¶øÕrÃÞÃ×·à=^»yB‹šÁrý^\&sGoïF ü‘³ó÷ÿ¡¬Ã)“LV¶œpÏäÂjb•Þ@YxCŒÐõ‘æsiqó£ÚT)cWøøÚ³ôÆ{MZ6ïŒrÎÜîcñÌrbž&ه¦R=ñb•ÖÉTD¨¦(sö‚ñ—«pZºy&úpf˜¡ú%¤ìr䜫æÜYÃt…wËáK ãÄ9¶§f±IÅäÉO¾´J !÷ÃàJ¨ÓHj“V¯U›>^!é
446
+HV½u§U愶Ó§H}žÿàD%XßìœÛ~3j<_®¿ë n Ý5¶ólFØEŸ81l˜~ãV`¶;²KRë9ùõL5W˜ÅÙyp×Ðr|[;m/q{EíùBHù'´ÒO/W›æP|Œ0cå R}õÌ<”Ør©Ö°ákÖÍ(¤xŒ_[Sº+t_0Ìv&MÁà´€ªJM|ò¯‹ %£c-*¨·¸l-1X9¢…y8Úu4¼´Xo[oê÷ìÀ#Š|æõºqQ*îdt`¼tx>7Y1Ãlo„Jð‡Lí‘~üþÕu96j Âm”Ë—Ò0ÜÛ„ÝØ"»¶à=iÍ ¿ÿÏeÙI;ðgtBªFK}v²‚ã8Ýt²'a萈n‚ƒÿ«)ÕR<•ó*r]ŠGÿ¶€#õŠh­ 5°b°V'è—p0*—ry°â²íù÷í/=5A`I×S´ÍKɲQäøÕu½YùÐʃá
447
+w8´.¹áÞ3‹íÍ0Û©Ò,‚¯É‘ÙZe‘¯šå|8¸ýBN®€o¶håüÊô|zªö]zŽNÃlÂ#ŠTþº|ðÏsØØ}6£^MâS_Á@v-ÕïGÌvÇH m‹_›ZÈy(.ۋµëÀs«Ø££2äçˆ<¼ôL±nN”I÷óØG\hô4Uêg—Ví|dë1Ù„a G¸dÑg¿u~™‚Ùötrˆl2l¼ãPD¹×G/õ"´_‡ ¶ vÁ~Ki4Š9Ui´d;`we–܈#ՋK],S­ýÌ&ŒMÕ±î÷š;_ipf¶5ndjŽß;·4Ȏ™† 30\ÁøµÚ/æŽBí!¤ y*ÕwÏ/c”õ2'a ós‰’0Üa²?qq•'3³‘‹Tpa±ù#ॡ Ñ× 3^rb½c>|b.¬Ý€™ÑÇ´Ô}¯ÉsÑæÎa:s³\^ɼ:%l3¯ø¡ãñ˫ͭþ~ ³…ˆ¶Y–kÉtܜŠ7¦¢Æé8Û5Õ§âÍé¨>7®®6¥Jôá[øÅ˜;‹TÁ
448
+£û…y(w3kŸœŽëÔ]›SexmNGÓáæb}k¿Ãl%n´¼ô¯‰TR ´Š®C”9‘MøžA—RˆvQjƒL’Îý[8‡aî`ÓDeImǃ9g¢ºÝ|@#g†SVjÙJ#qkÀӄöàÄ$ÖÌöFh딩{ªA‰Ð'i'qµWWæ^ ÓBªÁã+¶DB-F½B¹Z :÷æÞ@hAÝh™ƒ‰B`Æp“Ð=gá{‡®EI¿š¦€)
449
+'wà?È0#‹1_mÅÉÀ!G*i@P‚Ý÷%1œzòÀ.¬g¼^šxX3 Ã0 Ã0 Ã0 Ã0 Ã0 Ã0 Ã0 Ã0 Ã0 Ã0ÿg ýí pÿÿÿÿ_R\V endstream endobj 18 0 obj <</Intent 27 0 R/Name(Layer 1)/Type/OCG/Usage 28 0 R>> endobj 19 0 obj <</Intent 29 0 R/Name(Layer 2)/Type/OCG/Usage 30 0 R>> endobj 29 0 obj [/View/Design] endobj 30 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 30.2)/Subtype/Artwork>>>> endobj 27 0 obj [/View/Design] endobj 28 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 30.2)/Subtype/Artwork>>>> endobj 22 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 20 0 obj [19 0 R 18 0 R] endobj 31 0 obj <</CreationDate(D:20260321145540+01'00')/Creator(Adobe Illustrator 30.2 \(Macintosh\))/ModDate(D:20260321145541+01'00')/Producer(Adobe PDF library 18.00)/Title(PAILot)>> endobj xref
450
+0 32
451
+0000000004 65535 f
452
+0000000016 00000 n
453
+0000000166 00000 n
454
+0000018020 00000 n
455
+0000000000 00000 f
456
+0000018071 00000 n
457
+0000000000 00000 f
458
+0000000000 00000 f
459
+0000019638 00000 n
460
+0000019710 00000 n
461
+0000019850 00000 n
462
+0000021470 00000 n
463
+0000000000 00000 f
464
+0000000000 00000 f
465
+0000000000 00000 f
466
+0000000000 00000 f
467
+0000000000 00000 f
468
+0000000000 00000 f
469
+0000095490 00000 n
470
+0000095561 00000 n
471
+0000095977 00000 n
472
+0000018499 00000 n
473
+0000095864 00000 n
474
+0000074937 00000 n
475
+0000019262 00000 n
476
+0000074363 00000 n
477
+0000074411 00000 n
478
+0000095748 00000 n
479
+0000095779 00000 n
480
+0000095632 00000 n
481
+0000095663 00000 n
482
+0000096009 00000 n
483
+trailer <</Size 32/Root 1 0 R/Info 31 0 R/ID[<11165A476C9F420581BAD84D0C04D3C5><E318DCE21D3A40F39E790B7B02A4EE4F>]>> startxref 96195 %%EOF
assets/android-icon-background.png
deleted file mode 100644Binary files differ
assets/android-icon-foreground.png
deleted file mode 100644Binary files differ
assets/android-icon-monochrome.png
deleted file mode 100644Binary files differ
assets/favicon.png
deleted file mode 100644Binary files differ
assets/icon.png
deleted file mode 100644Binary files differ
assets/splash-icon.png
deleted file mode 100644Binary files differ
babel.config.js
deleted file mode 100644
....@@ -1,24 +0,0 @@
1
-module.exports = function (api) {
2
- api.cache(true);
3
- return {
4
- presets: [
5
- ["babel-preset-expo", { jsxImportSource: "nativewind" }],
6
- "nativewind/babel",
7
- ],
8
- plugins: [
9
- [
10
- "module-resolver",
11
- {
12
- alias: {
13
- "@components": "./components",
14
- "@contexts": "./contexts",
15
- "@services": "./services",
16
- "@core": "./core",
17
- "@types": "./types",
18
- },
19
- },
20
- ],
21
- "react-native-reanimated/plugin", // Must be LAST
22
- ],
23
- };
24
-};
bun.lock
deleted file mode 100644
....@@ -1,1667 +0,0 @@
1
-{
2
- "lockfileVersion": 1,
3
- "configVersion": 0,
4
- "workspaces": {
5
- "": {
6
- "name": "pailot",
7
- "dependencies": {
8
- "@react-navigation/bottom-tabs": "^7.15.3",
9
- "@react-navigation/native": "^7.1.31",
10
- "expo": "~55.0.4",
11
- "expo-audio": "^55.0.8",
12
- "expo-clipboard": "~55.0.8",
13
- "expo-constants": "~55.0.7",
14
- "expo-file-system": "~55.0.10",
15
- "expo-haptics": "~55.0.8",
16
- "expo-image-picker": "~55.0.11",
17
- "expo-linking": "~55.0.7",
18
- "expo-router": "~55.0.3",
19
- "expo-secure-store": "~55.0.8",
20
- "expo-sharing": "~55.0.11",
21
- "expo-splash-screen": "~55.0.10",
22
- "expo-status-bar": "~55.0.4",
23
- "expo-system-ui": "~55.0.9",
24
- "expo-web-browser": "~55.0.9",
25
- "nativewind": "^4",
26
- "react": "19.2.0",
27
- "react-dom": "^19.2.4",
28
- "react-native": "0.83.2",
29
- "react-native-draggable-flatlist": "^4.0.3",
30
- "react-native-gesture-handler": "~2.30.0",
31
- "react-native-reanimated": "4.2.1",
32
- "react-native-safe-area-context": "~5.6.2",
33
- "react-native-screens": "~4.23.0",
34
- "react-native-svg": "15.15.3",
35
- "react-native-udp": "^4.1.7",
36
- "react-native-web": "^0.21.0",
37
- "react-native-worklets": "0.7.2",
38
- },
39
- "devDependencies": {
40
- "@types/react": "~19.2.2",
41
- "babel-plugin-module-resolver": "^5.0.2",
42
- "babel-preset-expo": "^55.0.10",
43
- "tailwindcss": "^3.4.19",
44
- "typescript": "~5.9.2",
45
- },
46
- },
47
- },
48
- "packages": {
49
- "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
50
-
51
- "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
52
-
53
- "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
54
-
55
- "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
56
-
57
- "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
58
-
59
- "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
60
-
61
- "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
62
-
63
- "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow=="],
64
-
65
- "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
66
-
67
- "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.6", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "debug": "^4.4.3", "lodash.debounce": "^4.0.8", "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA=="],
68
-
69
- "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
70
-
71
- "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
72
-
73
- "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
74
-
75
- "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
76
-
77
- "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
78
-
79
- "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="],
80
-
81
- "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
82
-
83
- "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.28.6", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg=="],
84
-
85
- "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
86
-
87
- "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
88
-
89
- "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
90
-
91
- "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
92
-
93
- "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ=="],
94
-
95
- "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
96
-
97
- "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
98
-
99
- "@babel/plugin-proposal-decorators": ["@babel/plugin-proposal-decorators@7.29.0", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-syntax-decorators": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA=="],
100
-
101
- "@babel/plugin-proposal-export-default-from": ["@babel/plugin-proposal-export-default-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw=="],
102
-
103
- "@babel/plugin-syntax-async-generators": ["@babel/plugin-syntax-async-generators@7.8.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw=="],
104
-
105
- "@babel/plugin-syntax-bigint": ["@babel/plugin-syntax-bigint@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg=="],
106
-
107
- "@babel/plugin-syntax-class-properties": ["@babel/plugin-syntax-class-properties@7.12.13", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA=="],
108
-
109
- "@babel/plugin-syntax-class-static-block": ["@babel/plugin-syntax-class-static-block@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw=="],
110
-
111
- "@babel/plugin-syntax-decorators": ["@babel/plugin-syntax-decorators@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA=="],
112
-
113
- "@babel/plugin-syntax-dynamic-import": ["@babel/plugin-syntax-dynamic-import@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="],
114
-
115
- "@babel/plugin-syntax-export-default-from": ["@babel/plugin-syntax-export-default-from@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Svlx1fjJFnNz0LZeUaybRukSxZI3KkpApUmIRzEdXC5k8ErTOz0OD0kNrICi5Vc3GlpP5ZCeRyRO+mfWTSz+iQ=="],
116
-
117
- "@babel/plugin-syntax-flow": ["@babel/plugin-syntax-flow@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew=="],
118
-
119
- "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw=="],
120
-
121
- "@babel/plugin-syntax-import-meta": ["@babel/plugin-syntax-import-meta@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g=="],
122
-
123
- "@babel/plugin-syntax-json-strings": ["@babel/plugin-syntax-json-strings@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA=="],
124
-
125
- "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="],
126
-
127
- "@babel/plugin-syntax-logical-assignment-operators": ["@babel/plugin-syntax-logical-assignment-operators@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig=="],
128
-
129
- "@babel/plugin-syntax-nullish-coalescing-operator": ["@babel/plugin-syntax-nullish-coalescing-operator@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ=="],
130
-
131
- "@babel/plugin-syntax-numeric-separator": ["@babel/plugin-syntax-numeric-separator@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug=="],
132
-
133
- "@babel/plugin-syntax-object-rest-spread": ["@babel/plugin-syntax-object-rest-spread@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA=="],
134
-
135
- "@babel/plugin-syntax-optional-catch-binding": ["@babel/plugin-syntax-optional-catch-binding@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q=="],
136
-
137
- "@babel/plugin-syntax-optional-chaining": ["@babel/plugin-syntax-optional-chaining@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg=="],
138
-
139
- "@babel/plugin-syntax-private-property-in-object": ["@babel/plugin-syntax-private-property-in-object@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg=="],
140
-
141
- "@babel/plugin-syntax-top-level-await": ["@babel/plugin-syntax-top-level-await@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw=="],
142
-
143
- "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="],
144
-
145
- "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
146
-
147
- "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.29.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.29.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w=="],
148
-
149
- "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g=="],
150
-
151
- "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw=="],
152
-
153
- "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
154
-
155
- "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ=="],
156
-
157
- "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
158
-
159
- "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/template": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ=="],
160
-
161
- "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
162
-
163
- "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
164
-
165
- "@babel/plugin-transform-flow-strip-types": ["@babel/plugin-transform-flow-strip-types@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-flow": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg=="],
166
-
167
- "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
168
-
169
- "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
170
-
171
- "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
172
-
173
- "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A=="],
174
-
175
- "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="],
176
-
177
- "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.29.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ=="],
178
-
179
- "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
180
-
181
- "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w=="],
182
-
183
- "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.6", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA=="],
184
-
185
- "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ=="],
186
-
187
- "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="],
188
-
189
- "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
190
-
191
- "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg=="],
192
-
193
- "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA=="],
194
-
195
- "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
196
-
197
- "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-syntax-jsx": "^7.28.6", "@babel/types": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow=="],
198
-
199
- "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
200
-
201
- "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="],
202
-
203
- "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
204
-
205
- "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
206
-
207
- "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog=="],
208
-
209
- "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.29.0", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w=="],
210
-
211
- "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
212
-
213
- "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA=="],
214
-
215
- "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
216
-
217
- "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
218
-
219
- "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw=="],
220
-
221
- "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
222
-
223
- "@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
224
-
225
- "@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
226
-
227
- "@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="],
228
-
229
- "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
230
-
231
- "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
232
-
233
- "@babel/traverse--for-generate-function-map": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
234
-
235
- "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
236
-
237
- "@egjs/hammerjs": ["@egjs/hammerjs@2.0.17", "", { "dependencies": { "@types/hammerjs": "^2.0.36" } }, "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A=="],
238
-
239
- "@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.24", "", {}, "sha512-1bJ63Yv2Bn8SN2MjrlbwLwUhnC8COOeejd15H88WjCtw5iNErqEPaBnpvmYyqciVYwudGo5drUIdY9C/5yPGbg=="],
240
-
241
- "@expo/cli": ["@expo/cli@55.0.14", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~55.0.8", "@expo/config-plugins": "~55.0.6", "@expo/devcert": "^1.2.1", "@expo/env": "~2.1.1", "@expo/image-utils": "^0.8.12", "@expo/json-file": "^10.0.12", "@expo/log-box": "55.0.7", "@expo/metro": "~54.2.0", "@expo/metro-config": "~55.0.9", "@expo/osascript": "^2.4.2", "@expo/package-manager": "^1.10.3", "@expo/plist": "^0.5.2", "@expo/prebuild-config": "^55.0.8", "@expo/require-utils": "^55.0.2", "@expo/router-server": "^55.0.9", "@expo/schema-utils": "^55.0.2", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.4.0", "@react-native/dev-middleware": "0.83.2", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "dnssd-advertise": "^1.1.3", "expo-server": "^55.0.6", "fetch-nodeshim": "^0.4.6", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.0", "multitars": "^0.2.3", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.3", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "resolve-from": "^5.0.0", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "terminal-link": "^2.1.1", "toqr": "^0.1.1", "wrap-ansi": "^7.0.0", "ws": "^8.12.1", "zod": "^3.25.76" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "bin": { "expo-internal": "build/bin/cli" } }, "sha512-glXPSjjLCIz+KX/ezqLTGIF9eTE1lexiCxunvB3loRZNnGeBDGW3eF++cuPKudW26jeC6bqZkcqBG7Lp0Sp9qg=="],
242
-
243
- "@expo/code-signing-certificates": ["@expo/code-signing-certificates@0.0.6", "", { "dependencies": { "node-forge": "^1.3.3" } }, "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w=="],
244
-
245
- "@expo/config": ["@expo/config@55.0.8", "", { "dependencies": { "@expo/config-plugins": "~55.0.6", "@expo/config-types": "^55.0.5", "@expo/json-file": "^10.0.12", "@expo/require-utils": "^55.0.2", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-from": "^5.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4" } }, "sha512-D7RYYHfErCgEllGxNwdYdkgzLna7zkzUECBV3snbUpf7RvIpB5l1LpCgzuVoc5KVew5h7N1Tn4LnT/tBSUZsQg=="],
246
-
247
- "@expo/config-plugins": ["@expo/config-plugins@55.0.6", "", { "dependencies": { "@expo/config-types": "^55.0.5", "@expo/json-file": "~10.0.12", "@expo/plist": "^0.5.2", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-cIox6FjZlFaaX40rbQ3DvP9e87S5X85H9uw+BAxJE5timkMhuByy3GAlOsj1h96EyzSiol7Q6YIGgY1Jiz4M+A=="],
248
-
249
- "@expo/config-types": ["@expo/config-types@55.0.5", "", {}, "sha512-sCmSUZG4mZ/ySXvfyyBdhjivz8Q539X1NondwDdYG7s3SBsk+wsgPJzYsqgAG/P9+l0xWjUD2F+kQ1cAJ6NNLg=="],
250
-
251
- "@expo/devcert": ["@expo/devcert@1.2.1", "", { "dependencies": { "@expo/sudo-prompt": "^9.3.1", "debug": "^3.1.0" } }, "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA=="],
252
-
253
- "@expo/devtools": ["@expo/devtools@55.0.2", "", { "dependencies": { "chalk": "^4.1.2" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-4VsFn9MUriocyuhyA+ycJP3TJhUsOFHDc270l9h3LhNpXMf6wvIdGcA0QzXkZtORXmlDybWXRP2KT1k36HcQkA=="],
254
-
255
- "@expo/dom-webview": ["@expo/dom-webview@55.0.3", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-bY4/rfcZ0f43DvOtMn8/kmPlmo01tex5hRoc5hKbwBwQjqWQuQt0ACwu7akR9IHI4j0WNG48eL6cZB6dZUFrzg=="],
256
-
257
- "@expo/env": ["@expo/env@2.1.1", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "getenv": "^2.0.0" } }, "sha512-rVvHC4I6xlPcg+mAO09ydUi2Wjv1ZytpLmHOSzvXzBAz9mMrJggqCe4s4dubjJvi/Ino/xQCLhbaLCnTtLpikg=="],
258
-
259
- "@expo/fingerprint": ["@expo/fingerprint@0.16.5", "", { "dependencies": { "@expo/env": "^2.0.11", "@expo/spawn-async": "^1.7.2", "arg": "^5.0.2", "chalk": "^4.1.2", "debug": "^4.3.4", "getenv": "^2.0.0", "glob": "^13.0.0", "ignore": "^5.3.1", "minimatch": "^10.2.2", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "bin": { "fingerprint": "bin/cli.js" } }, "sha512-mLrcymtgkW9IJ/G1e8MH1Xt2VIb1MOS86ePY0ePcnV3nVyJqm7gfa/AXD1Hk+eZXvf8XhioYz6QZaamBdEzR3A=="],
260
-
261
- "@expo/image-utils": ["@expo/image-utils@0.8.12", "", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, "sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A=="],
262
-
263
- "@expo/json-file": ["@expo/json-file@10.0.12", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "json5": "^2.2.3" } }, "sha512-inbDycp1rMAelAofg7h/mMzIe+Owx6F7pur3XdQ3EPTy00tme+4P6FWgHKUcjN8dBSrnbRNpSyh5/shzHyVCyQ=="],
264
-
265
- "@expo/local-build-cache-provider": ["@expo/local-build-cache-provider@55.0.6", "", { "dependencies": { "@expo/config": "~55.0.8", "chalk": "^4.1.2" } }, "sha512-4kfdv48sKzokijMqi07fINYA9/XprshmPgSLf8i69XgzIv2YdRyBbb70SzrufB7PDneFoltz8N83icW8gOOj1g=="],
266
-
267
- "@expo/log-box": ["@expo/log-box@55.0.7", "", { "dependencies": { "@expo/dom-webview": "^55.0.3", "anser": "^1.4.9", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "@expo/dom-webview": "^55.0.3", "expo": "*", "react": "*", "react-native": "*" } }, "sha512-m7V1k2vlMp4NOj3fopjOg4zl/ANXyTRF3HMTMep2GZAKsPiDzgOQ41nm8CaU50/HlDIGXlCObss07gOn20UpHQ=="],
268
-
269
- "@expo/metro": ["@expo/metro@54.2.0", "", { "dependencies": { "metro": "0.83.3", "metro-babel-transformer": "0.83.3", "metro-cache": "0.83.3", "metro-cache-key": "0.83.3", "metro-config": "0.83.3", "metro-core": "0.83.3", "metro-file-map": "0.83.3", "metro-minify-terser": "0.83.3", "metro-resolver": "0.83.3", "metro-runtime": "0.83.3", "metro-source-map": "0.83.3", "metro-symbolicate": "0.83.3", "metro-transform-plugins": "0.83.3", "metro-transform-worker": "0.83.3" } }, "sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w=="],
270
-
271
- "@expo/metro-config": ["@expo/metro-config@55.0.9", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@expo/config": "~55.0.8", "@expo/env": "~2.1.1", "@expo/json-file": "~10.0.12", "@expo/metro": "~54.2.0", "@expo/spawn-async": "^1.7.2", "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", "getenv": "^2.0.0", "glob": "^13.0.0", "hermes-parser": "^0.32.0", "jsc-safe-url": "^0.2.4", "lightningcss": "^1.30.1", "picomatch": "^4.0.3", "postcss": "~8.4.32", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" } }, "sha512-ZJFEfat/+dLUhFyFFWrzMjAqAwwUaJ3RD42QNqR7jh+RVYkAf6XYLynb5qrKJTHI1EcOx4KoO1717yXYYRFDBA=="],
272
-
273
- "@expo/metro-runtime": ["@expo/metro-runtime@55.0.6", "", { "dependencies": { "@expo/log-box": "55.0.7", "anser": "^1.4.9", "pretty-format": "^29.7.0", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-dom": "*", "react-native": "*" } }, "sha512-l8VvgKN9md+URjeQDB+DnHVmvpcWI6zFLH6yv7GTv4sfRDKyaZ5zDXYjTP1phYdgW6ea2NrRtCGNIxylWhsgtg=="],
274
-
275
- "@expo/osascript": ["@expo/osascript@2.4.2", "", { "dependencies": { "@expo/spawn-async": "^1.7.2" } }, "sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw=="],
276
-
277
- "@expo/package-manager": ["@expo/package-manager@1.10.3", "", { "dependencies": { "@expo/json-file": "^10.0.12", "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "resolve-workspace-root": "^2.0.0" } }, "sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A=="],
278
-
279
- "@expo/plist": ["@expo/plist@0.5.2", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g=="],
280
-
281
- "@expo/prebuild-config": ["@expo/prebuild-config@55.0.8", "", { "dependencies": { "@expo/config": "~55.0.8", "@expo/config-plugins": "~55.0.6", "@expo/config-types": "^55.0.5", "@expo/image-utils": "^0.8.12", "@expo/json-file": "^10.0.12", "@react-native/normalize-colors": "0.83.2", "debug": "^4.3.1", "resolve-from": "^5.0.0", "semver": "^7.6.0", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-VJNJiOmmZgyDnR7JMmc3B8Z0ZepZ17I8Wtw+wAH/2+UCUsFg588XU+bwgYcFGw+is28kwGjY46z43kfufpxOnA=="],
282
-
283
- "@expo/require-utils": ["@expo/require-utils@55.0.2", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8" }, "peerDependencies": { "typescript": "^5.0.0 || ^5.0.0-0" } }, "sha512-dV5oCShQ1umKBKagMMT4B/N+SREsQe3lU4Zgmko5AO0rxKV0tynZT6xXs+e2JxuqT4Rz997atg7pki0BnZb4uw=="],
284
-
285
- "@expo/router-server": ["@expo/router-server@55.0.9", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@expo/metro-runtime": "^55.0.6", "expo": "*", "expo-constants": "^55.0.7", "expo-font": "^55.0.4", "expo-router": "*", "expo-server": "^55.0.6", "react": "*", "react-dom": "*", "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1" }, "optionalPeers": ["@expo/metro-runtime", "react-server-dom-webpack"] }, "sha512-LcCFi+P1qfZOsw0DO4JwNKRxtWt4u2bjTYj0PUe4WVf9NVG/NfUetAXYRbBS6P+gupfM6SC+/bdzdqCWQh7j8g=="],
286
-
287
- "@expo/schema-utils": ["@expo/schema-utils@55.0.2", "", {}, "sha512-QZ5WKbJOWkCrMq0/kfhV9ry8te/OaS34YgLVpG8u9y2gix96TlpRTbxM/YATjNcUR2s4fiQmPCOxkGtog4i37g=="],
288
-
289
- "@expo/sdk-runtime-versions": ["@expo/sdk-runtime-versions@1.0.0", "", {}, "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ=="],
290
-
291
- "@expo/spawn-async": ["@expo/spawn-async@1.7.2", "", { "dependencies": { "cross-spawn": "^7.0.3" } }, "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew=="],
292
-
293
- "@expo/sudo-prompt": ["@expo/sudo-prompt@9.3.2", "", {}, "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw=="],
294
-
295
- "@expo/vector-icons": ["@expo/vector-icons@15.1.1", "", { "peerDependencies": { "expo-font": ">=14.0.4", "react": "*", "react-native": "*" } }, "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw=="],
296
-
297
- "@expo/ws-tunnel": ["@expo/ws-tunnel@1.0.6", "", {}, "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q=="],
298
-
299
- "@expo/xcpretty": ["@expo/xcpretty@4.4.1", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg=="],
300
-
301
- "@isaacs/ttlcache": ["@isaacs/ttlcache@1.4.1", "", {}, "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="],
302
-
303
- "@istanbuljs/load-nyc-config": ["@istanbuljs/load-nyc-config@1.1.0", "", { "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" } }, "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ=="],
304
-
305
- "@istanbuljs/schema": ["@istanbuljs/schema@0.1.3", "", {}, "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA=="],
306
-
307
- "@jest/create-cache-key-function": ["@jest/create-cache-key-function@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3" } }, "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA=="],
308
-
309
- "@jest/environment": ["@jest/environment@29.7.0", "", { "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0" } }, "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw=="],
310
-
311
- "@jest/fake-timers": ["@jest/fake-timers@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", "jest-message-util": "^29.7.0", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ=="],
312
-
313
- "@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
314
-
315
- "@jest/transform": ["@jest/transform@29.7.0", "", { "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", "jest-haste-map": "^29.7.0", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", "write-file-atomic": "^4.0.2" } }, "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw=="],
316
-
317
- "@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
318
-
319
- "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
320
-
321
- "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
322
-
323
- "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
324
-
325
- "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="],
326
-
327
- "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
328
-
329
- "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
330
-
331
- "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
332
-
333
- "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
334
-
335
- "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
336
-
337
- "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
338
-
339
- "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="],
340
-
341
- "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="],
342
-
343
- "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
344
-
345
- "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
346
-
347
- "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
348
-
349
- "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
350
-
351
- "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
352
-
353
- "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
354
-
355
- "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
356
-
357
- "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
358
-
359
- "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
360
-
361
- "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
362
-
363
- "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="],
364
-
365
- "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
366
-
367
- "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
368
-
369
- "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
370
-
371
- "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="],
372
-
373
- "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
374
-
375
- "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
376
-
377
- "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
378
-
379
- "@react-native/assets-registry": ["@react-native/assets-registry@0.83.2", "", {}, "sha512-9I5l3pGAKnlpQ15uVkeB9Mgjvt3cZEaEc8EDtdexvdtZvLSjtwBzgourrOW4yZUijbjJr8h3YO2Y0q+THwUHTA=="],
380
-
381
- "@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.83.2", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@react-native/codegen": "0.83.2" } }, "sha512-XbcN/BEa64pVlb0Hb/E/Ph2SepjVN/FcNKrJcQvtaKZA6mBSO8pW8Eircdlr61/KBH94LihHbQoQDzkQFpeaTg=="],
382
-
383
- "@react-native/babel-preset": ["@react-native/babel-preset@0.83.2", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-transform-arrow-functions": "^7.24.7", "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-computed-properties": "^7.24.7", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-for-of": "^7.24.7", "@babel/plugin-transform-function-name": "^7.25.1", "@babel/plugin-transform-literals": "^7.25.2", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", "@babel/plugin-transform-numeric-separator": "^7.24.7", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-react-display-name": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.25.2", "@babel/plugin-transform-react-jsx-self": "^7.24.7", "@babel/plugin-transform-react-jsx-source": "^7.24.7", "@babel/plugin-transform-regenerator": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-shorthand-properties": "^7.24.7", "@babel/plugin-transform-spread": "^7.24.7", "@babel/plugin-transform-sticky-regex": "^7.24.7", "@babel/plugin-transform-typescript": "^7.25.2", "@babel/plugin-transform-unicode-regex": "^7.24.7", "@babel/template": "^7.25.0", "@react-native/babel-plugin-codegen": "0.83.2", "babel-plugin-syntax-hermes-parser": "0.32.0", "babel-plugin-transform-flow-enums": "^0.0.2", "react-refresh": "^0.14.0" }, "peerDependencies": { "@babel/core": "*" } }, "sha512-X/RAXDfe6W+om/Fw1i6htTxQXFhBJ2jgNOWx3WpI3KbjeIWbq7ib6vrpTeIAW2NUMg+K3mML1NzgD4dpZeqdjA=="],
384
-
385
- "@react-native/codegen": ["@react-native/codegen@0.83.2", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.25.3", "glob": "^7.1.1", "hermes-parser": "0.32.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "yargs": "^17.6.2" }, "peerDependencies": { "@babel/core": "*" } }, "sha512-9uK6X1miCXqtL4c759l74N/XbQeneWeQVjoV7SD2CGJuW7ZefxaoYenwGPs7rMoCdtS6wuIyR3hXQ+uWEBGYXA=="],
386
-
387
- "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.83.2", "", { "dependencies": { "@react-native/dev-middleware": "0.83.2", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.83.3", "metro-config": "^0.83.3", "metro-core": "^0.83.3", "semver": "^7.1.3" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "*" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-sTEF0eiUKtmImEP07Qo5c3Khvm1LIVX1Qyb6zWUqPL6W3MqFiXutZvKBjqLz6p49Szx8cplQLoXfLHT0bcDXKg=="],
388
-
389
- "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.83.2", "", {}, "sha512-t4fYfa7xopbUF5S4+ihNEwgaq4wLZLKLY0Ms8z72lkMteVd3bOX2Foxa8E2wTfRvdhPOkSpOsTeNDmD8ON4DoQ=="],
390
-
391
- "@react-native/debugger-shell": ["@react-native/debugger-shell@0.83.2", "", { "dependencies": { "cross-spawn": "^7.0.6", "fb-dotslash": "0.5.8" } }, "sha512-z9go6NJMsLSDJT5MW6VGugRsZHjYvUTwxtsVc3uLt4U9W6T3J6FWI2wHpXIzd2dUkXRfAiRQ3Zi8ZQQ8fRFg9A=="],
392
-
393
- "@react-native/dev-middleware": ["@react-native/dev-middleware@0.83.2", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.83.2", "@react-native/debugger-shell": "0.83.2", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.2.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^7.5.10" } }, "sha512-Zi4EVaAm28+icD19NN07Gh8Pqg/84QQu+jn4patfWKNkcToRFP5vPEbbp0eLOGWS+BVB1d1Fn5lvMrJsBbFcOg=="],
394
-
395
- "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.83.2", "", {}, "sha512-PqN11fXRAU+uJ0inZY1HWYlwJOXHOhF4SPyeHBBxjajKpm2PGunmvFWwkmBjmmUkP/CNO0ezTUudV0oj+2wiHQ=="],
396
-
397
- "@react-native/js-polyfills": ["@react-native/js-polyfills@0.83.2", "", {}, "sha512-dk6fIY2OrKW/2Nk2HydfYNrQau8g6LOtd7NVBrgaqa+lvuRyIML5iimShP5qPqQnx2ofHuzjFw+Ya0b5Q7nDbA=="],
398
-
399
- "@react-native/normalize-colors": ["@react-native/normalize-colors@0.83.2", "", {}, "sha512-gkZAb9LoVVzNuYzzOviH7DiPTXQoZPHuiTH2+O2+VWNtOkiznjgvqpwYAhg58a5zfRq5GXlbBdf5mzRj5+3Y5Q=="],
400
-
401
- "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.83.2", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "*" } }, "sha512-N7mRjHLW/+KWxMp9IHRWyE3VIkeG1m3PnZJAGEFLCN8VFb7e4VfI567o7tE/HYcdcXCylw+Eqhlciz8gDeQ71g=="],
402
-
403
- "@react-navigation/bottom-tabs": ["@react-navigation/bottom-tabs@7.15.3", "", { "dependencies": { "@react-navigation/elements": "^2.9.8", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { "@react-navigation/native": "^7.1.31", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-CIaHk5TuLeYlDgR1eij38kEbrQU5dAQxQZCC4Xv1wFZ/RRxppBopRMLzv2Il529a7mic6xG33OHcr9aEdOzq+A=="],
404
-
405
- "@react-navigation/core": ["@react-navigation/core@7.15.1", "", { "dependencies": { "@react-navigation/routers": "^7.5.3", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-Fqr6qxfZJIC4ewho7LtTa9zz6hcOzohX7D1lcDfrkGaYkS5xBwEZViGNxCJK/czUc74ua8NThyrObQFjB6Q/RQ=="],
406
-
407
- "@react-navigation/elements": ["@react-navigation/elements@2.9.8", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.31", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-3gpwUmVnDJYvK9nFmAA/YXw0hmT/C/lZx8RkRMK+ux9l1T+32EWnQFnn34Wa1BMDX8HN2r64yrlW93DIzKI7Uw=="],
408
-
409
- "@react-navigation/native": ["@react-navigation/native@7.1.31", "", { "dependencies": { "@react-navigation/core": "^7.15.1", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-+YCUwtfDgsux59Q0LDHc3Zid9ih93ecUCFWZOH6/+eNoUGnWx77wjS6ZfvBO/7E+EiIup11IVShDzCHR4of8hw=="],
410
-
411
- "@react-navigation/native-stack": ["@react-navigation/native-stack@7.14.2", "", { "dependencies": { "@react-navigation/elements": "^2.9.8", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0", "warn-once": "^0.1.1" }, "peerDependencies": { "@react-navigation/native": "^7.1.31", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-/nKxFAFSUSGV+NSXrXXcWEcGAHdyp8RyWjoGMDzVPdBhjCLblVSgHWx5y4mm+k0de9V1pkjsftUaroP7rQckzw=="],
412
-
413
- "@react-navigation/routers": ["@react-navigation/routers@7.5.3", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg=="],
414
-
415
- "@sinclair/typebox": ["@sinclair/typebox@0.27.10", "", {}, "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA=="],
416
-
417
- "@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="],
418
-
419
- "@sinonjs/fake-timers": ["@sinonjs/fake-timers@10.3.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA=="],
420
-
421
- "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
422
-
423
- "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
424
-
425
- "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="],
426
-
427
- "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
428
-
429
- "@types/graceful-fs": ["@types/graceful-fs@4.1.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ=="],
430
-
431
- "@types/hammerjs": ["@types/hammerjs@2.0.46", "", {}, "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="],
432
-
433
- "@types/istanbul-lib-coverage": ["@types/istanbul-lib-coverage@2.0.6", "", {}, "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w=="],
434
-
435
- "@types/istanbul-lib-report": ["@types/istanbul-lib-report@3.0.3", "", { "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA=="],
436
-
437
- "@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "*" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="],
438
-
439
- "@types/node": ["@types/node@25.3.3", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ=="],
440
-
441
- "@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
442
-
443
- "@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="],
444
-
445
- "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="],
446
-
447
- "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
448
-
449
- "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
450
-
451
- "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="],
452
-
453
- "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
454
-
455
- "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
456
-
457
- "acorn": ["acorn@8.16.0", "", { "bin": "bin/acorn" }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
458
-
459
- "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
460
-
461
- "anser": ["anser@1.4.10", "", {}, "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww=="],
462
-
463
- "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="],
464
-
465
- "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
466
-
467
- "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
468
-
469
- "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
470
-
471
- "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
472
-
473
- "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
474
-
475
- "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
476
-
477
- "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
478
-
479
- "array-timsort": ["array-timsort@1.0.3", "", {}, "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ=="],
480
-
481
- "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="],
482
-
483
- "babel-jest": ["babel-jest@29.7.0", "", { "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" } }, "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg=="],
484
-
485
- "babel-plugin-istanbul": ["babel-plugin-istanbul@6.1.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" } }, "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA=="],
486
-
487
- "babel-plugin-jest-hoist": ["babel-plugin-jest-hoist@29.6.3", "", { "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" } }, "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg=="],
488
-
489
- "babel-plugin-module-resolver": ["babel-plugin-module-resolver@5.0.2", "", { "dependencies": { "find-babel-config": "^2.1.1", "glob": "^9.3.3", "pkg-up": "^3.1.0", "reselect": "^4.1.7", "resolve": "^1.22.8" } }, "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg=="],
490
-
491
- "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.15", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-define-polyfill-provider": "^0.6.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw=="],
492
-
493
- "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
494
-
495
- "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.6", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.6" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A=="],
496
-
497
- "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="],
498
-
499
- "babel-plugin-react-native-web": ["babel-plugin-react-native-web@0.21.2", "", {}, "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA=="],
500
-
501
- "babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.32.0", "", { "dependencies": { "hermes-parser": "0.32.0" } }, "sha512-m5HthL++AbyeEA2FcdwOLfVFvWYECOBObLHNqdR8ceY4TsEdn4LdX2oTvbB2QJSSElE2AWA/b2MXZ/PF/CqLZg=="],
502
-
503
- "babel-plugin-transform-flow-enums": ["babel-plugin-transform-flow-enums@0.0.2", "", { "dependencies": { "@babel/plugin-syntax-flow": "^7.12.1" } }, "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ=="],
504
-
505
- "babel-preset-current-node-syntax": ["babel-preset-current-node-syntax@1.2.0", "", { "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-import-attributes": "^7.24.7", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg=="],
506
-
507
- "babel-preset-expo": ["babel-preset-expo@55.0.10", "", { "dependencies": { "@babel/generator": "^7.20.5", "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-react": "^7.22.15", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-preset": "0.83.2", "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.32.0", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4", "resolve-from": "^5.0.0" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "expo-widgets": "^55.0.2", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["expo-widgets"] }, "sha512-aRtW7qJKohGU2V0LUJ6IeP7py3+kVUo9zcc8+v1Kix8jGGuIvqvpo9S6W1Fmn9VFP2DBwkFDLiyzkCZS85urVA=="],
508
-
509
- "babel-preset-jest": ["babel-preset-jest@29.6.3", "", { "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA=="],
510
-
511
- "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
512
-
513
- "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
514
-
515
- "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": "dist/cli.cjs" }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
516
-
517
- "better-opn": ["better-opn@3.0.2", "", { "dependencies": { "open": "^8.0.4" } }, "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ=="],
518
-
519
- "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="],
520
-
521
- "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
522
-
523
- "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
524
-
525
- "bplist-creator": ["bplist-creator@0.1.0", "", { "dependencies": { "stream-buffers": "2.2.x" } }, "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg=="],
526
-
527
- "bplist-parser": ["bplist-parser@0.3.1", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA=="],
528
-
529
- "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
530
-
531
- "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
532
-
533
- "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": "cli.js" }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
534
-
535
- "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="],
536
-
537
- "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
538
-
539
- "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
540
-
541
- "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
542
-
543
- "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
544
-
545
- "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
546
-
547
- "caniuse-lite": ["caniuse-lite@1.0.30001775", "", {}, "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A=="],
548
-
549
- "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
550
-
551
- "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
552
-
553
- "chrome-launcher": ["chrome-launcher@0.15.2", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ=="],
554
-
555
- "chromium-edge-launcher": ["chromium-edge-launcher@0.2.0", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0", "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg=="],
556
-
557
- "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
558
-
559
- "cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "^2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="],
560
-
561
- "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
562
-
563
- "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
564
-
565
- "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
566
-
567
- "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
568
-
569
- "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
570
-
571
- "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
572
-
573
- "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
574
-
575
- "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
576
-
577
- "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
578
-
579
- "comment-json": ["comment-json@4.6.1", "", { "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", "esprima": "^4.0.1" } }, "sha512-kdBIsBGqD/sAeqvzeOhBvO/bhtpbfbIU/2lw7bp182FV1cVlY7gr1Jf3Q1I+NOsCk8e4gF5Sl9iYH5cNvVmx5w=="],
580
-
581
- "compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="],
582
-
583
- "compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="],
584
-
585
- "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
586
-
587
- "connect": ["connect@3.7.0", "", { "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", "parseurl": "~1.3.3", "utils-merge": "1.0.1" } }, "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ=="],
588
-
589
- "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
590
-
591
- "core-js-compat": ["core-js-compat@3.48.0", "", { "dependencies": { "browserslist": "^4.28.1" } }, "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q=="],
592
-
593
- "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
594
-
595
- "cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="],
596
-
597
- "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
598
-
599
- "css-in-js-utils": ["css-in-js-utils@3.1.0", "", { "dependencies": { "hyphenate-style-name": "^1.0.3" } }, "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A=="],
600
-
601
- "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
602
-
603
- "css-tree": ["css-tree@1.1.3", "", { "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q=="],
604
-
605
- "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
606
-
607
- "cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
608
-
609
- "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
610
-
611
- "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
612
-
613
- "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="],
614
-
615
- "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
616
-
617
- "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="],
618
-
619
- "define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="],
620
-
621
- "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
622
-
623
- "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
624
-
625
- "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
626
-
627
- "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
628
-
629
- "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
630
-
631
- "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
632
-
633
- "dnssd-advertise": ["dnssd-advertise@1.1.3", "", {}, "sha512-XENsHi3MBzWOCAXif3yZvU1Ah0l+nhJj1sjWL6TnOAYKvGiFhbTx32xHN7+wLMLUOCj7Nr0evADWG4R8JtqCDA=="],
634
-
635
- "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
636
-
637
- "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
638
-
639
- "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
640
-
641
- "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
642
-
643
- "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
644
-
645
- "electron-to-chromium": ["electron-to-chromium@1.5.302", "", {}, "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg=="],
646
-
647
- "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
648
-
649
- "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
650
-
651
- "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
652
-
653
- "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="],
654
-
655
- "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
656
-
657
- "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
658
-
659
- "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
660
-
661
- "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
662
-
663
- "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
664
-
665
- "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
666
-
667
- "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
668
-
669
- "expo": ["expo@55.0.4", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "55.0.14", "@expo/config": "~55.0.8", "@expo/config-plugins": "~55.0.6", "@expo/devtools": "55.0.2", "@expo/fingerprint": "0.16.5", "@expo/local-build-cache-provider": "55.0.6", "@expo/log-box": "55.0.7", "@expo/metro": "~54.2.0", "@expo/metro-config": "55.0.9", "@expo/vector-icons": "^15.0.2", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~55.0.10", "expo-asset": "~55.0.8", "expo-constants": "~55.0.7", "expo-file-system": "~55.0.10", "expo-font": "~55.0.4", "expo-keep-awake": "~55.0.4", "expo-modules-autolinking": "55.0.8", "expo-modules-core": "55.0.13", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-minimum": "^0.1.1" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "expo-modules-autolinking": "bin/autolinking", "fingerprint": "bin/fingerprint" } }, "sha512-cbQBPYwmH6FRvh942KR8mSdEcrVdsIMkjdHthtf59zlpzgrk28FabhOdL/Pc9WuS+CsIP3EIQbZqmLkTjv6qPg=="],
670
-
671
- "expo-asset": ["expo-asset@55.0.8", "", { "dependencies": { "@expo/image-utils": "^0.8.12", "expo-constants": "~55.0.7" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-yEz2svDX67R0yiW2skx6dJmcE0q7sj9ECpGMcxBExMCbctc+nMoZCnjUuhzPl5vhClUsO5HFFXS5vIGmf1bgHQ=="],
672
-
673
- "expo-audio": ["expo-audio@55.0.8", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-X61pQSikE2rsP2ZTMFUMThOmgGyYEHcmZpGVMrKJgcYtRCFKuctB/z69dFQPoumL+zTz8qlBoGohjkHVvA9P8A=="],
674
-
675
- "expo-clipboard": ["expo-clipboard@55.0.8", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-s0Hkop+dc6m09LwzUAWweNI0gzLAaX5CgEGR8TMdOdSPKTPc2rCl8h8Ji/cUNM1wYoJQ4Wysa15E8If/Vlu7WA=="],
676
-
677
- "expo-constants": ["expo-constants@55.0.7", "", { "dependencies": { "@expo/config": "~55.0.8", "@expo/env": "~2.1.1" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-kdcO4TsQRRqt0USvjaY5vgQMO9H52K3kBZ/ejC7F6rz70mv08GoowrZ1CYOr5O4JpPDRlIpQfZJUucaS/c+KWQ=="],
678
-
679
- "expo-file-system": ["expo-file-system@55.0.10", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-ysFdVdUgtfj2ApY0Cn+pBg+yK4xp+SNwcaH8j2B91JJQ4OXJmnyCSmrNZYz7J4mdYVuv2GzxIP+N/IGlHQG3Yw=="],
680
-
681
- "expo-font": ["expo-font@55.0.4", "", { "dependencies": { "fontfaceobserver": "^2.1.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-ZKeGTFffPygvY5dM/9ATM2p7QDkhsaHopH7wFAWgP2lKzqUMS9B/RxCvw5CaObr9Ro7x9YptyeRKX2HmgmMfrg=="],
682
-
683
- "expo-glass-effect": ["expo-glass-effect@55.0.7", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-G7Q9rUaEY0YC36fGE6irDljfsfvzz/y49zagARAKvSJSyQMUSrhR25WOr5LK5Cw7gQNNBEy9U1ctlr7yCay/fQ=="],
684
-
685
- "expo-haptics": ["expo-haptics@55.0.8", "", { "peerDependencies": { "expo": "*" } }, "sha512-yVR6EsQwl1WuhFITc0PpfI/7dsBdjK/F2YA8xB80UUW9iTa+Tqz21FpH4n/vtbargpzFxkhl5WNYMa419+QWFQ=="],
686
-
687
- "expo-image": ["expo-image@55.0.5", "", { "dependencies": { "sf-symbols-typescript": "^2.2.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" } }, "sha512-oejmMwy5O9EtC8po9NxkcurWHqND6p8xuJaj9FGNo8NXLt9e+w3cKWx7HuPzkH5y3qFXQ9Od+z+I/wxEci36fw=="],
688
-
689
- "expo-image-loader": ["expo-image-loader@55.0.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-NOjp56wDrfuA5aiNAybBIjqIn1IxKeGJ8CECWZncQ/GzjZfyTYAHTCyeApYkdKkMBLHINzI4BbTGSlbCa0fXXQ=="],
690
-
691
- "expo-image-picker": ["expo-image-picker@55.0.11", "", { "dependencies": { "expo-image-loader": "~55.0.0" }, "peerDependencies": { "expo": "*" } }, "sha512-geJklIGdAR2N16iSk86oyJe7QgX5RpqDX1FjKpxO53fF4D0eBmg5Irm6gRwT0b+DHP1kJevZgzzbVJsRAV362g=="],
692
-
693
- "expo-keep-awake": ["expo-keep-awake@55.0.4", "", { "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-vwfdMtMS5Fxaon8gC0AiE70SpxTsHJ+rjeoVJl8kdfdbxczF7OIaVmfjFJ5Gfigd/WZiLqxhfZk34VAkXF4PNg=="],
694
-
695
- "expo-linking": ["expo-linking@55.0.7", "", { "dependencies": { "expo-constants": "~55.0.7", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-MiGCedere1vzQTEi2aGrkzd7eh/rPSz4w6F3GMBuAJzYl+/0VhIuyhozpEGrueyDIXWfzaUVOcn3SfxVi+kwQQ=="],
696
-
697
- "expo-modules-autolinking": ["expo-modules-autolinking@55.0.8", "", { "dependencies": { "@expo/require-utils": "^55.0.2", "@expo/spawn-async": "^1.7.2", "chalk": "^4.1.0", "commander": "^7.2.0" }, "bin": "bin/expo-modules-autolinking.js" }, "sha512-nrWB1pkNp7bR8ECUTgYUiJ2Pyh6AvxCBXZ+lyPlfl1TzEIGhwU1Yqr+d78eJDueXaW+9zKeE0HqrTZoLS3ve4A=="],
698
-
699
- "expo-modules-core": ["expo-modules-core@55.0.13", "", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-DYLQTOJAR7jD3M9S0sH9myZaPEtShdicHrPiWcupIXMeMkQxFzErx+adUI8gZPy4AU45BgeGgtaogRfT25iLfw=="],
700
-
701
- "expo-router": ["expo-router@55.0.3", "", { "dependencies": { "@expo/metro-runtime": "^55.0.6", "@expo/schema-utils": "^55.0.2", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-navigation/bottom-tabs": "^7.10.1", "@react-navigation/native": "^7.1.28", "@react-navigation/native-stack": "^7.10.1", "client-only": "^0.0.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-glass-effect": "^55.0.7", "expo-image": "^55.0.5", "expo-server": "^55.0.6", "expo-symbols": "^55.0.4", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.2.1", "semver": "~7.6.3", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "use-latest-callback": "^0.2.1", "vaul": "^1.1.2" }, "peerDependencies": { "@expo/log-box": "55.0.7", "@expo/metro-runtime": "^55.0.6", "@react-navigation/drawer": "^7.7.2", "@testing-library/react-native": ">= 13.2.0", "expo": "*", "expo-constants": "^55.0.7", "expo-linking": "^55.0.7", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-screens": "*", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, "optionalPeers": ["@react-navigation/drawer", "@testing-library/react-native", "react-server-dom-webpack"] }, "sha512-B3MQAeZq9B2SS5kgEybGqXYR0AY7QYM7fQ5E4bJwtvZLJjWPmWhDALhBpD26ovK/i1k0fi9VgW47FKJODxM5Jg=="],
702
-
703
- "expo-secure-store": ["expo-secure-store@55.0.8", "", { "peerDependencies": { "expo": "*" } }, "sha512-8w9tQe8U6oRo5YIzqCqVhRrOnfoODNDoitBtLXEx+zS6WLUnkRq5kH7ViJuOgiM7PzLr9pvAliRiDOKyvFbTuQ=="],
704
-
705
- "expo-server": ["expo-server@55.0.6", "", {}, "sha512-xI72FTm469FfuuBL2R5aNtthgH+GR7ygOpsx/KcPS0K8AZaZd7VjtEExbzn9/qyyYkWW3T+3dAmCDKOMX8gdmQ=="],
706
-
707
- "expo-sharing": ["expo-sharing@55.0.11", "", { "dependencies": { "@expo/config-plugins": "^55.0.6", "@expo/config-types": "^55.0.5", "@expo/plist": "^0.5.2" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-YlVez832W0sYR2KJY4Dr8ON9aC+Wp8a/r40eQyhoHT9Tetkr2KBM7tWLT0CGKRuTTnrqJL1C51UacLkHJ9zmNA=="],
708
-
709
- "expo-splash-screen": ["expo-splash-screen@55.0.10", "", { "dependencies": { "@expo/prebuild-config": "^55.0.8" }, "peerDependencies": { "expo": "*" } }, "sha512-RN5qqrxudxFlRIjLFr/Ifmt+mUCLRc0gs66PekP6flzNS/JYEuoCbwJ+NmUwwJtPA+vyy60DYiky0QmS98ydmQ=="],
710
-
711
- "expo-status-bar": ["expo-status-bar@55.0.4", "", { "dependencies": { "react-native-is-edge-to-edge": "^1.2.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-BPDjUXKqv1F9j2YNGLRZfkBEZXIEEpqj+t81y4c+4fdSN3Pos7goIHXgcl2ozbKQLgKRZQyNZQtbUgh5UjHYUQ=="],
712
-
713
- "expo-symbols": ["expo-symbols@55.0.4", "", { "dependencies": { "@expo-google-fonts/material-symbols": "^0.4.1", "sf-symbols-typescript": "^2.0.0" }, "peerDependencies": { "expo": "*", "expo-font": "*", "react": "*", "react-native": "*" } }, "sha512-w9rxPlpta3gks0G4Tvpq/qQdiMp4R/XOeOzyjSruYUQakmsWbQBKA+Sd/fCVXs7qFJSvVTOGXiOhZm+YJRYZVg=="],
714
-
715
- "expo-system-ui": ["expo-system-ui@55.0.9", "", { "dependencies": { "@react-native/normalize-colors": "0.83.2", "debug": "^4.3.2" }, "peerDependencies": { "expo": "*", "react-native": "*", "react-native-web": "*" } }, "sha512-8ygP1B0uFAFI8s7eHY2IcGnE83GhFeZYwHBr/fQ4dSXnc7iVT9zp2PvyTyiDiibQ69dBG+fauMQ4KlPcOO51kQ=="],
716
-
717
- "expo-web-browser": ["expo-web-browser@55.0.9", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-PvAVsG401QmZabtTsYh1cYcpPiqvBPs8oiOkSrp0jIXnneiM466HxmeNtvo+fNxqJ2nwOBz9qLPiWRO91VBfsQ=="],
718
-
719
- "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="],
720
-
721
- "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
722
-
723
- "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
724
-
725
- "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
726
-
727
- "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
728
-
729
- "fb-dotslash": ["fb-dotslash@0.5.8", "", { "bin": { "dotslash": "bin/dotslash" } }, "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA=="],
730
-
731
- "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="],
732
-
733
- "fbjs": ["fbjs@3.0.5", "", { "dependencies": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", "loose-envify": "^1.0.0", "object-assign": "^4.1.0", "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^1.0.35" } }, "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg=="],
734
-
735
- "fbjs-css-vars": ["fbjs-css-vars@1.0.2", "", {}, "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="],
736
-
737
- "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
738
-
739
- "fetch-nodeshim": ["fetch-nodeshim@0.4.8", "", {}, "sha512-YW5vG33rabBq6JpYosLNoXoaMN69/WH26MeeX2hkDVjN6UlvRGq3Wkazl9H0kisH95aMu/HtHL64JUvv/+Nv/g=="],
740
-
741
- "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
742
-
743
- "filter-obj": ["filter-obj@1.1.0", "", {}, "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="],
744
-
745
- "finalhandler": ["finalhandler@1.1.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" } }, "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="],
746
-
747
- "find-babel-config": ["find-babel-config@2.1.2", "", { "dependencies": { "json5": "^2.2.3" } }, "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg=="],
748
-
749
- "find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "^3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="],
750
-
751
- "flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="],
752
-
753
- "fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="],
754
-
755
- "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
756
-
757
- "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
758
-
759
- "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
760
-
761
- "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
762
-
763
- "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
764
-
765
- "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
766
-
767
- "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
768
-
769
- "get-package-type": ["get-package-type@0.1.0", "", {}, "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="],
770
-
771
- "getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="],
772
-
773
- "glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="],
774
-
775
- "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
776
-
777
- "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
778
-
779
- "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
780
-
781
- "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
782
-
783
- "hermes-compiler": ["hermes-compiler@0.14.1", "", {}, "sha512-+RPPQlayoZ9n6/KXKt5SFILWXCGJ/LV5d24L5smXrvTDrPS4L6dSctPczXauuvzFP3QEJbD1YO7Z3Ra4a+4IhA=="],
784
-
785
- "hermes-estree": ["hermes-estree@0.32.0", "", {}, "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ=="],
786
-
787
- "hermes-parser": ["hermes-parser@0.32.0", "", { "dependencies": { "hermes-estree": "0.32.0" } }, "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw=="],
788
-
789
- "hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
790
-
791
- "hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="],
792
-
793
- "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
794
-
795
- "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
796
-
797
- "hyphenate-style-name": ["hyphenate-style-name@1.1.0", "", {}, "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="],
798
-
799
- "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
800
-
801
- "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
802
-
803
- "image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": "bin/image-size.js" }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="],
804
-
805
- "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
806
-
807
- "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
808
-
809
- "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
810
-
811
- "inline-style-prefixer": ["inline-style-prefixer@7.0.1", "", { "dependencies": { "css-in-js-utils": "^3.1.0" } }, "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw=="],
812
-
813
- "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="],
814
-
815
- "is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="],
816
-
817
- "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
818
-
819
- "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
820
-
821
- "is-docker": ["is-docker@2.2.1", "", { "bin": "cli.js" }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="],
822
-
823
- "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
824
-
825
- "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
826
-
827
- "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
828
-
829
- "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
830
-
831
- "is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
832
-
833
- "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
834
-
835
- "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="],
836
-
837
- "istanbul-lib-instrument": ["istanbul-lib-instrument@5.2.1", "", { "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg=="],
838
-
839
- "jest-environment-node": ["jest-environment-node@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw=="],
840
-
841
- "jest-get-type": ["jest-get-type@29.6.3", "", {}, "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw=="],
842
-
843
- "jest-haste-map": ["jest-haste-map@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA=="],
844
-
845
- "jest-message-util": ["jest-message-util@29.7.0", "", { "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w=="],
846
-
847
- "jest-mock": ["jest-mock@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "jest-util": "^29.7.0" } }, "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw=="],
848
-
849
- "jest-regex-util": ["jest-regex-util@29.6.3", "", {}, "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg=="],
850
-
851
- "jest-util": ["jest-util@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="],
852
-
853
- "jest-validate": ["jest-validate@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.6.3", "leven": "^3.1.0", "pretty-format": "^29.7.0" } }, "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw=="],
854
-
855
- "jest-worker": ["jest-worker@29.7.0", "", { "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw=="],
856
-
857
- "jimp-compact": ["jimp-compact@0.16.1", "", {}, "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww=="],
858
-
859
- "jiti": ["jiti@1.21.7", "", { "bin": "bin/jiti.js" }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
860
-
861
- "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
862
-
863
- "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
864
-
865
- "jsc-safe-url": ["jsc-safe-url@0.2.4", "", {}, "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q=="],
866
-
867
- "jsesc": ["jsesc@3.1.0", "", { "bin": "bin/jsesc" }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
868
-
869
- "json5": ["json5@2.2.3", "", { "bin": "lib/cli.js" }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
870
-
871
- "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
872
-
873
- "lan-network": ["lan-network@0.2.0", "", { "bin": "dist/lan-network-cli.js" }, "sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw=="],
874
-
875
- "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
876
-
877
- "lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="],
878
-
879
- "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
880
-
881
- "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
882
-
883
- "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
884
-
885
- "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
886
-
887
- "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
888
-
889
- "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
890
-
891
- "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
892
-
893
- "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
894
-
895
- "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
896
-
897
- "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
898
-
899
- "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
900
-
901
- "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
902
-
903
- "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
904
-
905
- "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
906
-
907
- "locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="],
908
-
909
- "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
910
-
911
- "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
912
-
913
- "log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="],
914
-
915
- "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
916
-
917
- "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
918
-
919
- "makeerror": ["makeerror@1.0.12", "", { "dependencies": { "tmpl": "1.0.5" } }, "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg=="],
920
-
921
- "marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="],
922
-
923
- "mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="],
924
-
925
- "memoize-one": ["memoize-one@5.2.1", "", {}, "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="],
926
-
927
- "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
928
-
929
- "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
930
-
931
- "metro": ["metro@0.83.3", "", { "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/core": "^7.25.2", "@babel/generator": "^7.25.0", "@babel/parser": "^7.25.3", "@babel/template": "^7.25.0", "@babel/traverse": "^7.25.3", "@babel/types": "^7.25.2", "accepts": "^1.3.7", "chalk": "^4.0.0", "ci-info": "^2.0.0", "connect": "^3.6.5", "debug": "^4.4.0", "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "hermes-parser": "0.32.0", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", "metro-babel-transformer": "0.83.3", "metro-cache": "0.83.3", "metro-cache-key": "0.83.3", "metro-config": "0.83.3", "metro-core": "0.83.3", "metro-file-map": "0.83.3", "metro-resolver": "0.83.3", "metro-runtime": "0.83.3", "metro-source-map": "0.83.3", "metro-symbolicate": "0.83.3", "metro-transform-plugins": "0.83.3", "metro-transform-worker": "0.83.3", "mime-types": "^2.1.27", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", "source-map": "^0.5.6", "throat": "^5.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "bin": "src/cli.js" }, "sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q=="],
932
-
933
- "metro-babel-transformer": ["metro-babel-transformer@0.83.3", "", { "dependencies": { "@babel/core": "^7.25.2", "flow-enums-runtime": "^0.0.6", "hermes-parser": "0.32.0", "nullthrows": "^1.1.1" } }, "sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g=="],
934
-
935
- "metro-cache": ["metro-cache@0.83.3", "", { "dependencies": { "exponential-backoff": "^3.1.1", "flow-enums-runtime": "^0.0.6", "https-proxy-agent": "^7.0.5", "metro-core": "0.83.3" } }, "sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q=="],
936
-
937
- "metro-cache-key": ["metro-cache-key@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw=="],
938
-
939
- "metro-config": ["metro-config@0.83.3", "", { "dependencies": { "connect": "^3.6.5", "flow-enums-runtime": "^0.0.6", "jest-validate": "^29.7.0", "metro": "0.83.3", "metro-cache": "0.83.3", "metro-core": "0.83.3", "metro-runtime": "0.83.3", "yaml": "^2.6.1" } }, "sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA=="],
940
-
941
- "metro-core": ["metro-core@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "lodash.throttle": "^4.1.1", "metro-resolver": "0.83.3" } }, "sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw=="],
942
-
943
- "metro-file-map": ["metro-file-map@0.83.3", "", { "dependencies": { "debug": "^4.4.0", "fb-watchman": "^2.0.0", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "nullthrows": "^1.1.1", "walker": "^1.0.7" } }, "sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA=="],
944
-
945
- "metro-minify-terser": ["metro-minify-terser@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "terser": "^5.15.0" } }, "sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ=="],
946
-
947
- "metro-resolver": ["metro-resolver@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ=="],
948
-
949
- "metro-runtime": ["metro-runtime@0.83.3", "", { "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" } }, "sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw=="],
950
-
951
- "metro-source-map": ["metro-source-map@0.83.3", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-symbolicate": "0.83.3", "nullthrows": "^1.1.1", "ob1": "0.83.3", "source-map": "^0.5.6", "vlq": "^1.0.0" } }, "sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg=="],
952
-
953
- "metro-symbolicate": ["metro-symbolicate@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.83.3", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": "src/index.js" }, "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw=="],
954
-
955
- "metro-transform-plugins": ["metro-transform-plugins@0.83.3", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.25.0", "@babel/template": "^7.25.0", "@babel/traverse": "^7.25.3", "flow-enums-runtime": "^0.0.6", "nullthrows": "^1.1.1" } }, "sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A=="],
956
-
957
- "metro-transform-worker": ["metro-transform-worker@0.83.3", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.25.0", "@babel/parser": "^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", "metro": "0.83.3", "metro-babel-transformer": "0.83.3", "metro-cache": "0.83.3", "metro-cache-key": "0.83.3", "metro-minify-terser": "0.83.3", "metro-source-map": "0.83.3", "metro-transform-plugins": "0.83.3", "nullthrows": "^1.1.1" } }, "sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA=="],
958
-
959
- "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
960
-
961
- "mime": ["mime@1.6.0", "", { "bin": "cli.js" }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
962
-
963
- "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
964
-
965
- "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
966
-
967
- "mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="],
968
-
969
- "minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="],
970
-
971
- "minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="],
972
-
973
- "mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
974
-
975
- "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
976
-
977
- "multitars": ["multitars@0.2.4", "", {}, "sha512-XgLbg1HHchFauMCQPRwMj6MSyDd5koPlTA1hM3rUFkeXzGpjU/I9fP3to7yrObE9jcN8ChIOQGrM0tV0kUZaKg=="],
978
-
979
- "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
980
-
981
- "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
982
-
983
- "nativewind": ["nativewind@4.2.2", "", { "dependencies": { "comment-json": "^4.2.5", "debug": "^4.3.7", "react-native-css-interop": "0.2.2" }, "peerDependencies": { "tailwindcss": ">3.3.0" } }, "sha512-kUGbUamKUWdnAIjfBuhIrtDHFtMyL1pEE3AEbCuKeg656pHuB0KtJRk6Lrie/+8haj8hCSlwOleQFJLrE1sZgA=="],
984
-
985
- "negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
986
-
987
- "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
988
-
989
- "node-forge": ["node-forge@1.3.3", "", {}, "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg=="],
990
-
991
- "node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="],
992
-
993
- "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
994
-
995
- "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
996
-
997
- "npm-package-arg": ["npm-package-arg@11.0.3", "", { "dependencies": { "hosted-git-info": "^7.0.0", "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" } }, "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw=="],
998
-
999
- "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
1000
-
1001
- "nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="],
1002
-
1003
- "ob1": ["ob1@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA=="],
1004
-
1005
- "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
1006
-
1007
- "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
1008
-
1009
- "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
1010
-
1011
- "on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="],
1012
-
1013
- "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
1014
-
1015
- "onetime": ["onetime@2.0.1", "", { "dependencies": { "mimic-fn": "^1.0.0" } }, "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ=="],
1016
-
1017
- "open": ["open@7.4.2", "", { "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="],
1018
-
1019
- "ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="],
1020
-
1021
- "p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
1022
-
1023
- "p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="],
1024
-
1025
- "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="],
1026
-
1027
- "parse-png": ["parse-png@2.1.0", "", { "dependencies": { "pngjs": "^3.3.0" } }, "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ=="],
1028
-
1029
- "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
1030
-
1031
- "path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="],
1032
-
1033
- "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
1034
-
1035
- "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
1036
-
1037
- "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
1038
-
1039
- "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
1040
-
1041
- "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
1042
-
1043
- "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1044
-
1045
- "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
1046
-
1047
- "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="],
1048
-
1049
- "pkg-up": ["pkg-up@3.1.0", "", { "dependencies": { "find-up": "^3.0.0" } }, "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA=="],
1050
-
1051
- "plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="],
1052
-
1053
- "pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="],
1054
-
1055
- "postcss": ["postcss@8.4.49", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA=="],
1056
-
1057
- "postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
1058
-
1059
- "postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="],
1060
-
1061
- "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["tsx"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="],
1062
-
1063
- "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="],
1064
-
1065
- "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
1066
-
1067
- "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
1068
-
1069
- "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="],
1070
-
1071
- "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="],
1072
-
1073
- "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
1074
-
1075
- "promise": ["promise@8.3.0", "", { "dependencies": { "asap": "~2.0.6" } }, "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg=="],
1076
-
1077
- "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
1078
-
1079
- "query-string": ["query-string@7.1.3", "", { "dependencies": { "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" } }, "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg=="],
1080
-
1081
- "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="],
1082
-
1083
- "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
1084
-
1085
- "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
1086
-
1087
- "react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
1088
-
1089
- "react-devtools-core": ["react-devtools-core@6.1.5", "", { "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA=="],
1090
-
1091
- "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
1092
-
1093
- "react-fast-compare": ["react-fast-compare@3.2.2", "", {}, "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="],
1094
-
1095
- "react-freeze": ["react-freeze@1.0.4", "", { "peerDependencies": { "react": ">=17.0.0" } }, "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA=="],
1096
-
1097
- "react-is": ["react-is@19.2.4", "", {}, "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA=="],
1098
-
1099
- "react-native": ["react-native@0.83.2", "", { "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.83.2", "@react-native/codegen": "0.83.2", "@react-native/community-cli-plugin": "0.83.2", "@react-native/gradle-plugin": "0.83.2", "@react-native/js-polyfills": "0.83.2", "@react-native/normalize-colors": "0.83.2", "@react-native/virtualized-lists": "0.83.2", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-jest": "^29.7.0", "babel-plugin-syntax-hermes-parser": "0.32.0", "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", "glob": "^7.1.1", "hermes-compiler": "0.14.1", "invariant": "^2.2.4", "jest-environment-node": "^29.7.0", "memoize-one": "^5.0.0", "metro-runtime": "^0.83.3", "metro-source-map": "^0.83.3", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", "scheduler": "0.27.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "peerDependencies": { "@types/react": "^19.1.1", "react": "^19.2.0" }, "bin": "cli.js" }, "sha512-ZDma3SLkRN2U2dg0/EZqxNBAx4of/oTnPjXAQi299VLq2gdnbZowGy9hzqv+O7sTA62g+lM1v+2FM5DUnJ/6hg=="],
1100
-
1101
- "react-native-css-interop": ["react-native-css-interop@0.2.2", "", { "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/traverse": "^7.23.0", "@babel/types": "^7.23.0", "debug": "^4.3.7", "lightningcss": "~1.27.0", "semver": "^7.6.3" }, "peerDependencies": { "react": ">=18", "react-native": "*", "react-native-reanimated": ">=3.6.2", "tailwindcss": "~3" } }, "sha512-2eUyl7RH1RT6TYbe5nm+d4HZ2Pr6Nmve158B57tb5W4Bo52Xzp+PFeWAdFnAr2HNB+r9b6qa8o3xH1YREVQU0g=="],
1102
-
1103
- "react-native-draggable-flatlist": ["react-native-draggable-flatlist@4.0.3", "", { "dependencies": { "@babel/preset-typescript": "^7.17.12" }, "peerDependencies": { "react-native": ">=0.64.0", "react-native-gesture-handler": ">=2.0.0", "react-native-reanimated": ">=2.8.0" } }, "sha512-2F4x5BFieWdGq9SetD2nSAR7s7oQCSgNllYgERRXXtNfSOuAGAVbDb/3H3lP0y5f7rEyNwabKorZAD/SyyNbDw=="],
1104
-
1105
- "react-native-gesture-handler": ["react-native-gesture-handler@2.30.0", "", { "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-5YsnKHGa0X9C8lb5oCnKm0fLUPM6CRduvUUw2Bav4RIj/C3HcFh4RIUnF8wgG6JQWCL1//gRx4v+LVWgcIQdGA=="],
1106
-
1107
- "react-native-is-edge-to-edge": ["react-native-is-edge-to-edge@1.2.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q=="],
1108
-
1109
- "react-native-reanimated": ["react-native-reanimated@4.2.1", "", { "dependencies": { "react-native-is-edge-to-edge": "1.2.1", "semver": "7.7.3" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": ">=0.7.0" } }, "sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg=="],
1110
-
1111
- "react-native-safe-area-context": ["react-native-safe-area-context@5.6.2", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg=="],
1112
-
1113
- "react-native-screens": ["react-native-screens@4.23.0", "", { "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-XhO3aK0UeLpBn4kLecd+J+EDeRRJlI/Ro9Fze06vo1q163VeYtzfU9QS09/VyDFMWR1qxDC1iazCArTPSFFiPw=="],
1114
-
1115
- "react-native-svg": ["react-native-svg@15.15.3", "", { "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-/k4KYwPBLGcx2f5d4FjE+vCScK7QOX14cl2lIASJ28u4slHHtIhL0SZKU7u9qmRBHxTCKPoPBtN6haT1NENJNA=="],
1116
-
1117
- "react-native-udp": ["react-native-udp@4.1.7", "", { "dependencies": { "buffer": "^5.6.0", "events": "^3.1.0" } }, "sha512-NUE3zewu61NCdSsLlj+l0ad6qojcVEZPT4hVG/x6DU9U4iCzwtfZSASh9vm7teAcVzLkdD+cO3411LHshAi/wA=="],
1118
-
1119
- "react-native-web": ["react-native-web@0.21.2", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^7.0.1", "memoize-one": "^6.0.0", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "styleq": "^0.1.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg=="],
1120
-
1121
- "react-native-worklets": ["react-native-worklets@0.7.2", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "7.27.1", "@babel/plugin-transform-class-properties": "7.27.1", "@babel/plugin-transform-classes": "7.28.4", "@babel/plugin-transform-nullish-coalescing-operator": "7.27.1", "@babel/plugin-transform-optional-chaining": "7.27.1", "@babel/plugin-transform-shorthand-properties": "7.27.1", "@babel/plugin-transform-template-literals": "7.27.1", "@babel/plugin-transform-unicode-regex": "7.27.1", "@babel/preset-typescript": "7.27.1", "convert-source-map": "2.0.0", "semver": "7.7.3" }, "peerDependencies": { "@babel/core": "*", "react": "*", "react-native": "*" } }, "sha512-DuLu1kMV/Uyl9pQHp3hehAlThoLw7Yk2FwRTpzASOmI+cd4845FWn3m2bk9MnjUw8FBRIyhwLqYm2AJaXDXsog=="],
1122
-
1123
- "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
1124
-
1125
- "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="],
1126
-
1127
- "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
1128
-
1129
- "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
1130
-
1131
- "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
1132
-
1133
- "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
1134
-
1135
- "regenerate": ["regenerate@1.4.2", "", {}, "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="],
1136
-
1137
- "regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
1138
-
1139
- "regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="],
1140
-
1141
- "regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
1142
-
1143
- "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="],
1144
-
1145
- "regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": "bin/parser" }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
1146
-
1147
- "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
1148
-
1149
- "reselect": ["reselect@4.1.8", "", {}, "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="],
1150
-
1151
- "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
1152
-
1153
- "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
1154
-
1155
- "resolve-workspace-root": ["resolve-workspace-root@2.0.1", "", {}, "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w=="],
1156
-
1157
- "restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="],
1158
-
1159
- "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
1160
-
1161
- "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": "bin.js" }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
1162
-
1163
- "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
1164
-
1165
- "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
1166
-
1167
- "sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="],
1168
-
1169
- "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
1170
-
1171
- "semver": ["semver@7.6.3", "", { "bin": "bin/semver.js" }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
1172
-
1173
- "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="],
1174
-
1175
- "serialize-error": ["serialize-error@2.1.0", "", {}, "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw=="],
1176
-
1177
- "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
1178
-
1179
- "server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="],
1180
-
1181
- "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="],
1182
-
1183
- "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
1184
-
1185
- "sf-symbols-typescript": ["sf-symbols-typescript@2.2.0", "", {}, "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw=="],
1186
-
1187
- "shallowequal": ["shallowequal@1.1.0", "", {}, "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="],
1188
-
1189
- "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
1190
-
1191
- "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
1192
-
1193
- "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
1194
-
1195
- "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
1196
-
1197
- "simple-plist": ["simple-plist@1.3.1", "", { "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.1", "plist": "^3.0.5" } }, "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw=="],
1198
-
1199
- "simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="],
1200
-
1201
- "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
1202
-
1203
- "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
1204
-
1205
- "slugify": ["slugify@1.6.6", "", {}, "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw=="],
1206
-
1207
- "source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
1208
-
1209
- "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
1210
-
1211
- "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
1212
-
1213
- "split-on-first": ["split-on-first@1.1.0", "", {}, "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="],
1214
-
1215
- "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
1216
-
1217
- "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="],
1218
-
1219
- "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="],
1220
-
1221
- "stacktrace-parser": ["stacktrace-parser@0.1.11", "", { "dependencies": { "type-fest": "^0.7.1" } }, "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg=="],
1222
-
1223
- "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
1224
-
1225
- "stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="],
1226
-
1227
- "strict-uri-encode": ["strict-uri-encode@2.0.0", "", {}, "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="],
1228
-
1229
- "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
1230
-
1231
- "strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="],
1232
-
1233
- "structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="],
1234
-
1235
- "styleq": ["styleq@0.1.3", "", {}, "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="],
1236
-
1237
- "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="],
1238
-
1239
- "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
1240
-
1241
- "supports-hyperlinks": ["supports-hyperlinks@2.3.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA=="],
1242
-
1243
- "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
1244
-
1245
- "tailwindcss": ["tailwindcss@3.4.19", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ=="],
1246
-
1247
- "terminal-link": ["terminal-link@2.1.1", "", { "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" } }, "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="],
1248
-
1249
- "terser": ["terser@5.46.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": "bin/terser" }, "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg=="],
1250
-
1251
- "test-exclude": ["test-exclude@6.0.0", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" } }, "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="],
1252
-
1253
- "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
1254
-
1255
- "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
1256
-
1257
- "throat": ["throat@5.0.0", "", {}, "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA=="],
1258
-
1259
- "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
1260
-
1261
- "tmpl": ["tmpl@1.0.5", "", {}, "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="],
1262
-
1263
- "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
1264
-
1265
- "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
1266
-
1267
- "toqr": ["toqr@0.1.1", "", {}, "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA=="],
1268
-
1269
- "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
1270
-
1271
- "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
1272
-
1273
- "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1274
-
1275
- "type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="],
1276
-
1277
- "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="],
1278
-
1279
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
1280
-
1281
- "ua-parser-js": ["ua-parser-js@1.0.41", "", { "bin": "script/cli.js" }, "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug=="],
1282
-
1283
- "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
1284
-
1285
- "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="],
1286
-
1287
- "unicode-match-property-ecmascript": ["unicode-match-property-ecmascript@2.0.0", "", { "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" } }, "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q=="],
1288
-
1289
- "unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
1290
-
1291
- "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="],
1292
-
1293
- "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
1294
-
1295
- "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
1296
-
1297
- "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
1298
-
1299
- "use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="],
1300
-
1301
- "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
1302
-
1303
- "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
1304
-
1305
- "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
1306
-
1307
- "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
1308
-
1309
- "uuid": ["uuid@7.0.3", "", { "bin": "dist/bin/uuid" }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="],
1310
-
1311
- "validate-npm-package-name": ["validate-npm-package-name@5.0.1", "", {}, "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="],
1312
-
1313
- "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
1314
-
1315
- "vaul": ["vaul@1.1.2", "", { "dependencies": { "@radix-ui/react-dialog": "^1.1.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA=="],
1316
-
1317
- "vlq": ["vlq@1.0.1", "", {}, "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="],
1318
-
1319
- "walker": ["walker@1.0.8", "", { "dependencies": { "makeerror": "1.0.12" } }, "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ=="],
1320
-
1321
- "warn-once": ["warn-once@0.1.1", "", {}, "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q=="],
1322
-
1323
- "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="],
1324
-
1325
- "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
1326
-
1327
- "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="],
1328
-
1329
- "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
1330
-
1331
- "whatwg-url-minimum": ["whatwg-url-minimum@0.1.1", "", {}, "sha512-u2FNVjFVFZhdjb502KzXy1gKn1mEisQRJssmSJT8CPhZdZa0AP6VCbWlXERKyGu0l09t0k50FiDiralpGhBxgA=="],
1332
-
1333
- "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
1334
-
1335
- "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
1336
-
1337
- "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
1338
-
1339
- "write-file-atomic": ["write-file-atomic@4.0.2", "", { "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" } }, "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg=="],
1340
-
1341
- "ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="],
1342
-
1343
- "xcode": ["xcode@3.0.1", "", { "dependencies": { "simple-plist": "^1.1.0", "uuid": "^7.0.3" } }, "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA=="],
1344
-
1345
- "xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="],
1346
-
1347
- "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="],
1348
-
1349
- "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
1350
-
1351
- "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
1352
-
1353
- "yaml": ["yaml@2.8.2", "", { "bin": "bin.mjs" }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="],
1354
-
1355
- "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
1356
-
1357
- "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
1358
-
1359
- "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
1360
-
1361
- "@babel/core/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1362
-
1363
- "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
1364
-
1365
- "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1366
-
1367
- "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1368
-
1369
- "@babel/helper-create-regexp-features-plugin/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1370
-
1371
- "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1372
-
1373
- "@expo/cli/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
1374
-
1375
- "@expo/cli/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1376
-
1377
- "@expo/cli/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1378
-
1379
- "@expo/cli/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
1380
-
1381
- "@expo/config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
1382
-
1383
- "@expo/config/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1384
-
1385
- "@expo/config-plugins/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
1386
-
1387
- "@expo/config-plugins/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1388
-
1389
- "@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1390
-
1391
- "@expo/fingerprint/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
1392
-
1393
- "@expo/fingerprint/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
1394
-
1395
- "@expo/fingerprint/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1396
-
1397
- "@expo/image-utils/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1398
-
1399
- "@expo/metro-config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
1400
-
1401
- "@expo/metro-config/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1402
-
1403
- "@expo/prebuild-config/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1404
-
1405
- "@istanbuljs/load-nyc-config/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
1406
-
1407
- "@istanbuljs/load-nyc-config/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
1408
-
1409
- "@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": "bin/js-yaml.js" }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
1410
-
1411
- "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1412
-
1413
- "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1414
-
1415
- "@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1416
-
1417
- "@react-native/babel-preset/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw=="],
1418
-
1419
- "@react-native/babel-preset/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-replace-supers": "^7.28.6", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q=="],
1420
-
1421
- "@react-native/babel-preset/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg=="],
1422
-
1423
- "@react-native/babel-preset/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w=="],
1424
-
1425
- "@react-native/codegen/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
1426
-
1427
- "@react-native/community-cli-plugin/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1428
-
1429
- "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
1430
-
1431
- "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1432
-
1433
- "better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
1434
-
1435
- "chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
1436
-
1437
- "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1438
-
1439
- "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
1440
-
1441
- "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
1442
-
1443
- "compression/negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="],
1444
-
1445
- "connect/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
1446
-
1447
- "css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
1448
-
1449
- "expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
1450
-
1451
- "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1452
-
1453
- "fbjs/promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="],
1454
-
1455
- "fdir/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1456
-
1457
- "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
1458
-
1459
- "finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
1460
-
1461
- "finalhandler/on-finished": ["on-finished@2.3.0", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww=="],
1462
-
1463
- "finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="],
1464
-
1465
- "hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
1466
-
1467
- "istanbul-lib-instrument/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1468
-
1469
- "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
1470
-
1471
- "lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
1472
-
1473
- "log-symbols/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
1474
-
1475
- "metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="],
1476
-
1477
- "npm-package-arg/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1478
-
1479
- "ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
1480
-
1481
- "path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1482
-
1483
- "pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
1484
-
1485
- "react-native/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
1486
-
1487
- "react-native/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1488
-
1489
- "react-native-css-interop/lightningcss": ["lightningcss@1.27.0", "", { "dependencies": { "detect-libc": "^1.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.27.0", "lightningcss-darwin-x64": "1.27.0", "lightningcss-freebsd-x64": "1.27.0", "lightningcss-linux-arm-gnueabihf": "1.27.0", "lightningcss-linux-arm64-gnu": "1.27.0", "lightningcss-linux-arm64-musl": "1.27.0", "lightningcss-linux-x64-gnu": "1.27.0", "lightningcss-linux-x64-musl": "1.27.0", "lightningcss-win32-arm64-msvc": "1.27.0", "lightningcss-win32-x64-msvc": "1.27.0" } }, "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ=="],
1490
-
1491
- "react-native-css-interop/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1492
-
1493
- "react-native-reanimated/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
1494
-
1495
- "react-native-web/@react-native/normalize-colors": ["@react-native/normalize-colors@0.74.89", "", {}, "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg=="],
1496
-
1497
- "react-native-web/memoize-one": ["memoize-one@6.0.0", "", {}, "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="],
1498
-
1499
- "react-native-worklets/@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="],
1500
-
1501
- "react-native-worklets/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
1502
-
1503
- "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
1504
-
1505
- "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
1506
-
1507
- "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
1508
-
1509
- "stack-utils/escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="],
1510
-
1511
- "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
1512
-
1513
- "strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="],
1514
-
1515
- "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
1516
-
1517
- "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
1518
-
1519
- "test-exclude/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
1520
-
1521
- "test-exclude/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
1522
-
1523
- "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1524
-
1525
- "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
1526
-
1527
- "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
1528
-
1529
- "xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
1530
-
1531
- "@expo/cli/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
1532
-
1533
- "@expo/cli/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1534
-
1535
- "@expo/cli/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
1536
-
1537
- "@expo/config-plugins/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
1538
-
1539
- "@expo/config-plugins/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1540
-
1541
- "@expo/config-plugins/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
1542
-
1543
- "@expo/config/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
1544
-
1545
- "@expo/config/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1546
-
1547
- "@expo/config/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
1548
-
1549
- "@expo/fingerprint/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1550
-
1551
- "@expo/fingerprint/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
1552
-
1553
- "@expo/fingerprint/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
1554
-
1555
- "@expo/metro-config/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
1556
-
1557
- "@expo/metro-config/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1558
-
1559
- "@expo/metro-config/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
1560
-
1561
- "@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
1562
-
1563
- "@istanbuljs/load-nyc-config/find-up/path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
1564
-
1565
- "@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
1566
-
1567
- "@react-native/codegen/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
1568
-
1569
- "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
1570
-
1571
- "connect/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
1572
-
1573
- "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
1574
-
1575
- "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
1576
-
1577
- "log-symbols/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
1578
-
1579
- "log-symbols/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
1580
-
1581
- "log-symbols/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
1582
-
1583
- "ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
1584
-
1585
- "ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
1586
-
1587
- "ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
1588
-
1589
- "react-native-css-interop/lightningcss/detect-libc": ["detect-libc@1.0.3", "", { "bin": "bin/detect-libc.js" }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
1590
-
1591
- "react-native-css-interop/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.27.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ=="],
1592
-
1593
- "react-native-css-interop/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.27.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg=="],
1594
-
1595
- "react-native-css-interop/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.27.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA=="],
1596
-
1597
- "react-native-css-interop/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.27.0", "", { "os": "linux", "cpu": "arm" }, "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA=="],
1598
-
1599
- "react-native-css-interop/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.27.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A=="],
1600
-
1601
- "react-native-css-interop/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.27.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg=="],
1602
-
1603
- "react-native-css-interop/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.27.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A=="],
1604
-
1605
- "react-native-css-interop/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.27.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA=="],
1606
-
1607
- "react-native-css-interop/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.27.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ=="],
1608
-
1609
- "react-native-css-interop/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.27.0", "", { "os": "win32", "cpu": "x64" }, "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw=="],
1610
-
1611
- "react-native/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
1612
-
1613
- "rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
1614
-
1615
- "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
1616
-
1617
- "test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
1618
-
1619
- "@expo/cli/glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
1620
-
1621
- "@expo/cli/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
1622
-
1623
- "@expo/config-plugins/glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
1624
-
1625
- "@expo/config-plugins/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
1626
-
1627
- "@expo/config/glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
1628
-
1629
- "@expo/config/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
1630
-
1631
- "@expo/fingerprint/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
1632
-
1633
- "@expo/fingerprint/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
1634
-
1635
- "@expo/metro-config/glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
1636
-
1637
- "@expo/metro-config/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
1638
-
1639
- "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
1640
-
1641
- "@react-native/codegen/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
1642
-
1643
- "log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
1644
-
1645
- "log-symbols/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
1646
-
1647
- "ora/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
1648
-
1649
- "ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
1650
-
1651
- "react-native/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
1652
-
1653
- "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
1654
-
1655
- "@expo/cli/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
1656
-
1657
- "@expo/config-plugins/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
1658
-
1659
- "@expo/config/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
1660
-
1661
- "@expo/metro-config/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
1662
-
1663
- "log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
1664
-
1665
- "ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
1666
- }
1667
-}
components/SessionDrawer.tsx
deleted file mode 100644
....@@ -1,727 +0,0 @@
1
-/**
2
- * SessionDrawer — Gmail-style left drawer for session navigation.
3
- *
4
- * Slides in from the left with a dark overlay. Shows sessions with
5
- * unread badges. Swipe left to remove, long press to rename.
6
- */
7
-import React, { useCallback, useEffect, useRef, useState } from "react";
8
-import {
9
- Animated,
10
- Dimensions,
11
- Keyboard,
12
- LayoutAnimation,
13
- Pressable,
14
- ScrollView,
15
- StyleSheet,
16
- Text,
17
- TextInput,
18
- View,
19
-} from "react-native";
20
-import {
21
- GestureHandlerRootView,
22
- Swipeable,
23
-} from "react-native-gesture-handler";
24
-import DraggableFlatList, {
25
- RenderItemParams,
26
- ScaleDecorator,
27
-} from "react-native-draggable-flatlist";
28
-import * as Haptics from "expo-haptics";
29
-import { WsSession, PaiProject } from "../types";
30
-import { useChat } from "../contexts/ChatContext";
31
-import { useTheme, type ThemeColors } from "../contexts/ThemeContext";
32
-
33
-const SCREEN_WIDTH = Dimensions.get("window").width;
34
-const DRAWER_WIDTH = SCREEN_WIDTH * 0.82;
35
-const ROW_WIDTH = DRAWER_WIDTH;
36
-
37
-interface SessionDrawerProps {
38
- visible: boolean;
39
- onClose: () => void;
40
-}
41
-
42
-/* ── Swipeable row ── */
43
-
44
-function SessionRow({
45
- session,
46
- unreadCount,
47
- isUnread,
48
- onSwitch,
49
- onLongPress,
50
- onDelete,
51
- onDrag,
52
- isDragging,
53
- colors,
54
-}: {
55
- session: WsSession;
56
- unreadCount: number;
57
- isUnread: boolean;
58
- onSwitch: () => void;
59
- onLongPress: () => void;
60
- onDelete: () => void;
61
- onDrag: () => void;
62
- isDragging: boolean;
63
- colors: ThemeColors;
64
-}) {
65
- const swipeRef = useRef<Swipeable>(null);
66
-
67
- const renderRightActions = (
68
- _progress: Animated.AnimatedInterpolation<number>,
69
- dragX: Animated.AnimatedInterpolation<number>,
70
- ) => {
71
- const scale = dragX.interpolate({
72
- inputRange: [-80, -40, 0],
73
- outputRange: [1, 0.8, 0],
74
- extrapolate: "clamp",
75
- });
76
- return (
77
- <Pressable
78
- onPress={() => {
79
- swipeRef.current?.close();
80
- onDelete();
81
- }}
82
- style={{
83
- backgroundColor: colors.danger,
84
- justifyContent: "center",
85
- alignItems: "center",
86
- width: 72,
87
- borderRadius: 12,
88
- marginLeft: 8,
89
- }}
90
- >
91
- <Animated.Text
92
- style={{
93
- color: "#FFF",
94
- fontSize: 13,
95
- fontWeight: "600",
96
- transform: [{ scale }],
97
- }}
98
- >
99
- Remove
100
- </Animated.Text>
101
- </Pressable>
102
- );
103
- };
104
-
105
- return (
106
- <View style={{ width: ROW_WIDTH }}>
107
- <Swipeable
108
- ref={swipeRef}
109
- renderRightActions={renderRightActions}
110
- rightThreshold={50}
111
- friction={2}
112
- overshootRight={false}
113
- >
114
- <Pressable onPress={onSwitch} onLongPress={onLongPress} delayLongPress={400}>
115
- <View
116
- style={{
117
- width: ROW_WIDTH,
118
- flexDirection: "row",
119
- alignItems: "center",
120
- paddingVertical: 14,
121
- paddingLeft: 16,
122
- paddingRight: 12,
123
- backgroundColor: session.isActive ? colors.accentBg : "transparent",
124
- borderRadius: 12,
125
- opacity: isDragging ? 0.8 : 1,
126
- }}
127
- >
128
- {/* Icon — left */}
129
- <View
130
- style={{
131
- width: 40,
132
- height: 40,
133
- borderRadius: 20,
134
- backgroundColor: session.isActive ? colors.accent : colors.border,
135
- alignItems: "center",
136
- justifyContent: "center",
137
- }}
138
- >
139
- {session.isActive ? (
140
- <View
141
- style={{
142
- width: 10,
143
- height: 10,
144
- borderRadius: 5,
145
- backgroundColor: "#FFF",
146
- }}
147
- />
148
- ) : (
149
- <Text style={{ color: colors.textSecondary, fontSize: 15, fontWeight: "700" }}>
150
- {session.kind === "api" ? "A" : "T"}
151
- </Text>
152
- )}
153
- </View>
154
-
155
- {/* Name + subtitle — middle */}
156
- <View style={{ flex: 1, marginLeft: 14 }}>
157
- <View style={{ flexDirection: "row", alignItems: "center" }}>
158
- <Text
159
- style={{
160
- color: session.isActive ? colors.accent : colors.text,
161
- fontSize: 17,
162
- fontWeight: session.isActive ? "700" : "600",
163
- flexShrink: 1,
164
- }}
165
- numberOfLines={1}
166
- >
167
- {session.name}
168
- </Text>
169
- {/* Server-pushed unread dot — shown when the server signals new activity */}
170
- {isUnread && unreadCount === 0 && (
171
- <View
172
- style={{
173
- width: 8,
174
- height: 8,
175
- borderRadius: 4,
176
- backgroundColor: colors.accent,
177
- marginLeft: 6,
178
- flexShrink: 0,
179
- }}
180
- />
181
- )}
182
- </View>
183
- <Text
184
- style={{
185
- color: colors.textMuted,
186
- fontSize: 12,
187
- marginTop: 2,
188
- }}
189
- numberOfLines={1}
190
- >
191
- {session.kind === "api" ? "Headless" : "Terminal"}
192
- {session.isActive ? " — active" : ""}
193
- </Text>
194
- </View>
195
-
196
- {/* Unread badge */}
197
- {unreadCount > 0 && (
198
- <View
199
- style={{
200
- minWidth: 24,
201
- height: 24,
202
- borderRadius: 12,
203
- backgroundColor: colors.accent,
204
- alignItems: "center",
205
- justifyContent: "center",
206
- paddingHorizontal: 7,
207
- }}
208
- >
209
- <Text style={{ color: "#FFF", fontSize: 12, fontWeight: "700" }}>
210
- {unreadCount > 99 ? "99+" : unreadCount}
211
- </Text>
212
- </View>
213
- )}
214
-
215
- {/* Drag handle */}
216
- <Pressable
217
- onPressIn={onDrag}
218
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
219
- style={{
220
- marginLeft: 8,
221
- paddingHorizontal: 4,
222
- paddingVertical: 8,
223
- }}
224
- >
225
- <Text style={{ color: colors.textMuted, fontSize: 16, letterSpacing: 1 }}>⋮⋮</Text>
226
- </Pressable>
227
- </View>
228
- </Pressable>
229
- </Swipeable>
230
- </View>
231
- );
232
-}
233
-
234
-/* ── Inline rename ── */
235
-
236
-function RenameEditor({
237
- name,
238
- onConfirm,
239
- onCancel,
240
- colors,
241
-}: {
242
- name: string;
243
- onConfirm: (newName: string) => void;
244
- onCancel: () => void;
245
- colors: ThemeColors;
246
-}) {
247
- const [editName, setEditName] = useState(name);
248
- return (
249
- <View style={{ paddingHorizontal: 16, paddingVertical: 8, width: ROW_WIDTH }}>
250
- <TextInput
251
- value={editName}
252
- onChangeText={setEditName}
253
- autoFocus
254
- onSubmitEditing={() => onConfirm(editName.trim())}
255
- onBlur={onCancel}
256
- returnKeyType="done"
257
- style={{
258
- color: colors.text,
259
- fontSize: 17,
260
- fontWeight: "600",
261
- borderBottomWidth: 2,
262
- borderBottomColor: colors.accent,
263
- paddingVertical: 10,
264
- paddingHorizontal: 4,
265
- }}
266
- placeholderTextColor={colors.textMuted}
267
- placeholder="Session name..."
268
- />
269
- </View>
270
- );
271
-}
272
-
273
-/* ── Main Drawer ── */
274
-
275
-export function SessionDrawer({ visible, onClose }: SessionDrawerProps) {
276
- const {
277
- sessions,
278
- activeSessionId,
279
- requestSessions,
280
- switchSession,
281
- renameSession,
282
- removeSession,
283
- createSession,
284
- fetchProjects,
285
- projects,
286
- unreadCounts,
287
- unreadSessions,
288
- } = useChat();
289
- const { colors } = useTheme();
290
- const [editingId, setEditingId] = useState<string | null>(null);
291
- const [showProjectPicker, setShowProjectPicker] = useState(false);
292
- const [customPath, setCustomPath] = useState("");
293
- const slideAnim = useRef(new Animated.Value(-DRAWER_WIDTH)).current;
294
- const fadeAnim = useRef(new Animated.Value(0)).current;
295
- const [rendered, setRendered] = useState(false);
296
- const [keyboardHeight, setKeyboardHeight] = useState(0);
297
- const pickerScrollRef = useRef<ScrollView>(null);
298
- const listRef = useRef<DraggableFlatList<WsSession>>(null);
299
-
300
- useEffect(() => {
301
- const showSub = Keyboard.addListener("keyboardWillShow", (e) => {
302
- setKeyboardHeight(e.endCoordinates.height);
303
- });
304
- const hideSub = Keyboard.addListener("keyboardWillHide", () => {
305
- setKeyboardHeight(0);
306
- });
307
- return () => { showSub.remove(); hideSub.remove(); };
308
- }, []);
309
-
310
- // Local ordering: merge server sessions while preserving user's drag order
311
- const [orderedSessions, setOrderedSessions] = useState<WsSession[]>([]);
312
- useEffect(() => {
313
- setOrderedSessions((prev) => {
314
- if (prev.length === 0) return sessions;
315
- const serverIds = new Set(sessions.map((s) => s.id));
316
- // Keep existing order, update session data, remove deleted
317
- const kept = prev
318
- .filter((p) => serverIds.has(p.id))
319
- .map((p) => sessions.find((s) => s.id === p.id)!);
320
- // Append any new sessions at the end
321
- const keptIds = new Set(kept.map((s) => s.id));
322
- const added = sessions.filter((s) => !keptIds.has(s.id));
323
- return [...kept, ...added];
324
- });
325
- }, [sessions]);
326
-
327
- useEffect(() => {
328
- if (visible) {
329
- Keyboard.dismiss();
330
- setRendered(true);
331
- requestSessions();
332
- Animated.parallel([
333
- Animated.spring(slideAnim, {
334
- toValue: 0,
335
- useNativeDriver: true,
336
- damping: 22,
337
- stiffness: 200,
338
- }),
339
- Animated.timing(fadeAnim, {
340
- toValue: 1,
341
- duration: 200,
342
- useNativeDriver: true,
343
- }),
344
- ]).start();
345
- } else {
346
- Animated.parallel([
347
- Animated.timing(slideAnim, {
348
- toValue: -DRAWER_WIDTH,
349
- duration: 200,
350
- useNativeDriver: true,
351
- }),
352
- Animated.timing(fadeAnim, {
353
- toValue: 0,
354
- duration: 200,
355
- useNativeDriver: true,
356
- }),
357
- ]).start(() => {
358
- setRendered(false);
359
- setEditingId(null);
360
- });
361
- }
362
- }, [visible]);
363
-
364
- const handleClose = useCallback(() => {
365
- setEditingId(null);
366
- setShowProjectPicker(false);
367
- setCustomPath("");
368
- Keyboard.dismiss();
369
- onClose();
370
- }, [onClose]);
371
-
372
- const handleSwitch = useCallback(
373
- (session: WsSession) => {
374
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
375
- switchSession(session.id);
376
- handleClose();
377
- },
378
- [switchSession, handleClose],
379
- );
380
-
381
- const handleStartRename = useCallback((session: WsSession) => {
382
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
383
- setEditingId(session.id);
384
- // Scroll to the item after keyboard appears so it's visible
385
- const idx = orderedSessions.findIndex(s => s.id === session.id);
386
- if (idx >= 0 && listRef.current) {
387
- setTimeout(() => {
388
- try {
389
- (listRef.current as any)?.scrollToIndex({ index: idx, animated: true, viewPosition: 0.3 });
390
- } catch { /* ignore if index out of range */ }
391
- }, 400);
392
- }
393
- }, [orderedSessions]);
394
-
395
- const handleConfirmRename = useCallback(
396
- (sessionId: string, newName: string) => {
397
- if (newName) renameSession(sessionId, newName);
398
- setEditingId(null);
399
- },
400
- [renameSession],
401
- );
402
-
403
- const handleRemove = useCallback(
404
- (session: WsSession) => {
405
- Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
406
- LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
407
- removeSession(session.id);
408
- },
409
- [removeSession],
410
- );
411
-
412
- const handleNewSession = useCallback(() => {
413
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
414
- setShowProjectPicker((prev) => {
415
- if (!prev) fetchProjects();
416
- return !prev;
417
- });
418
- }, [fetchProjects]);
419
-
420
- const launchSession = useCallback((opts?: { project?: string; path?: string }) => {
421
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
422
- createSession(opts);
423
- setShowProjectPicker(false);
424
- setCustomPath("");
425
- handleClose();
426
- setTimeout(() => requestSessions(), 2500);
427
- }, [createSession, requestSessions, handleClose]);
428
-
429
- const renderItem = useCallback(
430
- ({ item, drag, isActive }: RenderItemParams<WsSession>) => {
431
- if (editingId === item.id) {
432
- return (
433
- <RenameEditor
434
- name={item.name}
435
- onConfirm={(name) => handleConfirmRename(item.id, name)}
436
- onCancel={() => setEditingId(null)}
437
- colors={colors}
438
- />
439
- );
440
- }
441
- return (
442
- <ScaleDecorator>
443
- <SessionRow
444
- session={item}
445
- unreadCount={unreadCounts[item.id] ?? 0}
446
- isUnread={unreadSessions.has(item.id)}
447
- onSwitch={() => handleSwitch(item)}
448
- onLongPress={() => handleStartRename(item)}
449
- onDelete={() => handleRemove(item)}
450
- onDrag={drag}
451
- isDragging={isActive}
452
- colors={colors}
453
- />
454
- </ScaleDecorator>
455
- );
456
- },
457
- [editingId, unreadCounts, unreadSessions, colors, handleSwitch, handleStartRename, handleRemove, handleConfirmRename],
458
- );
459
-
460
- const keyExtractor = useCallback((item: WsSession) => item.id, []);
461
-
462
- const handleDragEnd = useCallback(
463
- ({ data }: { data: WsSession[] }) => {
464
- setOrderedSessions(data);
465
- },
466
- [],
467
- );
468
-
469
- const renderSeparator = useCallback(
470
- () => (
471
- <View
472
- style={{
473
- height: 1,
474
- backgroundColor: colors.border,
475
- marginHorizontal: 16,
476
- marginVertical: 1,
477
- }}
478
- />
479
- ),
480
- [colors.border],
481
- );
482
-
483
- if (!rendered) return null;
484
-
485
- return (
486
- <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
487
- <View style={{ ...StyleSheet.absoluteFillObject, zIndex: 100 }}>
488
- {/* Backdrop */}
489
- <Animated.View
490
- style={{
491
- ...StyleSheet.absoluteFillObject,
492
- backgroundColor: "rgba(0,0,0,0.5)",
493
- opacity: fadeAnim,
494
- }}
495
- >
496
- <Pressable style={{ flex: 1 }} onPress={handleClose} />
497
- </Animated.View>
498
-
499
- {/* Drawer panel */}
500
- <Animated.View
501
- style={{
502
- position: "absolute",
503
- top: 0,
504
- bottom: 0,
505
- left: 0,
506
- width: DRAWER_WIDTH,
507
- backgroundColor: colors.bgSecondary,
508
- transform: [{ translateX: slideAnim }],
509
- shadowColor: "#000",
510
- shadowOffset: { width: 4, height: 0 },
511
- shadowOpacity: 0.4,
512
- shadowRadius: 12,
513
- elevation: 20,
514
- }}
515
- >
516
- <GestureHandlerRootView style={{ flex: 1, paddingBottom: keyboardHeight }}>
517
- {/* Header */}
518
- <View
519
- style={{
520
- paddingTop: 60,
521
- paddingHorizontal: 20,
522
- paddingBottom: 16,
523
- borderBottomWidth: 1,
524
- borderBottomColor: colors.border,
525
- }}
526
- >
527
- <View
528
- style={{
529
- flexDirection: "row",
530
- alignItems: "center",
531
- justifyContent: "space-between",
532
- }}
533
- >
534
- <Text
535
- style={{
536
- color: colors.text,
537
- fontSize: 22,
538
- fontWeight: "800",
539
- letterSpacing: -0.5,
540
- }}
541
- >
542
- Sessions
543
- </Text>
544
- <Pressable
545
- onPress={() => requestSessions()}
546
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
547
- style={({ pressed }) => ({
548
- paddingHorizontal: 10,
549
- paddingVertical: 5,
550
- borderRadius: 10,
551
- backgroundColor: pressed ? colors.bgTertiary : colors.bgTertiary + "80",
552
- })}
553
- >
554
- <Text style={{ color: colors.textSecondary, fontSize: 13 }}>
555
- Refresh
556
- </Text>
557
- </Pressable>
558
- </View>
559
- </View>
560
-
561
- {/* Session list */}
562
- {orderedSessions.length === 0 ? (
563
- <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
564
- <Text style={{ color: colors.textMuted, fontSize: 14 }}>
565
- No sessions found
566
- </Text>
567
- </View>
568
- ) : (
569
- <DraggableFlatList
570
- ref={listRef}
571
- data={orderedSessions}
572
- keyExtractor={keyExtractor}
573
- renderItem={renderItem}
574
- onDragEnd={handleDragEnd}
575
- ItemSeparatorComponent={renderSeparator}
576
- contentContainerStyle={{ paddingVertical: 4 }}
577
- showsVerticalScrollIndicator={false}
578
- keyboardShouldPersistTaps="handled"
579
- />
580
- )}
581
-
582
- {/* New session button + project picker */}
583
- <View style={{ paddingVertical: 8 }}>
584
- <View style={{ alignItems: "center", paddingBottom: showProjectPicker ? 8 : 0 }}>
585
- <Pressable
586
- onPress={handleNewSession}
587
- style={{
588
- flexDirection: "row",
589
- alignItems: "center",
590
- gap: 6,
591
- paddingHorizontal: 20,
592
- paddingVertical: 10,
593
- borderRadius: 24,
594
- backgroundColor: colors.accent,
595
- }}
596
- >
597
- <Text style={{ color: "#FFF", fontSize: 18, fontWeight: "700" }}>+</Text>
598
- <Text style={{ color: "#FFF", fontSize: 15, fontWeight: "600" }}>New Session</Text>
599
- </Pressable>
600
- </View>
601
-
602
- {showProjectPicker && (
603
- <ScrollView
604
- ref={pickerScrollRef}
605
- style={{
606
- marginHorizontal: 12,
607
- borderRadius: 12,
608
- backgroundColor: colors.bgTertiary,
609
- maxHeight: 300,
610
- }}
611
- keyboardShouldPersistTaps="handled"
612
- >
613
- {/* Home directory — always first */}
614
- <Pressable
615
- onPress={() => launchSession({ path: "~" })}
616
- style={{
617
- flexDirection: "row",
618
- alignItems: "center",
619
- paddingHorizontal: 16,
620
- paddingVertical: 14,
621
- }}
622
- >
623
- <Text style={{ fontSize: 20, width: 32 }}>🏠</Text>
624
- <View style={{ flex: 1 }}>
625
- <Text style={{ color: colors.text, fontSize: 16, fontWeight: "600" }}>Home</Text>
626
- <Text style={{ color: colors.textMuted, fontSize: 12 }}>~/</Text>
627
- </View>
628
- </Pressable>
629
-
630
- {/* PAI projects */}
631
- {projects.map((p) => (
632
- <Pressable
633
- key={p.slug}
634
- onPress={() => launchSession({ project: p.name })}
635
- style={{
636
- flexDirection: "row",
637
- alignItems: "center",
638
- paddingHorizontal: 16,
639
- paddingVertical: 14,
640
- borderTopWidth: 1,
641
- borderTopColor: colors.border,
642
- }}
643
- >
644
- <Text style={{ fontSize: 20, width: 32 }}>📂</Text>
645
- <View style={{ flex: 1 }}>
646
- <Text style={{ color: colors.text, fontSize: 16, fontWeight: "500" }}>{p.name}</Text>
647
- <Text style={{ color: colors.textMuted, fontSize: 12 }} numberOfLines={1}>
648
- {p.path.replace(/^\/Users\/[^/]+/, "~")}
649
- </Text>
650
- </View>
651
- </Pressable>
652
- ))}
653
-
654
- {/* Custom path input */}
655
- <View style={{
656
- flexDirection: "row",
657
- alignItems: "center",
658
- borderTopWidth: 1,
659
- borderTopColor: colors.border,
660
- paddingHorizontal: 16,
661
- paddingVertical: 10,
662
- }}>
663
- <TextInput
664
- value={customPath}
665
- onChangeText={setCustomPath}
666
- placeholder="Custom path…"
667
- placeholderTextColor={colors.textMuted}
668
- autoCapitalize="none"
669
- autoCorrect={false}
670
- returnKeyType="go"
671
- onFocus={() => {
672
- setTimeout(() => pickerScrollRef.current?.scrollToEnd({ animated: true }), 100);
673
- }}
674
- onSubmitEditing={() => {
675
- if (customPath.trim()) launchSession({ path: customPath.trim() });
676
- }}
677
- style={{
678
- flex: 1,
679
- color: colors.text,
680
- fontSize: 15,
681
- paddingVertical: 6,
682
- }}
683
- />
684
- {customPath.trim().length > 0 && (
685
- <Pressable
686
- onPress={() => launchSession({ path: customPath.trim() })}
687
- style={{
688
- paddingHorizontal: 14,
689
- paddingVertical: 8,
690
- borderRadius: 8,
691
- backgroundColor: colors.accent,
692
- marginLeft: 8,
693
- }}
694
- >
695
- <Text style={{ color: "#FFF", fontSize: 14, fontWeight: "600" }}>Go</Text>
696
- </Pressable>
697
- )}
698
- </View>
699
- </ScrollView>
700
- )}
701
- </View>
702
-
703
- {/* Footer */}
704
- <View
705
- style={{
706
- paddingVertical: 8,
707
- paddingHorizontal: 20,
708
- borderTopWidth: 1,
709
- borderTopColor: colors.border,
710
- }}
711
- >
712
- <Text
713
- style={{
714
- color: colors.textMuted,
715
- fontSize: 11,
716
- textAlign: "center",
717
- }}
718
- >
719
- Tap to switch — Long press to rename — Swipe to remove
720
- </Text>
721
- </View>
722
- </GestureHandlerRootView>
723
- </Animated.View>
724
- </View>
725
- </View>
726
- );
727
-}
components/SessionPicker.tsx
deleted file mode 100644
....@@ -1,468 +0,0 @@
1
-import React, { useCallback, useEffect, useRef, useState } from "react";
2
-import {
3
- Animated,
4
- Keyboard,
5
- LayoutAnimation,
6
- Modal,
7
- Platform,
8
- Pressable,
9
- ScrollView,
10
- Text,
11
- TextInput,
12
- UIManager,
13
- View,
14
-} from "react-native";
15
-import {
16
- GestureHandlerRootView,
17
- PanGestureHandler,
18
- PanGestureHandlerGestureEvent,
19
- State,
20
- Swipeable,
21
-} from "react-native-gesture-handler";
22
-import * as Haptics from "expo-haptics";
23
-import { WsSession } from "../types";
24
-import { useChat } from "../contexts/ChatContext";
25
-
26
-if (
27
- Platform.OS === "android" &&
28
- UIManager.setLayoutAnimationEnabledExperimental
29
-) {
30
- UIManager.setLayoutAnimationEnabledExperimental(true);
31
-}
32
-
33
-interface SessionPickerProps {
34
- visible: boolean;
35
- onClose: () => void;
36
-}
37
-
38
-/* ── Swipeable row with delete action ── */
39
-
40
-function SessionRow({
41
- session,
42
- onSwitch,
43
- onLongPress,
44
- onDelete,
45
-}: {
46
- session: WsSession;
47
- onSwitch: () => void;
48
- onLongPress: () => void;
49
- onDelete: () => void;
50
-}) {
51
- const swipeRef = useRef<Swipeable>(null);
52
-
53
- const renderRightActions = (
54
- _progress: Animated.AnimatedInterpolation<number>,
55
- dragX: Animated.AnimatedInterpolation<number>,
56
- ) => {
57
- const scale = dragX.interpolate({
58
- inputRange: [-100, -50, 0],
59
- outputRange: [1, 0.8, 0],
60
- extrapolate: "clamp",
61
- });
62
-
63
- return (
64
- <Pressable
65
- onPress={() => {
66
- swipeRef.current?.close();
67
- onDelete();
68
- }}
69
- style={{
70
- backgroundColor: "#FF3B30",
71
- justifyContent: "center",
72
- alignItems: "center",
73
- width: 80,
74
- borderRadius: 16,
75
- marginLeft: 8,
76
- }}
77
- >
78
- <Animated.Text
79
- style={{
80
- color: "#FFF",
81
- fontSize: 14,
82
- fontWeight: "600",
83
- transform: [{ scale }],
84
- }}
85
- >
86
- Remove
87
- </Animated.Text>
88
- </Pressable>
89
- );
90
- };
91
-
92
- return (
93
- <Swipeable
94
- ref={swipeRef}
95
- renderRightActions={renderRightActions}
96
- rightThreshold={60}
97
- friction={2}
98
- overshootRight={false}
99
- >
100
- <Pressable
101
- onPress={onSwitch}
102
- onLongPress={onLongPress}
103
- delayLongPress={400}
104
- style={({ pressed }) => ({
105
- width: "100%",
106
- backgroundColor: pressed ? "#252538" : "#1E1E2E",
107
- borderRadius: 16,
108
- padding: 14,
109
- flexDirection: "row",
110
- alignItems: "center",
111
- borderWidth: session.isActive ? 2 : 1,
112
- borderColor: session.isActive ? "#4A9EFF" : "#2E2E45",
113
- })}
114
- >
115
- {/* Number badge */}
116
- <View
117
- style={{
118
- width: 32,
119
- height: 32,
120
- borderRadius: 16,
121
- backgroundColor: session.isActive ? "#4A9EFF" : "#252538",
122
- alignItems: "center",
123
- justifyContent: "center",
124
- marginRight: 12,
125
- }}
126
- >
127
- <Text
128
- style={{
129
- color: session.isActive ? "#FFF" : "#9898B0",
130
- fontSize: 14,
131
- fontWeight: "700",
132
- }}
133
- >
134
- {session.index}
135
- </Text>
136
- </View>
137
-
138
- {/* Session info */}
139
- <View style={{ flex: 1 }}>
140
- <Text
141
- style={{
142
- color: "#E8E8F0",
143
- fontSize: 16,
144
- fontWeight: "600",
145
- }}
146
- numberOfLines={1}
147
- >
148
- {session.name}
149
- </Text>
150
- <Text
151
- style={{
152
- color: "#5A5A78",
153
- fontSize: 11,
154
- marginTop: 1,
155
- }}
156
- >
157
- {session.kind === "api"
158
- ? "Headless"
159
- : session.kind === "visual"
160
- ? "Visual"
161
- : session.type === "terminal"
162
- ? "Terminal"
163
- : "Claude"}
164
- {session.isActive ? " — active" : ""}
165
- </Text>
166
- </View>
167
-
168
- {/* Active indicator */}
169
- {session.isActive && (
170
- <View
171
- style={{
172
- width: 8,
173
- height: 8,
174
- borderRadius: 4,
175
- backgroundColor: "#2ED573",
176
- }}
177
- />
178
- )}
179
- </Pressable>
180
- </Swipeable>
181
- );
182
-}
183
-
184
-/* ── Inline rename editor ── */
185
-
186
-function RenameEditor({
187
- name,
188
- onConfirm,
189
- onCancel,
190
-}: {
191
- name: string;
192
- onConfirm: (newName: string) => void;
193
- onCancel: () => void;
194
-}) {
195
- const [editName, setEditName] = useState(name);
196
-
197
- return (
198
- <View
199
- style={{
200
- backgroundColor: "#1E1E2E",
201
- borderRadius: 16,
202
- padding: 14,
203
- borderWidth: 2,
204
- borderColor: "#4A9EFF",
205
- }}
206
- >
207
- <TextInput
208
- value={editName}
209
- onChangeText={setEditName}
210
- autoFocus
211
- onSubmitEditing={() => onConfirm(editName.trim())}
212
- onBlur={onCancel}
213
- returnKeyType="done"
214
- style={{
215
- color: "#E8E8F0",
216
- fontSize: 16,
217
- fontWeight: "600",
218
- padding: 0,
219
- marginBottom: 10,
220
- }}
221
- placeholderTextColor="#5A5A78"
222
- placeholder="Session name..."
223
- />
224
- <View style={{ flexDirection: "row", gap: 8 }}>
225
- <Pressable
226
- onPress={() => onConfirm(editName.trim())}
227
- style={{
228
- flex: 1,
229
- backgroundColor: "#4A9EFF",
230
- borderRadius: 10,
231
- paddingVertical: 8,
232
- alignItems: "center",
233
- }}
234
- >
235
- <Text style={{ color: "#FFF", fontSize: 14, fontWeight: "600" }}>
236
- Save
237
- </Text>
238
- </Pressable>
239
- <Pressable
240
- onPress={onCancel}
241
- style={{
242
- flex: 1,
243
- backgroundColor: "#252538",
244
- borderRadius: 10,
245
- paddingVertical: 8,
246
- alignItems: "center",
247
- }}
248
- >
249
- <Text style={{ color: "#9898B0", fontSize: 14 }}>Cancel</Text>
250
- </Pressable>
251
- </View>
252
- </View>
253
- );
254
-}
255
-
256
-/* ── Main SessionPicker ── */
257
-
258
-export function SessionPicker({ visible, onClose }: SessionPickerProps) {
259
- const {
260
- sessions,
261
- requestSessions,
262
- switchSession,
263
- renameSession,
264
- removeSession,
265
- } = useChat();
266
- const [editingId, setEditingId] = useState<string | null>(null);
267
- const [keyboardHeight, setKeyboardHeight] = useState(0);
268
- const sessionScrollRef = useRef<ScrollView>(null);
269
-
270
- // Sort: active first, then by index
271
- const sortedSessions = [...sessions].sort((a, b) => {
272
- if (a.isActive && !b.isActive) return -1;
273
- if (!a.isActive && b.isActive) return 1;
274
- return a.index - b.index;
275
- });
276
-
277
- useEffect(() => {
278
- const showSub = Keyboard.addListener("keyboardWillShow", (e) =>
279
- setKeyboardHeight(e.endCoordinates.height),
280
- );
281
- const hideSub = Keyboard.addListener("keyboardWillHide", () =>
282
- setKeyboardHeight(0),
283
- );
284
- return () => {
285
- showSub.remove();
286
- hideSub.remove();
287
- };
288
- }, []);
289
-
290
- useEffect(() => {
291
- if (!visible) {
292
- setEditingId(null);
293
- } else {
294
- requestSessions();
295
- }
296
- }, [visible, requestSessions]);
297
-
298
- const handleClose = useCallback(() => {
299
- setEditingId(null);
300
- Keyboard.dismiss();
301
- onClose();
302
- }, [onClose]);
303
-
304
- const handleSwitch = useCallback(
305
- (session: WsSession) => {
306
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
307
- switchSession(session.id);
308
- handleClose();
309
- },
310
- [switchSession, handleClose],
311
- );
312
-
313
- const handleStartRename = useCallback((session: WsSession) => {
314
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
315
- setEditingId(session.id);
316
- // Scroll down after keyboard appears so the rename field is visible
317
- const idx = sortedSessions.findIndex(s => s.id === session.id);
318
- if (idx >= 0 && sessionScrollRef.current) {
319
- setTimeout(() => {
320
- sessionScrollRef.current?.scrollTo({ y: idx * 60, animated: true });
321
- }, 400);
322
- }
323
- }, [sortedSessions]);
324
-
325
- const handleConfirmRename = useCallback(
326
- (sessionId: string, newName: string) => {
327
- if (newName) {
328
- renameSession(sessionId, newName);
329
- }
330
- setEditingId(null);
331
- },
332
- [renameSession],
333
- );
334
-
335
- const handleRemove = useCallback(
336
- (session: WsSession) => {
337
- Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
338
- LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
339
- removeSession(session.id);
340
- },
341
- [removeSession],
342
- );
343
-
344
- return (
345
- <Modal
346
- visible={visible}
347
- animationType="slide"
348
- transparent
349
- onRequestClose={handleClose}
350
- >
351
- <GestureHandlerRootView style={{ flex: 1 }}>
352
- <View
353
- style={{
354
- flex: 1,
355
- backgroundColor: "rgba(0,0,0,0.6)",
356
- justifyContent: "flex-end",
357
- }}
358
- >
359
- <Pressable style={{ flex: 1 }} onPress={handleClose} />
360
- <View
361
- style={{
362
- backgroundColor: "#14141F",
363
- borderTopLeftRadius: 24,
364
- borderTopRightRadius: 24,
365
- maxHeight: "70%",
366
- paddingBottom: Math.max(40, keyboardHeight),
367
- }}
368
- >
369
- {/* Handle bar */}
370
- <View
371
- style={{ alignItems: "center", paddingTop: 12, paddingBottom: 8 }}
372
- >
373
- <View
374
- style={{
375
- width: 40,
376
- height: 4,
377
- borderRadius: 2,
378
- backgroundColor: "#2E2E45",
379
- }}
380
- />
381
- </View>
382
-
383
- {/* Header */}
384
- <View
385
- style={{
386
- flexDirection: "row",
387
- alignItems: "center",
388
- justifyContent: "space-between",
389
- paddingHorizontal: 20,
390
- paddingBottom: 12,
391
- }}
392
- >
393
- <Text
394
- style={{
395
- color: "#E8E8F0",
396
- fontSize: 20,
397
- fontWeight: "700",
398
- }}
399
- >
400
- Sessions
401
- </Text>
402
- <Pressable
403
- onPress={() => requestSessions()}
404
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
405
- style={({ pressed }) => ({
406
- paddingHorizontal: 12,
407
- paddingVertical: 6,
408
- borderRadius: 12,
409
- backgroundColor: pressed ? "#252538" : "#1E1E2E",
410
- })}
411
- >
412
- <Text style={{ color: "#9898B0", fontSize: 13 }}>Refresh</Text>
413
- </Pressable>
414
- </View>
415
-
416
- {/* Session list */}
417
- <ScrollView
418
- ref={sessionScrollRef}
419
- style={{ paddingHorizontal: 16 }}
420
- showsVerticalScrollIndicator={false}
421
- keyboardShouldPersistTaps="handled"
422
- >
423
- {sortedSessions.length === 0 ? (
424
- <View style={{ alignItems: "center", paddingVertical: 32 }}>
425
- <Text style={{ color: "#5A5A78", fontSize: 15 }}>
426
- No sessions found
427
- </Text>
428
- </View>
429
- ) : (
430
- sortedSessions.map((session) => (
431
- <View key={session.id} style={{ marginBottom: 6 }}>
432
- {editingId === session.id ? (
433
- <RenameEditor
434
- name={session.name}
435
- onConfirm={(name) =>
436
- handleConfirmRename(session.id, name)
437
- }
438
- onCancel={() => setEditingId(null)}
439
- />
440
- ) : (
441
- <SessionRow
442
- session={session}
443
- onSwitch={() => handleSwitch(session)}
444
- onLongPress={() => handleStartRename(session)}
445
- onDelete={() => handleRemove(session)}
446
- />
447
- )}
448
- </View>
449
- ))
450
- )}
451
-
452
- <Text
453
- style={{
454
- color: "#5A5A78",
455
- fontSize: 11,
456
- textAlign: "center",
457
- paddingVertical: 10,
458
- }}
459
- >
460
- Tap to switch — Long press to rename — Swipe left to remove
461
- </Text>
462
- </ScrollView>
463
- </View>
464
- </View>
465
- </GestureHandlerRootView>
466
- </Modal>
467
- );
468
-}
components/chat/CommandBar.tsx
deleted file mode 100644
....@@ -1,108 +0,0 @@
1
-import React, { useState } from "react";
2
-import { Pressable, Text, View } from "react-native";
3
-import * as Haptics from "expo-haptics";
4
-import { useTheme } from "../../contexts/ThemeContext";
5
-
6
-interface CommandBarProps {
7
- onScreenshot: () => void;
8
- onNavigate: () => void;
9
- onPhoto: () => void;
10
- onClear: () => void;
11
-}
12
-
13
-export function CommandBar({ onScreenshot, onNavigate, onPhoto, onClear }: CommandBarProps) {
14
- const { colors } = useTheme();
15
- return (
16
- <View
17
- style={{
18
- flexDirection: "row",
19
- paddingHorizontal: 12,
20
- paddingVertical: 6,
21
- gap: 8,
22
- }}
23
- >
24
- <CmdBtn icon="📸" label="Screen" onPress={onScreenshot} colors={colors} />
25
- <CmdBtn icon="🧭" label="Navigate" onPress={onNavigate} colors={colors} />
26
- <CmdBtn icon="📎" label="Photo" onPress={onPhoto} colors={colors} />
27
- <CmdBtn icon="🗑" label="Clear" onPress={onClear} colors={colors} />
28
- </View>
29
- );
30
-}
31
-
32
-interface TextModeCommandBarProps {
33
- onScreenshot: () => void;
34
- onNavigate: () => void;
35
- onPhoto: () => void;
36
- onHelp: () => void;
37
- onClear: () => void;
38
-}
39
-
40
-export function TextModeCommandBar({
41
- onScreenshot,
42
- onNavigate,
43
- onPhoto,
44
- onHelp,
45
- onClear,
46
-}: TextModeCommandBarProps) {
47
- const { colors } = useTheme();
48
- return (
49
- <View
50
- style={{
51
- flexDirection: "row",
52
- paddingHorizontal: 12,
53
- paddingVertical: 6,
54
- gap: 8,
55
- }}
56
- >
57
- <CmdBtn icon="📸" label="Screen" onPress={onScreenshot} colors={colors} />
58
- <CmdBtn icon="🧭" label="Navigate" onPress={onNavigate} colors={colors} />
59
- <CmdBtn icon="📎" label="Photo" onPress={onPhoto} colors={colors} />
60
- <CmdBtn icon="❓" label="Help" onPress={onHelp} colors={colors} />
61
- <CmdBtn icon="🗑" label="Clear" onPress={onClear} colors={colors} />
62
- </View>
63
- );
64
-}
65
-
66
-function CmdBtn({
67
- icon,
68
- label,
69
- onPress,
70
- colors,
71
-}: {
72
- icon: string;
73
- label: string;
74
- onPress: () => void;
75
- colors: ReturnType<typeof useTheme>["colors"];
76
-}) {
77
- const [pressed, setPressed] = useState(false);
78
-
79
- return (
80
- <View style={{ flex: 1 }}>
81
- <Pressable
82
- onPressIn={() => setPressed(true)}
83
- onPressOut={() => setPressed(false)}
84
- onPress={() => {
85
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
86
- onPress();
87
- }}
88
- >
89
- <View
90
- style={{
91
- height: 68,
92
- borderRadius: 16,
93
- alignItems: "center",
94
- justifyContent: "center",
95
- backgroundColor: pressed ? colors.accent : colors.bgTertiary,
96
- borderWidth: 1.5,
97
- borderColor: pressed ? colors.accent : colors.border,
98
- }}
99
- >
100
- <Text style={{ fontSize: 26, marginBottom: 2 }}>{icon}</Text>
101
- <Text style={{ color: colors.textSecondary, fontSize: 13, fontWeight: "700" }}>
102
- {label}
103
- </Text>
104
- </View>
105
- </Pressable>
106
- </View>
107
- );
108
-}
components/chat/ImageCaptionModal.tsx
deleted file mode 100644
....@@ -1,172 +0,0 @@
1
-import React, { useEffect, useRef, useState } from "react";
2
-import {
3
- Dimensions,
4
- FlatList,
5
- Image,
6
- KeyboardAvoidingView,
7
- Modal,
8
- Platform,
9
- Pressable,
10
- Text,
11
- TextInput,
12
- View,
13
-} from "react-native";
14
-import { useTheme } from "../../contexts/ThemeContext";
15
-
16
-interface ImageItem {
17
- uri: string;
18
-}
19
-
20
-interface ImageCaptionModalProps {
21
- visible: boolean;
22
- images: ImageItem[];
23
- onSend: (caption: string) => void;
24
- onCancel: () => void;
25
-}
26
-
27
-export function ImageCaptionModal({ visible, images, onSend, onCancel }: ImageCaptionModalProps) {
28
- const { colors } = useTheme();
29
- const [caption, setCaption] = useState("");
30
- const [selectedIndex, setSelectedIndex] = useState(0);
31
- const inputRef = useRef<TextInput>(null);
32
- const { width, height } = Dimensions.get("window");
33
-
34
- useEffect(() => {
35
- if (visible) {
36
- setCaption("");
37
- setSelectedIndex(0);
38
- setTimeout(() => inputRef.current?.focus(), 300);
39
- }
40
- }, [visible]);
41
-
42
- const handleSend = () => {
43
- onSend(caption.trim());
44
- setCaption("");
45
- };
46
-
47
- const currentImage = images[selectedIndex]?.uri ?? "";
48
- const isMultiple = images.length > 1;
49
-
50
- return (
51
- <Modal visible={visible} animationType="slide" transparent={false} onRequestClose={onCancel}>
52
- <View style={{ flex: 1, backgroundColor: "#000" }}>
53
- <KeyboardAvoidingView
54
- style={{ flex: 1 }}
55
- behavior={Platform.OS === "ios" ? "padding" : undefined}
56
- keyboardVerticalOffset={0}
57
- >
58
- {/* Top bar with cancel + count */}
59
- <View
60
- style={{
61
- paddingTop: 54,
62
- paddingHorizontal: 16,
63
- paddingBottom: 12,
64
- flexDirection: "row",
65
- alignItems: "center",
66
- justifyContent: "space-between",
67
- }}
68
- >
69
- <Pressable
70
- onPress={onCancel}
71
- hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
72
- style={{
73
- paddingHorizontal: 12,
74
- paddingVertical: 6,
75
- borderRadius: 16,
76
- backgroundColor: "rgba(255,255,255,0.15)",
77
- }}
78
- >
79
- <Text style={{ color: "#fff", fontSize: 16, fontWeight: "600" }}>Cancel</Text>
80
- </Pressable>
81
- {isMultiple && (
82
- <Text style={{ color: "rgba(255,255,255,0.6)", fontSize: 14 }}>
83
- {selectedIndex + 1} / {images.length}
84
- </Text>
85
- )}
86
- </View>
87
-
88
- {/* Image preview */}
89
- <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
90
- <Image
91
- source={{ uri: currentImage }}
92
- style={{ width, height: isMultiple ? height * 0.45 : height * 0.55 }}
93
- resizeMode="contain"
94
- />
95
- </View>
96
-
97
- {/* Thumbnail strip — only for multiple images */}
98
- {isMultiple && (
99
- <FlatList
100
- data={images}
101
- horizontal
102
- showsHorizontalScrollIndicator={false}
103
- keyExtractor={(_, i) => String(i)}
104
- contentContainerStyle={{ paddingHorizontal: 12, paddingVertical: 8, gap: 8 }}
105
- renderItem={({ item, index }) => (
106
- <Pressable onPress={() => setSelectedIndex(index)}>
107
- <Image
108
- source={{ uri: item.uri }}
109
- style={{
110
- width: 56,
111
- height: 56,
112
- borderRadius: 8,
113
- borderWidth: index === selectedIndex ? 2 : 0,
114
- borderColor: colors.accent,
115
- }}
116
- resizeMode="cover"
117
- />
118
- </Pressable>
119
- )}
120
- />
121
- )}
122
-
123
- {/* Caption input + send */}
124
- <View
125
- style={{
126
- flexDirection: "row",
127
- alignItems: "flex-end",
128
- paddingHorizontal: 12,
129
- paddingVertical: 10,
130
- paddingBottom: 34,
131
- gap: 8,
132
- }}
133
- >
134
- <TextInput
135
- ref={inputRef}
136
- value={caption}
137
- onChangeText={setCaption}
138
- placeholder="Add a caption..."
139
- placeholderTextColor="rgba(255,255,255,0.4)"
140
- multiline
141
- maxLength={2000}
142
- style={{
143
- flex: 1,
144
- backgroundColor: "rgba(255,255,255,0.12)",
145
- borderRadius: 20,
146
- paddingHorizontal: 16,
147
- paddingVertical: 10,
148
- maxHeight: 100,
149
- color: "#fff",
150
- fontSize: 16,
151
- }}
152
- />
153
- <Pressable
154
- onPress={handleSend}
155
- style={{
156
- width: 44,
157
- height: 44,
158
- borderRadius: 22,
159
- alignItems: "center",
160
- justifyContent: "center",
161
- backgroundColor: colors.accent,
162
- marginBottom: 1,
163
- }}
164
- >
165
- <Text style={{ fontSize: 20, fontWeight: "bold", color: "#fff" }}>{"\u2191"}</Text>
166
- </Pressable>
167
- </View>
168
- </KeyboardAvoidingView>
169
- </View>
170
- </Modal>
171
- );
172
-}
components/chat/ImageViewer.tsx
deleted file mode 100644
....@@ -1,184 +0,0 @@
1
-import React, { useCallback } from "react";
2
-import {
3
- Alert,
4
- Dimensions,
5
- Image,
6
- Modal,
7
- Pressable,
8
- ScrollView,
9
- Text,
10
- View,
11
-} from "react-native";
12
-import { cacheDirectory, writeAsStringAsync } from "expo-file-system/legacy";
13
-import * as Clipboard from "expo-clipboard";
14
-import * as Sharing from "expo-sharing";
15
-
16
-/** Apple-style share icon (square with upward arrow) */
17
-function ShareIcon({ size = 18, color = "#fff" }: { size?: number; color?: string }) {
18
- const boxSize = size * 0.7;
19
- const arrowWidth = 2;
20
- return (
21
- <View style={{ width: size, height: size, alignItems: "center", justifyContent: "flex-end" }}>
22
- {/* Arrow shaft + head */}
23
- <View
24
- style={{
25
- position: "absolute",
26
- top: 0,
27
- width: arrowWidth,
28
- height: size * 0.65,
29
- backgroundColor: color,
30
- borderRadius: 1,
31
- }}
32
- />
33
- <View
34
- style={{
35
- position: "absolute",
36
- top: 0,
37
- width: 0,
38
- height: 0,
39
- borderLeftWidth: size * 0.22,
40
- borderRightWidth: size * 0.22,
41
- borderBottomWidth: size * 0.25,
42
- borderLeftColor: "transparent",
43
- borderRightColor: "transparent",
44
- borderBottomColor: color,
45
- transform: [{ translateY: -size * 0.12 }],
46
- }}
47
- />
48
- {/* Open box (3 sides) */}
49
- <View
50
- style={{
51
- width: boxSize,
52
- height: boxSize * 0.7,
53
- borderWidth: arrowWidth,
54
- borderTopWidth: 0,
55
- borderColor: color,
56
- borderRadius: 2,
57
- }}
58
- />
59
- </View>
60
- );
61
-}
62
-
63
-interface ImageViewerProps {
64
- visible: boolean;
65
- imageBase64: string;
66
- onClose: () => void;
67
-}
68
-
69
-export function ImageViewer({ visible, imageBase64, onClose }: ImageViewerProps) {
70
- const { width, height } = Dimensions.get("window");
71
-
72
- const handleCopy = useCallback(async () => {
73
- try {
74
- await Clipboard.setImageAsync(imageBase64);
75
- } catch (err: any) {
76
- Alert.alert("Copy Error", err?.message ?? String(err));
77
- }
78
- }, [imageBase64]);
79
-
80
- const handleShare = useCallback(async () => {
81
- try {
82
- const fileUri = `${cacheDirectory}pailot-screenshot-${Date.now()}.png`;
83
- await writeAsStringAsync(fileUri, imageBase64, {
84
- encoding: "base64",
85
- });
86
- if (!(await Sharing.isAvailableAsync())) {
87
- Alert.alert("Sharing not available on this device");
88
- return;
89
- }
90
- await Sharing.shareAsync(fileUri, { mimeType: "image/png" });
91
- } catch (err: any) {
92
- if (err?.message?.includes("User did not share")) return;
93
- Alert.alert("Share Error", err?.message ?? String(err));
94
- }
95
- }, [imageBase64]);
96
-
97
- return (
98
- <Modal
99
- visible={visible}
100
- transparent
101
- animationType="fade"
102
- onRequestClose={onClose}
103
- >
104
- <View style={{ flex: 1, backgroundColor: "rgba(0,0,0,0.95)" }}>
105
- {/* Top bar: share + close */}
106
- <View
107
- style={{
108
- position: "absolute",
109
- top: 60,
110
- right: 20,
111
- zIndex: 10,
112
- flexDirection: "row",
113
- gap: 12,
114
- }}
115
- >
116
- <Pressable
117
- onPress={handleCopy}
118
- hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
119
- style={{
120
- width: 40,
121
- height: 40,
122
- borderRadius: 20,
123
- backgroundColor: "rgba(255,255,255,0.15)",
124
- alignItems: "center",
125
- justifyContent: "center",
126
- }}
127
- >
128
- <Text style={{ color: "#fff", fontSize: 18 }}>📋</Text>
129
- </Pressable>
130
- <Pressable
131
- onPress={handleShare}
132
- hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
133
- style={{
134
- width: 40,
135
- height: 40,
136
- borderRadius: 20,
137
- backgroundColor: "rgba(255,255,255,0.15)",
138
- alignItems: "center",
139
- justifyContent: "center",
140
- }}
141
- >
142
- <ShareIcon size={20} color="#fff" />
143
- </Pressable>
144
- <Pressable
145
- onPress={onClose}
146
- hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
147
- style={{
148
- width: 40,
149
- height: 40,
150
- borderRadius: 20,
151
- backgroundColor: "rgba(255,255,255,0.15)",
152
- alignItems: "center",
153
- justifyContent: "center",
154
- }}
155
- >
156
- <Text style={{ color: "#fff", fontSize: 20, fontWeight: "600" }}>
157
- ✕
158
- </Text>
159
- </Pressable>
160
- </View>
161
-
162
- {/* Zoomable image */}
163
- <ScrollView
164
- maximumZoomScale={5}
165
- minimumZoomScale={1}
166
- centerContent
167
- contentContainerStyle={{
168
- flex: 1,
169
- justifyContent: "center",
170
- alignItems: "center",
171
- }}
172
- showsVerticalScrollIndicator={false}
173
- showsHorizontalScrollIndicator={false}
174
- >
175
- <Image
176
- source={{ uri: `data:image/png;base64,${imageBase64}` }}
177
- style={{ width, height: height * 0.85 }}
178
- resizeMode="contain"
179
- />
180
- </ScrollView>
181
- </View>
182
- </Modal>
183
- );
184
-}
components/chat/InputBar.tsx
deleted file mode 100644
....@@ -1,200 +0,0 @@
1
-import React, { useCallback, useRef, useState } from "react";
2
-import {
3
- Keyboard,
4
- Pressable,
5
- Text,
6
- TextInput,
7
- View,
8
-} from "react-native";
9
-import * as Haptics from "expo-haptics";
10
-import { VoiceButton } from "./VoiceButton";
11
-import { useTheme } from "../../contexts/ThemeContext";
12
-
13
-interface InputBarProps {
14
- onSendText: (text: string) => void;
15
- onVoiceRecorded: (uri: string, durationMs?: number) => void;
16
- onReplay: () => void;
17
- isTextMode: boolean;
18
- onToggleMode: () => void;
19
- audioPlaying?: boolean;
20
-}
21
-
22
-export function InputBar({
23
- onSendText,
24
- onVoiceRecorded,
25
- onReplay,
26
- isTextMode,
27
- onToggleMode,
28
- audioPlaying = false,
29
-}: InputBarProps) {
30
- const [text, setText] = useState("");
31
- const inputRef = useRef<TextInput>(null);
32
- const { colors } = useTheme();
33
-
34
- const canSend = !!text.trim();
35
-
36
- const handleSend = useCallback(() => {
37
- const trimmed = text.trim();
38
- if (!trimmed) return;
39
- onSendText(trimmed);
40
- setText("");
41
- Keyboard.dismiss();
42
- }, [text, onSendText]);
43
-
44
- if (!isTextMode) {
45
- // Voice mode: [Replay] [Talk] [Aa]
46
- return (
47
- <View
48
- style={{
49
- flexDirection: "row",
50
- gap: 10,
51
- paddingHorizontal: 16,
52
- paddingVertical: 10,
53
- paddingBottom: 6,
54
- borderTopWidth: 1,
55
- borderTopColor: colors.border,
56
- alignItems: "center",
57
- }}
58
- >
59
- {/* Replay / Stop */}
60
- <Pressable
61
- onPress={() => {
62
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
63
- onReplay();
64
- }}
65
- >
66
- <View
67
- style={{
68
- width: 68,
69
- height: 68,
70
- borderRadius: 34,
71
- alignItems: "center",
72
- justifyContent: "center",
73
- backgroundColor: colors.bgTertiary,
74
- borderWidth: 1.5,
75
- borderColor: colors.border,
76
- }}
77
- >
78
- <Text style={{ fontSize: 24 }}>{audioPlaying ? "\u23F8" : "\u25B6"}</Text>
79
- <Text style={{ color: colors.textSecondary, fontSize: 10, marginTop: 1, fontWeight: "600" }}>
80
- {audioPlaying ? "Stop" : "Replay"}
81
- </Text>
82
- </View>
83
- </Pressable>
84
-
85
- {/* Talk button */}
86
- <View style={{ flex: 1, alignItems: "center" }}>
87
- <VoiceButton onVoiceRecorded={onVoiceRecorded} />
88
- </View>
89
-
90
- {/* Text mode toggle */}
91
- <Pressable
92
- onPress={() => {
93
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
94
- onToggleMode();
95
- setTimeout(() => inputRef.current?.focus(), 150);
96
- }}
97
- >
98
- <View
99
- style={{
100
- width: 68,
101
- height: 68,
102
- borderRadius: 34,
103
- alignItems: "center",
104
- justifyContent: "center",
105
- backgroundColor: colors.bgTertiary,
106
- borderWidth: 1.5,
107
- borderColor: colors.border,
108
- }}
109
- >
110
- <Text style={{ fontSize: 22, color: colors.textSecondary, fontWeight: "700" }}>Aa</Text>
111
- </View>
112
- </Pressable>
113
- </View>
114
- );
115
- }
116
-
117
- // Text mode: [Mic] [TextInput] [Send]
118
- return (
119
- <View
120
- style={{
121
- flexDirection: "row",
122
- gap: 8,
123
- paddingHorizontal: 12,
124
- paddingVertical: 8,
125
- borderTopWidth: 1,
126
- borderTopColor: colors.border,
127
- alignItems: "flex-end",
128
- }}
129
- >
130
- {/* Voice mode toggle */}
131
- <Pressable
132
- onPress={() => {
133
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
134
- Keyboard.dismiss();
135
- onToggleMode();
136
- }}
137
- style={{
138
- width: 40,
139
- height: 40,
140
- borderRadius: 20,
141
- alignItems: "center",
142
- justifyContent: "center",
143
- backgroundColor: colors.bgTertiary,
144
- marginBottom: 2,
145
- }}
146
- >
147
- <Text style={{ fontSize: 20 }}>{"\uD83C\uDFA4"}</Text>
148
- </Pressable>
149
-
150
- {/* Text input */}
151
- <TextInput
152
- ref={inputRef}
153
- value={text}
154
- onChangeText={setText}
155
- placeholder="Message PAI..."
156
- placeholderTextColor={colors.textMuted}
157
- multiline
158
- maxLength={2000}
159
- onSubmitEditing={handleSend}
160
- returnKeyType="send"
161
- blurOnSubmit
162
- style={{
163
- flex: 1,
164
- backgroundColor: colors.bgTertiary,
165
- borderRadius: 20,
166
- paddingHorizontal: 16,
167
- paddingVertical: 10,
168
- maxHeight: 120,
169
- color: colors.text,
170
- fontSize: 16,
171
- }}
172
- />
173
-
174
- {/* Send button */}
175
- <Pressable
176
- onPress={handleSend}
177
- disabled={!canSend}
178
- style={{
179
- width: 40,
180
- height: 40,
181
- borderRadius: 20,
182
- alignItems: "center",
183
- justifyContent: "center",
184
- marginBottom: 2,
185
- backgroundColor: canSend ? colors.accent : colors.bgTertiary,
186
- }}
187
- >
188
- <Text
189
- style={{
190
- fontSize: 18,
191
- fontWeight: "bold",
192
- color: canSend ? "#FFFFFF" : colors.textMuted,
193
- }}
194
- >
195
- {"\u2191"}
196
- </Text>
197
- </Pressable>
198
- </View>
199
- );
200
-}
components/chat/MessageBubble.tsx
deleted file mode 100644
....@@ -1,254 +0,0 @@
1
-import React, { useCallback, useEffect, useState } from "react";
2
-import { ActionSheetIOS, Alert, Image, Platform, Pressable, Text, View } from "react-native";
3
-import * as Clipboard from "expo-clipboard";
4
-import { Message } from "../../types";
5
-import { playSingle, stopPlayback, onPlayingChange } from "../../services/audio";
6
-import { ImageViewer } from "./ImageViewer";
7
-import { useTheme } from "../../contexts/ThemeContext";
8
-
9
-interface MessageBubbleProps {
10
- message: Message;
11
- onDelete?: (id: string) => void;
12
- onPlayVoice?: (id: string) => void;
13
-}
14
-
15
-function formatDuration(ms?: number): string | null {
16
- if (!ms || ms <= 0) return null;
17
- const totalSeconds = Math.floor(ms / 1000);
18
- const minutes = Math.floor(totalSeconds / 60);
19
- const seconds = totalSeconds % 60;
20
- return `${minutes}:${seconds.toString().padStart(2, "0")}`;
21
-}
22
-
23
-function formatTime(timestamp: number): string {
24
- const d = new Date(timestamp);
25
- return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
26
-}
27
-
28
-export function MessageBubble({ message, onDelete, onPlayVoice }: MessageBubbleProps) {
29
- const [isPlaying, setIsPlaying] = useState(false);
30
- const [showViewer, setShowViewer] = useState(false);
31
- const { colors, isDark } = useTheme();
32
-
33
- const handleLongPress = useCallback(() => {
34
- const hasText = !!message.content;
35
- if (Platform.OS === "ios") {
36
- const options = ["Cancel"];
37
- if (hasText) options.push("Copy");
38
- if (onDelete) options.push("Delete Message");
39
- const destructiveIndex = onDelete ? options.indexOf("Delete Message") : undefined;
40
-
41
- ActionSheetIOS.showActionSheetWithOptions(
42
- {
43
- options,
44
- destructiveButtonIndex: destructiveIndex,
45
- cancelButtonIndex: 0,
46
- },
47
- (index) => {
48
- const selected = options[index];
49
- if (selected === "Copy") Clipboard.setStringAsync(message.content ?? "");
50
- else if (selected === "Delete Message") onDelete?.(message.id);
51
- },
52
- );
53
- } else {
54
- const buttons: any[] = [{ text: "Cancel", style: "cancel" }];
55
- if (hasText) buttons.push({ text: "Copy", onPress: () => Clipboard.setStringAsync(message.content ?? "") });
56
- if (onDelete) buttons.push({ text: "Delete", style: "destructive", onPress: () => onDelete(message.id) });
57
- Alert.alert("Message", undefined, buttons);
58
- }
59
- }, [onDelete, message.id, message.content]);
60
-
61
- // Track whether THIS bubble's audio is playing via the singleton URI
62
- useEffect(() => {
63
- return onPlayingChange((uri) => {
64
- setIsPlaying(uri !== null && uri === message.audioUri);
65
- });
66
- }, [message.audioUri]);
67
-
68
- const isUser = message.role === "user";
69
- const isSystem = message.role === "system";
70
-
71
- const handleVoicePress = useCallback(async () => {
72
- if (!message.audioUri) return;
73
-
74
- if (isPlaying) {
75
- await stopPlayback();
76
- } else if (onPlayVoice) {
77
- // Let parent handle chain playback (plays this + subsequent chunks)
78
- onPlayVoice(message.id);
79
- } else {
80
- await playSingle(message.audioUri, () => {});
81
- }
82
- }, [isPlaying, message.audioUri, onPlayVoice, message.id]);
83
-
84
- if (isSystem) {
85
- return (
86
- <View style={{ alignItems: "center", marginVertical: 4, paddingHorizontal: 16 }}>
87
- <Text style={{ color: colors.textMuted, fontSize: 12 }}>{message.content}</Text>
88
- </View>
89
- );
90
- }
91
-
92
- const bubbleBg = isUser
93
- ? colors.accent
94
- : isDark ? "#252538" : colors.bgSecondary;
95
- const bubbleRadius = isUser
96
- ? { borderTopRightRadius: 4 }
97
- : { borderTopLeftRadius: 4 };
98
-
99
- return (
100
- <Pressable
101
- onLongPress={handleLongPress}
102
- delayLongPress={500}
103
- style={{
104
- flexDirection: "row",
105
- marginVertical: 4,
106
- paddingHorizontal: 12,
107
- justifyContent: isUser ? "flex-end" : "flex-start",
108
- }}
109
- >
110
- <View
111
- style={{
112
- maxWidth: "78%",
113
- borderRadius: 16,
114
- paddingHorizontal: 16,
115
- paddingVertical: 12,
116
- backgroundColor: bubbleBg,
117
- ...bubbleRadius,
118
- }}
119
- >
120
- {message.type === "image" && message.imageBase64 ? (
121
- <View>
122
- <Pressable onPress={() => setShowViewer(true)}>
123
- <Image
124
- source={{ uri: `data:image/png;base64,${message.imageBase64}` }}
125
- style={{
126
- width: 260,
127
- height: 180,
128
- borderRadius: 10,
129
- backgroundColor: colors.bgTertiary,
130
- }}
131
- resizeMode="contain"
132
- />
133
- </Pressable>
134
- {message.content ? (
135
- <Text
136
- style={{
137
- color: isUser ? "#FFF" : colors.textSecondary,
138
- fontSize: 12,
139
- marginTop: 4,
140
- }}
141
- >
142
- {message.content}
143
- </Text>
144
- ) : null}
145
- <ImageViewer
146
- visible={showViewer}
147
- imageBase64={message.imageBase64}
148
- onClose={() => setShowViewer(false)}
149
- />
150
- </View>
151
- ) : message.type === "voice" ? (
152
- <View>
153
- <Pressable
154
- onPress={handleVoicePress}
155
- style={{ flexDirection: "row", alignItems: "center", gap: 12 }}
156
- >
157
- <View
158
- style={{
159
- width: 36,
160
- height: 36,
161
- borderRadius: 18,
162
- alignItems: "center",
163
- justifyContent: "center",
164
- backgroundColor: isPlaying
165
- ? "#FF9F43"
166
- : isUser
167
- ? "rgba(255,255,255,0.2)"
168
- : colors.border,
169
- }}
170
- >
171
- <Text style={{ fontSize: 14, color: isUser ? "#FFF" : colors.text }}>
172
- {isPlaying ? "\u23F8" : "\u25B6"}
173
- </Text>
174
- </View>
175
-
176
- <View style={{ flex: 1, flexDirection: "row", alignItems: "center", gap: 1, height: 32 }}>
177
- {Array.from({ length: 20 }).map((_, i) => (
178
- <View
179
- key={i}
180
- style={{
181
- flex: 1,
182
- borderRadius: 2,
183
- backgroundColor: isPlaying && i < 10
184
- ? "#FF9F43"
185
- : isUser
186
- ? "rgba(255,255,255,0.5)"
187
- : colors.textMuted,
188
- height: `${20 + Math.sin(i * 0.8) * 60}%`,
189
- }}
190
- />
191
- ))}
192
- </View>
193
-
194
- {formatDuration(message.duration) && (
195
- <Text
196
- style={{
197
- fontSize: 11,
198
- color: isUser ? "rgba(255,255,255,0.8)" : colors.textSecondary,
199
- }}
200
- >
201
- {formatDuration(message.duration)}
202
- </Text>
203
- )}
204
- </Pressable>
205
- {message.content ? (
206
- <Text
207
- style={{
208
- fontSize: 14,
209
- lineHeight: 20,
210
- marginTop: 8,
211
- color: isUser ? "rgba(255,255,255,0.9)" : colors.textSecondary,
212
- }}
213
- >
214
- {message.content}
215
- </Text>
216
- ) : null}
217
- </View>
218
- ) : (
219
- <Text
220
- style={{
221
- fontSize: 16,
222
- lineHeight: 24,
223
- color: isUser ? "#FFF" : colors.text,
224
- }}
225
- >
226
- {message.content}
227
- </Text>
228
- )}
229
-
230
- <View
231
- style={{
232
- flexDirection: "row",
233
- alignItems: "center",
234
- marginTop: 4,
235
- gap: 4,
236
- justifyContent: isUser ? "flex-end" : "flex-start",
237
- }}
238
- >
239
- <Text
240
- style={{
241
- fontSize: 10,
242
- color: isUser ? "rgba(255,255,255,0.6)" : colors.textMuted,
243
- }}
244
- >
245
- {formatTime(message.timestamp)}
246
- </Text>
247
- {isUser && message.status === "error" && (
248
- <Text style={{ fontSize: 10, color: colors.danger }}> !</Text>
249
- )}
250
- </View>
251
- </View>
252
- </Pressable>
253
- );
254
-}
components/chat/MessageList.tsx
deleted file mode 100644
....@@ -1,75 +0,0 @@
1
-import React, { useCallback, useMemo } from "react";
2
-import { ActivityIndicator, FlatList, View } from "react-native";
3
-import { Message } from "../../types";
4
-import { MessageBubble } from "./MessageBubble";
5
-import { TypingIndicator } from "./TypingIndicator";
6
-import { stopPlayback, playAudio } from "../../services/audio";
7
-
8
-interface MessageListProps {
9
- messages: Message[];
10
- isTyping?: boolean;
11
- onDeleteMessage?: (id: string) => void;
12
- onLoadMore?: () => void;
13
- hasMore?: boolean;
14
-}
15
-
16
-export function MessageList({ messages, isTyping, onDeleteMessage, onLoadMore, hasMore }: MessageListProps) {
17
- // Inverted FlatList renders bottom-up — newest messages at the bottom (visually),
18
- // which means we reverse the data so index 0 = newest = rendered at bottom.
19
- const invertedData = useMemo(() => [...messages].reverse(), [messages]);
20
-
21
- // Play from a voice message and auto-chain all consecutive assistant voice messages after it
22
- const handlePlayVoice = useCallback(async (messageId: string) => {
23
- const idx = messages.findIndex((m) => m.id === messageId);
24
- if (idx === -1) return;
25
-
26
- const chain: Message[] = [];
27
- for (let i = idx; i < messages.length; i++) {
28
- const m = messages[i];
29
- if (m.role === "assistant" && m.type === "voice" && m.audioUri) {
30
- chain.push(m);
31
- } else if (i > idx) {
32
- break;
33
- }
34
- }
35
-
36
- if (chain.length === 0) return;
37
-
38
- await stopPlayback();
39
- for (const m of chain) {
40
- playAudio(m.audioUri!);
41
- }
42
- }, [messages]);
43
-
44
- return (
45
- <FlatList
46
- inverted
47
- data={invertedData}
48
- keyExtractor={(item) => item.id}
49
- renderItem={({ item }) => (
50
- <MessageBubble
51
- message={item}
52
- onDelete={onDeleteMessage}
53
- onPlayVoice={handlePlayVoice}
54
- />
55
- )}
56
- onEndReached={hasMore ? onLoadMore : undefined}
57
- onEndReachedThreshold={0.5}
58
- contentContainerStyle={{ paddingVertical: 12 }}
59
- showsVerticalScrollIndicator={false}
60
- ListHeaderComponent={
61
- <>
62
- {isTyping && <TypingIndicator />}
63
- <View style={{ height: 4 }} />
64
- </>
65
- }
66
- ListFooterComponent={
67
- hasMore ? (
68
- <View style={{ paddingVertical: 16, alignItems: "center" }}>
69
- <ActivityIndicator size="small" />
70
- </View>
71
- ) : null
72
- }
73
- />
74
- );
75
-}
components/chat/TypingIndicator.tsx
deleted file mode 100644
....@@ -1,78 +0,0 @@
1
-import React, { useEffect, useRef } from "react";
2
-import { Animated, View } from "react-native";
3
-import { useTheme } from "../../contexts/ThemeContext";
4
-
5
-export function TypingIndicator() {
6
- const { colors, isDark } = useTheme();
7
- const dot1 = useRef(new Animated.Value(0)).current;
8
- const dot2 = useRef(new Animated.Value(0)).current;
9
- const dot3 = useRef(new Animated.Value(0)).current;
10
-
11
- useEffect(() => {
12
- const animate = (dot: Animated.Value, delay: number) =>
13
- Animated.loop(
14
- Animated.sequence([
15
- Animated.delay(delay),
16
- Animated.timing(dot, { toValue: 1, duration: 300, useNativeDriver: true }),
17
- Animated.timing(dot, { toValue: 0, duration: 300, useNativeDriver: true }),
18
- ])
19
- );
20
-
21
- const a1 = animate(dot1, 0);
22
- const a2 = animate(dot2, 200);
23
- const a3 = animate(dot3, 400);
24
- a1.start();
25
- a2.start();
26
- a3.start();
27
-
28
- return () => { a1.stop(); a2.stop(); a3.stop(); };
29
- }, [dot1, dot2, dot3]);
30
-
31
- const bubbleBg = isDark ? "#252538" : colors.bgSecondary;
32
- const dotColor = colors.textMuted;
33
-
34
- return (
35
- <View
36
- style={{
37
- flexDirection: "row",
38
- marginVertical: 4,
39
- paddingHorizontal: 12,
40
- justifyContent: "flex-start",
41
- }}
42
- >
43
- <View
44
- style={{
45
- borderRadius: 16,
46
- borderTopLeftRadius: 4,
47
- paddingHorizontal: 16,
48
- paddingVertical: 14,
49
- backgroundColor: bubbleBg,
50
- flexDirection: "row",
51
- gap: 4,
52
- alignItems: "center",
53
- }}
54
- >
55
- {[dot1, dot2, dot3].map((dot, i) => (
56
- <Animated.View
57
- key={i}
58
- style={{
59
- width: 8,
60
- height: 8,
61
- borderRadius: 4,
62
- backgroundColor: dotColor,
63
- opacity: dot.interpolate({ inputRange: [0, 1], outputRange: [0.3, 1] }),
64
- transform: [
65
- {
66
- translateY: dot.interpolate({
67
- inputRange: [0, 1],
68
- outputRange: [0, -4],
69
- }),
70
- },
71
- ],
72
- }}
73
- />
74
- ))}
75
- </View>
76
- </View>
77
- );
78
-}
components/chat/VoiceButton.tsx
deleted file mode 100644
....@@ -1,191 +0,0 @@
1
-import React, { useCallback, useRef, useState } from "react";
2
-import { Animated, Pressable, Text, View } from "react-native";
3
-import * as Haptics from "expo-haptics";
4
-import {
5
- useAudioRecorder,
6
- RecordingPresets,
7
- requestRecordingPermissionsAsync,
8
- setAudioModeAsync,
9
-} from "expo-audio";
10
-import { stopPlayback } from "../../services/audio";
11
-
12
-interface VoiceButtonProps {
13
- onVoiceRecorded: (uri: string, durationMs?: number) => void;
14
-}
15
-
16
-const VOICE_BUTTON_SIZE = 72;
17
-
18
-/**
19
- * Tap-to-toggle voice button using expo-audio recording.
20
- * Records audio and returns the file URI for the caller to send.
21
- * - Tap once: start recording
22
- * - Tap again: stop and send
23
- * - Long-press while recording: cancel (discard)
24
- */
25
-export function VoiceButton({ onVoiceRecorded }: VoiceButtonProps) {
26
- const [isRecording, setIsRecording] = useState(false);
27
- const pulseAnim = useRef(new Animated.Value(1)).current;
28
- const glowAnim = useRef(new Animated.Value(0)).current;
29
- const pulseLoop = useRef<Animated.CompositeAnimation | null>(null);
30
-
31
- const recorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
32
-
33
- const startPulse = useCallback(() => {
34
- pulseLoop.current = Animated.loop(
35
- Animated.sequence([
36
- Animated.timing(pulseAnim, {
37
- toValue: 1.15,
38
- duration: 700,
39
- useNativeDriver: true,
40
- }),
41
- Animated.timing(pulseAnim, {
42
- toValue: 1,
43
- duration: 700,
44
- useNativeDriver: true,
45
- }),
46
- ])
47
- );
48
- pulseLoop.current.start();
49
- Animated.timing(glowAnim, {
50
- toValue: 1,
51
- duration: 300,
52
- useNativeDriver: true,
53
- }).start();
54
- }, [pulseAnim, glowAnim]);
55
-
56
- const stopPulse = useCallback(() => {
57
- pulseLoop.current?.stop();
58
- pulseAnim.setValue(1);
59
- Animated.timing(glowAnim, {
60
- toValue: 0,
61
- duration: 200,
62
- useNativeDriver: true,
63
- }).start();
64
- }, [pulseAnim, glowAnim]);
65
-
66
- const startRecording = useCallback(async () => {
67
- try {
68
- await stopPlayback();
69
-
70
- const { granted } = await requestRecordingPermissionsAsync();
71
- if (!granted) return;
72
-
73
- await setAudioModeAsync({
74
- allowsRecording: true,
75
- playsInSilentMode: true,
76
- });
77
-
78
- startPulse();
79
- await recorder.prepareToRecordAsync();
80
- recorder.record();
81
- setIsRecording(true);
82
- } catch (err) {
83
- console.error("Failed to start recording:", err);
84
- stopPulse();
85
- setIsRecording(false);
86
- }
87
- }, [recorder, startPulse, stopPulse]);
88
-
89
- const stopAndSend = useCallback(async () => {
90
- stopPulse();
91
- setIsRecording(false);
92
- try {
93
- await recorder.stop();
94
- // Reset audio mode for playback
95
- await setAudioModeAsync({
96
- allowsRecording: false,
97
- playsInSilentMode: true,
98
- });
99
- const uri = recorder.uri;
100
- if (uri) {
101
- // currentTime is in seconds after stop
102
- const durationMs = recorder.currentTime > 0
103
- ? Math.round(recorder.currentTime * 1000)
104
- : undefined;
105
- onVoiceRecorded(uri, durationMs);
106
- }
107
- } catch (err) {
108
- console.error("Failed to stop recording:", err);
109
- }
110
- }, [recorder, stopPulse, onVoiceRecorded]);
111
-
112
- const cancelRecording = useCallback(async () => {
113
- Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
114
- stopPulse();
115
- setIsRecording(false);
116
- try {
117
- await recorder.stop();
118
- } catch {
119
- // ignore
120
- }
121
- }, [recorder, stopPulse]);
122
-
123
- const handleTap = useCallback(async () => {
124
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
125
- if (isRecording) {
126
- await stopAndSend();
127
- } else {
128
- await startRecording();
129
- }
130
- }, [isRecording, stopAndSend, startRecording]);
131
-
132
- const handleLongPress = useCallback(() => {
133
- if (isRecording) {
134
- cancelRecording();
135
- }
136
- }, [isRecording, cancelRecording]);
137
-
138
- return (
139
- <View style={{ alignItems: "center", justifyContent: "center" }}>
140
- {/* Outer pulse ring */}
141
- <Animated.View
142
- style={{
143
- position: "absolute",
144
- width: VOICE_BUTTON_SIZE + 24,
145
- height: VOICE_BUTTON_SIZE + 24,
146
- borderRadius: (VOICE_BUTTON_SIZE + 24) / 2,
147
- backgroundColor: isRecording ? "rgba(255, 159, 67, 0.12)" : "transparent",
148
- transform: [{ scale: pulseAnim }],
149
- opacity: glowAnim,
150
- }}
151
- />
152
-
153
- {/* Button */}
154
- <Pressable
155
- onPress={handleTap}
156
- onLongPress={handleLongPress}
157
- delayLongPress={600}
158
- >
159
- <View
160
- style={{
161
- width: VOICE_BUTTON_SIZE,
162
- height: VOICE_BUTTON_SIZE,
163
- borderRadius: VOICE_BUTTON_SIZE / 2,
164
- backgroundColor: isRecording ? "#FF9F43" : "#4A9EFF",
165
- alignItems: "center",
166
- justifyContent: "center",
167
- shadowColor: isRecording ? "#FF9F43" : "#4A9EFF",
168
- shadowOffset: { width: 0, height: 4 },
169
- shadowOpacity: 0.4,
170
- shadowRadius: 12,
171
- elevation: 8,
172
- }}
173
- >
174
- <Text style={{ fontSize: 28 }}>{isRecording ? "⏹" : "🎤"}</Text>
175
- </View>
176
- </Pressable>
177
-
178
- {/* Label */}
179
- <Text
180
- style={{
181
- color: isRecording ? "#FF9F43" : "#5A5A78",
182
- fontSize: 11,
183
- marginTop: 4,
184
- fontWeight: isRecording ? "600" : "400",
185
- }}
186
- >
187
- {isRecording ? "Recording..." : "Tap to talk"}
188
- </Text>
189
- </View>
190
- );
191
-}
components/ui/IconButton.tsx
deleted file mode 100644
....@@ -1,30 +0,0 @@
1
-import React from "react";
2
-import { Pressable, Text, ViewStyle } from "react-native";
3
-import { useTheme } from "../../contexts/ThemeContext";
4
-
5
-interface IconButtonProps {
6
- onPress: () => void;
7
- label: string;
8
- size?: number;
9
- style?: ViewStyle;
10
-}
11
-
12
-export function IconButton({
13
- onPress,
14
- label,
15
- size = 24,
16
-}: IconButtonProps) {
17
- const { colors } = useTheme();
18
-
19
- return (
20
- <Pressable
21
- onPress={onPress}
22
- style={{ width: size, height: size, alignItems: "center", justifyContent: "center" }}
23
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
24
- >
25
- <Text style={{ color: colors.textSecondary, fontSize: size * 0.7 }}>
26
- {label}
27
- </Text>
28
- </Pressable>
29
- );
30
-}
components/ui/IncomingToast.tsx
deleted file mode 100644
....@@ -1,89 +0,0 @@
1
-import React, { useEffect, useRef } from "react";
2
-import { Animated, Pressable, Text, View } from "react-native";
3
-import { useTheme } from "../../contexts/ThemeContext";
4
-
5
-interface IncomingToastProps {
6
- sessionName: string;
7
- preview: string;
8
- onTap: () => void;
9
- onDismiss: () => void;
10
-}
11
-
12
-const DISPLAY_MS = 4000;
13
-
14
-export function IncomingToast({ sessionName, preview, onTap, onDismiss }: IncomingToastProps) {
15
- const { colors } = useTheme();
16
- const translateY = useRef(new Animated.Value(-60)).current;
17
-
18
- useEffect(() => {
19
- // Slide in from above (no opacity — keeps background solid)
20
- Animated.spring(translateY, {
21
- toValue: 0,
22
- useNativeDriver: true,
23
- tension: 80,
24
- friction: 10,
25
- }).start();
26
-
27
- // Auto-dismiss
28
- const timer = setTimeout(() => {
29
- Animated.timing(translateY, {
30
- toValue: -60,
31
- duration: 200,
32
- useNativeDriver: true,
33
- }).start(() => onDismiss());
34
- }, DISPLAY_MS);
35
-
36
- return () => clearTimeout(timer);
37
- }, []);
38
-
39
- return (
40
- <Animated.View
41
- style={{
42
- position: "absolute",
43
- top: 4,
44
- left: 12,
45
- right: 12,
46
- zIndex: 100,
47
- transform: [{ translateY }],
48
- }}
49
- >
50
- <Pressable
51
- onPress={onTap}
52
- style={({ pressed }) => ({
53
- flexDirection: "row",
54
- alignItems: "center",
55
- gap: 10,
56
- paddingHorizontal: 14,
57
- paddingVertical: 10,
58
- borderRadius: 12,
59
- backgroundColor: pressed ? colors.bgTertiary : colors.bgSecondary,
60
- borderWidth: 1,
61
- borderColor: colors.accent,
62
- shadowColor: "#000",
63
- shadowOffset: { width: 0, height: 4 },
64
- shadowOpacity: 0.4,
65
- shadowRadius: 8,
66
- elevation: 8,
67
- })}
68
- >
69
- <View
70
- style={{
71
- width: 10,
72
- height: 10,
73
- borderRadius: 5,
74
- backgroundColor: colors.accent,
75
- }}
76
- />
77
- <View style={{ flex: 1 }}>
78
- <Text style={{ color: colors.text, fontSize: 14, fontWeight: "700" }} numberOfLines={1}>
79
- {sessionName}
80
- </Text>
81
- <Text style={{ color: colors.textMuted, fontSize: 12, marginTop: 2 }} numberOfLines={1}>
82
- {preview}
83
- </Text>
84
- </View>
85
- <Text style={{ color: colors.accent, fontSize: 11, fontWeight: "600" }}>switch</Text>
86
- </Pressable>
87
- </Animated.View>
88
- );
89
-}
components/ui/StatusDot.tsx
deleted file mode 100644
....@@ -1,26 +0,0 @@
1
-import React from "react";
2
-import { View } from "react-native";
3
-import { ConnectionStatus } from "../../types";
4
-
5
-interface StatusDotProps {
6
- status: ConnectionStatus;
7
- size?: number;
8
-}
9
-
10
-export function StatusDot({ status, size = 10 }: StatusDotProps) {
11
- const color =
12
- status === "connected"
13
- ? "#22c55e"
14
- : status === "compacting"
15
- ? "#3b82f6"
16
- : status === "connecting" || status === "reconnecting"
17
- ? "#eab308"
18
- : "#ef4444";
19
-
20
- return (
21
- <View
22
- className="rounded-full"
23
- style={{ width: size, height: size, backgroundColor: color }}
24
- />
25
- );
26
-}
contexts/ChatContext.tsx
deleted file mode 100644
....@@ -1,723 +0,0 @@
1
-import React, {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useEffect,
6
- useRef,
7
- useState,
8
-} from "react";
9
-import { AppState, AppStateStatus } from "react-native";
10
-import { Message, WsIncoming, WsSession, PaiProject } from "../types";
11
-import { useConnection } from "./ConnectionContext";
12
-import { playAudio, encodeAudioToBase64, saveBase64Audio, canAutoplay } from "../services/audio";
13
-import { requestNotificationPermissions, notifyIncomingMessage } from "../services/notifications";
14
-
15
-function generateId(): string {
16
- return Date.now().toString(36) + Math.random().toString(36).slice(2);
17
-}
18
-
19
-// --- Message persistence ---
20
-// Lazily import expo-file-system/legacy so a missing native module doesn't crash the app.
21
-
22
-let _fsReady: Promise<typeof import("expo-file-system/legacy")> | null = null;
23
-function getFs() {
24
- if (!_fsReady) _fsReady = import("expo-file-system/legacy");
25
- return _fsReady;
26
-}
27
-
28
-const MESSAGES_DIR = "pailot-messages";
29
-
30
-/** Strip heavy fields (base64 images, audio URIs) before persisting.
31
- * Voice messages keep their content (transcript) but lose audioUri
32
- * since cache files won't survive app restarts. */
33
-function lightMessage(m: Message): Message {
34
- const light = { ...m };
35
- if (light.imageBase64) light.imageBase64 = undefined;
36
- if (light.audioUri) light.audioUri = undefined;
37
- return light;
38
-}
39
-
40
-async function persistMessages(map: Record<string, Message[]>): Promise<void> {
41
- try {
42
- const fs = await getFs();
43
- const dir = `${fs.documentDirectory}${MESSAGES_DIR}/`;
44
- const dirInfo = await fs.getInfoAsync(dir);
45
- if (!dirInfo.exists) await fs.makeDirectoryAsync(dir, { intermediates: true });
46
- // Save each session's messages
47
- for (const [sessionId, msgs] of Object.entries(map)) {
48
- if (msgs.length === 0) continue;
49
- const light = msgs.map(lightMessage);
50
- await fs.writeAsStringAsync(`${dir}${sessionId}.json`, JSON.stringify(light));
51
- }
52
- } catch {
53
- // Persistence is best-effort
54
- }
55
-}
56
-
57
-async function loadMessages(): Promise<Record<string, Message[]>> {
58
- try {
59
- const fs = await getFs();
60
- const dir = `${fs.documentDirectory}${MESSAGES_DIR}/`;
61
- const dirInfo = await fs.getInfoAsync(dir);
62
- if (!dirInfo.exists) return {};
63
- const files = await fs.readDirectoryAsync(dir);
64
- const result: Record<string, Message[]> = {};
65
- for (const file of files) {
66
- if (!file.endsWith(".json")) continue;
67
- const sessionId = file.replace(".json", "");
68
- const content = await fs.readAsStringAsync(`${dir}${file}`);
69
- result[sessionId] = (JSON.parse(content) as Message[])
70
- // Drop voice messages with no audio and no content (empty chunks)
71
- .filter((m) => !(m.type === "voice" && !m.audioUri && !m.content))
72
- .map((m) => {
73
- // Voice messages without audio but with transcript → show as text
74
- if (m.type === "voice" && !m.audioUri && m.content) {
75
- return { ...m, type: "text" };
76
- }
77
- return m;
78
- });
79
- }
80
- return result;
81
- } catch {
82
- return {};
83
- }
84
-}
85
-
86
-async function deletePersistedSession(sessionId: string): Promise<void> {
87
- try {
88
- const fs = await getFs();
89
- const path = `${fs.documentDirectory}${MESSAGES_DIR}/${sessionId}.json`;
90
- const info = await fs.getInfoAsync(path);
91
- if (info.exists) await fs.deleteAsync(path);
92
- } catch {
93
- // Best-effort
94
- }
95
-}
96
-
97
-async function clearPersistedMessages(sessionId: string): Promise<void> {
98
- try {
99
- const fs = await getFs();
100
- await fs.writeAsStringAsync(
101
- `${fs.documentDirectory}${MESSAGES_DIR}/${sessionId}.json`,
102
- "[]"
103
- );
104
- } catch {
105
- // Best-effort
106
- }
107
-}
108
-
109
-// --- Debounced save ---
110
-let saveTimer: ReturnType<typeof setTimeout> | null = null;
111
-function debouncedSave(map: Record<string, Message[]>): void {
112
- if (saveTimer) clearTimeout(saveTimer);
113
- saveTimer = setTimeout(() => persistMessages(map), 1000);
114
-}
115
-
116
-const PAGE_SIZE = 50;
117
-
118
-// --- Context ---
119
-
120
-interface IncomingToast {
121
- sessionId: string;
122
- sessionName: string;
123
- preview: string;
124
-}
125
-
126
-interface ChatContextValue {
127
- messages: Message[];
128
- sendTextMessage: (text: string) => void;
129
- sendVoiceMessage: (audioUri: string, durationMs?: number) => void;
130
- sendImageMessage: (imageBase64: string, caption: string, mimeType: string) => void;
131
- deleteMessage: (id: string) => void;
132
- clearMessages: () => void;
133
- isTyping: boolean;
134
- sessions: WsSession[];
135
- activeSessionId: string | null;
136
- requestSessions: () => void;
137
- switchSession: (sessionId: string) => void;
138
- renameSession: (sessionId: string, name: string) => void;
139
- removeSession: (sessionId: string) => void;
140
- createSession: (opts?: { project?: string; path?: string }) => void;
141
- fetchProjects: () => void;
142
- projects: PaiProject[];
143
- loadMoreMessages: () => void;
144
- hasMoreMessages: boolean;
145
- unreadCounts: Record<string, number>;
146
- unreadSessions: Set<string>;
147
- incomingToast: IncomingToast | null;
148
- dismissToast: () => void;
149
- latestScreenshot: string | null;
150
- requestScreenshot: () => void;
151
- sendNavKey: (key: string) => void;
152
-}
153
-
154
-const ChatContext = createContext<ChatContextValue | null>(null);
155
-
156
-export function ChatProvider({ children }: { children: React.ReactNode }) {
157
- const [sessions, setSessions] = useState<WsSession[]>([]);
158
- const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
159
- const activeSessionIdRef = useRef<string | null>(null);
160
- const [latestScreenshot, setLatestScreenshot] = useState<string | null>(null);
161
- const needsSync = useRef(true);
162
-
163
- // Sequence tracking for catch_up protocol
164
- const lastSeqRef = useRef(0);
165
- const seenSeqsRef = useRef(new Set<number>());
166
-
167
- // Per-session message storage
168
- const messagesMapRef = useRef<Record<string, Message[]>>({});
169
- // Messages for the active session (drives re-renders)
170
- const [messages, setMessages] = useState<Message[]>([]);
171
- // Unread counts for non-active sessions
172
- const [unreadCounts, setUnreadCounts] = useState<Record<string, number>>({});
173
- // Server-pushed unread indicators (sessions with new activity since last viewed)
174
- const [unreadSessions, setUnreadSessions] = useState<Set<string>>(new Set());
175
- // Per-session typing indicator (sessionId → boolean)
176
- const typingMapRef = useRef<Record<string, boolean>>({});
177
- const [isTyping, setIsTyping] = useState(false);
178
- // Toast queue for other-session incoming messages (show one at a time)
179
- const toastQueueRef = useRef<{ sessionId: string; sessionName: string; preview: string }[]>([]);
180
- const [incomingToast, setIncomingToast] = useState<{ sessionId: string; sessionName: string; preview: string } | null>(null);
181
- // PAI projects list
182
- const [projects, setProjects] = useState<PaiProject[]>([]);
183
- // Pagination: does the active session have more messages in storage?
184
- const [hasMoreMessages, setHasMoreMessages] = useState(false);
185
-
186
- const {
187
- status,
188
- sendTextMessage: wsSend,
189
- sendVoiceMessage: wsVoice,
190
- sendImageMessage: wsImageSend,
191
- sendCommand,
192
- onMessageReceived,
193
- } = useConnection();
194
-
195
- // Restore persisted messages on mount + request notification permissions
196
- useEffect(() => {
197
- loadMessages().then((loaded) => {
198
- if (Object.keys(loaded).length > 0) {
199
- messagesMapRef.current = loaded;
200
- }
201
- });
202
- requestNotificationPermissions();
203
- }, []);
204
-
205
- // Derive active session ID from sessions list when it arrives
206
- const syncActiveFromSessions = useCallback((incoming: WsSession[]) => {
207
- const active = incoming.find((s) => s.isActive);
208
- if (active) {
209
- setActiveSessionId((prev) => {
210
- if (prev !== active.id) {
211
- // No need to save prev — messagesMapRef is kept in sync by all mutators
212
- const all = messagesMapRef.current[active.id] ?? [];
213
- const page = all.length > PAGE_SIZE ? all.slice(-PAGE_SIZE) : all;
214
- setMessages(page);
215
- setHasMoreMessages(all.length > PAGE_SIZE);
216
- setUnreadCounts((u) => {
217
- if (!u[active.id]) return u;
218
- const next = { ...u };
219
- delete next[active.id];
220
- return next;
221
- });
222
- setUnreadSessions((prev) => {
223
- if (!prev.has(active.id)) return prev;
224
- const next = new Set(prev);
225
- next.delete(active.id);
226
- return next;
227
- });
228
- // Sync typing indicator for the new active session
229
- const activeTyping = typingMapRef.current[active.id] ?? false;
230
- setIsTyping(activeTyping);
231
- }
232
- activeSessionIdRef.current = active.id;
233
- return active.id;
234
- });
235
- }
236
- }, []);
237
-
238
- // On connect: ask gateway to sync sessions, then request catch_up for missed messages.
239
- useEffect(() => {
240
- if (status === "connected") {
241
- needsSync.current = true;
242
- const id = activeSessionIdRef.current;
243
- sendCommand("sync", id ? { activeSessionId: id } : undefined);
244
- // Request any messages we missed while disconnected/backgrounded
245
- sendCommand("catch_up", { lastSeq: lastSeqRef.current });
246
- } else if (status === "disconnected") {
247
- setIsTyping(false);
248
- }
249
- // eslint-disable-next-line react-hooks/exhaustive-deps — only fire on status change
250
- }, [status, sendCommand]);
251
-
252
- // On foreground resume: request catch_up for any messages missed while backgrounded.
253
- // iOS keeps the WebSocket "open" at TCP level but suspends the app — messages sent
254
- // during that time are lost. catch_up replays them from the server's message log.
255
- useEffect(() => {
256
- let lastState: AppStateStatus = AppState.currentState;
257
- const sub = AppState.addEventListener("change", (nextState) => {
258
- if (lastState.match(/inactive|background/) && nextState === "active") {
259
- if (status === "connected") {
260
- sendCommand("catch_up", { lastSeq: lastSeqRef.current });
261
- }
262
- }
263
- lastState = nextState;
264
- });
265
- return () => sub.remove();
266
- }, [status, sendCommand]);
267
-
268
- // Helper: add a message to the active session
269
- const addMessageToActive = useCallback((msg: Message) => {
270
- setMessages((prev) => {
271
- const next = [...prev, msg];
272
- const id = activeSessionIdRef.current;
273
- if (id) {
274
- messagesMapRef.current[id] = next;
275
- debouncedSave(messagesMapRef.current);
276
- }
277
- return next;
278
- });
279
- }, []);
280
-
281
- // Helper: add a message to a specific session (may not be active)
282
- const addMessageToSession = useCallback((sessionId: string, msg: Message) => {
283
- const currentActive = activeSessionIdRef.current;
284
- if (sessionId === currentActive) {
285
- setMessages((prev) => {
286
- const next = [...prev, msg];
287
- messagesMapRef.current[sessionId] = next;
288
- debouncedSave(messagesMapRef.current);
289
- return next;
290
- });
291
- } else {
292
- const existing = messagesMapRef.current[sessionId] ?? [];
293
- messagesMapRef.current[sessionId] = [...existing, msg];
294
- debouncedSave(messagesMapRef.current);
295
- setUnreadCounts((u) => ({
296
- ...u,
297
- [sessionId]: (u[sessionId] ?? 0) + 1,
298
- }));
299
- // Queue toast for other-session messages (assistant only, skip system noise)
300
- if (msg.role === "assistant") {
301
- setSessions((prev) => {
302
- const session = prev.find((s) => s.id === sessionId);
303
- const name = session?.name ?? sessionId.slice(0, 8);
304
- const preview = msg.type === "voice" ? "🎤 Voice note" : msg.type === "image" ? "📷 Image" : (msg.content ?? "").slice(0, 60);
305
- const toast = { sessionId, sessionName: name, preview };
306
- // If no toast is showing, show immediately; otherwise queue
307
- setIncomingToast((current) => {
308
- if (current === null) return toast;
309
- toastQueueRef.current.push(toast);
310
- return current;
311
- });
312
- return prev;
313
- });
314
- }
315
- }
316
- }, []);
317
-
318
- const updateMessageStatus = useCallback(
319
- (id: string, status: Message["status"]) => {
320
- setMessages((prev) =>
321
- prev.map((m) => (m.id === id ? { ...m, status } : m))
322
- );
323
- },
324
- []
325
- );
326
-
327
- // Update a message's content (e.g., voice transcript reflection)
328
- const updateMessageContent = useCallback((id: string, content: string) => {
329
- setMessages((prev) => {
330
- const next = prev.map((m) =>
331
- m.id === id ? { ...m, content } : m
332
- );
333
- const sessId = activeSessionIdRef.current;
334
- if (sessId) {
335
- messagesMapRef.current[sessId] = next;
336
- debouncedSave(messagesMapRef.current);
337
- }
338
- return next;
339
- });
340
- }, []);
341
-
342
- // Process a single incoming message (used by both live delivery and catch_up replay)
343
- const processIncoming = useCallback(async (data: WsIncoming, isCatchUp = false) => {
344
- // Dedup by seq: if we've seen this seq before, skip it
345
- const seq = (data as any).seq as number | undefined;
346
- if (seq) {
347
- if (seenSeqsRef.current.has(seq)) return;
348
- seenSeqsRef.current.add(seq);
349
- lastSeqRef.current = Math.max(lastSeqRef.current, seq);
350
- // Keep seen set bounded (last 500 seqs)
351
- if (seenSeqsRef.current.size > 500) {
352
- const arr = Array.from(seenSeqsRef.current).sort((a, b) => a - b);
353
- seenSeqsRef.current = new Set(arr.slice(-300));
354
- }
355
- }
356
-
357
- switch (data.type) {
358
- case "text": {
359
- if (!isCatchUp) setIsTyping(false);
360
- const msg: Message = {
361
- id: generateId(),
362
- role: "assistant",
363
- type: "text",
364
- content: data.content,
365
- timestamp: Date.now(),
366
- status: "sent",
367
- };
368
- if (data.sessionId) {
369
- addMessageToSession(data.sessionId, msg);
370
- } else {
371
- addMessageToActive(msg);
372
- }
373
- if (!isCatchUp) notifyIncomingMessage("PAILot", data.content ?? "New message");
374
- break;
375
- }
376
- case "voice": {
377
- if (!isCatchUp) setIsTyping(false);
378
- let audioUri: string | undefined;
379
- if (data.audioBase64) {
380
- try {
381
- audioUri = await saveBase64Audio(data.audioBase64);
382
- } catch {
383
- // fallback: no playable audio
384
- }
385
- }
386
- const msg: Message = {
387
- id: generateId(),
388
- role: "assistant",
389
- type: "voice",
390
- content: data.content ?? "",
391
- audioUri,
392
- timestamp: Date.now(),
393
- status: "sent",
394
- };
395
- const isForActive = !data.sessionId || data.sessionId === activeSessionIdRef.current;
396
- if (data.sessionId) {
397
- addMessageToSession(data.sessionId, msg);
398
- } else {
399
- addMessageToActive(msg);
400
- }
401
- if (!isCatchUp) notifyIncomingMessage("PAILot", data.content ?? "Voice message");
402
- // Only autoplay if live (not catch_up) and for the currently viewed session
403
- if (!isCatchUp && msg.audioUri && canAutoplay() && isForActive) {
404
- playAudio(msg.audioUri).catch(() => {});
405
- }
406
- break;
407
- }
408
- case "image": {
409
- setLatestScreenshot(data.imageBase64);
410
- const msg: Message = {
411
- id: generateId(),
412
- role: "assistant",
413
- type: "image",
414
- content: data.caption ?? "Screenshot",
415
- imageBase64: data.imageBase64,
416
- timestamp: Date.now(),
417
- status: "sent",
418
- };
419
- if (data.sessionId) {
420
- addMessageToSession(data.sessionId, msg);
421
- } else {
422
- addMessageToActive(msg);
423
- }
424
- if (!isCatchUp) notifyIncomingMessage("PAILot", data.caption ?? "New image");
425
- break;
426
- }
427
- case "sessions": {
428
- const incoming = data.sessions as WsSession[];
429
- setSessions(incoming);
430
- syncActiveFromSessions(incoming);
431
- needsSync.current = false;
432
- break;
433
- }
434
- case "session_switched": {
435
- sendCommand("sessions");
436
- break;
437
- }
438
- case "session_renamed": {
439
- sendCommand("sessions");
440
- break;
441
- }
442
- case "transcript": {
443
- updateMessageContent(data.messageId, data.content);
444
- break;
445
- }
446
- case "typing": {
447
- const typingSession = (data.sessionId as string) || activeSessionIdRef.current || "_global";
448
- typingMapRef.current[typingSession] = !!data.typing;
449
- const activeTyping = typingMapRef.current[activeSessionIdRef.current ?? ""] ?? false;
450
- setIsTyping(activeTyping);
451
- break;
452
- }
453
- case "status": {
454
- break;
455
- }
456
- case "projects": {
457
- setProjects(data.projects ?? []);
458
- break;
459
- }
460
- case "unread": {
461
- const targetId = data.sessionId as string;
462
- if (targetId && targetId !== activeSessionIdRef.current) {
463
- setUnreadSessions((prev) => {
464
- if (prev.has(targetId)) return prev;
465
- const next = new Set(prev);
466
- next.add(targetId);
467
- return next;
468
- });
469
- }
470
- break;
471
- }
472
- case "error": {
473
- const errMsg: Message = {
474
- id: generateId(),
475
- role: "system",
476
- type: "text",
477
- content: data.message,
478
- timestamp: Date.now(),
479
- };
480
- addMessageToActive(errMsg);
481
- break;
482
- }
483
- }
484
- }, [addMessageToActive, addMessageToSession, sendCommand, syncActiveFromSessions, updateMessageContent]);
485
-
486
- // Handle incoming WebSocket messages
487
- useEffect(() => {
488
- onMessageReceived.current = async (data: WsIncoming) => {
489
- // Handle catch_up response: replay all missed messages
490
- if (data.type === "catch_up") {
491
- const messages = (data as any).messages as WsIncoming[];
492
- const serverSeq = (data as any).serverSeq as number | undefined;
493
- if (serverSeq) lastSeqRef.current = Math.max(lastSeqRef.current, serverSeq);
494
- if (messages && messages.length > 0) {
495
- for (const msg of messages) {
496
- await processIncoming(msg, true);
497
- }
498
- }
499
- return;
500
- }
501
- // Live message — process normally
502
- await processIncoming(data);
503
- };
504
-
505
- return () => {
506
- onMessageReceived.current = null;
507
- };
508
- }, [onMessageReceived, processIncoming]);
509
-
510
- const sendTextMessage = useCallback(
511
- (text: string) => {
512
- const id = generateId();
513
- const msg: Message = {
514
- id,
515
- role: "user",
516
- type: "text",
517
- content: text,
518
- timestamp: Date.now(),
519
- status: "sending",
520
- };
521
- addMessageToActive(msg);
522
- const sent = wsSend(text, activeSessionIdRef.current ?? undefined);
523
- updateMessageStatus(id, sent ? "sent" : "error");
524
- },
525
- [wsSend, addMessageToActive, updateMessageStatus]
526
- );
527
-
528
- const sendVoiceMessage = useCallback(
529
- async (audioUri: string, durationMs?: number) => {
530
- const id = generateId();
531
- const msg: Message = {
532
- id,
533
- role: "user",
534
- type: "voice",
535
- content: "",
536
- audioUri,
537
- timestamp: Date.now(),
538
- status: "sending",
539
- duration: durationMs,
540
- };
541
- addMessageToActive(msg);
542
- try {
543
- const base64 = await encodeAudioToBase64(audioUri);
544
- const sent = wsVoice(base64, "", id, activeSessionIdRef.current ?? undefined);
545
- updateMessageStatus(id, sent ? "sent" : "error");
546
- } catch (err) {
547
- console.error("Failed to encode audio:", err);
548
- updateMessageStatus(id, "error");
549
- }
550
- },
551
- [wsVoice, addMessageToActive, updateMessageStatus]
552
- );
553
-
554
- const sendImageMessage = useCallback(
555
- (imageBase64: string, caption: string, mimeType: string) => {
556
- const id = generateId();
557
- const msg: Message = {
558
- id,
559
- role: "user",
560
- type: "image",
561
- content: caption || "Photo",
562
- imageBase64,
563
- timestamp: Date.now(),
564
- status: "sending",
565
- };
566
- addMessageToActive(msg);
567
- const sent = wsImageSend(imageBase64, caption, mimeType, activeSessionIdRef.current ?? undefined);
568
- updateMessageStatus(id, sent ? "sent" : "error");
569
- },
570
- [wsImageSend, addMessageToActive, updateMessageStatus]
571
- );
572
-
573
- const deleteMessage = useCallback((id: string) => {
574
- setMessages((prev) => {
575
- const next = prev.filter((m) => m.id !== id);
576
- const sessId = activeSessionIdRef.current;
577
- if (sessId) {
578
- messagesMapRef.current[sessId] = next;
579
- debouncedSave(messagesMapRef.current);
580
- }
581
- return next;
582
- });
583
- }, []);
584
-
585
- const clearMessages = useCallback(() => {
586
- setMessages([]);
587
- const id = activeSessionIdRef.current;
588
- if (id) {
589
- messagesMapRef.current[id] = [];
590
- clearPersistedMessages(id);
591
- }
592
- }, []);
593
-
594
- // --- Session management ---
595
- const requestSessions = useCallback(() => {
596
- sendCommand("sessions");
597
- }, [sendCommand]);
598
-
599
- const switchSession = useCallback(
600
- (sessionId: string) => {
601
- // messagesMapRef is already kept in sync by all mutators — no need to save here
602
- sendCommand("switch", { sessionId });
603
- // Clear the server-pushed unread indicator immediately on user intent
604
- setUnreadSessions((prev) => {
605
- if (!prev.has(sessionId)) return prev;
606
- const next = new Set(prev);
607
- next.delete(sessionId);
608
- return next;
609
- });
610
- },
611
- [sendCommand]
612
- );
613
-
614
- const renameSession = useCallback(
615
- (sessionId: string, name: string) => {
616
- sendCommand("rename", { sessionId, name });
617
- },
618
- [sendCommand]
619
- );
620
-
621
- const removeSession = useCallback(
622
- (sessionId: string) => {
623
- sendCommand("remove", { sessionId });
624
- delete messagesMapRef.current[sessionId];
625
- deletePersistedSession(sessionId);
626
- setUnreadCounts((u) => {
627
- if (!u[sessionId]) return u;
628
- const next = { ...u };
629
- delete next[sessionId];
630
- return next;
631
- });
632
- setUnreadSessions((prev) => {
633
- if (!prev.has(sessionId)) return prev;
634
- const next = new Set(prev);
635
- next.delete(sessionId);
636
- return next;
637
- });
638
- },
639
- [sendCommand]
640
- );
641
-
642
- const createSession = useCallback((opts?: { project?: string; path?: string }) => {
643
- sendCommand("create", opts ?? {});
644
- }, [sendCommand]);
645
-
646
- const fetchProjects = useCallback(() => {
647
- sendCommand("projects");
648
- }, [sendCommand]);
649
-
650
- const dismissToast = useCallback(() => {
651
- // Show next queued toast, or clear
652
- const next = toastQueueRef.current.shift();
653
- setIncomingToast(next ?? null);
654
- }, []);
655
-
656
- const loadMoreMessages = useCallback(() => {
657
- const sessId = activeSessionIdRef.current;
658
- if (!sessId) return;
659
- const all = messagesMapRef.current[sessId] ?? [];
660
- setMessages((current) => {
661
- if (current.length >= all.length) {
662
- setHasMoreMessages(false);
663
- return current;
664
- }
665
- const nextSize = Math.min(current.length + PAGE_SIZE, all.length);
666
- const page = all.slice(-nextSize);
667
- setHasMoreMessages(nextSize < all.length);
668
- return page;
669
- });
670
- }, []);
671
-
672
- // --- Screenshot / navigation ---
673
- const requestScreenshot = useCallback(() => {
674
- sendCommand("screenshot");
675
- }, [sendCommand]);
676
-
677
- const sendNavKey = useCallback(
678
- (key: string) => {
679
- sendCommand("nav", { key });
680
- },
681
- [sendCommand]
682
- );
683
-
684
- return (
685
- <ChatContext.Provider
686
- value={{
687
- messages,
688
- sendTextMessage,
689
- sendVoiceMessage,
690
- sendImageMessage,
691
- deleteMessage,
692
- clearMessages,
693
- isTyping,
694
- sessions,
695
- activeSessionId,
696
- requestSessions,
697
- switchSession,
698
- renameSession,
699
- removeSession,
700
- createSession,
701
- fetchProjects,
702
- projects,
703
- loadMoreMessages,
704
- hasMoreMessages,
705
- unreadCounts,
706
- unreadSessions,
707
- incomingToast,
708
- dismissToast,
709
- latestScreenshot,
710
- requestScreenshot,
711
- sendNavKey,
712
- }}
713
- >
714
- {children}
715
- </ChatContext.Provider>
716
- );
717
-}
718
-
719
-export function useChat() {
720
- const ctx = useContext(ChatContext);
721
- if (!ctx) throw new Error("useChat must be used within ChatProvider");
722
- return ctx;
723
-}
contexts/ConnectionContext.tsx
deleted file mode 100644
....@@ -1,175 +0,0 @@
1
-import React, {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useEffect,
6
- useRef,
7
- useState,
8
-} from "react";
9
-import * as SecureStore from "expo-secure-store";
10
-import {
11
- ConnectionStatus,
12
- ServerConfig,
13
- WsIncoming,
14
- WsOutgoing,
15
-} from "../types";
16
-import { wsClient } from "../services/websocket";
17
-import { sendWol, isValidMac } from "../services/wol";
18
-
19
-const SECURE_STORE_KEY = "pailot_server_config";
20
-
21
-interface ConnectionContextValue {
22
- serverConfig: ServerConfig | null;
23
- status: ConnectionStatus;
24
- connect: (config?: ServerConfig) => void;
25
- disconnect: () => void;
26
- sendTextMessage: (text: string, sessionId?: string) => boolean;
27
- sendVoiceMessage: (audioBase64: string, transcript?: string, messageId?: string, sessionId?: string) => boolean;
28
- sendImageMessage: (imageBase64: string, caption: string, mimeType: string, sessionId?: string) => boolean;
29
- sendCommand: (command: string, args?: Record<string, unknown>, sessionId?: string) => boolean;
30
- saveServerConfig: (config: ServerConfig) => Promise<void>;
31
- onMessageReceived: React.MutableRefObject<
32
- ((data: WsIncoming) => void) | null
33
- >;
34
-}
35
-
36
-const ConnectionContext = createContext<ConnectionContextValue | null>(null);
37
-
38
-export function ConnectionProvider({
39
- children,
40
-}: {
41
- children: React.ReactNode;
42
-}) {
43
- const [serverConfig, setServerConfig] = useState<ServerConfig | null>(null);
44
- const [status, setStatus] = useState<ConnectionStatus>("disconnected");
45
- const onMessageReceived = useRef<((data: WsIncoming) => void) | null>(null);
46
-
47
- useEffect(() => {
48
- loadConfig();
49
- }, []);
50
-
51
- useEffect(() => {
52
- wsClient.setCallbacks({
53
- onOpen: () => setStatus("connected"),
54
- onClose: () => setStatus("disconnected"),
55
- onReconnecting: () => setStatus("reconnecting"),
56
- onError: () => setStatus("disconnected"),
57
- onMessage: (data) => {
58
- const msg = data as unknown as WsIncoming;
59
- // Handle server-side status changes (compaction indicator)
60
- if (msg.type === "status") {
61
- if (msg.status === "compacting") setStatus("compacting");
62
- else if (msg.status === "online") setStatus("connected");
63
- return;
64
- }
65
- onMessageReceived.current?.(msg);
66
- },
67
- });
68
- }, []);
69
-
70
- async function loadConfig() {
71
- try {
72
- const stored = await SecureStore.getItemAsync(SECURE_STORE_KEY);
73
- if (stored) {
74
- const config = JSON.parse(stored) as ServerConfig;
75
- setServerConfig(config);
76
- connectToServer(config);
77
- }
78
- } catch {
79
- // No stored config
80
- }
81
- }
82
-
83
- async function connectToServer(config: ServerConfig) {
84
- setStatus("connecting");
85
-
86
- // Fire-and-forget WoL — never block the WebSocket connection
87
- if (config.macAddress && isValidMac(config.macAddress)) {
88
- sendWol(config.macAddress, config.host).catch(() => {});
89
- }
90
-
91
- // Build URL list: local first (preferred), then remote
92
- const urls: string[] = [];
93
- if (config.localHost) {
94
- urls.push(`ws://${config.localHost}:${config.port}`);
95
- }
96
- urls.push(`ws://${config.host}:${config.port}`);
97
- wsClient.connect(urls);
98
- }
99
-
100
- const connect = useCallback(
101
- (config?: ServerConfig) => {
102
- const target = config ?? serverConfig;
103
- if (!target) return;
104
- connectToServer(target);
105
- },
106
- [serverConfig]
107
- );
108
-
109
- const disconnect = useCallback(() => {
110
- wsClient.disconnect();
111
- setStatus("disconnected");
112
- }, []);
113
-
114
- const saveServerConfig = useCallback(async (config: ServerConfig) => {
115
- await SecureStore.setItemAsync(SECURE_STORE_KEY, JSON.stringify(config));
116
- setServerConfig(config);
117
- }, []);
118
-
119
- const sendTextMessage = useCallback((text: string, sessionId?: string): boolean => {
120
- return wsClient.send({ type: "text", content: text, sessionId });
121
- }, []);
122
-
123
- const sendVoiceMessage = useCallback(
124
- (audioBase64: string, transcript: string = "", messageId?: string, sessionId?: string): boolean => {
125
- return wsClient.send({
126
- type: "voice",
127
- content: transcript,
128
- audioBase64,
129
- messageId,
130
- sessionId,
131
- });
132
- },
133
- []
134
- );
135
-
136
- const sendImageMessage = useCallback(
137
- (imageBase64: string, caption: string = "", mimeType: string = "image/jpeg", sessionId?: string): boolean => {
138
- return wsClient.send({ type: "image", imageBase64, caption, mimeType, sessionId });
139
- },
140
- []
141
- );
142
-
143
- const sendCommand = useCallback(
144
- (command: string, args?: Record<string, unknown>, sessionId?: string): boolean => {
145
- const msg: WsOutgoing = { type: "command", command, args, sessionId };
146
- return wsClient.send(msg as any);
147
- },
148
- []
149
- );
150
-
151
- return (
152
- <ConnectionContext.Provider
153
- value={{
154
- serverConfig,
155
- status,
156
- connect,
157
- disconnect,
158
- sendTextMessage,
159
- sendVoiceMessage,
160
- sendImageMessage,
161
- sendCommand,
162
- saveServerConfig,
163
- onMessageReceived,
164
- }}
165
- >
166
- {children}
167
- </ConnectionContext.Provider>
168
- );
169
-}
170
-
171
-export function useConnection() {
172
- const ctx = useContext(ConnectionContext);
173
- if (!ctx) throw new Error("useConnection must be used within ConnectionProvider");
174
- return ctx;
175
-}
contexts/ThemeContext.tsx
deleted file mode 100644
....@@ -1,97 +0,0 @@
1
-import React, { createContext, useCallback, useContext, useEffect, useState } from "react";
2
-import { useColorScheme } from "react-native";
3
-import * as SecureStore from "expo-secure-store";
4
-
5
-const THEME_KEY = "pailot_theme";
6
-
7
-type ThemeMode = "light" | "dark" | "system";
8
-
9
-export interface ThemeColors {
10
- bg: string;
11
- bgSecondary: string;
12
- bgTertiary: string;
13
- text: string;
14
- textSecondary: string;
15
- textMuted: string;
16
- border: string;
17
- accent: string;
18
- accentBg: string;
19
- danger: string;
20
-}
21
-
22
-const darkColors: ThemeColors = {
23
- bg: "#0A0A0F",
24
- bgSecondary: "#14141F",
25
- bgTertiary: "#1E1E2E",
26
- text: "#E8E8F0",
27
- textSecondary: "#9898B0",
28
- textMuted: "#5A5A78",
29
- border: "#2E2E45",
30
- accent: "#4A9EFF",
31
- accentBg: "#4A9EFF18",
32
- danger: "#FF3B30",
33
-};
34
-
35
-const lightColors: ThemeColors = {
36
- bg: "#FFFFFF",
37
- bgSecondary: "#F5F5F7",
38
- bgTertiary: "#EEEEF0",
39
- text: "#1C1C1E",
40
- textSecondary: "#636366",
41
- textMuted: "#AEAEB2",
42
- border: "#D1D1D6",
43
- accent: "#007AFF",
44
- accentBg: "#007AFF14",
45
- danger: "#FF3B30",
46
-};
47
-
48
-interface ThemeContextValue {
49
- mode: ThemeMode;
50
- isDark: boolean;
51
- colors: ThemeColors;
52
- setMode: (mode: ThemeMode) => void;
53
- cycleMode: () => void;
54
-}
55
-
56
-const ThemeContext = createContext<ThemeContextValue | null>(null);
57
-
58
-export function ThemeProvider({ children }: { children: React.ReactNode }) {
59
- const systemScheme = useColorScheme();
60
- const [mode, setModeState] = useState<ThemeMode>("dark");
61
-
62
- useEffect(() => {
63
- SecureStore.getItemAsync(THEME_KEY).then((stored) => {
64
- if (stored === "light" || stored === "dark" || stored === "system") {
65
- setModeState(stored);
66
- }
67
- });
68
- }, []);
69
-
70
- const setMode = useCallback((m: ThemeMode) => {
71
- setModeState(m);
72
- SecureStore.setItemAsync(THEME_KEY, m);
73
- }, []);
74
-
75
- const cycleMode = useCallback(() => {
76
- setModeState((prev) => {
77
- const next = prev === "dark" ? "light" : prev === "light" ? "system" : "dark";
78
- SecureStore.setItemAsync(THEME_KEY, next);
79
- return next;
80
- });
81
- }, []);
82
-
83
- const isDark = mode === "dark" || (mode === "system" && systemScheme !== "light");
84
- const colors = isDark ? darkColors : lightColors;
85
-
86
- return (
87
- <ThemeContext.Provider value={{ mode, isDark, colors, setMode, cycleMode }}>
88
- {children}
89
- </ThemeContext.Provider>
90
- );
91
-}
92
-
93
-export function useTheme() {
94
- const ctx = useContext(ThemeContext);
95
- if (!ctx) throw new Error("useTheme must be used within ThemeProvider");
96
- return ctx;
97
-}
global.css
deleted file mode 100644
....@@ -1,3 +0,0 @@
1
-@tailwind base;
2
-@tailwind components;
3
-@tailwind utilities;
ios/.gitignore
....@@ -0,0 +1,34 @@
1
+**/dgph
2
+*.mode1v3
3
+*.mode2v3
4
+*.moved-aside
5
+*.pbxuser
6
+*.perspectivev3
7
+**/*sync/
8
+.sconsign.dblite
9
+.tags*
10
+**/.vagrant/
11
+**/DerivedData/
12
+Icon?
13
+**/Pods/
14
+**/.symlinks/
15
+profile
16
+xcuserdata
17
+**/.generated/
18
+Flutter/App.framework
19
+Flutter/Flutter.framework
20
+Flutter/Flutter.podspec
21
+Flutter/Generated.xcconfig
22
+Flutter/ephemeral/
23
+Flutter/app.flx
24
+Flutter/app.zip
25
+Flutter/flutter_assets/
26
+Flutter/flutter_export_environment.sh
27
+ServiceDefinitions.json
28
+Runner/GeneratedPluginRegistrant.*
29
+
30
+# Exceptions to above rules.
31
+!default.mode1v3
32
+!default.mode2v3
33
+!default.pbxuser
34
+!default.perspectivev3
ios/Flutter/AppFrameworkInfo.plist
....@@ -0,0 +1,24 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>en</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>App</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>io.flutter.flutter.app</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>App</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>FMWK</string>
17
+ <key>CFBundleShortVersionString</key>
18
+ <string>1.0</string>
19
+ <key>CFBundleSignature</key>
20
+ <string>????</string>
21
+ <key>CFBundleVersion</key>
22
+ <string>1.0</string>
23
+</dict>
24
+</plist>
ios/Flutter/Debug.xcconfig
....@@ -0,0 +1,2 @@
1
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2
+#include "Generated.xcconfig"
ios/Flutter/Release.xcconfig
....@@ -0,0 +1,2 @@
1
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2
+#include "Generated.xcconfig"
ios/Podfile
....@@ -0,0 +1,43 @@
1
+# Uncomment this line to define a global platform for your project
2
+# platform :ios, '13.0'
3
+
4
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6
+
7
+project 'Runner', {
8
+ 'Debug' => :debug,
9
+ 'Profile' => :release,
10
+ 'Release' => :release,
11
+}
12
+
13
+def flutter_root
14
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15
+ unless File.exist?(generated_xcode_build_settings_path)
16
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17
+ end
18
+
19
+ File.foreach(generated_xcode_build_settings_path) do |line|
20
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
21
+ return matches[1].strip if matches
22
+ end
23
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24
+end
25
+
26
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27
+
28
+flutter_ios_podfile_setup
29
+
30
+target 'Runner' do
31
+ use_frameworks!
32
+
33
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
34
+ target 'RunnerTests' do
35
+ inherit! :search_paths
36
+ end
37
+end
38
+
39
+post_install do |installer|
40
+ installer.pods_project.targets.each do |target|
41
+ flutter_additional_ios_build_settings(target)
42
+ end
43
+end
ios/Podfile.lock
....@@ -0,0 +1,164 @@
1
+PODS:
2
+ - audioplayers_darwin (0.0.1):
3
+ - Flutter
4
+ - FlutterMacOS
5
+ - bonsoir_darwin (0.0.1):
6
+ - Flutter
7
+ - FlutterMacOS
8
+ - connectivity_plus (0.0.1):
9
+ - Flutter
10
+ - device_info_plus (0.0.1):
11
+ - Flutter
12
+ - DKImagePickerController/Core (4.3.9):
13
+ - DKImagePickerController/ImageDataManager
14
+ - DKImagePickerController/Resource
15
+ - DKImagePickerController/ImageDataManager (4.3.9)
16
+ - DKImagePickerController/PhotoGallery (4.3.9):
17
+ - DKImagePickerController/Core
18
+ - DKPhotoGallery
19
+ - DKImagePickerController/Resource (4.3.9)
20
+ - DKPhotoGallery (0.0.19):
21
+ - DKPhotoGallery/Core (= 0.0.19)
22
+ - DKPhotoGallery/Model (= 0.0.19)
23
+ - DKPhotoGallery/Preview (= 0.0.19)
24
+ - DKPhotoGallery/Resource (= 0.0.19)
25
+ - SDWebImage
26
+ - SwiftyGif
27
+ - DKPhotoGallery/Core (0.0.19):
28
+ - DKPhotoGallery/Model
29
+ - DKPhotoGallery/Preview
30
+ - SDWebImage
31
+ - SwiftyGif
32
+ - DKPhotoGallery/Model (0.0.19):
33
+ - SDWebImage
34
+ - SwiftyGif
35
+ - DKPhotoGallery/Preview (0.0.19):
36
+ - DKPhotoGallery/Model
37
+ - DKPhotoGallery/Resource
38
+ - SDWebImage
39
+ - SwiftyGif
40
+ - DKPhotoGallery/Resource (0.0.19):
41
+ - SDWebImage
42
+ - SwiftyGif
43
+ - file_picker (0.0.1):
44
+ - DKImagePickerController/PhotoGallery
45
+ - Flutter
46
+ - Flutter (1.0.0)
47
+ - flutter_app_badger (1.3.0):
48
+ - Flutter
49
+ - flutter_secure_storage (6.0.0):
50
+ - Flutter
51
+ - image_picker_ios (0.0.1):
52
+ - Flutter
53
+ - in_app_purchase_storekit (0.0.1):
54
+ - Flutter
55
+ - FlutterMacOS
56
+ - permission_handler_apple (9.3.0):
57
+ - Flutter
58
+ - push (0.0.1):
59
+ - Flutter
60
+ - FlutterMacOS
61
+ - record_ios (1.2.0):
62
+ - Flutter
63
+ - SDWebImage (5.21.7):
64
+ - SDWebImage/Core (= 5.21.7)
65
+ - SDWebImage/Core (5.21.7)
66
+ - share_plus (0.0.1):
67
+ - Flutter
68
+ - shared_preferences_foundation (0.0.1):
69
+ - Flutter
70
+ - FlutterMacOS
71
+ - SwiftyGif (5.4.5)
72
+ - url_launcher_ios (0.0.1):
73
+ - Flutter
74
+ - vibration (1.7.5):
75
+ - Flutter
76
+
77
+DEPENDENCIES:
78
+ - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/darwin`)
79
+ - bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`)
80
+ - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
81
+ - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
82
+ - file_picker (from `.symlinks/plugins/file_picker/ios`)
83
+ - Flutter (from `Flutter`)
84
+ - flutter_app_badger (from `.symlinks/plugins/flutter_app_badger/ios`)
85
+ - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
86
+ - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
87
+ - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
88
+ - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
89
+ - push (from `.symlinks/plugins/push/darwin`)
90
+ - record_ios (from `.symlinks/plugins/record_ios/ios`)
91
+ - share_plus (from `.symlinks/plugins/share_plus/ios`)
92
+ - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
93
+ - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
94
+ - vibration (from `.symlinks/plugins/vibration/ios`)
95
+
96
+SPEC REPOS:
97
+ trunk:
98
+ - DKImagePickerController
99
+ - DKPhotoGallery
100
+ - SDWebImage
101
+ - SwiftyGif
102
+
103
+EXTERNAL SOURCES:
104
+ audioplayers_darwin:
105
+ :path: ".symlinks/plugins/audioplayers_darwin/darwin"
106
+ bonsoir_darwin:
107
+ :path: ".symlinks/plugins/bonsoir_darwin/darwin"
108
+ connectivity_plus:
109
+ :path: ".symlinks/plugins/connectivity_plus/ios"
110
+ device_info_plus:
111
+ :path: ".symlinks/plugins/device_info_plus/ios"
112
+ file_picker:
113
+ :path: ".symlinks/plugins/file_picker/ios"
114
+ Flutter:
115
+ :path: Flutter
116
+ flutter_app_badger:
117
+ :path: ".symlinks/plugins/flutter_app_badger/ios"
118
+ flutter_secure_storage:
119
+ :path: ".symlinks/plugins/flutter_secure_storage/ios"
120
+ image_picker_ios:
121
+ :path: ".symlinks/plugins/image_picker_ios/ios"
122
+ in_app_purchase_storekit:
123
+ :path: ".symlinks/plugins/in_app_purchase_storekit/darwin"
124
+ permission_handler_apple:
125
+ :path: ".symlinks/plugins/permission_handler_apple/ios"
126
+ push:
127
+ :path: ".symlinks/plugins/push/darwin"
128
+ record_ios:
129
+ :path: ".symlinks/plugins/record_ios/ios"
130
+ share_plus:
131
+ :path: ".symlinks/plugins/share_plus/ios"
132
+ shared_preferences_foundation:
133
+ :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
134
+ url_launcher_ios:
135
+ :path: ".symlinks/plugins/url_launcher_ios/ios"
136
+ vibration:
137
+ :path: ".symlinks/plugins/vibration/ios"
138
+
139
+SPEC CHECKSUMS:
140
+ audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
141
+ bonsoir_darwin: 29c7ccf356646118844721f36e1de4b61f6cbd0e
142
+ connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
143
+ device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
144
+ DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
145
+ DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
146
+ file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
147
+ Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
148
+ flutter_app_badger: 16b371e989d04cd265df85be2c3851b49cb68d18
149
+ flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
150
+ image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
151
+ in_app_purchase_storekit: 22cca7d08eebca9babdf4d07d0baccb73325d3c8
152
+ permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
153
+ push: 91373ae39c5341c6de6adefa3fda7f7287d646bf
154
+ record_ios: 412daca2350b228e698fffcd08f1f94ceb1e3844
155
+ SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
156
+ share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
157
+ shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
158
+ SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
159
+ url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
160
+ vibration: 8e2f50fc35bb736f9eecb7dd9f7047fbb6a6e888
161
+
162
+PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
163
+
164
+COCOAPODS: 1.16.2
ios/Runner.xcodeproj/project.pbxproj
....@@ -0,0 +1,770 @@
1
+// !$*UTF8*$!
2
+{
3
+ archiveVersion = 1;
4
+ classes = {
5
+ };
6
+ objectVersion = 54;
7
+ objects = {
8
+
9
+/* Begin PBXBuildFile section */
10
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
12
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
14
+ 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
15
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
16
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
17
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
18
+ D9D2DFE3EFA5DBB0F5D794AB /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 198A88F1D8A4463DB192CC8B /* Pods_RunnerTests.framework */; };
19
+ FE1E66A89E015390FAFFEABC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E8ED95FB2D20F34294BD581 /* Pods_Runner.framework */; };
20
+ A2B3C4D5E6F7012345678902 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = A2B3C4D5E6F7012345678901 /* PrivacyInfo.xcprivacy */; };
21
+/* End PBXBuildFile section */
22
+
23
+/* Begin PBXContainerItemProxy section */
24
+ 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
25
+ isa = PBXContainerItemProxy;
26
+ containerPortal = 97C146E61CF9000F007C117D /* Project object */;
27
+ proxyType = 1;
28
+ remoteGlobalIDString = 97C146ED1CF9000F007C117D;
29
+ remoteInfo = Runner;
30
+ };
31
+/* End PBXContainerItemProxy section */
32
+
33
+/* Begin PBXCopyFilesBuildPhase section */
34
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
35
+ isa = PBXCopyFilesBuildPhase;
36
+ buildActionMask = 2147483647;
37
+ dstPath = "";
38
+ dstSubfolderSpec = 10;
39
+ files = (
40
+ );
41
+ name = "Embed Frameworks";
42
+ runOnlyForDeploymentPostprocessing = 0;
43
+ };
44
+/* End PBXCopyFilesBuildPhase section */
45
+
46
+/* Begin PBXFileReference section */
47
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
48
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
49
+ 198A88F1D8A4463DB192CC8B /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50
+ 19B0FCC2C76B1AA22EB4F8AD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
51
+ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
52
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
53
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
54
+ 6E8ED95FB2D20F34294BD581 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
55
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
56
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
57
+ A1B2C3D4E5F601234567890A /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
58
+ 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
59
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
60
+ 923BC14277A1E9646A04D00D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
61
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
62
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
63
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
64
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
65
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
66
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
67
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
68
+ A2B3C4D5E6F7012345678901 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
69
+ BE2A6F8B33F88BBA24CADC20 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
70
+ C26A52EB77D6E672D863508C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
71
+ DAE814C44F203C4F28292572 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
72
+ E2CF470C12EB3169196469BE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
73
+/* End PBXFileReference section */
74
+
75
+/* Begin PBXFrameworksBuildPhase section */
76
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
77
+ isa = PBXFrameworksBuildPhase;
78
+ buildActionMask = 2147483647;
79
+ files = (
80
+ FE1E66A89E015390FAFFEABC /* Pods_Runner.framework in Frameworks */,
81
+ );
82
+ runOnlyForDeploymentPostprocessing = 0;
83
+ };
84
+ C1739C9798107FD8ACC5B094 /* Frameworks */ = {
85
+ isa = PBXFrameworksBuildPhase;
86
+ buildActionMask = 2147483647;
87
+ files = (
88
+ D9D2DFE3EFA5DBB0F5D794AB /* Pods_RunnerTests.framework in Frameworks */,
89
+ );
90
+ runOnlyForDeploymentPostprocessing = 0;
91
+ };
92
+/* End PBXFrameworksBuildPhase section */
93
+
94
+/* Begin PBXGroup section */
95
+ 331C8082294A63A400263BE5 /* RunnerTests */ = {
96
+ isa = PBXGroup;
97
+ children = (
98
+ 331C807B294A618700263BE5 /* RunnerTests.swift */,
99
+ );
100
+ path = RunnerTests;
101
+ sourceTree = "<group>";
102
+ };
103
+ 4F1B037CBD685AE0292D1DCF /* Frameworks */ = {
104
+ isa = PBXGroup;
105
+ children = (
106
+ 6E8ED95FB2D20F34294BD581 /* Pods_Runner.framework */,
107
+ 198A88F1D8A4463DB192CC8B /* Pods_RunnerTests.framework */,
108
+ );
109
+ name = Frameworks;
110
+ sourceTree = "<group>";
111
+ };
112
+ 9740EEB11CF90186004384FC /* Flutter */ = {
113
+ isa = PBXGroup;
114
+ children = (
115
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
116
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
117
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
118
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
119
+ );
120
+ name = Flutter;
121
+ sourceTree = "<group>";
122
+ };
123
+ 97C146E51CF9000F007C117D = {
124
+ isa = PBXGroup;
125
+ children = (
126
+ 9740EEB11CF90186004384FC /* Flutter */,
127
+ 97C146F01CF9000F007C117D /* Runner */,
128
+ 97C146EF1CF9000F007C117D /* Products */,
129
+ 331C8082294A63A400263BE5 /* RunnerTests */,
130
+ D3DAD9847230599D547F405F /* Pods */,
131
+ 4F1B037CBD685AE0292D1DCF /* Frameworks */,
132
+ );
133
+ sourceTree = "<group>";
134
+ };
135
+ 97C146EF1CF9000F007C117D /* Products */ = {
136
+ isa = PBXGroup;
137
+ children = (
138
+ 97C146EE1CF9000F007C117D /* Runner.app */,
139
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
140
+ );
141
+ name = Products;
142
+ sourceTree = "<group>";
143
+ };
144
+ 97C146F01CF9000F007C117D /* Runner */ = {
145
+ isa = PBXGroup;
146
+ children = (
147
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
148
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
149
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
150
+ 97C147021CF9000F007C117D /* Info.plist */,
151
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
152
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
153
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
154
+ 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */,
155
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
156
+ A1B2C3D4E5F601234567890A /* Runner.entitlements */,
157
+ A2B3C4D5E6F7012345678901 /* PrivacyInfo.xcprivacy */,
158
+ );
159
+ path = Runner;
160
+ sourceTree = "<group>";
161
+ };
162
+ D3DAD9847230599D547F405F /* Pods */ = {
163
+ isa = PBXGroup;
164
+ children = (
165
+ C26A52EB77D6E672D863508C /* Pods-Runner.debug.xcconfig */,
166
+ 923BC14277A1E9646A04D00D /* Pods-Runner.release.xcconfig */,
167
+ 19B0FCC2C76B1AA22EB4F8AD /* Pods-Runner.profile.xcconfig */,
168
+ E2CF470C12EB3169196469BE /* Pods-RunnerTests.debug.xcconfig */,
169
+ DAE814C44F203C4F28292572 /* Pods-RunnerTests.release.xcconfig */,
170
+ BE2A6F8B33F88BBA24CADC20 /* Pods-RunnerTests.profile.xcconfig */,
171
+ );
172
+ name = Pods;
173
+ path = Pods;
174
+ sourceTree = "<group>";
175
+ };
176
+/* End PBXGroup section */
177
+
178
+/* Begin PBXNativeTarget section */
179
+ 331C8080294A63A400263BE5 /* RunnerTests */ = {
180
+ isa = PBXNativeTarget;
181
+ buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
182
+ buildPhases = (
183
+ D2270C4AC2F791E9C2CF249B /* [CP] Check Pods Manifest.lock */,
184
+ 331C807D294A63A400263BE5 /* Sources */,
185
+ 331C807F294A63A400263BE5 /* Resources */,
186
+ C1739C9798107FD8ACC5B094 /* Frameworks */,
187
+ );
188
+ buildRules = (
189
+ );
190
+ dependencies = (
191
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */,
192
+ );
193
+ name = RunnerTests;
194
+ productName = RunnerTests;
195
+ productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
196
+ productType = "com.apple.product-type.bundle.unit-test";
197
+ };
198
+ 97C146ED1CF9000F007C117D /* Runner */ = {
199
+ isa = PBXNativeTarget;
200
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
201
+ buildPhases = (
202
+ 88D362BE06B1B449DDEAB7AC /* [CP] Check Pods Manifest.lock */,
203
+ 9740EEB61CF901F6004384FC /* Run Script */,
204
+ 97C146EA1CF9000F007C117D /* Sources */,
205
+ 97C146EB1CF9000F007C117D /* Frameworks */,
206
+ 97C146EC1CF9000F007C117D /* Resources */,
207
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
208
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
209
+ F1A1A47ABE978AE3EEC22360 /* [CP] Embed Pods Frameworks */,
210
+ 80693933C45470DE029A8BD4 /* [CP] Copy Pods Resources */,
211
+ );
212
+ buildRules = (
213
+ );
214
+ dependencies = (
215
+ );
216
+ name = Runner;
217
+ productName = Runner;
218
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
219
+ productType = "com.apple.product-type.application";
220
+ };
221
+/* End PBXNativeTarget section */
222
+
223
+/* Begin PBXProject section */
224
+ 97C146E61CF9000F007C117D /* Project object */ = {
225
+ isa = PBXProject;
226
+ attributes = {
227
+ BuildIndependentTargetsInParallel = YES;
228
+ LastUpgradeCheck = 1510;
229
+ ORGANIZATIONNAME = "";
230
+ TargetAttributes = {
231
+ 331C8080294A63A400263BE5 = {
232
+ CreatedOnToolsVersion = 14.0;
233
+ TestTargetID = 97C146ED1CF9000F007C117D;
234
+ };
235
+ 97C146ED1CF9000F007C117D = {
236
+ CreatedOnToolsVersion = 7.3.1;
237
+ LastSwiftMigration = 1100;
238
+ SystemCapabilities = {
239
+ com.apple.Push = {
240
+ enabled = 1;
241
+ };
242
+ com.apple.BackgroundModes = {
243
+ enabled = 1;
244
+ };
245
+ };
246
+ };
247
+ };
248
+ };
249
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
250
+ compatibilityVersion = "Xcode 9.3";
251
+ developmentRegion = en;
252
+ hasScannedForEncodings = 0;
253
+ knownRegions = (
254
+ en,
255
+ Base,
256
+ );
257
+ mainGroup = 97C146E51CF9000F007C117D;
258
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
259
+ projectDirPath = "";
260
+ projectRoot = "";
261
+ targets = (
262
+ 97C146ED1CF9000F007C117D /* Runner */,
263
+ 331C8080294A63A400263BE5 /* RunnerTests */,
264
+ );
265
+ };
266
+/* End PBXProject section */
267
+
268
+/* Begin PBXResourcesBuildPhase section */
269
+ 331C807F294A63A400263BE5 /* Resources */ = {
270
+ isa = PBXResourcesBuildPhase;
271
+ buildActionMask = 2147483647;
272
+ files = (
273
+ );
274
+ runOnlyForDeploymentPostprocessing = 0;
275
+ };
276
+ 97C146EC1CF9000F007C117D /* Resources */ = {
277
+ isa = PBXResourcesBuildPhase;
278
+ buildActionMask = 2147483647;
279
+ files = (
280
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
281
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
282
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
283
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
284
+ A2B3C4D5E6F7012345678902 /* PrivacyInfo.xcprivacy in Resources */,
285
+ );
286
+ runOnlyForDeploymentPostprocessing = 0;
287
+ };
288
+/* End PBXResourcesBuildPhase section */
289
+
290
+/* Begin PBXShellScriptBuildPhase section */
291
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
292
+ isa = PBXShellScriptBuildPhase;
293
+ alwaysOutOfDate = 1;
294
+ buildActionMask = 2147483647;
295
+ files = (
296
+ );
297
+ inputPaths = (
298
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
299
+ );
300
+ name = "Thin Binary";
301
+ outputPaths = (
302
+ );
303
+ runOnlyForDeploymentPostprocessing = 0;
304
+ shellPath = /bin/sh;
305
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
306
+ };
307
+ 80693933C45470DE029A8BD4 /* [CP] Copy Pods Resources */ = {
308
+ isa = PBXShellScriptBuildPhase;
309
+ buildActionMask = 2147483647;
310
+ files = (
311
+ );
312
+ inputFileListPaths = (
313
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
314
+ );
315
+ name = "[CP] Copy Pods Resources";
316
+ outputFileListPaths = (
317
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
318
+ );
319
+ runOnlyForDeploymentPostprocessing = 0;
320
+ shellPath = /bin/sh;
321
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
322
+ showEnvVarsInLog = 0;
323
+ };
324
+ 88D362BE06B1B449DDEAB7AC /* [CP] Check Pods Manifest.lock */ = {
325
+ isa = PBXShellScriptBuildPhase;
326
+ buildActionMask = 2147483647;
327
+ files = (
328
+ );
329
+ inputFileListPaths = (
330
+ );
331
+ inputPaths = (
332
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
333
+ "${PODS_ROOT}/Manifest.lock",
334
+ );
335
+ name = "[CP] Check Pods Manifest.lock";
336
+ outputFileListPaths = (
337
+ );
338
+ outputPaths = (
339
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
340
+ );
341
+ runOnlyForDeploymentPostprocessing = 0;
342
+ shellPath = /bin/sh;
343
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
344
+ showEnvVarsInLog = 0;
345
+ };
346
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
347
+ isa = PBXShellScriptBuildPhase;
348
+ alwaysOutOfDate = 1;
349
+ buildActionMask = 2147483647;
350
+ files = (
351
+ );
352
+ inputPaths = (
353
+ );
354
+ name = "Run Script";
355
+ outputPaths = (
356
+ );
357
+ runOnlyForDeploymentPostprocessing = 0;
358
+ shellPath = /bin/sh;
359
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
360
+ };
361
+ D2270C4AC2F791E9C2CF249B /* [CP] Check Pods Manifest.lock */ = {
362
+ isa = PBXShellScriptBuildPhase;
363
+ buildActionMask = 2147483647;
364
+ files = (
365
+ );
366
+ inputFileListPaths = (
367
+ );
368
+ inputPaths = (
369
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
370
+ "${PODS_ROOT}/Manifest.lock",
371
+ );
372
+ name = "[CP] Check Pods Manifest.lock";
373
+ outputFileListPaths = (
374
+ );
375
+ outputPaths = (
376
+ "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
377
+ );
378
+ runOnlyForDeploymentPostprocessing = 0;
379
+ shellPath = /bin/sh;
380
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
381
+ showEnvVarsInLog = 0;
382
+ };
383
+ F1A1A47ABE978AE3EEC22360 /* [CP] Embed Pods Frameworks */ = {
384
+ isa = PBXShellScriptBuildPhase;
385
+ buildActionMask = 2147483647;
386
+ files = (
387
+ );
388
+ inputFileListPaths = (
389
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
390
+ );
391
+ name = "[CP] Embed Pods Frameworks";
392
+ outputFileListPaths = (
393
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
394
+ );
395
+ runOnlyForDeploymentPostprocessing = 0;
396
+ shellPath = /bin/sh;
397
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
398
+ showEnvVarsInLog = 0;
399
+ };
400
+/* End PBXShellScriptBuildPhase section */
401
+
402
+/* Begin PBXSourcesBuildPhase section */
403
+ 331C807D294A63A400263BE5 /* Sources */ = {
404
+ isa = PBXSourcesBuildPhase;
405
+ buildActionMask = 2147483647;
406
+ files = (
407
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
408
+ );
409
+ runOnlyForDeploymentPostprocessing = 0;
410
+ };
411
+ 97C146EA1CF9000F007C117D /* Sources */ = {
412
+ isa = PBXSourcesBuildPhase;
413
+ buildActionMask = 2147483647;
414
+ files = (
415
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
416
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
417
+ 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */,
418
+ );
419
+ runOnlyForDeploymentPostprocessing = 0;
420
+ };
421
+/* End PBXSourcesBuildPhase section */
422
+
423
+/* Begin PBXTargetDependency section */
424
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
425
+ isa = PBXTargetDependency;
426
+ target = 97C146ED1CF9000F007C117D /* Runner */;
427
+ targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
428
+ };
429
+/* End PBXTargetDependency section */
430
+
431
+/* Begin PBXVariantGroup section */
432
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
433
+ isa = PBXVariantGroup;
434
+ children = (
435
+ 97C146FB1CF9000F007C117D /* Base */,
436
+ );
437
+ name = Main.storyboard;
438
+ sourceTree = "<group>";
439
+ };
440
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
441
+ isa = PBXVariantGroup;
442
+ children = (
443
+ 97C147001CF9000F007C117D /* Base */,
444
+ );
445
+ name = LaunchScreen.storyboard;
446
+ sourceTree = "<group>";
447
+ };
448
+/* End PBXVariantGroup section */
449
+
450
+/* Begin XCBuildConfiguration section */
451
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
452
+ isa = XCBuildConfiguration;
453
+ buildSettings = {
454
+ ALWAYS_SEARCH_USER_PATHS = NO;
455
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
456
+ CLANG_ANALYZER_NONNULL = YES;
457
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
458
+ CLANG_CXX_LIBRARY = "libc++";
459
+ CLANG_ENABLE_MODULES = YES;
460
+ CLANG_ENABLE_OBJC_ARC = YES;
461
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
462
+ CLANG_WARN_BOOL_CONVERSION = YES;
463
+ CLANG_WARN_COMMA = YES;
464
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
465
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
466
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
467
+ CLANG_WARN_EMPTY_BODY = YES;
468
+ CLANG_WARN_ENUM_CONVERSION = YES;
469
+ CLANG_WARN_INFINITE_RECURSION = YES;
470
+ CLANG_WARN_INT_CONVERSION = YES;
471
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
472
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
473
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
474
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
475
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
476
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
477
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
478
+ CLANG_WARN_UNREACHABLE_CODE = YES;
479
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
480
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
481
+ COPY_PHASE_STRIP = NO;
482
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
483
+ ENABLE_NS_ASSERTIONS = NO;
484
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
485
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
486
+ GCC_C_LANGUAGE_STANDARD = gnu99;
487
+ GCC_NO_COMMON_BLOCKS = YES;
488
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
489
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
490
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
491
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
492
+ GCC_WARN_UNUSED_FUNCTION = YES;
493
+ GCC_WARN_UNUSED_VARIABLE = YES;
494
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
495
+ MTL_ENABLE_DEBUG_INFO = NO;
496
+ SDKROOT = iphoneos;
497
+ SUPPORTED_PLATFORMS = iphoneos;
498
+ TARGETED_DEVICE_FAMILY = "1,2";
499
+ VALIDATE_PRODUCT = YES;
500
+ };
501
+ name = Profile;
502
+ };
503
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
504
+ isa = XCBuildConfiguration;
505
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
506
+ buildSettings = {
507
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
508
+ CLANG_ENABLE_MODULES = YES;
509
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
510
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
511
+ DEVELOPMENT_TEAM = 7KU642K5ZL;
512
+ ENABLE_BITCODE = NO;
513
+ INFOPLIST_FILE = Runner/Info.plist;
514
+ LD_RUNPATH_SEARCH_PATHS = (
515
+ "$(inherited)",
516
+ "@executable_path/Frameworks",
517
+ );
518
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot;
519
+ PRODUCT_NAME = PAILot;
520
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
521
+ SWIFT_VERSION = 5.0;
522
+ VERSIONING_SYSTEM = "apple-generic";
523
+ };
524
+ name = Profile;
525
+ };
526
+ 331C8088294A63A400263BE5 /* Debug */ = {
527
+ isa = XCBuildConfiguration;
528
+ baseConfigurationReference = E2CF470C12EB3169196469BE /* Pods-RunnerTests.debug.xcconfig */;
529
+ buildSettings = {
530
+ BUNDLE_LOADER = "$(TEST_HOST)";
531
+ CODE_SIGN_STYLE = Automatic;
532
+ CURRENT_PROJECT_VERSION = 1;
533
+ GENERATE_INFOPLIST_FILE = YES;
534
+ MARKETING_VERSION = 1.0;
535
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot.RunnerTests;
536
+ PRODUCT_NAME = PAILot;
537
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
538
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
539
+ SWIFT_VERSION = 5.0;
540
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
541
+ };
542
+ name = Debug;
543
+ };
544
+ 331C8089294A63A400263BE5 /* Release */ = {
545
+ isa = XCBuildConfiguration;
546
+ baseConfigurationReference = DAE814C44F203C4F28292572 /* Pods-RunnerTests.release.xcconfig */;
547
+ buildSettings = {
548
+ BUNDLE_LOADER = "$(TEST_HOST)";
549
+ CODE_SIGN_STYLE = Automatic;
550
+ CURRENT_PROJECT_VERSION = 1;
551
+ GENERATE_INFOPLIST_FILE = YES;
552
+ MARKETING_VERSION = 1.0;
553
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot.RunnerTests;
554
+ PRODUCT_NAME = PAILot;
555
+ SWIFT_VERSION = 5.0;
556
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
557
+ };
558
+ name = Release;
559
+ };
560
+ 331C808A294A63A400263BE5 /* Profile */ = {
561
+ isa = XCBuildConfiguration;
562
+ baseConfigurationReference = BE2A6F8B33F88BBA24CADC20 /* Pods-RunnerTests.profile.xcconfig */;
563
+ buildSettings = {
564
+ BUNDLE_LOADER = "$(TEST_HOST)";
565
+ CODE_SIGN_STYLE = Automatic;
566
+ CURRENT_PROJECT_VERSION = 1;
567
+ GENERATE_INFOPLIST_FILE = YES;
568
+ MARKETING_VERSION = 1.0;
569
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot.RunnerTests;
570
+ PRODUCT_NAME = PAILot;
571
+ SWIFT_VERSION = 5.0;
572
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
573
+ };
574
+ name = Profile;
575
+ };
576
+ 97C147031CF9000F007C117D /* Debug */ = {
577
+ isa = XCBuildConfiguration;
578
+ buildSettings = {
579
+ ALWAYS_SEARCH_USER_PATHS = NO;
580
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
581
+ CLANG_ANALYZER_NONNULL = YES;
582
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
583
+ CLANG_CXX_LIBRARY = "libc++";
584
+ CLANG_ENABLE_MODULES = YES;
585
+ CLANG_ENABLE_OBJC_ARC = YES;
586
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
587
+ CLANG_WARN_BOOL_CONVERSION = YES;
588
+ CLANG_WARN_COMMA = YES;
589
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
590
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
591
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
592
+ CLANG_WARN_EMPTY_BODY = YES;
593
+ CLANG_WARN_ENUM_CONVERSION = YES;
594
+ CLANG_WARN_INFINITE_RECURSION = YES;
595
+ CLANG_WARN_INT_CONVERSION = YES;
596
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
597
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
598
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
599
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
600
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
601
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
602
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
603
+ CLANG_WARN_UNREACHABLE_CODE = YES;
604
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
605
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
606
+ COPY_PHASE_STRIP = NO;
607
+ DEBUG_INFORMATION_FORMAT = dwarf;
608
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
609
+ ENABLE_TESTABILITY = YES;
610
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
611
+ GCC_C_LANGUAGE_STANDARD = gnu99;
612
+ GCC_DYNAMIC_NO_PIC = NO;
613
+ GCC_NO_COMMON_BLOCKS = YES;
614
+ GCC_OPTIMIZATION_LEVEL = 0;
615
+ GCC_PREPROCESSOR_DEFINITIONS = (
616
+ "DEBUG=1",
617
+ "$(inherited)",
618
+ );
619
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
620
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
621
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
622
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
623
+ GCC_WARN_UNUSED_FUNCTION = YES;
624
+ GCC_WARN_UNUSED_VARIABLE = YES;
625
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
626
+ MTL_ENABLE_DEBUG_INFO = YES;
627
+ ONLY_ACTIVE_ARCH = YES;
628
+ SDKROOT = iphoneos;
629
+ TARGETED_DEVICE_FAMILY = "1,2";
630
+ };
631
+ name = Debug;
632
+ };
633
+ 97C147041CF9000F007C117D /* Release */ = {
634
+ isa = XCBuildConfiguration;
635
+ buildSettings = {
636
+ ALWAYS_SEARCH_USER_PATHS = NO;
637
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
638
+ CLANG_ANALYZER_NONNULL = YES;
639
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
640
+ CLANG_CXX_LIBRARY = "libc++";
641
+ CLANG_ENABLE_MODULES = YES;
642
+ CLANG_ENABLE_OBJC_ARC = YES;
643
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
644
+ CLANG_WARN_BOOL_CONVERSION = YES;
645
+ CLANG_WARN_COMMA = YES;
646
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
647
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
648
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
649
+ CLANG_WARN_EMPTY_BODY = YES;
650
+ CLANG_WARN_ENUM_CONVERSION = YES;
651
+ CLANG_WARN_INFINITE_RECURSION = YES;
652
+ CLANG_WARN_INT_CONVERSION = YES;
653
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
654
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
655
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
656
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
657
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
658
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
659
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
660
+ CLANG_WARN_UNREACHABLE_CODE = YES;
661
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
662
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
663
+ COPY_PHASE_STRIP = NO;
664
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
665
+ ENABLE_NS_ASSERTIONS = NO;
666
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
667
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
668
+ GCC_C_LANGUAGE_STANDARD = gnu99;
669
+ GCC_NO_COMMON_BLOCKS = YES;
670
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
671
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
672
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
673
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
674
+ GCC_WARN_UNUSED_FUNCTION = YES;
675
+ GCC_WARN_UNUSED_VARIABLE = YES;
676
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
677
+ MTL_ENABLE_DEBUG_INFO = NO;
678
+ SDKROOT = iphoneos;
679
+ SUPPORTED_PLATFORMS = iphoneos;
680
+ SWIFT_COMPILATION_MODE = wholemodule;
681
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
682
+ TARGETED_DEVICE_FAMILY = "1,2";
683
+ VALIDATE_PRODUCT = YES;
684
+ };
685
+ name = Release;
686
+ };
687
+ 97C147061CF9000F007C117D /* Debug */ = {
688
+ isa = XCBuildConfiguration;
689
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
690
+ buildSettings = {
691
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
692
+ CLANG_ENABLE_MODULES = YES;
693
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
694
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
695
+ DEVELOPMENT_TEAM = 7KU642K5ZL;
696
+ ENABLE_BITCODE = NO;
697
+ INFOPLIST_FILE = Runner/Info.plist;
698
+ LD_RUNPATH_SEARCH_PATHS = (
699
+ "$(inherited)",
700
+ "@executable_path/Frameworks",
701
+ );
702
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot;
703
+ PRODUCT_NAME = PAILot;
704
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
705
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
706
+ SWIFT_VERSION = 5.0;
707
+ VERSIONING_SYSTEM = "apple-generic";
708
+ };
709
+ name = Debug;
710
+ };
711
+ 97C147071CF9000F007C117D /* Release */ = {
712
+ isa = XCBuildConfiguration;
713
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
714
+ buildSettings = {
715
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
716
+ CLANG_ENABLE_MODULES = YES;
717
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
718
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
719
+ DEVELOPMENT_TEAM = 7KU642K5ZL;
720
+ ENABLE_BITCODE = NO;
721
+ INFOPLIST_FILE = Runner/Info.plist;
722
+ LD_RUNPATH_SEARCH_PATHS = (
723
+ "$(inherited)",
724
+ "@executable_path/Frameworks",
725
+ );
726
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot;
727
+ PRODUCT_NAME = PAILot;
728
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
729
+ SWIFT_VERSION = 5.0;
730
+ VERSIONING_SYSTEM = "apple-generic";
731
+ };
732
+ name = Release;
733
+ };
734
+/* End XCBuildConfiguration section */
735
+
736
+/* Begin XCConfigurationList section */
737
+ 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
738
+ isa = XCConfigurationList;
739
+ buildConfigurations = (
740
+ 331C8088294A63A400263BE5 /* Debug */,
741
+ 331C8089294A63A400263BE5 /* Release */,
742
+ 331C808A294A63A400263BE5 /* Profile */,
743
+ );
744
+ defaultConfigurationIsVisible = 0;
745
+ defaultConfigurationName = Release;
746
+ };
747
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
748
+ isa = XCConfigurationList;
749
+ buildConfigurations = (
750
+ 97C147031CF9000F007C117D /* Debug */,
751
+ 97C147041CF9000F007C117D /* Release */,
752
+ 249021D3217E4FDB00AE95B9 /* Profile */,
753
+ );
754
+ defaultConfigurationIsVisible = 0;
755
+ defaultConfigurationName = Release;
756
+ };
757
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
758
+ isa = XCConfigurationList;
759
+ buildConfigurations = (
760
+ 97C147061CF9000F007C117D /* Debug */,
761
+ 97C147071CF9000F007C117D /* Release */,
762
+ 249021D4217E4FDB00AE95B9 /* Profile */,
763
+ );
764
+ defaultConfigurationIsVisible = 0;
765
+ defaultConfigurationName = Release;
766
+ };
767
+/* End XCConfigurationList section */
768
+ };
769
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
770
+}
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
....@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:">
6
+ </FileRef>
7
+</Workspace>
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+</dict>
8
+</plist>
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>PreviewsEnabled</key>
6
+ <false/>
7
+</dict>
8
+</plist>
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
....@@ -0,0 +1,101 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+ LastUpgradeVersion = "1510"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
18
+ BuildableName = "PAILot.app"
19
+ BlueprintName = "Runner"
20
+ ReferencedContainer = "container:Runner.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
30
+ shouldUseLaunchSchemeArgsEnv = "YES">
31
+ <MacroExpansion>
32
+ <BuildableReference
33
+ BuildableIdentifier = "primary"
34
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
35
+ BuildableName = "PAILot.app"
36
+ BlueprintName = "Runner"
37
+ ReferencedContainer = "container:Runner.xcodeproj">
38
+ </BuildableReference>
39
+ </MacroExpansion>
40
+ <Testables>
41
+ <TestableReference
42
+ skipped = "NO"
43
+ parallelizable = "YES">
44
+ <BuildableReference
45
+ BuildableIdentifier = "primary"
46
+ BlueprintIdentifier = "331C8080294A63A400263BE5"
47
+ BuildableName = "PAILot.xctest"
48
+ BlueprintName = "RunnerTests"
49
+ ReferencedContainer = "container:Runner.xcodeproj">
50
+ </BuildableReference>
51
+ </TestableReference>
52
+ </Testables>
53
+ </TestAction>
54
+ <LaunchAction
55
+ buildConfiguration = "Debug"
56
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
57
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
58
+ customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
59
+ launchStyle = "0"
60
+ useCustomWorkingDirectory = "NO"
61
+ ignoresPersistentStateOnLaunch = "NO"
62
+ debugDocumentVersioning = "YES"
63
+ debugServiceExtension = "internal"
64
+ enableGPUValidationMode = "1"
65
+ allowLocationSimulation = "YES">
66
+ <BuildableProductRunnable
67
+ runnableDebuggingMode = "0">
68
+ <BuildableReference
69
+ BuildableIdentifier = "primary"
70
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
71
+ BuildableName = "PAILot.app"
72
+ BlueprintName = "Runner"
73
+ ReferencedContainer = "container:Runner.xcodeproj">
74
+ </BuildableReference>
75
+ </BuildableProductRunnable>
76
+ </LaunchAction>
77
+ <ProfileAction
78
+ buildConfiguration = "Profile"
79
+ shouldUseLaunchSchemeArgsEnv = "YES"
80
+ savedToolIdentifier = ""
81
+ useCustomWorkingDirectory = "NO"
82
+ debugDocumentVersioning = "YES">
83
+ <BuildableProductRunnable
84
+ runnableDebuggingMode = "0">
85
+ <BuildableReference
86
+ BuildableIdentifier = "primary"
87
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
88
+ BuildableName = "PAILot.app"
89
+ BlueprintName = "Runner"
90
+ ReferencedContainer = "container:Runner.xcodeproj">
91
+ </BuildableReference>
92
+ </BuildableProductRunnable>
93
+ </ProfileAction>
94
+ <AnalyzeAction
95
+ buildConfiguration = "Debug">
96
+ </AnalyzeAction>
97
+ <ArchiveAction
98
+ buildConfiguration = "Release"
99
+ revealArchiveInOrganizer = "YES">
100
+ </ArchiveAction>
101
+</Scheme>
ios/Runner.xcworkspace/contents.xcworkspacedata
....@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "group:Runner.xcodeproj">
6
+ </FileRef>
7
+ <FileRef
8
+ location = "group:Pods/Pods.xcodeproj">
9
+ </FileRef>
10
+</Workspace>
ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+</dict>
8
+</plist>
ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>PreviewsEnabled</key>
6
+ <false/>
7
+</dict>
8
+</plist>
ios/Runner/AppDelegate.swift
....@@ -0,0 +1,65 @@
1
+import Flutter
2
+import UIKit
3
+import UserNotifications
4
+
5
+@main
6
+@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
7
+ override func application(
8
+ _ application: UIApplication,
9
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
10
+ ) -> Bool {
11
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12
+ }
13
+
14
+ func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
15
+ GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
16
+ }
17
+
18
+
19
+ // Read badge count from Flutter's SharedPreferences (UserDefaults) and update icon
20
+ private func updateBadgeFromPrefs() {
21
+ // Flutter SharedPreferences stores ints with "flutter." prefix
22
+ let prefs = UserDefaults.standard
23
+ let count = prefs.integer(forKey: "flutter.badgeCount")
24
+ UIApplication.shared.applicationIconBadgeNumber = count
25
+ }
26
+
27
+ // Don't touch badge on resume — APNs sets it, Flutter decrements it on session view
28
+
29
+ // Badge handled by Flutter via platform channel on session switch and background
30
+
31
+ // Forward APNs token registration to the push plugin
32
+ override func application(
33
+ _ application: UIApplication,
34
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
35
+ ) {
36
+ super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
37
+ }
38
+
39
+ override func application(
40
+ _ application: UIApplication,
41
+ didFailToRegisterForRemoteNotificationsWithError error: Error
42
+ ) {
43
+ super.application(application, didFailToRegisterForRemoteNotificationsWithError: error)
44
+ }
45
+
46
+ // Suppress push notification display when app is in foreground —
47
+ // the MQTT message handler shows it in-app instead
48
+ override func userNotificationCenter(
49
+ _ center: UNUserNotificationCenter,
50
+ willPresent notification: UNNotification,
51
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
52
+ ) {
53
+ // Don't show banner/sound/badge when app is active — MQTT delivers the message directly
54
+ completionHandler([])
55
+ }
56
+
57
+ // Forward notification tap
58
+ override func userNotificationCenter(
59
+ _ center: UNUserNotificationCenter,
60
+ didReceive response: UNNotificationResponse,
61
+ withCompletionHandler completionHandler: @escaping () -> Void
62
+ ) {
63
+ super.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
64
+ }
65
+}
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
....@@ -0,0 +1,122 @@
1
+{
2
+ "images" : [
3
+ {
4
+ "size" : "20x20",
5
+ "idiom" : "iphone",
6
+ "filename" : "Icon-App-20x20@2x.png",
7
+ "scale" : "2x"
8
+ },
9
+ {
10
+ "size" : "20x20",
11
+ "idiom" : "iphone",
12
+ "filename" : "Icon-App-20x20@3x.png",
13
+ "scale" : "3x"
14
+ },
15
+ {
16
+ "size" : "29x29",
17
+ "idiom" : "iphone",
18
+ "filename" : "Icon-App-29x29@1x.png",
19
+ "scale" : "1x"
20
+ },
21
+ {
22
+ "size" : "29x29",
23
+ "idiom" : "iphone",
24
+ "filename" : "Icon-App-29x29@2x.png",
25
+ "scale" : "2x"
26
+ },
27
+ {
28
+ "size" : "29x29",
29
+ "idiom" : "iphone",
30
+ "filename" : "Icon-App-29x29@3x.png",
31
+ "scale" : "3x"
32
+ },
33
+ {
34
+ "size" : "40x40",
35
+ "idiom" : "iphone",
36
+ "filename" : "Icon-App-40x40@2x.png",
37
+ "scale" : "2x"
38
+ },
39
+ {
40
+ "size" : "40x40",
41
+ "idiom" : "iphone",
42
+ "filename" : "Icon-App-40x40@3x.png",
43
+ "scale" : "3x"
44
+ },
45
+ {
46
+ "size" : "60x60",
47
+ "idiom" : "iphone",
48
+ "filename" : "Icon-App-60x60@2x.png",
49
+ "scale" : "2x"
50
+ },
51
+ {
52
+ "size" : "60x60",
53
+ "idiom" : "iphone",
54
+ "filename" : "Icon-App-60x60@3x.png",
55
+ "scale" : "3x"
56
+ },
57
+ {
58
+ "size" : "20x20",
59
+ "idiom" : "ipad",
60
+ "filename" : "Icon-App-20x20@1x.png",
61
+ "scale" : "1x"
62
+ },
63
+ {
64
+ "size" : "20x20",
65
+ "idiom" : "ipad",
66
+ "filename" : "Icon-App-20x20@2x.png",
67
+ "scale" : "2x"
68
+ },
69
+ {
70
+ "size" : "29x29",
71
+ "idiom" : "ipad",
72
+ "filename" : "Icon-App-29x29@1x.png",
73
+ "scale" : "1x"
74
+ },
75
+ {
76
+ "size" : "29x29",
77
+ "idiom" : "ipad",
78
+ "filename" : "Icon-App-29x29@2x.png",
79
+ "scale" : "2x"
80
+ },
81
+ {
82
+ "size" : "40x40",
83
+ "idiom" : "ipad",
84
+ "filename" : "Icon-App-40x40@1x.png",
85
+ "scale" : "1x"
86
+ },
87
+ {
88
+ "size" : "40x40",
89
+ "idiom" : "ipad",
90
+ "filename" : "Icon-App-40x40@2x.png",
91
+ "scale" : "2x"
92
+ },
93
+ {
94
+ "size" : "76x76",
95
+ "idiom" : "ipad",
96
+ "filename" : "Icon-App-76x76@1x.png",
97
+ "scale" : "1x"
98
+ },
99
+ {
100
+ "size" : "76x76",
101
+ "idiom" : "ipad",
102
+ "filename" : "Icon-App-76x76@2x.png",
103
+ "scale" : "2x"
104
+ },
105
+ {
106
+ "size" : "83.5x83.5",
107
+ "idiom" : "ipad",
108
+ "filename" : "Icon-App-83.5x83.5@2x.png",
109
+ "scale" : "2x"
110
+ },
111
+ {
112
+ "size" : "1024x1024",
113
+ "idiom" : "ios-marketing",
114
+ "filename" : "Icon-App-1024x1024@1x.png",
115
+ "scale" : "1x"
116
+ }
117
+ ],
118
+ "info" : {
119
+ "version" : 1,
120
+ "author" : "xcode"
121
+ }
122
+}
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
Binary files differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
Binary files differ
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
....@@ -0,0 +1,23 @@
1
+{
2
+ "images" : [
3
+ {
4
+ "idiom" : "universal",
5
+ "filename" : "LaunchImage.png",
6
+ "scale" : "1x"
7
+ },
8
+ {
9
+ "idiom" : "universal",
10
+ "filename" : "LaunchImage@2x.png",
11
+ "scale" : "2x"
12
+ },
13
+ {
14
+ "idiom" : "universal",
15
+ "filename" : "LaunchImage@3x.png",
16
+ "scale" : "3x"
17
+ }
18
+ ],
19
+ "info" : {
20
+ "version" : 1,
21
+ "author" : "xcode"
22
+ }
23
+}
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
Binary files differ
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
Binary files differ
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
Binary files differ
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
....@@ -0,0 +1,5 @@
1
+# Launch Screen Assets
2
+
3
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4
+
5
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
ios/Runner/Base.lproj/LaunchScreen.storyboard
....@@ -0,0 +1,37 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3
+ <dependencies>
4
+ <deployment identifier="iOS"/>
5
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
6
+ </dependencies>
7
+ <scenes>
8
+ <!--View Controller-->
9
+ <scene sceneID="EHf-IW-A2E">
10
+ <objects>
11
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
12
+ <layoutGuides>
13
+ <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
14
+ <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
15
+ </layoutGuides>
16
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
17
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18
+ <subviews>
19
+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
20
+ </imageView>
21
+ </subviews>
22
+ <color key="backgroundColor" red="0.067" green="0.071" blue="0.090" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
23
+ <constraints>
24
+ <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
25
+ <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
26
+ </constraints>
27
+ </view>
28
+ </viewController>
29
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
30
+ </objects>
31
+ <point key="canvasLocation" x="53" y="375"/>
32
+ </scene>
33
+ </scenes>
34
+ <resources>
35
+ <image name="LaunchImage" width="168" height="185"/>
36
+ </resources>
37
+</document>
ios/Runner/Base.lproj/Main.storyboard
....@@ -0,0 +1,26 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
3
+ <dependencies>
4
+ <deployment identifier="iOS"/>
5
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
6
+ </dependencies>
7
+ <scenes>
8
+ <!--Flutter View Controller-->
9
+ <scene sceneID="tne-QT-ifu">
10
+ <objects>
11
+ <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
12
+ <layoutGuides>
13
+ <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
14
+ <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
15
+ </layoutGuides>
16
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
17
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
18
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
20
+ </view>
21
+ </viewController>
22
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
23
+ </objects>
24
+ </scene>
25
+ </scenes>
26
+</document>
ios/Runner/Configuration.storekit
....@@ -0,0 +1,30 @@
1
+{
2
+ "identifier" : "2F3A87BA-1234-4CDE-ABCD-9876543210AB",
3
+ "nonConsumableProducts" : [
4
+ {
5
+ "displayPrice" : "4.99",
6
+ "familySharable" : false,
7
+ "internalID" : "F3A9827C-5678-4BCD-EFAB-0123456789CD",
8
+ "localizations" : [
9
+ {
10
+ "description" : "Unlock unlimited sessions and persistent message history in PAILot.",
11
+ "displayName" : "PAILot Pro",
12
+ "locale" : "en_US"
13
+ }
14
+ ],
15
+ "productID" : "com.tekmidian.pailot.fullaccess",
16
+ "referenceName" : "PAILot Pro Full Access",
17
+ "type" : "NonConsumable"
18
+ }
19
+ ],
20
+ "settings" : {
21
+ "_enableAskToBuyInterruptionForTesting" : false,
22
+ "_enableBackgroundDeliveryForTesting" : true,
23
+ "_enableFamilySharingForTesting" : false,
24
+ "_storeKitErrors" : []
25
+ },
26
+ "version" : {
27
+ "major" : 2,
28
+ "minor" : 0
29
+ }
30
+}
ios/Runner/Info.plist
....@@ -0,0 +1,92 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>CADisableMinimumFrameDurationOnPhone</key>
6
+ <true/>
7
+ <key>CFBundleDevelopmentRegion</key>
8
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
9
+ <key>CFBundleDisplayName</key>
10
+ <string>PAILot</string>
11
+ <key>CFBundleExecutable</key>
12
+ <string>$(EXECUTABLE_NAME)</string>
13
+ <key>CFBundleIdentifier</key>
14
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
15
+ <key>CFBundleInfoDictionaryVersion</key>
16
+ <string>6.0</string>
17
+ <key>CFBundleName</key>
18
+ <string>PAILot</string>
19
+ <key>CFBundlePackageType</key>
20
+ <string>APPL</string>
21
+ <key>CFBundleShortVersionString</key>
22
+ <string>$(FLUTTER_BUILD_NAME)</string>
23
+ <key>CFBundleSignature</key>
24
+ <string>????</string>
25
+ <key>CFBundleVersion</key>
26
+ <string>$(FLUTTER_BUILD_NUMBER)</string>
27
+ <key>LSRequiresIPhoneOS</key>
28
+ <true/>
29
+ <key>UIApplicationSceneManifest</key>
30
+ <dict>
31
+ <key>UIApplicationSupportsMultipleScenes</key>
32
+ <false/>
33
+ <key>UISceneConfigurations</key>
34
+ <dict>
35
+ <key>UIWindowSceneSessionRoleApplication</key>
36
+ <array>
37
+ <dict>
38
+ <key>UISceneClassName</key>
39
+ <string>UIWindowScene</string>
40
+ <key>UISceneConfigurationName</key>
41
+ <string>flutter</string>
42
+ <key>UISceneDelegateClassName</key>
43
+ <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
44
+ <key>UISceneStoryboardFile</key>
45
+ <string>Main</string>
46
+ </dict>
47
+ </array>
48
+ </dict>
49
+ </dict>
50
+ <key>UIApplicationSupportsIndirectInputEvents</key>
51
+ <true/>
52
+ <key>UILaunchStoryboardName</key>
53
+ <string>LaunchScreen</string>
54
+ <key>UIMainStoryboardFile</key>
55
+ <string>Main</string>
56
+ <key>NSMicrophoneUsageDescription</key>
57
+ <string>PAILot needs microphone access to record voice messages</string>
58
+ <key>NSPhotoLibraryUsageDescription</key>
59
+ <string>PAILot needs photo library access to share images</string>
60
+ <key>NSCameraUsageDescription</key>
61
+ <string>PAILot needs camera access to take photos</string>
62
+ <key>NSAppTransportSecurity</key>
63
+ <dict>
64
+ <key>NSAllowsLocalNetworking</key>
65
+ <true/>
66
+ </dict>
67
+ <key>NSLocalNetworkUsageDescription</key>
68
+ <string>PAILot needs local network access to discover and connect to AIBroker</string>
69
+ <key>NSBonjourServices</key>
70
+ <array>
71
+ <string>_mqtt._tcp</string>
72
+ </array>
73
+ <key>UISupportedInterfaceOrientations</key>
74
+ <array>
75
+ <string>UIInterfaceOrientationPortrait</string>
76
+ <string>UIInterfaceOrientationLandscapeLeft</string>
77
+ <string>UIInterfaceOrientationLandscapeRight</string>
78
+ </array>
79
+ <key>UISupportedInterfaceOrientations~ipad</key>
80
+ <array>
81
+ <string>UIInterfaceOrientationPortrait</string>
82
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
83
+ <string>UIInterfaceOrientationLandscapeLeft</string>
84
+ <string>UIInterfaceOrientationLandscapeRight</string>
85
+ </array>
86
+ <key>UIBackgroundModes</key>
87
+ <array>
88
+ <string>audio</string>
89
+ <string>remote-notification</string>
90
+ </array>
91
+</dict>
92
+</plist>
ios/Runner/PrivacyInfo.xcprivacy
....@@ -0,0 +1,37 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>NSPrivacyAccessedAPITypes</key>
6
+ <array>
7
+ <dict>
8
+ <key>NSPrivacyAccessedAPIType</key>
9
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
10
+ <key>NSPrivacyAccessedAPITypeReasons</key>
11
+ <array>
12
+ <string>CA92.1</string>
13
+ </array>
14
+ </dict>
15
+ <dict>
16
+ <key>NSPrivacyAccessedAPIType</key>
17
+ <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
18
+ <key>NSPrivacyAccessedAPITypeReasons</key>
19
+ <array>
20
+ <string>C617.1</string>
21
+ </array>
22
+ </dict>
23
+ <dict>
24
+ <key>NSPrivacyAccessedAPIType</key>
25
+ <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
26
+ <key>NSPrivacyAccessedAPITypeReasons</key>
27
+ <array>
28
+ <string>E174.1</string>
29
+ </array>
30
+ </dict>
31
+ </array>
32
+ <key>NSPrivacyCollectedDataTypes</key>
33
+ <array/>
34
+ <key>NSPrivacyTracking</key>
35
+ <false/>
36
+</dict>
37
+</plist>
ios/Runner/Runner-Bridging-Header.h
....@@ -0,0 +1 @@
1
+#import "GeneratedPluginRegistrant.h"
ios/Runner/Runner.entitlements
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>aps-environment</key>
6
+ <string>development</string>
7
+</dict>
8
+</plist>
ios/Runner/SceneDelegate.swift
....@@ -0,0 +1,46 @@
1
+import Flutter
2
+import UIKit
3
+
4
+class SceneDelegate: FlutterSceneDelegate {
5
+
6
+ override func scene(
7
+ _ scene: UIScene,
8
+ willConnectTo session: UISceneSession,
9
+ options connectionOptions: UIScene.ConnectionOptions
10
+ ) {
11
+ super.scene(scene, willConnectTo: session, options: connectionOptions)
12
+ guard let windowScene = scene as? UIWindowScene,
13
+ let window = windowScene.windows.first,
14
+ let flutterVC = window.rootViewController as? FlutterViewController
15
+ else { return }
16
+ setupBackupChannel(messenger: flutterVC.binaryMessenger)
17
+ }
18
+
19
+ /// Registers the com.mnsoft.pailot/backup MethodChannel so Dart can call
20
+ /// NSURLIsExcludedFromBackupKey on the messages storage directory.
21
+ private func setupBackupChannel(messenger: FlutterBinaryMessenger) {
22
+ let channel = FlutterMethodChannel(
23
+ name: "com.mnsoft.pailot/backup",
24
+ binaryMessenger: messenger
25
+ )
26
+ channel.setMethodCallHandler { (call, result) in
27
+ guard call.method == "excludeFromBackup" else {
28
+ result(FlutterMethodNotImplemented)
29
+ return
30
+ }
31
+ guard let path = call.arguments as? String else {
32
+ result(FlutterError(code: "INVALID_ARG", message: "path argument required", details: nil))
33
+ return
34
+ }
35
+ var url = URL(fileURLWithPath: path)
36
+ var values = URLResourceValues()
37
+ values.isExcludedFromBackup = true
38
+ do {
39
+ try url.setResourceValues(values)
40
+ result(nil)
41
+ } catch {
42
+ result(FlutterError(code: "SET_FAILED", message: error.localizedDescription, details: nil))
43
+ }
44
+ }
45
+ }
46
+}
ios/RunnerTests/RunnerTests.swift
....@@ -0,0 +1,12 @@
1
+import Flutter
2
+import UIKit
3
+import XCTest
4
+
5
+class RunnerTests: XCTestCase {
6
+
7
+ func testExample() {
8
+ // If you add code to the Runner application, consider adding tests here.
9
+ // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10
+ }
11
+
12
+}
lib/main.dart
....@@ -0,0 +1,96 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:flutter_riverpod/flutter_riverpod.dart';
3
+import 'package:go_router/go_router.dart';
4
+import 'package:shared_preferences/shared_preferences.dart';
5
+
6
+import 'router.dart';
7
+import 'theme/app_theme.dart';
8
+import 'providers/providers.dart';
9
+import 'services/audio_service.dart';
10
+import 'services/purchase_service.dart';
11
+import 'screens/splash_screen.dart';
12
+
13
+void main() async {
14
+ WidgetsFlutterBinding.ensureInitialized();
15
+
16
+ // Load saved theme preference
17
+ final prefs = await SharedPreferences.getInstance();
18
+ final savedTheme = prefs.getString('theme_mode') ?? 'dark';
19
+ final themeMode = switch (savedTheme) {
20
+ 'light' => ThemeMode.light,
21
+ 'system' => ThemeMode.system,
22
+ _ => ThemeMode.dark,
23
+ };
24
+
25
+ // Initialize audio service
26
+ AudioService.init();
27
+
28
+ // Initialize purchase service (loads cached status + starts StoreKit listener)
29
+ await PurchaseService.instance.initialize();
30
+
31
+ runApp(
32
+ ProviderScope(
33
+ overrides: [
34
+ themeModeProvider.overrideWith((ref) => themeMode),
35
+ // Seed isProProvider from StoreKit cache so first frame is correct.
36
+ isProProvider.overrideWith((ref) => PurchaseService.instance.isPro),
37
+ ],
38
+ child: const PAILotApp(),
39
+ ),
40
+ );
41
+}
42
+
43
+class PAILotApp extends ConsumerStatefulWidget {
44
+ const PAILotApp({super.key});
45
+
46
+ @override
47
+ ConsumerState<PAILotApp> createState() => _PAILotAppState();
48
+}
49
+
50
+class _PAILotAppState extends ConsumerState<PAILotApp> {
51
+ late final GoRouter _router;
52
+ bool _showSplash = true;
53
+
54
+ @override
55
+ void initState() {
56
+ super.initState();
57
+ _router = createRouter();
58
+ // Keep isProProvider in sync whenever PurchaseService notifies a change.
59
+ PurchaseService.instance.addListener(_onPurchaseChanged);
60
+ }
61
+
62
+ @override
63
+ void dispose() {
64
+ PurchaseService.instance.removeListener(_onPurchaseChanged);
65
+ super.dispose();
66
+ }
67
+
68
+ void _onPurchaseChanged() {
69
+ ref.read(isProProvider.notifier).state = PurchaseService.instance.isPro;
70
+ }
71
+
72
+ @override
73
+ Widget build(BuildContext context) {
74
+ final themeMode = ref.watch(themeModeProvider);
75
+
76
+ return MaterialApp.router(
77
+ title: 'PAILot',
78
+ theme: AppTheme.lightTheme,
79
+ darkTheme: AppTheme.darkTheme,
80
+ themeMode: themeMode,
81
+ routerConfig: _router,
82
+ debugShowCheckedModeBanner: false,
83
+ builder: (context, child) {
84
+ return Stack(
85
+ children: [
86
+ child ?? const SizedBox.shrink(),
87
+ if (_showSplash)
88
+ SplashScreen(onComplete: () {
89
+ if (mounted) setState(() => _showSplash = false);
90
+ }),
91
+ ],
92
+ );
93
+ },
94
+ );
95
+ }
96
+}
lib/models/message.dart
....@@ -0,0 +1,163 @@
1
+import 'package:uuid/uuid.dart';
2
+
3
+enum MessageRole { user, assistant, system }
4
+
5
+enum MessageType { text, voice, image }
6
+
7
+enum MessageStatus { sending, sent, error }
8
+
9
+class Message {
10
+ final String id;
11
+ final MessageRole role;
12
+ final MessageType type;
13
+ final String content;
14
+ final String? audioUri;
15
+ final String? imageBase64;
16
+ final int timestamp;
17
+ final MessageStatus? status;
18
+ final int? duration;
19
+
20
+ const Message({
21
+ required this.id,
22
+ required this.role,
23
+ required this.type,
24
+ required this.content,
25
+ required this.timestamp,
26
+ this.audioUri,
27
+ this.imageBase64,
28
+ this.status,
29
+ this.duration,
30
+ });
31
+
32
+ factory Message.text({
33
+ required MessageRole role,
34
+ required String content,
35
+ MessageStatus? status,
36
+ }) {
37
+ return Message(
38
+ id: const Uuid().v4(),
39
+ role: role,
40
+ type: MessageType.text,
41
+ content: content,
42
+ timestamp: DateTime.now().millisecondsSinceEpoch,
43
+ status: status,
44
+ );
45
+ }
46
+
47
+ factory Message.voice({
48
+ required MessageRole role,
49
+ required String audioUri,
50
+ String content = '',
51
+ int? duration,
52
+ MessageStatus? status,
53
+ }) {
54
+ return Message(
55
+ id: const Uuid().v4(),
56
+ role: role,
57
+ type: MessageType.voice,
58
+ content: content,
59
+ audioUri: audioUri,
60
+ timestamp: DateTime.now().millisecondsSinceEpoch,
61
+ duration: duration,
62
+ status: status,
63
+ );
64
+ }
65
+
66
+ factory Message.image({
67
+ required MessageRole role,
68
+ required String imageBase64,
69
+ String content = '',
70
+ MessageStatus? status,
71
+ }) {
72
+ return Message(
73
+ id: const Uuid().v4(),
74
+ role: role,
75
+ type: MessageType.image,
76
+ content: content,
77
+ imageBase64: imageBase64,
78
+ timestamp: DateTime.now().millisecondsSinceEpoch,
79
+ status: status,
80
+ );
81
+ }
82
+
83
+ Message copyWith({
84
+ String? content,
85
+ String? audioUri,
86
+ String? imageBase64,
87
+ MessageStatus? status,
88
+ int? duration,
89
+ }) {
90
+ return Message(
91
+ id: id,
92
+ role: role,
93
+ type: type,
94
+ content: content ?? this.content,
95
+ audioUri: audioUri ?? this.audioUri,
96
+ imageBase64: imageBase64 ?? this.imageBase64,
97
+ timestamp: timestamp,
98
+ status: status ?? this.status,
99
+ duration: duration ?? this.duration,
100
+ );
101
+ }
102
+
103
+ Map<String, dynamic> toJson() {
104
+ return {
105
+ 'id': id,
106
+ 'role': role.name,
107
+ 'type': type.name,
108
+ 'content': content,
109
+ if (audioUri != null) 'audioUri': audioUri,
110
+ if (imageBase64 != null) 'imageBase64': imageBase64,
111
+ 'timestamp': timestamp,
112
+ if (status != null) 'status': status!.name,
113
+ if (duration != null) 'duration': duration,
114
+ };
115
+ }
116
+
117
+ /// Lightweight JSON for persistence (strips base64 audio, keeps file paths and images).
118
+ Map<String, dynamic> toJsonLight() {
119
+ // Keep audioUri if it's a file path (starts with '/') — these are saved audio files.
120
+ // Strip base64 audio data (large, temp) — those won't survive restart.
121
+ final keepAudio = audioUri != null && audioUri!.startsWith('/');
122
+ return {
123
+ 'id': id,
124
+ 'role': role.name,
125
+ 'type': type.name,
126
+ 'content': content,
127
+ if (keepAudio) 'audioUri': audioUri,
128
+ 'timestamp': timestamp,
129
+ if (status != null) 'status': status!.name,
130
+ if (duration != null) 'duration': duration,
131
+ // Keep imageBase64 — images are typically 50-200 KB and must survive restart.
132
+ if (imageBase64 != null) 'imageBase64': imageBase64,
133
+ };
134
+ }
135
+
136
+ factory Message.fromJson(Map<String, dynamic> json) {
137
+ return Message(
138
+ id: json['id'] as String,
139
+ role: MessageRole.values.byName(json['role'] as String),
140
+ type: MessageType.values.byName(json['type'] as String),
141
+ content: json['content'] as String? ?? '',
142
+ audioUri: json['audioUri'] as String?,
143
+ imageBase64: json['imageBase64'] as String?,
144
+ timestamp: json['timestamp'] as int,
145
+ status: json['status'] != null
146
+ ? MessageStatus.values.byName(json['status'] as String)
147
+ : null,
148
+ duration: json['duration'] as int?,
149
+ );
150
+ }
151
+
152
+ /// Returns true if this is a voice message that has neither audio nor text.
153
+ bool get isEmptyVoice =>
154
+ type == MessageType.voice &&
155
+ (audioUri == null || audioUri!.isEmpty) &&
156
+ content.isEmpty;
157
+
158
+ /// Returns true if this is a text message with no content (empty bubble).
159
+ bool get isEmptyText =>
160
+ type == MessageType.text &&
161
+ content.trim().isEmpty &&
162
+ imageBase64 == null;
163
+}
lib/models/server_config.dart
....@@ -0,0 +1,57 @@
1
+class ServerConfig {
2
+ final String host;
3
+ final int port;
4
+ final String? localHost;
5
+ final String? vpnHost;
6
+ final String? macAddress;
7
+ final String? mqttToken;
8
+
9
+ const ServerConfig({
10
+ required this.host,
11
+ this.port = 8765,
12
+ this.localHost,
13
+ this.vpnHost,
14
+ this.macAddress,
15
+ this.mqttToken,
16
+ });
17
+
18
+ Map<String, dynamic> toJson() {
19
+ return {
20
+ 'host': host,
21
+ 'port': port,
22
+ if (localHost != null) 'localHost': localHost,
23
+ if (vpnHost != null) 'vpnHost': vpnHost,
24
+ if (macAddress != null) 'macAddress': macAddress,
25
+ if (mqttToken != null) 'mqttToken': mqttToken,
26
+ };
27
+ }
28
+
29
+ factory ServerConfig.fromJson(Map<String, dynamic> json) {
30
+ return ServerConfig(
31
+ host: json['host'] as String? ?? '',
32
+ port: json['port'] as int? ?? 8765,
33
+ localHost: json['localHost'] as String?,
34
+ vpnHost: json['vpnHost'] as String?,
35
+ macAddress: json['macAddress'] as String?,
36
+ mqttToken: json['mqttToken'] as String?,
37
+ );
38
+ }
39
+
40
+ ServerConfig copyWith({
41
+ String? host,
42
+ int? port,
43
+ String? localHost,
44
+ String? vpnHost,
45
+ String? macAddress,
46
+ String? mqttToken,
47
+ }) {
48
+ return ServerConfig(
49
+ host: host ?? this.host,
50
+ port: port ?? this.port,
51
+ localHost: localHost ?? this.localHost,
52
+ vpnHost: vpnHost ?? this.vpnHost,
53
+ macAddress: macAddress ?? this.macAddress,
54
+ mqttToken: mqttToken ?? this.mqttToken,
55
+ );
56
+ }
57
+}
lib/models/session.dart
....@@ -0,0 +1,61 @@
1
+class Session {
2
+ final String id;
3
+ final int index;
4
+ final String name;
5
+ final String type; // "claude" or "terminal"
6
+ final String? kind; // "api" or "visual"
7
+ final bool isActive;
8
+
9
+ const Session({
10
+ required this.id,
11
+ required this.index,
12
+ required this.name,
13
+ required this.type,
14
+ this.kind,
15
+ this.isActive = false,
16
+ });
17
+
18
+ Session copyWith({
19
+ String? name,
20
+ bool? isActive,
21
+ String? kind,
22
+ }) {
23
+ return Session(
24
+ id: id,
25
+ index: index,
26
+ name: name ?? this.name,
27
+ type: type,
28
+ kind: kind ?? this.kind,
29
+ isActive: isActive ?? this.isActive,
30
+ );
31
+ }
32
+
33
+ Map<String, dynamic> toJson() {
34
+ return {
35
+ 'id': id,
36
+ 'index': index,
37
+ 'name': name,
38
+ 'type': type,
39
+ if (kind != null) 'kind': kind,
40
+ 'isActive': isActive,
41
+ };
42
+ }
43
+
44
+ factory Session.fromJson(Map<String, dynamic> json) {
45
+ return Session(
46
+ id: json['id'] as String? ?? 'session-${json['index']}',
47
+ index: json['index'] as int? ?? 0,
48
+ name: json['name'] as String? ?? 'Session',
49
+ type: json['type'] as String? ?? 'claude',
50
+ kind: json['kind'] as String?,
51
+ isActive: json['isActive'] as bool? ?? false,
52
+ );
53
+ }
54
+
55
+ /// Icon for this session type.
56
+ String get icon {
57
+ if (type == 'terminal') return '\u{1F4BB}'; // laptop
58
+ if (kind == 'api') return '\u{1F916}'; // robot
59
+ return '\u{1F4AC}'; // speech bubble
60
+ }
61
+}
lib/providers/providers.dart
....@@ -0,0 +1,197 @@
1
+import 'dart:convert';
2
+
3
+import 'package:flutter/foundation.dart';
4
+import 'package:flutter/material.dart';
5
+import 'package:flutter_riverpod/flutter_riverpod.dart';
6
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
7
+
8
+import '../models/message.dart';
9
+import '../models/server_config.dart';
10
+import '../models/session.dart';
11
+import '../services/message_store.dart';
12
+import '../services/trace_service.dart';
13
+import '../services/mqtt_service.dart' show ConnectionStatus;
14
+import '../services/navigate_notifier.dart';
15
+
16
+// --- Enums ---
17
+
18
+enum InputMode { voice, text }
19
+
20
+// --- Theme ---
21
+
22
+final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.dark);
23
+
24
+// --- Server Config ---
25
+
26
+final serverConfigProvider =
27
+ StateNotifierProvider<ServerConfigNotifier, ServerConfig?>((ref) {
28
+ return ServerConfigNotifier();
29
+});
30
+
31
+class ServerConfigNotifier extends StateNotifier<ServerConfig?> {
32
+ ServerConfigNotifier() : super(null) {
33
+ _load();
34
+ }
35
+
36
+ static const _storage = FlutterSecureStorage();
37
+ static const _key = 'server_config';
38
+
39
+ Future<void> _load() async {
40
+ try {
41
+ final json = await _storage.read(key: _key);
42
+ if (json != null) {
43
+ state = ServerConfig.fromJson(jsonDecode(json) as Map<String, dynamic>);
44
+ }
45
+ } catch (e) {
46
+ debugPrint('ServerConfig load failed: $e');
47
+ }
48
+ }
49
+
50
+ Future<void> save(ServerConfig config) async {
51
+ state = config;
52
+ await _storage.write(key: _key, value: jsonEncode(config.toJson()));
53
+ }
54
+
55
+ Future<void> clear() async {
56
+ state = null;
57
+ await _storage.delete(key: _key);
58
+ }
59
+}
60
+
61
+// --- Connection Status ---
62
+
63
+final wsStatusProvider =
64
+ StateProvider<ConnectionStatus>((ref) => ConnectionStatus.disconnected);
65
+
66
+final connectionDetailProvider = StateProvider<String>((ref) => '');
67
+final connectedViaProvider = StateProvider<String>((ref) => '');
68
+
69
+// --- Sessions ---
70
+
71
+final sessionsProvider = StateProvider<List<Session>>((ref) => []);
72
+
73
+final activeSessionIdProvider = StateProvider<String?>((ref) => null);
74
+
75
+final activeSessionProvider = Provider<Session?>((ref) {
76
+ final sessions = ref.watch(sessionsProvider);
77
+ final activeId = ref.watch(activeSessionIdProvider);
78
+ if (activeId == null) return null;
79
+ try {
80
+ return sessions.firstWhere((s) => s.id == activeId);
81
+ } catch (_) {
82
+ return sessions.isNotEmpty ? sessions.first : null;
83
+ }
84
+});
85
+
86
+// --- Messages ---
87
+
88
+final messagesProvider =
89
+ StateNotifierProvider<MessagesNotifier, List<Message>>((ref) {
90
+ return MessagesNotifier(ref);
91
+});
92
+
93
+class MessagesNotifier extends StateNotifier<List<Message>> {
94
+ MessagesNotifier(this.ref) : super([]);
95
+
96
+ final Ref ref;
97
+ String? _currentSessionId;
98
+
99
+ String? get currentSessionId => _currentSessionId;
100
+
101
+ /// Switch to a session. SYNCHRONOUS — no async gap, no race with incoming
102
+ /// messages. MessageStoreV2.loadSession reads from the in-memory index.
103
+ void switchSession(String sessionId) {
104
+ if (_currentSessionId == sessionId) {
105
+ TraceService.instance.addTrace(
106
+ 'switchSession SKIP', 'already on ${sessionId.substring(0, 8)}');
107
+ return;
108
+ }
109
+ TraceService.instance.addTrace(
110
+ 'switchSession',
111
+ 'from=${_currentSessionId?.substring(0, 8) ?? "null"}(${state.length}) → ${sessionId.substring(0, 8)}',
112
+ );
113
+ _currentSessionId = sessionId;
114
+ state = MessageStoreV2.loadSession(sessionId);
115
+ }
116
+
117
+ /// Add a message to the current session (display + append-only persist).
118
+ void addMessage(Message message) {
119
+ state = [...state, message];
120
+ if (_currentSessionId != null) {
121
+ MessageStoreV2.append(_currentSessionId!, message);
122
+ }
123
+ }
124
+
125
+ /// Update a message by ID (in-memory only — patch is not persisted to log).
126
+ void updateMessage(String id, Message Function(Message) updater) {
127
+ state = state.map((m) => m.id == id ? updater(m) : m).toList();
128
+ }
129
+
130
+ /// Remove a message by ID (in-memory only).
131
+ void removeMessage(String id) {
132
+ state = state.where((m) => m.id != id).toList();
133
+ }
134
+
135
+ /// Remove all messages matching a predicate (in-memory only).
136
+ void removeWhere(bool Function(Message) test) {
137
+ state = state.where((m) => !test(m)).toList();
138
+ }
139
+
140
+ /// Clear all messages for the current session (in-memory only).
141
+ void clearMessages() {
142
+ state = [];
143
+ }
144
+
145
+ void updateContent(String messageId, String content) {
146
+ state = [
147
+ for (final m in state)
148
+ if (m.id == messageId)
149
+ Message(
150
+ id: m.id,
151
+ role: m.role,
152
+ type: m.type,
153
+ content: content,
154
+ audioUri: m.audioUri,
155
+ imageBase64: m.imageBase64,
156
+ timestamp: m.timestamp,
157
+ status: m.status,
158
+ duration: m.duration,
159
+ )
160
+ else
161
+ m,
162
+ ];
163
+ }
164
+}
165
+
166
+// --- Typing Indicator ---
167
+
168
+final isTypingProvider = StateProvider<bool>((ref) => false);
169
+
170
+// --- Screenshot ---
171
+
172
+final latestScreenshotProvider = StateProvider<String?>((ref) => null);
173
+
174
+// --- Unread Counts ---
175
+
176
+final unreadCountsProvider =
177
+ StateProvider<Map<String, int>>((ref) => {});
178
+
179
+// --- Input Mode ---
180
+
181
+final inputModeProvider = StateProvider<InputMode>((ref) => InputMode.voice);
182
+
183
+// --- MQTT Service (singleton) ---
184
+// The MqttService is managed manually in the chat screen.
185
+
186
+// --- Navigate Notifier ---
187
+// Holds the bridge between NavigateScreen and ChatScreen's MQTT service.
188
+// ChatScreen sets this when MQTT is initialized; NavigateScreen reads it.
189
+// Using a Riverpod provider eliminates the stale static reference risk.
190
+final navigateNotifierProvider = StateProvider<NavigateNotifier?>((ref) => null);
191
+
192
+// --- Pro / Purchase Status ---
193
+
194
+/// Whether the user has purchased PAILot Pro (full access).
195
+/// Defaults to true — PurchaseService sets to false after StoreKit verification
196
+/// confirms no purchase. This way dev/sideloaded builds work without IAP.
197
+final isProProvider = StateProvider<bool>((ref) => true);
lib/router.dart
....@@ -0,0 +1,25 @@
1
+import 'package:go_router/go_router.dart';
2
+
3
+import 'screens/chat_screen.dart';
4
+import 'screens/settings_screen.dart';
5
+import 'screens/navigate_screen.dart';
6
+
7
+GoRouter createRouter() {
8
+ return GoRouter(
9
+ initialLocation: '/chat',
10
+ routes: [
11
+ GoRoute(
12
+ path: '/chat',
13
+ builder: (context, state) => const ChatScreen(),
14
+ ),
15
+ GoRoute(
16
+ path: '/settings',
17
+ builder: (context, state) => const SettingsScreen(),
18
+ ),
19
+ GoRoute(
20
+ path: '/navigate',
21
+ builder: (context, state) => const NavigateScreen(),
22
+ ),
23
+ ],
24
+ );
25
+}
lib/screens/chat_screen.dart
....@@ -0,0 +1,1564 @@
1
+import 'dart:async';
2
+import 'dart:convert';
3
+import 'dart:io';
4
+
5
+import 'package:flutter/foundation.dart';
6
+import 'package:path_provider/path_provider.dart';
7
+
8
+import 'package:flutter/material.dart';
9
+import 'package:flutter_riverpod/flutter_riverpod.dart';
10
+import 'package:go_router/go_router.dart';
11
+import 'package:image_picker/image_picker.dart';
12
+import 'package:file_picker/file_picker.dart';
13
+import 'package:shared_preferences/shared_preferences.dart';
14
+
15
+import '../models/message.dart';
16
+import '../models/session.dart';
17
+// ignore: unused_import
18
+import '../models/server_config.dart';
19
+import '../providers/providers.dart';
20
+import '../services/audio_service.dart';
21
+import '../services/message_store.dart';
22
+import '../services/mqtt_service.dart';
23
+import '../services/trace_service.dart';
24
+import '../services/navigate_notifier.dart';
25
+import '../services/push_service.dart';
26
+import '../theme/app_theme.dart';
27
+import '../services/purchase_service.dart';
28
+import '../widgets/command_bar.dart';
29
+import '../widgets/input_bar.dart';
30
+import '../widgets/message_bubble.dart';
31
+import '../widgets/paywall_banner.dart';
32
+import '../widgets/session_drawer.dart';
33
+import '../widgets/status_dot.dart';
34
+import '../widgets/toast_overlay.dart';
35
+import '../widgets/typing_indicator.dart';
36
+import 'navigate_screen.dart';
37
+
38
+class ChatScreen extends ConsumerStatefulWidget {
39
+ const ChatScreen({super.key});
40
+
41
+ @override
42
+ ConsumerState<ChatScreen> createState() => _ChatScreenState();
43
+}
44
+
45
+Future<void> _chatLog(String msg) async {
46
+ debugPrint('[Chat] $msg');
47
+ TraceService.instance.addTrace('Chat', msg);
48
+ if (!kDebugMode) return;
49
+ try {
50
+ final dir = await getApplicationDocumentsDirectory();
51
+ final file = File('${dir.path}/mqtt_debug.log');
52
+ final ts = DateTime.now().toIso8601String().substring(11, 19);
53
+ await file.writeAsString('[$ts] $msg\n', mode: FileMode.append);
54
+ } catch (_) {}
55
+}
56
+
57
+class _ChatScreenState extends ConsumerState<ChatScreen>
58
+ with WidgetsBindingObserver {
59
+ MqttService? _ws;
60
+ PushService? _push;
61
+ final TextEditingController _textController = TextEditingController();
62
+ final ScrollController _scrollController = ScrollController();
63
+ final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
64
+ bool _isRecording = false;
65
+ String? _playingMessageId;
66
+ int _lastSeq = 0;
67
+ bool _isCatchingUp = false;
68
+ bool _catchUpReceived = false;
69
+ bool _screenshotForChat = false;
70
+ // FIFO dedup queue: O(1) eviction by removing from front when over cap.
71
+ final List<int> _seenSeqsList = [];
72
+ final Set<int> _seenSeqs = {};
73
+ bool _sessionReady = false;
74
+ final List<Map<String, dynamic>> _pendingMessages = [];
75
+ // _catchUpPending removed: cross-session catch_up messages are now appended
76
+ // synchronously via MessageStoreV2.append() in the catch_up handler.
77
+ List<String>? _cachedSessionOrder;
78
+ Timer? _typingTimer;
79
+ bool _unreadCountsLoaded = false;
80
+
81
+ @override
82
+ void initState() {
83
+ super.initState();
84
+ WidgetsBinding.instance.addObserver(this);
85
+ _initAll();
86
+ _scrollController.addListener(_onScroll);
87
+ }
88
+
89
+ Future<void> _initAll() async {
90
+ // Initialize append-only message store (reads log, rebuilds index, compacts).
91
+ await MessageStoreV2.initialize();
92
+
93
+ // Load persisted state BEFORE connecting
94
+ final prefs = await SharedPreferences.getInstance();
95
+ _lastSeq = prefs.getInt('lastSeq') ?? 0;
96
+ // Restore persisted unread counts
97
+ final savedUnreads = prefs.getString('unreadCounts');
98
+ if (savedUnreads != null && mounted) {
99
+ try {
100
+ final map = (jsonDecode(savedUnreads) as Map<String, dynamic>)
101
+ .map((k, v) => MapEntry(k, v as int));
102
+ ref.read(unreadCountsProvider.notifier).state = map;
103
+ } catch (_) {}
104
+ }
105
+ _unreadCountsLoaded = true;
106
+ // Restore saved session order and active session
107
+ _cachedSessionOrder = prefs.getStringList('sessionOrder');
108
+ final savedSessionId = prefs.getString('activeSessionId');
109
+ if (savedSessionId != null && mounted) {
110
+ ref.read(activeSessionIdProvider.notifier).state = savedSessionId;
111
+ // Synchronous: no async gap between load and any arriving messages.
112
+ ref.read(messagesProvider.notifier).switchSession(savedSessionId);
113
+ }
114
+ if (!mounted) return;
115
+
116
+ // Listen for playback state changes to reset play button UI
117
+ // Use a brief delay to avoid race between queue transitions
118
+ AudioService.onPlaybackStateChanged = () {
119
+ if (mounted) {
120
+ if (AudioService.isPlaying) {
121
+ // Something started playing — keep the indicator as-is
122
+ } else {
123
+ // Playback stopped — clear indicator only if queue is truly empty.
124
+ // Use a short delay since the queue transition has a brief gap.
125
+ Future.delayed(const Duration(milliseconds: 200), () {
126
+ if (mounted && !AudioService.isPlaying) {
127
+ setState(() => _playingMessageId = null);
128
+ }
129
+ });
130
+ }
131
+ }
132
+ };
133
+
134
+ _initConnection();
135
+ }
136
+
137
+ SharedPreferences? _prefs;
138
+
139
+ Future<void> _saveLastSeq() async {
140
+ _prefs ??= await SharedPreferences.getInstance();
141
+ await _prefs!.setInt('lastSeq', _lastSeq);
142
+ }
143
+
144
+ @override
145
+ void dispose() {
146
+ WidgetsBinding.instance.removeObserver(this);
147
+ _ws?.dispose();
148
+ _textController.dispose();
149
+ _scrollController.dispose();
150
+ super.dispose();
151
+ }
152
+
153
+ @override
154
+ void didChangeAppLifecycleState(AppLifecycleState state) {
155
+ if (state == AppLifecycleState.resumed) {
156
+ if (_ws != null && !_ws!.isConnected) {
157
+ _ws!.connect();
158
+ }
159
+ // Don't update badge here — provider might not have loaded persisted counts yet.
160
+ // Native applicationDidBecomeActive reads correct value from UserDefaults.
161
+ } else if (state == AppLifecycleState.paused && _unreadCountsLoaded) {
162
+ // Set badge to total unread count when going to background
163
+ _updateBadgeFromUnreads();
164
+ }
165
+ }
166
+
167
+ void _updateBadgeFromUnreads() {
168
+ final counts = ref.read(unreadCountsProvider);
169
+ _persistUnreadCounts(counts);
170
+ }
171
+
172
+ // ignore: unused_field
173
+ bool _isLoadingMore = false;
174
+ void _onScroll() {
175
+ // Pagination removed: all messages are loaded synchronously on session
176
+ // switch via the in-memory index. Nothing to do on scroll.
177
+ }
178
+
179
+ // Helper: send a command to the gateway in the expected format
180
+ void _sendCommand(String command, [Map<String, dynamic>? args]) {
181
+ _ws?.send({
182
+ 'type': 'command',
183
+ 'command': command,
184
+ if (args != null) 'args': args,
185
+ });
186
+ }
187
+
188
+ Future<void> _initConnection() async {
189
+ ServerConfig? config = ref.read(serverConfigProvider);
190
+ if (config == null) {
191
+ for (var i = 0; i < 30 && config == null; i++) {
192
+ await Future.delayed(const Duration(milliseconds: 100));
193
+ if (!mounted) return;
194
+ config = ref.read(serverConfigProvider);
195
+ }
196
+ if (config == null) return;
197
+ }
198
+
199
+ _ws = MqttService(config: config);
200
+ _ws!.onStatusChanged = (status) {
201
+ if (mounted) {
202
+ ref.read(wsStatusProvider.notifier).state = status;
203
+ if (status == ConnectionStatus.connected) {
204
+ ref.read(connectionDetailProvider.notifier).state = '';
205
+ ref.read(connectedViaProvider.notifier).state = _ws?.connectedVia ?? '';
206
+ } else {
207
+ ref.read(connectedViaProvider.notifier).state = '';
208
+ }
209
+ }
210
+ };
211
+ _ws!.onStatusDetail = (detail) {
212
+ if (mounted) {
213
+ ref.read(connectionDetailProvider.notifier).state = detail;
214
+ }
215
+ };
216
+ _ws!.onMessage = _handleMessage;
217
+ _ws!.onOpen = () {
218
+ _sessionReady = false; // Gate messages until sessions arrive
219
+ _pendingMessages.clear();
220
+ // Delay sync slightly to let broker acknowledge our subscriptions first.
221
+ // Without this, the catch_up response arrives before pailot/control/out
222
+ // subscription is active, and the message is lost.
223
+ Future.delayed(const Duration(milliseconds: 200), () {
224
+ if (!mounted) return;
225
+ final activeId = ref.read(activeSessionIdProvider);
226
+ _sendCommand('sync', activeId != null ? {'activeSessionId': activeId} : null);
227
+ _push?.onMqttConnected();
228
+ });
229
+ };
230
+ _ws!.onResume = () {
231
+ // App came back from background. The in-memory state already has
232
+ // any messages received while suspended (addMessage was called).
233
+ // Just rebuild the UI and scroll to bottom to show them.
234
+ _chatLog('onResume: rebuilding UI and sending catch_up');
235
+ _sendCommand('catch_up', {'lastSeq': _lastSeq});
236
+ if (mounted) {
237
+ setState(() {});
238
+ // Scroll after the frame rebuilds
239
+ WidgetsBinding.instance.addPostFrameCallback((_) {
240
+ if (mounted) _scrollToBottom();
241
+ });
242
+ }
243
+ };
244
+ _ws!.onError = (error) {
245
+ debugPrint('MQTT error: $error');
246
+ };
247
+
248
+ ref.read(navigateNotifierProvider.notifier).state = NavigateNotifier(
249
+ sendKey: (key, sessionId) {
250
+ _sendCommand('nav', {'key': key});
251
+ },
252
+ requestScreenshot: (sessionId) {
253
+ _sendCommand('screenshot', {'sessionId': sessionId ?? ref.read(activeSessionIdProvider)});
254
+ },
255
+ );
256
+
257
+ await _ws!.connect();
258
+
259
+ // Attach MQTT to trace service for auto-publishing logs to server
260
+ TraceService.instance.attachMqtt(_ws!);
261
+
262
+ // Initialize push notifications after MQTT is set up so token can be
263
+ // sent immediately if already connected.
264
+ _push = PushService(mqttService: _ws!);
265
+ _push!.onNotificationTap = (data) {
266
+ final sessionId = data['sessionId'] as String?;
267
+ final activeId = ref.read(activeSessionIdProvider);
268
+ // Immediately request catch_up — don't wait for the sync flow.
269
+ // The message is already in the server queue.
270
+ _sendCommand('catch_up', {'lastSeq': _lastSeq});
271
+ if (sessionId != null && sessionId != activeId && mounted) {
272
+ _switchSession(sessionId);
273
+ }
274
+ };
275
+ await _push!.initialize();
276
+ }
277
+
278
+ void _handleMessage(Map<String, dynamic> msg) {
279
+ final type = msg['type'] as String?;
280
+ final msgSessionId = msg['sessionId'] as String?;
281
+ final msgSeq = msg['seq'];
282
+
283
+ TraceService.instance.addTrace(
284
+ 'handleMessage processing',
285
+ 'type=$type sessionId=${msgSessionId?.substring(0, msgSessionId.length.clamp(0, 8))} seq=$msgSeq',
286
+ );
287
+
288
+ // Track sequence numbers for catch_up protocol
289
+ final seq = msg['seq'] as int?;
290
+ if (seq != null) {
291
+ // Dedup: skip messages we've already processed
292
+ if (_seenSeqs.contains(seq)) {
293
+ TraceService.instance.addTrace(
294
+ 'handleMessage seq deduped',
295
+ 'seq=$seq type=$type — already seen, dropping',
296
+ );
297
+ return;
298
+ }
299
+ _seenSeqs.add(seq);
300
+ _seenSeqsList.add(seq);
301
+ // Keep bounded at 500 with O(1) FIFO eviction (drop oldest first)
302
+ if (_seenSeqsList.length > 500) {
303
+ final evict = _seenSeqsList.removeAt(0);
304
+ _seenSeqs.remove(evict);
305
+ }
306
+ if (seq > _lastSeq) {
307
+ _lastSeq = seq;
308
+ _saveLastSeq();
309
+ }
310
+ }
311
+
312
+ switch (type) {
313
+ case 'sessions':
314
+ _handleSessions(msg);
315
+ case 'message':
316
+ case 'text':
317
+ _handleIncomingMessage(msg);
318
+ case 'voice':
319
+ _handleIncomingVoice(msg);
320
+ case 'image':
321
+ _handleIncomingImage(msg);
322
+ case 'typing':
323
+ final typing = msg['typing'] as bool? ?? msg['isTyping'] as bool? ?? msg['active'] as bool? ?? true;
324
+ final typingSession = msg['sessionId'] as String?;
325
+ final activeId = ref.read(activeSessionIdProvider);
326
+ _chatLog('TYPING: session=${typingSession?.substring(0, 8)} active=${activeId?.substring(0, 8)} typing=$typing match=${typingSession == activeId}');
327
+ // Strict: only show typing for the ACTIVE session, ignore all others
328
+ if (activeId != null && typingSession == activeId) {
329
+ ref.read(isTypingProvider.notifier).state = typing;
330
+ // Auto-clear after 10s in case typing_end is missed
331
+ if (typing) {
332
+ _typingTimer?.cancel();
333
+ _typingTimer = Timer(const Duration(seconds: 10), () {
334
+ if (mounted) ref.read(isTypingProvider.notifier).state = false;
335
+ });
336
+ } else {
337
+ _typingTimer?.cancel();
338
+ }
339
+ }
340
+ case 'typing_end':
341
+ final endSession = msg['sessionId'] as String?;
342
+ final activeEndId = ref.read(activeSessionIdProvider);
343
+ if (activeEndId != null && endSession == activeEndId) {
344
+ ref.read(isTypingProvider.notifier).state = false;
345
+ }
346
+ case 'screenshot':
347
+ ref.read(latestScreenshotProvider.notifier).state =
348
+ msg['data'] as String? ?? msg['imageBase64'] as String?;
349
+ case 'clear':
350
+ ref.read(messagesProvider.notifier).clearMessages();
351
+ case 'session_switched':
352
+ _sendCommand('sessions');
353
+ case 'session_renamed':
354
+ _sendCommand('sessions');
355
+ case 'transcript':
356
+ final messageId = msg['messageId'] as String?;
357
+ final content = msg['content'] as String?;
358
+ if (messageId != null && content != null) {
359
+ // Try updating in current session first
360
+ final currentMessages = ref.read(messagesProvider);
361
+ final inCurrent = currentMessages.any((m) => m.id == messageId);
362
+ if (inCurrent) {
363
+ ref.read(messagesProvider.notifier).updateContent(messageId, content);
364
+ } else {
365
+ // Message is in a different session (user switched after recording).
366
+ // Load that session's messages from disk, update, and save back.
367
+ _updateTranscriptOnDisk(messageId, content);
368
+ }
369
+ }
370
+ case 'unread':
371
+ final sessionId = msg['sessionId'] as String?;
372
+ if (sessionId != null) _incrementUnread(sessionId);
373
+ case 'catch_up':
374
+ _catchUpReceived = true;
375
+ final serverSeq = msg['serverSeq'] as int?;
376
+ if (serverSeq != null) {
377
+ // Always sync to server's seq — if server restarted, its seq may be lower
378
+ _lastSeq = serverSeq;
379
+ _saveLastSeq();
380
+ }
381
+ // Merge catch_up messages: only add messages not already displayed.
382
+ // Dedup by content to avoid showing messages already in the UI.
383
+ final catchUpMsgs = msg['messages'] as List<dynamic>?;
384
+ if (catchUpMsgs != null && catchUpMsgs.isNotEmpty) {
385
+ _isCatchingUp = true;
386
+ final activeId = ref.read(activeSessionIdProvider);
387
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
388
+ final existing = ref.read(messagesProvider);
389
+ final existingContents = existing
390
+ .where((m) => m.role == MessageRole.assistant)
391
+ .map((m) => m.content)
392
+ .toSet();
393
+
394
+ // Collect cross-session sessions that received messages (for toasts).
395
+ final crossSessionCounts = <String, int>{};
396
+ final crossSessionPreviews = <String, String>{};
397
+
398
+ for (final m in catchUpMsgs) {
399
+ final map = m as Map<String, dynamic>;
400
+ final msgType = map['type'] as String? ?? 'text';
401
+ final content = map['content'] as String? ?? map['transcript'] as String? ?? map['caption'] as String? ?? '';
402
+ final msgSessionId = map['sessionId'] as String?;
403
+ final imageData = map['imageBase64'] as String?;
404
+
405
+ // Skip empty text messages (images with no caption are OK)
406
+ if (content.isEmpty && imageData == null) continue;
407
+ // Dedup by content (skip images from dedup — they have unique msgIds)
408
+ if (imageData == null && content.isNotEmpty && existingContents.contains(content)) continue;
409
+
410
+ final Message message;
411
+ if (msgType == 'image' && imageData != null) {
412
+ message = Message.image(
413
+ role: MessageRole.assistant,
414
+ imageBase64: imageData,
415
+ content: content,
416
+ status: MessageStatus.sent,
417
+ );
418
+ } else {
419
+ message = Message.text(
420
+ role: MessageRole.assistant,
421
+ content: content,
422
+ status: MessageStatus.sent,
423
+ );
424
+ }
425
+
426
+ _chatLog('catch_up msg: session=${msgSessionId?.substring(0, 8) ?? "NULL"} active=${activeId?.substring(0, 8)} content="${content.substring(0, content.length.clamp(0, 40))}"');
427
+
428
+ if (msgSessionId == null || msgSessionId == currentId) {
429
+ // Active session or no session: add to UI (addMessage also appends to log).
430
+ ref.read(messagesProvider.notifier).addMessage(message);
431
+ } else {
432
+ // Cross-session: synchronous append — no race condition.
433
+ MessageStoreV2.append(msgSessionId, message);
434
+ _incrementUnread(msgSessionId);
435
+ crossSessionCounts[msgSessionId] = (crossSessionCounts[msgSessionId] ?? 0) + 1;
436
+ crossSessionPreviews.putIfAbsent(msgSessionId, () => content);
437
+ }
438
+ existingContents.add(content);
439
+ }
440
+
441
+ _isCatchingUp = false;
442
+ _scrollToBottom();
443
+
444
+ // Show one toast per cross-session that received messages.
445
+ if (crossSessionCounts.isNotEmpty && mounted) {
446
+ final sessions = ref.read(sessionsProvider);
447
+ for (final entry in crossSessionCounts.entries) {
448
+ final sid = entry.key;
449
+ final count = entry.value;
450
+ final session = sessions.firstWhere(
451
+ (s) => s.id == sid,
452
+ orElse: () => Session(id: sid, index: 0, name: 'Unknown', type: 'claude'),
453
+ );
454
+ final preview = count == 1
455
+ ? (crossSessionPreviews[sid] ?? '')
456
+ : '$count messages';
457
+ ToastManager.show(
458
+ context,
459
+ sessionName: session.name,
460
+ preview: preview.length > 100 ? '${preview.substring(0, 100)}...' : preview,
461
+ onTap: () => _switchSession(sid),
462
+ );
463
+ }
464
+ }
465
+
466
+ // Clear unread for active session
467
+ if (activeId != null) {
468
+ final counts = Map<String, int>.from(ref.read(unreadCountsProvider));
469
+ counts.remove(activeId);
470
+ ref.read(unreadCountsProvider.notifier).state = counts;
471
+ }
472
+ }
473
+ case 'pong':
474
+ break; // heartbeat response, ignore
475
+ case 'delete_message':
476
+ final msgId = msg['messageId'] as String?;
477
+ if (msgId != null) {
478
+ ref.read(messagesProvider.notifier).removeMessage(msgId);
479
+ }
480
+ default:
481
+ break;
482
+ }
483
+ }
484
+
485
+ void _handleSessions(Map<String, dynamic> msg) {
486
+ final sessionsJson = msg['sessions'] as List<dynamic>?;
487
+ if (sessionsJson == null) return;
488
+
489
+ var sessions = sessionsJson
490
+ .map((s) => Session.fromJson(s as Map<String, dynamic>))
491
+ .toList();
492
+ // Apply saved custom order (reordered sessions persist across updates)
493
+ sessions = _applyCustomOrder(sessions);
494
+ ref.read(sessionsProvider.notifier).state = sessions;
495
+
496
+ final activeId = ref.read(activeSessionIdProvider);
497
+ if (activeId == null && sessions.isNotEmpty) {
498
+ final active = sessions.firstWhere(
499
+ (s) => s.isActive,
500
+ orElse: () => sessions.first,
501
+ );
502
+ ref.read(activeSessionIdProvider.notifier).state = active.id;
503
+ // Synchronous session switch — no async gap.
504
+ ref.read(messagesProvider.notifier).switchSession(active.id);
505
+ SharedPreferences.getInstance().then((p) => p.setString('activeSessionId', active.id));
506
+ }
507
+
508
+ // Session is ready — process any pending messages that arrived before sessions list
509
+ if (!_sessionReady) {
510
+ _sessionReady = true;
511
+ // Request catch_up now that session is set
512
+ _sendCommand('catch_up', {'lastSeq': _lastSeq});
513
+ // Drain messages that arrived before sessions list
514
+ if (_pendingMessages.isNotEmpty) {
515
+ final pending = List<Map<String, dynamic>>.from(_pendingMessages);
516
+ _pendingMessages.clear();
517
+ for (final m in pending) {
518
+ _handleMessage(m);
519
+ }
520
+ }
521
+ }
522
+ }
523
+
524
+ void _handleIncomingMessage(Map<String, dynamic> msg) {
525
+ final sessionId = msg['sessionId'] as String?;
526
+ final content = msg['content'] as String? ??
527
+ msg['text'] as String? ??
528
+ '';
529
+
530
+ TraceService.instance.addTrace(
531
+ 'handleMessage processing type=text',
532
+ 'sessionId=${sessionId?.substring(0, sessionId.length.clamp(0, 8))}',
533
+ );
534
+
535
+ final message = Message.text(
536
+ role: MessageRole.assistant,
537
+ content: content,
538
+ status: MessageStatus.sent,
539
+ );
540
+
541
+ // Use currentSessionId from notifier (what's actually loaded in the provider),
542
+ // not activeSessionIdProvider (can be stale after background resume).
543
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
544
+ if (sessionId != null && sessionId != currentId) {
545
+ // Append directly to the log for the target session — synchronous, no race.
546
+ TraceService.instance.addTrace(
547
+ 'message stored for session',
548
+ 'sessionId=${sessionId.substring(0, sessionId.length.clamp(0, 8))}, toast shown',
549
+ );
550
+ MessageStoreV2.append(sessionId, message);
551
+ _incrementUnread(sessionId);
552
+ final sessions = ref.read(sessionsProvider);
553
+ final session = sessions.firstWhere(
554
+ (s) => s.id == sessionId,
555
+ orElse: () => Session(id: sessionId, index: 0, name: 'Unknown', type: 'claude'),
556
+ );
557
+ if (mounted) {
558
+ ToastManager.show(
559
+ context,
560
+ sessionName: session.name,
561
+ preview: content.length > 100 ? '${content.substring(0, 100)}...' : content,
562
+ onTap: () => _switchSession(sessionId),
563
+ );
564
+ }
565
+ } else {
566
+ TraceService.instance.addTrace(
567
+ 'message displayed in chat',
568
+ 'sessionId=${sessionId?.substring(0, sessionId.length.clamp(0, 8)) ?? "global"} len=${content.length}',
569
+ );
570
+ ref.read(messagesProvider.notifier).addMessage(message);
571
+ ref.read(isTypingProvider.notifier).state = false;
572
+ _scrollToBottom();
573
+ }
574
+ }
575
+
576
+ Future<void> _handleIncomingVoice(Map<String, dynamic> msg) async {
577
+ final sessionId = msg['sessionId'] as String?;
578
+ final audioData = msg['audioBase64'] as String? ?? msg['audio'] as String? ?? msg['data'] as String?;
579
+ final content = msg['content'] as String? ?? msg['transcript'] as String? ?? msg['text'] as String? ?? '';
580
+ final duration = msg['duration'] as int?;
581
+
582
+ final message = Message(
583
+ id: msg['id'] as String? ?? DateTime.now().millisecondsSinceEpoch.toString(),
584
+ role: MessageRole.assistant,
585
+ type: MessageType.voice,
586
+ content: content,
587
+ audioUri: audioData,
588
+ timestamp: DateTime.now().millisecondsSinceEpoch,
589
+ status: MessageStatus.sent,
590
+ duration: duration,
591
+ );
592
+
593
+ // Save audio to file so it survives persistence (base64 gets stripped)
594
+ String? savedAudioPath;
595
+ if (audioData != null) {
596
+ try {
597
+ final dir = await getTemporaryDirectory();
598
+ savedAudioPath = '${dir.path}/voice_${message.id}.m4a';
599
+ final bytes = base64Decode(audioData.contains(',') ? audioData.split(',').last : audioData);
600
+ await File(savedAudioPath).writeAsBytes(bytes);
601
+ } catch (_) {
602
+ savedAudioPath = null;
603
+ }
604
+ }
605
+
606
+ final storedMessage = Message(
607
+ id: message.id,
608
+ role: message.role,
609
+ type: message.type,
610
+ content: content,
611
+ audioUri: savedAudioPath ?? audioData,
612
+ timestamp: message.timestamp,
613
+ status: message.status,
614
+ duration: duration,
615
+ );
616
+
617
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
618
+ _chatLog('voice: sessionId=$sessionId currentId=$currentId audioPath=$savedAudioPath content="${content.substring(0, content.length.clamp(0, 30))}"');
619
+ if (sessionId != null && sessionId != currentId) {
620
+ _chatLog('voice: cross-session, appending to store for $sessionId');
621
+ // Synchronous append — no async gap, no race condition.
622
+ MessageStoreV2.append(sessionId, storedMessage);
623
+ _chatLog('voice: appended, incrementing unread');
624
+ _incrementUnread(sessionId);
625
+ final sessions = ref.read(sessionsProvider);
626
+ final session = sessions.firstWhere(
627
+ (s) => s.id == sessionId,
628
+ orElse: () => Session(id: sessionId, index: 0, name: 'Unknown', type: 'claude'),
629
+ );
630
+ if (mounted) {
631
+ ToastManager.show(
632
+ context,
633
+ sessionName: session.name,
634
+ preview: '🎤 Voice note',
635
+ onTap: () => _switchSession(sessionId),
636
+ );
637
+ }
638
+ return;
639
+ }
640
+
641
+ ref.read(messagesProvider.notifier).addMessage(storedMessage);
642
+ ref.read(isTypingProvider.notifier).state = false;
643
+ _scrollToBottom();
644
+
645
+ if (audioData != null && !AudioService.isBackgrounded && !_isCatchingUp && !_isRecording) {
646
+ setState(() => _playingMessageId = storedMessage.id);
647
+ AudioService.queueBase64(audioData);
648
+ }
649
+ }
650
+
651
+ void _handleIncomingImage(Map<String, dynamic> msg) {
652
+ final imageData = msg['imageBase64'] as String? ?? msg['data'] as String? ?? msg['image'] as String?;
653
+ final content = msg['content'] as String? ?? msg['caption'] as String? ?? '';
654
+ final sessionId = msg['sessionId'] as String?;
655
+
656
+ if (imageData == null) return;
657
+
658
+ // Always update the Navigate screen screenshot provider
659
+ ref.read(latestScreenshotProvider.notifier).state = imageData;
660
+
661
+ final isScreenshot = content == 'Screenshot' ||
662
+ content == 'Capturing screenshot...' ||
663
+ (msg['type'] == 'screenshot');
664
+
665
+ if (isScreenshot) {
666
+ // Remove any "Capturing screenshot..." placeholder text messages
667
+ ref.read(messagesProvider.notifier).removeWhere(
668
+ (m) => m.role == MessageRole.assistant && m.content == 'Capturing screenshot...',
669
+ );
670
+
671
+ // Only add to chat if the Screen button explicitly requested it
672
+ if (!_screenshotForChat) {
673
+ final activeId = ref.read(activeSessionIdProvider);
674
+ if (sessionId == null || sessionId == activeId) {
675
+ ref.read(isTypingProvider.notifier).state = false;
676
+ }
677
+ return;
678
+ }
679
+ _screenshotForChat = false;
680
+ }
681
+
682
+ final message = Message.image(
683
+ role: MessageRole.assistant,
684
+ imageBase64: imageData,
685
+ content: content,
686
+ status: MessageStatus.sent,
687
+ );
688
+
689
+ // Cross-session routing: append to log for target session if not currently loaded.
690
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
691
+ if (sessionId != null && sessionId != currentId) {
692
+ MessageStoreV2.append(sessionId, message);
693
+ _incrementUnread(sessionId);
694
+ return;
695
+ }
696
+
697
+ ref.read(messagesProvider.notifier).addMessage(message);
698
+ ref.read(isTypingProvider.notifier).state = false;
699
+ _scrollToBottom();
700
+ }
701
+
702
+ /// Superseded by MessageStoreV2.append() — call sites now use the synchronous
703
+ /// append directly. Kept as dead code until all callers are confirmed removed.
704
+ // ignore: unused_element
705
+ void _storeForSession(String sessionId, Message message) {
706
+ MessageStoreV2.append(sessionId, message);
707
+ }
708
+
709
+ /// With the append-only log, transcript updates for cross-session messages
710
+ /// are not patched back to disk (the append-only design doesn't support
711
+ /// in-place edits). The transcript is updated in-memory if the message is
712
+ /// in the active session. Cross-session transcript updates are a no-op.
713
+ Future<void> _updateTranscriptOnDisk(String messageId, String content) async {
714
+ _chatLog('transcript: cross-session update for messageId=$messageId — in-memory only (append-only log)');
715
+ }
716
+
717
+ void _incrementUnread(String sessionId) {
718
+ final counts = Map<String, int>.from(ref.read(unreadCountsProvider));
719
+ counts[sessionId] = (counts[sessionId] ?? 0) + 1;
720
+ ref.read(unreadCountsProvider.notifier).state = counts;
721
+ _persistUnreadCounts(counts);
722
+ }
723
+
724
+ void _persistUnreadCounts(Map<String, int> counts) {
725
+ final total = counts.values.fold<int>(0, (sum, v) => sum + v);
726
+ // Set badge immediately via platform channel (synchronous native call)
727
+ PushService.setBadge(total);
728
+ // Also persist to SharedPreferences for app restart
729
+ SharedPreferences.getInstance().then((prefs) {
730
+ prefs.setString('unreadCounts', jsonEncode(counts));
731
+ prefs.setInt('badgeCount', total);
732
+ });
733
+ }
734
+
735
+ Future<void> _switchSession(String sessionId) async {
736
+ // Stop any playing audio, dismiss keyboard, and clear typing indicator
737
+ await AudioService.stopPlayback();
738
+ setState(() => _playingMessageId = null);
739
+ if (mounted) FocusScope.of(context).unfocus();
740
+ ref.read(isTypingProvider.notifier).state = false;
741
+
742
+ ref.read(activeSessionIdProvider.notifier).state = sessionId;
743
+ // Synchronous — no async gap between session switch and incoming messages.
744
+ ref.read(messagesProvider.notifier).switchSession(sessionId);
745
+ SharedPreferences.getInstance().then((p) => p.setString('activeSessionId', sessionId));
746
+
747
+ final counts = Map<String, int>.from(ref.read(unreadCountsProvider));
748
+ counts.remove(sessionId);
749
+ ref.read(unreadCountsProvider.notifier).state = counts;
750
+ _persistUnreadCounts(counts);
751
+
752
+ // Update badge to reflect remaining unreads
753
+ _updateBadgeFromUnreads();
754
+
755
+ _sendCommand('switch', {'sessionId': sessionId});
756
+ _scrollToBottom();
757
+ }
758
+
759
+ void _sendTextMessage() {
760
+ final text = _textController.text.trim();
761
+ if (text.isEmpty) return;
762
+
763
+ final message = Message.text(
764
+ role: MessageRole.user,
765
+ content: text,
766
+ status: MessageStatus.sent,
767
+ );
768
+
769
+ ref.read(messagesProvider.notifier).addMessage(message);
770
+ _textController.clear();
771
+ FocusScope.of(context).unfocus(); // dismiss keyboard
772
+
773
+ // Send as plain text (not command) — gateway handles plain messages
774
+ _ws?.send({
775
+ 'content': text,
776
+ 'sessionId': ref.read(activeSessionIdProvider),
777
+ });
778
+
779
+ _scrollToBottom();
780
+ }
781
+
782
+ String? _recordingSessionId; // Capture session at recording start
783
+
784
+ Future<void> _startRecording() async {
785
+ // Stop any playing audio before recording
786
+ if (AudioService.isPlaying) {
787
+ await AudioService.stopPlayback();
788
+ setState(() => _playingMessageId = null);
789
+ }
790
+ _recordingSessionId = ref.read(activeSessionIdProvider);
791
+ final path = await AudioService.startRecording();
792
+ if (path != null) {
793
+ setState(() => _isRecording = true);
794
+ } else {
795
+ _recordingSessionId = null;
796
+ }
797
+ }
798
+
799
+ Future<void> _stopRecording() async {
800
+ final targetSession = _recordingSessionId;
801
+ _recordingSessionId = null;
802
+ final path = await AudioService.stopRecording();
803
+ setState(() => _isRecording = false);
804
+
805
+ if (path == null) return;
806
+
807
+ final file = File(path);
808
+ if (!await file.exists()) return;
809
+
810
+ final bytes = await file.readAsBytes();
811
+ final b64 = base64Encode(bytes);
812
+
813
+ final message = Message.voice(
814
+ role: MessageRole.user,
815
+ audioUri: path,
816
+ status: MessageStatus.sent,
817
+ );
818
+
819
+ ref.read(messagesProvider.notifier).addMessage(message);
820
+
821
+ _ws?.send({
822
+ 'type': 'voice',
823
+ 'audioBase64': b64,
824
+ 'content': '',
825
+ 'messageId': message.id,
826
+ 'sessionId': targetSession,
827
+ });
828
+
829
+ _scrollToBottom();
830
+ }
831
+
832
+ Future<void> _cancelRecording() async {
833
+ await AudioService.cancelRecording();
834
+ setState(() => _isRecording = false);
835
+ }
836
+
837
+ void _replayLast() {
838
+ final messages = ref.read(messagesProvider);
839
+ for (var i = messages.length - 1; i >= 0; i--) {
840
+ final m = messages[i];
841
+ if (m.role == MessageRole.assistant &&
842
+ m.type == MessageType.voice &&
843
+ m.audioUri != null) {
844
+ _playMessage(m);
845
+ return;
846
+ }
847
+ }
848
+ for (var i = messages.length - 1; i >= 0; i--) {
849
+ final m = messages[i];
850
+ if (m.role == MessageRole.assistant && m.type == MessageType.text) {
851
+ _ws?.send({
852
+ 'type': 'tts',
853
+ 'text': m.content,
854
+ 'sessionId': ref.read(activeSessionIdProvider),
855
+ });
856
+ return;
857
+ }
858
+ }
859
+ }
860
+
861
+ void _playMessage(Message message) async {
862
+ if (message.audioUri == null) return;
863
+
864
+ // Toggle: if this message is already playing, stop it
865
+ if (_playingMessageId == message.id) {
866
+ await AudioService.stopPlayback();
867
+ setState(() => _playingMessageId = null);
868
+ return;
869
+ }
870
+
871
+ // Stop any current playback first, then set playing ID AFTER stop completes
872
+ // (stopPlayback triggers onPlaybackStateChanged which clears _playingMessageId)
873
+ await AudioService.stopPlayback();
874
+
875
+ if (!mounted) return;
876
+ setState(() => _playingMessageId = message.id);
877
+
878
+ if (message.audioUri!.startsWith('/')) {
879
+ AudioService.playSingle(message.audioUri!);
880
+ } else {
881
+ AudioService.playBase64(message.audioUri!);
882
+ }
883
+ }
884
+
885
+ void _chainPlayFrom(Message message) {
886
+ final messages = ref.read(messagesProvider);
887
+ final startIndex = messages.indexWhere((m) => m.id == message.id);
888
+ if (startIndex < 0) return;
889
+
890
+ final chain = <String>[];
891
+ for (var i = startIndex; i < messages.length; i++) {
892
+ final m = messages[i];
893
+ if (m.role == MessageRole.assistant &&
894
+ m.type == MessageType.voice &&
895
+ m.audioUri != null) {
896
+ chain.add(m.audioUri!);
897
+ } else if (m.role != MessageRole.assistant) {
898
+ break;
899
+ }
900
+ }
901
+
902
+ if (chain.isNotEmpty) {
903
+ AudioService.playChain(chain);
904
+ }
905
+ }
906
+
907
+ Future<void> _pickFiles(String? targetSessionId) async {
908
+ final result = await FilePicker.platform.pickFiles(
909
+ allowMultiple: true,
910
+ type: FileType.any,
911
+ );
912
+ if (result == null || result.files.isEmpty) return;
913
+
914
+ // Build attachments list
915
+ final attachments = <Map<String, dynamic>>[];
916
+ for (final file in result.files) {
917
+ if (file.path == null) continue;
918
+ final bytes = await File(file.path!).readAsBytes();
919
+ final b64 = base64Encode(bytes);
920
+ final mimeType = _guessMimeType(file.name);
921
+ attachments.add({
922
+ 'data': b64,
923
+ 'mimeType': mimeType,
924
+ 'fileName': file.name,
925
+ });
926
+ }
927
+ if (attachments.isEmpty) return;
928
+
929
+ // Show caption dialog
930
+ final fileNames = result.files.map((f) => f.name).join(', ');
931
+ final caption = await _showCaptionDialog(result.files.length);
932
+ if (caption == null) {
933
+ if (mounted) FocusManager.instance.primaryFocus?.unfocus();
934
+ return;
935
+ }
936
+
937
+ // Handle voice caption
938
+ String textCaption = caption;
939
+ String? voiceB64;
940
+ if (caption.startsWith('__voice__:')) {
941
+ final voicePath = caption.substring('__voice__:'.length);
942
+ final voiceFile = File(voicePath);
943
+ if (await voiceFile.exists()) {
944
+ voiceB64 = base64Encode(await voiceFile.readAsBytes());
945
+ }
946
+ textCaption = '';
947
+ }
948
+
949
+ // Send voice first if present
950
+ if (voiceB64 != null) {
951
+ final voiceMsg = Message.voice(
952
+ role: MessageRole.user,
953
+ audioUri: caption.substring('__voice__:'.length),
954
+ status: MessageStatus.sent,
955
+ );
956
+ ref.read(messagesProvider.notifier).addMessage(voiceMsg);
957
+ _ws?.send({
958
+ 'type': 'voice',
959
+ 'audioBase64': voiceB64,
960
+ 'content': '',
961
+ 'messageId': voiceMsg.id,
962
+ 'sessionId': targetSessionId,
963
+ });
964
+ }
965
+
966
+ // Send all files as one atomic bundle
967
+ _ws?.send({
968
+ 'type': 'bundle',
969
+ 'caption': textCaption,
970
+ 'attachments': attachments,
971
+ 'sessionId': targetSessionId,
972
+ });
973
+
974
+ // Show in chat
975
+ for (final att in attachments) {
976
+ final mime = att['mimeType'] as String;
977
+ final name = att['fileName'] as String? ?? 'file';
978
+ if (mime.startsWith('image/')) {
979
+ ref.read(messagesProvider.notifier).addMessage(Message.image(
980
+ role: MessageRole.user,
981
+ imageBase64: att['data'] as String,
982
+ content: name,
983
+ status: MessageStatus.sent,
984
+ ));
985
+ } else {
986
+ final size = base64Decode(att['data'] as String).length;
987
+ ref.read(messagesProvider.notifier).addMessage(Message.text(
988
+ role: MessageRole.user,
989
+ content: textCaption.isNotEmpty
990
+ ? '$textCaption\n📎 $name (${_formatSize(size)})'
991
+ : '📎 $name (${_formatSize(size)})',
992
+ status: MessageStatus.sent,
993
+ ));
994
+ }
995
+ }
996
+
997
+ // Dismiss keyboard after file flow completes
998
+ if (mounted) FocusManager.instance.primaryFocus?.unfocus();
999
+ _scrollToBottom();
1000
+ }
1001
+
1002
+ String _guessMimeType(String name) {
1003
+ final ext = name.split('.').last.toLowerCase();
1004
+ const map = {
1005
+ 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png',
1006
+ 'gif': 'image/gif', 'webp': 'image/webp', 'heic': 'image/heic',
1007
+ 'pdf': 'application/pdf', 'doc': 'application/msword',
1008
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
1009
+ 'xls': 'application/vnd.ms-excel',
1010
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
1011
+ 'txt': 'text/plain', 'csv': 'text/csv', 'json': 'application/json',
1012
+ 'zip': 'application/zip', 'mp3': 'audio/mpeg', 'mp4': 'video/mp4',
1013
+ };
1014
+ return map[ext] ?? 'application/octet-stream';
1015
+ }
1016
+
1017
+ String _formatSize(int bytes) {
1018
+ if (bytes < 1024) return '$bytes B';
1019
+ if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
1020
+ return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
1021
+ }
1022
+
1023
+ void _requestScreenshot() {
1024
+ _screenshotForChat = true;
1025
+ _sendCommand('screenshot', {'sessionId': ref.read(activeSessionIdProvider)});
1026
+ if (mounted) {
1027
+ ScaffoldMessenger.of(context).showSnackBar(
1028
+ const SnackBar(
1029
+ content: Text('Capturing screenshot...'),
1030
+ duration: Duration(seconds: 2),
1031
+ behavior: SnackBarBehavior.floating,
1032
+ ),
1033
+ );
1034
+ }
1035
+ }
1036
+
1037
+ void _navigateToTerminal() {
1038
+ _requestScreenshot();
1039
+ context.push('/navigate');
1040
+ }
1041
+
1042
+ Future<void> _pickPhoto() async {
1043
+ final targetSessionId = ref.read(activeSessionIdProvider);
1044
+
1045
+ // Show picker options
1046
+ final source = await showModalBottomSheet<String>(
1047
+ context: context,
1048
+ builder: (ctx) => SafeArea(
1049
+ child: Column(
1050
+ mainAxisSize: MainAxisSize.min,
1051
+ children: [
1052
+ ListTile(
1053
+ leading: const Icon(Icons.camera_alt),
1054
+ title: const Text('Take Photo'),
1055
+ onTap: () => Navigator.pop(ctx, 'camera'),
1056
+ ),
1057
+ ListTile(
1058
+ leading: const Icon(Icons.photo_library),
1059
+ title: const Text('Photo Library'),
1060
+ onTap: () => Navigator.pop(ctx, 'gallery'),
1061
+ ),
1062
+ ListTile(
1063
+ leading: const Icon(Icons.attach_file),
1064
+ title: const Text('Files'),
1065
+ onTap: () => Navigator.pop(ctx, 'files'),
1066
+ ),
1067
+ ],
1068
+ ),
1069
+ ),
1070
+ );
1071
+ if (source == null) return;
1072
+
1073
+ if (source == 'files') {
1074
+ await _pickFiles(targetSessionId);
1075
+ return;
1076
+ }
1077
+
1078
+ List<XFile> images;
1079
+ final picker = ImagePicker();
1080
+ if (source == 'camera') {
1081
+ final photo = await picker.pickImage(
1082
+ source: ImageSource.camera,
1083
+ maxWidth: 1920,
1084
+ maxHeight: 1080,
1085
+ imageQuality: 85,
1086
+ );
1087
+ if (photo == null) return;
1088
+ images = [photo];
1089
+ } else {
1090
+ images = await picker.pickMultiImage(
1091
+ maxWidth: 1920,
1092
+ maxHeight: 1080,
1093
+ imageQuality: 85,
1094
+ );
1095
+ }
1096
+
1097
+ if (images.isEmpty) return;
1098
+
1099
+ // Encode all images first
1100
+ final encodedImages = <String>[];
1101
+ for (final img in images) {
1102
+ final bytes = await img.readAsBytes();
1103
+ encodedImages.add(base64Encode(bytes));
1104
+ }
1105
+
1106
+ final caption = await _showCaptionDialog(images.length);
1107
+ if (caption == null) {
1108
+ if (mounted) FocusManager.instance.primaryFocus?.unfocus();
1109
+ return; // user cancelled
1110
+ }
1111
+
1112
+ // Handle voice caption
1113
+ String textCaption = caption;
1114
+ String? voiceB64;
1115
+ if (caption.startsWith('__voice__:')) {
1116
+ final voicePath = caption.substring('__voice__:'.length);
1117
+ final voiceFile = File(voicePath);
1118
+ if (await voiceFile.exists()) {
1119
+ final voiceBytes = await voiceFile.readAsBytes();
1120
+ voiceB64 = base64Encode(voiceBytes);
1121
+ }
1122
+ textCaption = '';
1123
+ }
1124
+
1125
+ final attachments = encodedImages.map((b64) =>
1126
+ <String, dynamic>{'data': b64, 'mimeType': 'image/jpeg'}
1127
+ ).toList();
1128
+
1129
+ // Create the first image message early so we have its ID for transcript reflection
1130
+ final firstImageMsg = Message.image(
1131
+ role: MessageRole.user,
1132
+ imageBase64: encodedImages[0],
1133
+ content: textCaption.isNotEmpty ? textCaption : (voiceB64 != null ? '🎤 ...' : ''),
1134
+ status: MessageStatus.sent,
1135
+ );
1136
+
1137
+ // Send everything as a single atomic bundle
1138
+ _ws?.send({
1139
+ 'type': 'bundle',
1140
+ 'caption': textCaption,
1141
+ if (voiceB64 != null) 'audioBase64': voiceB64,
1142
+ if (voiceB64 != null) 'voiceMessageId': firstImageMsg.id,
1143
+ 'attachments': attachments,
1144
+ 'sessionId': targetSessionId,
1145
+ });
1146
+
1147
+ // Show as combined image+caption bubbles
1148
+ ref.read(messagesProvider.notifier).addMessage(firstImageMsg);
1149
+ for (var i = 1; i < encodedImages.length; i++) {
1150
+ final message = Message.image(
1151
+ role: MessageRole.user,
1152
+ imageBase64: encodedImages[i],
1153
+ content: '',
1154
+ status: MessageStatus.sent,
1155
+ );
1156
+ ref.read(messagesProvider.notifier).addMessage(message);
1157
+ }
1158
+
1159
+ // Dismiss keyboard after image flow completes
1160
+ if (mounted) FocusManager.instance.primaryFocus?.unfocus();
1161
+ _scrollToBottom();
1162
+ }
1163
+
1164
+ Future<String?> _showCaptionDialog(int imageCount) async {
1165
+ final captionController = TextEditingController();
1166
+ String? voicePath;
1167
+ bool isVoiceRecording = false;
1168
+ bool hasVoiceCaption = false;
1169
+
1170
+ final result = await showModalBottomSheet<String>(
1171
+ context: context,
1172
+ isScrollControlled: true,
1173
+ builder: (ctx) => StatefulBuilder(
1174
+ builder: (ctx, setSheetState) => Padding(
1175
+ padding: EdgeInsets.only(
1176
+ bottom: MediaQuery.of(ctx).viewInsets.bottom,
1177
+ left: 16,
1178
+ right: 16,
1179
+ top: 16,
1180
+ ),
1181
+ child: Column(
1182
+ mainAxisSize: MainAxisSize.min,
1183
+ children: [
1184
+ Text(
1185
+ '$imageCount image${imageCount > 1 ? 's' : ''} selected',
1186
+ style: Theme.of(ctx).textTheme.titleSmall,
1187
+ ),
1188
+ const SizedBox(height: 12),
1189
+ // Text caption input
1190
+ if (!isVoiceRecording && !hasVoiceCaption)
1191
+ TextField(
1192
+ controller: captionController,
1193
+ decoration: const InputDecoration(
1194
+ hintText: 'Add a text caption (optional)',
1195
+ border: OutlineInputBorder(),
1196
+ ),
1197
+ autofocus: true,
1198
+ maxLines: 3,
1199
+ ),
1200
+ // Voice recording indicator
1201
+ if (isVoiceRecording)
1202
+ Container(
1203
+ padding: const EdgeInsets.symmetric(vertical: 20),
1204
+ child: const Row(
1205
+ mainAxisAlignment: MainAxisAlignment.center,
1206
+ children: [
1207
+ Icon(Icons.fiber_manual_record, color: Colors.red, size: 16),
1208
+ SizedBox(width: 8),
1209
+ Text('Recording voice caption...', style: TextStyle(fontSize: 16)),
1210
+ ],
1211
+ ),
1212
+ ),
1213
+ // Voice recorded confirmation
1214
+ if (hasVoiceCaption && !isVoiceRecording)
1215
+ Container(
1216
+ padding: const EdgeInsets.symmetric(vertical: 20),
1217
+ child: const Row(
1218
+ mainAxisAlignment: MainAxisAlignment.center,
1219
+ children: [
1220
+ Icon(Icons.check_circle, color: Colors.green, size: 20),
1221
+ SizedBox(width: 8),
1222
+ Text('Voice caption recorded', style: TextStyle(fontSize: 16)),
1223
+ ],
1224
+ ),
1225
+ ),
1226
+ const SizedBox(height: 12),
1227
+ // Action row: mic/stop + cancel + send
1228
+ Row(
1229
+ children: [
1230
+ // Mic / Stop button — large and clear
1231
+ if (!hasVoiceCaption)
1232
+ IconButton.filled(
1233
+ onPressed: () async {
1234
+ if (isVoiceRecording) {
1235
+ final path = await AudioService.stopRecording();
1236
+ setSheetState(() {
1237
+ isVoiceRecording = false;
1238
+ if (path != null) {
1239
+ voicePath = path;
1240
+ hasVoiceCaption = true;
1241
+ }
1242
+ });
1243
+ } else {
1244
+ final path = await AudioService.startRecording();
1245
+ if (path != null) {
1246
+ setSheetState(() => isVoiceRecording = true);
1247
+ }
1248
+ }
1249
+ },
1250
+ icon: Icon(isVoiceRecording ? Icons.stop : Icons.mic),
1251
+ style: IconButton.styleFrom(
1252
+ backgroundColor: isVoiceRecording ? Colors.red : null,
1253
+ foregroundColor: isVoiceRecording ? Colors.white : null,
1254
+ ),
1255
+ ),
1256
+ const Spacer(),
1257
+ TextButton(
1258
+ onPressed: () async {
1259
+ if (isVoiceRecording) {
1260
+ await AudioService.cancelRecording();
1261
+ }
1262
+ if (ctx.mounted) Navigator.pop(ctx);
1263
+ },
1264
+ child: const Text('Cancel'),
1265
+ ),
1266
+ const SizedBox(width: 8),
1267
+ FilledButton(
1268
+ onPressed: isVoiceRecording
1269
+ ? null // disable Send while recording
1270
+ : () {
1271
+ if (voicePath != null) {
1272
+ Navigator.pop(ctx, '__voice__:$voicePath');
1273
+ } else {
1274
+ Navigator.pop(ctx, captionController.text);
1275
+ }
1276
+ },
1277
+ child: const Text('Send'),
1278
+ ),
1279
+ ],
1280
+ ),
1281
+ const SizedBox(height: 16),
1282
+ ],
1283
+ ),
1284
+ ),
1285
+ ),
1286
+ );
1287
+
1288
+ // Safety net: clean up recording if sheet dismissed by swipe/tap outside
1289
+ if (isVoiceRecording) {
1290
+ await AudioService.cancelRecording();
1291
+ }
1292
+
1293
+ captionController.dispose();
1294
+ return result;
1295
+ }
1296
+
1297
+ void _clearChat() {
1298
+ showDialog(
1299
+ context: context,
1300
+ builder: (ctx) => AlertDialog(
1301
+ title: const Text('Clear chat?'),
1302
+ content: const Text('This will clear the message history.'),
1303
+ actions: [
1304
+ TextButton(
1305
+ onPressed: () => Navigator.pop(ctx),
1306
+ child: const Text('Cancel'),
1307
+ ),
1308
+ TextButton(
1309
+ onPressed: () {
1310
+ Navigator.pop(ctx);
1311
+ ref.read(messagesProvider.notifier).clearMessages();
1312
+ },
1313
+ child: const Text('Clear', style: TextStyle(color: AppColors.error)),
1314
+ ),
1315
+ ],
1316
+ ),
1317
+ );
1318
+ }
1319
+
1320
+ void _sendHelp() {
1321
+ _ws?.send({
1322
+ 'content': '/h',
1323
+ 'sessionId': ref.read(activeSessionIdProvider),
1324
+ });
1325
+ }
1326
+
1327
+ void _toggleTheme() async {
1328
+ final current = ref.read(themeModeProvider);
1329
+ final next = current == ThemeMode.dark ? ThemeMode.light : ThemeMode.dark;
1330
+ ref.read(themeModeProvider.notifier).state = next;
1331
+ final prefs = await SharedPreferences.getInstance();
1332
+ await prefs.setString('theme_mode', next == ThemeMode.dark ? 'dark' : 'light');
1333
+ }
1334
+
1335
+ void _scrollToBottom() {
1336
+ WidgetsBinding.instance.addPostFrameCallback((_) {
1337
+ if (_scrollController.hasClients) {
1338
+ _scrollController.animateTo(
1339
+ 0,
1340
+ duration: const Duration(milliseconds: 200),
1341
+ curve: Curves.easeOut,
1342
+ );
1343
+ }
1344
+ });
1345
+ }
1346
+
1347
+ void _handleNewSession() {
1348
+ _sendCommand('create');
1349
+ }
1350
+
1351
+ /// Called when the user taps an upgrade CTA in the drawer or paywall banner.
1352
+ Future<void> _handleUpgrade() async {
1353
+ await PurchaseService.instance.purchaseFullAccess();
1354
+ }
1355
+
1356
+ void _handleSessionRename(Session session, String newName) {
1357
+ _sendCommand('rename', {'sessionId': session.id, 'name': newName});
1358
+ final sessions = ref.read(sessionsProvider);
1359
+ ref.read(sessionsProvider.notifier).state = sessions
1360
+ .map((s) => s.id == session.id ? s.copyWith(name: newName) : s)
1361
+ .toList();
1362
+ }
1363
+
1364
+ void _handleSessionRemove(Session session) {
1365
+ _sendCommand('remove', {'sessionId': session.id});
1366
+ final sessions = ref.read(sessionsProvider);
1367
+ ref.read(sessionsProvider.notifier).state =
1368
+ sessions.where((s) => s.id != session.id).toList();
1369
+ }
1370
+
1371
+ void _handleSessionReorder(int oldIndex, int newIndex) {
1372
+ if (newIndex > oldIndex) newIndex--;
1373
+ final sessions = List<Session>.from(ref.read(sessionsProvider));
1374
+ final item = sessions.removeAt(oldIndex);
1375
+ sessions.insert(newIndex, item);
1376
+ ref.read(sessionsProvider.notifier).state = sessions;
1377
+ // Persist custom order AND update cache so next server update preserves it
1378
+ final ids = sessions.map((s) => s.id).toList();
1379
+ _cachedSessionOrder = ids;
1380
+ _saveSessionOrder(ids);
1381
+ }
1382
+
1383
+ void _saveSessionOrder(List<String> ids) {
1384
+ SharedPreferences.getInstance().then((p) => p.setStringList('sessionOrder', ids));
1385
+ }
1386
+
1387
+ /// Apply saved custom order to a server-provided session list.
1388
+ /// New sessions (not in saved order) are appended at the end.
1389
+ List<Session> _applyCustomOrder(List<Session> sessions) {
1390
+ if (_cachedSessionOrder == null || _cachedSessionOrder!.isEmpty) return sessions;
1391
+ final order = _cachedSessionOrder!;
1392
+ final byId = {for (final s in sessions) s.id: s};
1393
+ final ordered = <Session>[];
1394
+ for (final id in order) {
1395
+ final s = byId.remove(id);
1396
+ if (s != null) ordered.add(s);
1397
+ }
1398
+ // Append any new sessions not in saved order
1399
+ ordered.addAll(byId.values);
1400
+ return ordered;
1401
+ }
1402
+
1403
+ void _refreshSessions() {
1404
+ _sendCommand('sessions');
1405
+ }
1406
+
1407
+ @override
1408
+ Widget build(BuildContext context) {
1409
+ final allMessages = ref.watch(messagesProvider);
1410
+ final isPro = ref.watch(isProProvider);
1411
+ // Free tier: filter out messages older than 15 minutes on display.
1412
+ // Storage is unchanged — messages reappear if the user later upgrades.
1413
+ final messages = isPro
1414
+ ? allMessages
1415
+ : allMessages.where((m) {
1416
+ final ts = DateTime.fromMillisecondsSinceEpoch(m.timestamp);
1417
+ final age = DateTime.now().difference(ts);
1418
+ return age <= kFreeTierMessageTtl;
1419
+ }).toList();
1420
+ final wsStatus = ref.watch(wsStatusProvider);
1421
+ final isTyping = ref.watch(isTypingProvider);
1422
+ final connectionDetail = ref.watch(connectionDetailProvider);
1423
+ final sessions = ref.watch(sessionsProvider);
1424
+ final activeSession = ref.watch(activeSessionProvider);
1425
+ final unreadCounts = ref.watch(unreadCountsProvider);
1426
+ final inputMode = ref.watch(inputModeProvider);
1427
+
1428
+ return GestureDetector(
1429
+ behavior: HitTestBehavior.translucent,
1430
+ onTap: () => FocusScope.of(context).unfocus(),
1431
+ child: Scaffold(
1432
+ key: _scaffoldKey,
1433
+ appBar: AppBar(
1434
+ leading: IconButton(
1435
+ icon: const Icon(Icons.menu),
1436
+ onPressed: () {
1437
+ FocusScope.of(context).unfocus();
1438
+ _scaffoldKey.currentState?.openDrawer();
1439
+ },
1440
+ ),
1441
+ title: Column(
1442
+ crossAxisAlignment: CrossAxisAlignment.center,
1443
+ mainAxisSize: MainAxisSize.min,
1444
+ children: [
1445
+ Text(
1446
+ activeSession?.name ?? 'PAILot',
1447
+ style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
1448
+ ),
1449
+ if (connectionDetail.isNotEmpty && wsStatus != ConnectionStatus.connected)
1450
+ Text(
1451
+ connectionDetail,
1452
+ style: TextStyle(fontSize: 11, color: Colors.grey.shade400),
1453
+ ),
1454
+ if (wsStatus == ConnectionStatus.connected && ref.watch(connectedViaProvider).isNotEmpty)
1455
+ Text(
1456
+ 'via ${ref.watch(connectedViaProvider)}',
1457
+ style: TextStyle(fontSize: 11, color: Colors.grey.shade500),
1458
+ ),
1459
+ ],
1460
+ ),
1461
+ actions: [
1462
+ StatusDot(status: wsStatus),
1463
+ const SizedBox(width: 12),
1464
+ IconButton(
1465
+ icon: Icon(
1466
+ Theme.of(context).brightness == Brightness.dark
1467
+ ? Icons.light_mode
1468
+ : Icons.dark_mode,
1469
+ size: 20,
1470
+ ),
1471
+ onPressed: _toggleTheme,
1472
+ ),
1473
+ IconButton(
1474
+ icon: const Icon(Icons.settings, size: 20),
1475
+ onPressed: () => context.push('/settings'),
1476
+ ),
1477
+ ],
1478
+ ),
1479
+ onDrawerChanged: (isOpened) {
1480
+ if (isOpened) FocusManager.instance.primaryFocus?.unfocus();
1481
+ },
1482
+ drawer: SessionDrawer(
1483
+ sessions: sessions,
1484
+ activeSessionId: activeSession?.id,
1485
+ unreadCounts: unreadCounts,
1486
+ isPro: ref.watch(isProProvider),
1487
+ onSelect: (s) => _switchSession(s.id),
1488
+ onRemove: _handleSessionRemove,
1489
+ onRename: _handleSessionRename,
1490
+ onReorder: _handleSessionReorder,
1491
+ onNewSession: _handleNewSession,
1492
+ onRefresh: _refreshSessions,
1493
+ onUpgrade: _handleUpgrade,
1494
+ ),
1495
+ body: Column(
1496
+ children: [
1497
+ const PaywallBanner(),
1498
+ Expanded(
1499
+ child: ListView.builder(
1500
+ controller: _scrollController,
1501
+ reverse: true,
1502
+ padding: const EdgeInsets.only(top: 8, bottom: 8),
1503
+ itemCount: messages.length + (isTyping ? 1 : 0),
1504
+ itemBuilder: (context, index) {
1505
+ if (isTyping && index == 0) {
1506
+ return const TypingIndicator();
1507
+ }
1508
+
1509
+ final msgIndex = isTyping
1510
+ ? messages.length - index
1511
+ : messages.length - 1 - index;
1512
+
1513
+ if (msgIndex < 0 || msgIndex >= messages.length) {
1514
+ return const SizedBox.shrink();
1515
+ }
1516
+
1517
+ final message = messages[msgIndex];
1518
+ return MessageBubble(
1519
+ message: message,
1520
+ isPlaying: _playingMessageId == message.id,
1521
+ onPlay: message.type == MessageType.voice
1522
+ ? () => _playMessage(message)
1523
+ : null,
1524
+ onChainPlay: message.type == MessageType.voice &&
1525
+ message.role == MessageRole.assistant
1526
+ ? () => _chainPlayFrom(message)
1527
+ : null,
1528
+ onDelete: () {
1529
+ ref.read(messagesProvider.notifier).removeMessage(message.id);
1530
+ },
1531
+ );
1532
+ },
1533
+ ),
1534
+ ),
1535
+ CommandBar(
1536
+ onScreen: _requestScreenshot,
1537
+ onNavigate: _navigateToTerminal,
1538
+ onPhoto: _pickPhoto,
1539
+ onClear: _clearChat,
1540
+ onHelp: inputMode == InputMode.text ? _sendHelp : null,
1541
+ showHelp: inputMode == InputMode.text,
1542
+ ),
1543
+ InputBar(
1544
+ mode: inputMode,
1545
+ isRecording: _isRecording,
1546
+ textController: _textController,
1547
+ onToggleMode: () {
1548
+ ref.read(inputModeProvider.notifier).state =
1549
+ inputMode == InputMode.voice
1550
+ ? InputMode.text
1551
+ : InputMode.voice;
1552
+ },
1553
+ onRecordStart: _startRecording,
1554
+ onRecordStop: _stopRecording,
1555
+ onRecordCancel: _cancelRecording,
1556
+ onReplay: _replayLast,
1557
+ onSendText: _sendTextMessage,
1558
+ ),
1559
+ ],
1560
+ ),
1561
+ ),
1562
+ );
1563
+ }
1564
+}
lib/screens/navigate_screen.dart
....@@ -0,0 +1,222 @@
1
+import 'dart:convert';
2
+
3
+import 'package:flutter/material.dart';
4
+import 'package:flutter_riverpod/flutter_riverpod.dart';
5
+import 'package:vibration/vibration.dart';
6
+
7
+import '../providers/providers.dart';
8
+import '../services/navigate_notifier.dart';
9
+import '../theme/app_theme.dart';
10
+
11
+/// Terminal navigation screen with screenshot display and key grid.
12
+class NavigateScreen extends ConsumerStatefulWidget {
13
+ const NavigateScreen({super.key});
14
+
15
+ @override
16
+ ConsumerState<NavigateScreen> createState() => _NavigateScreenState();
17
+}
18
+
19
+class _NavigateScreenState extends ConsumerState<NavigateScreen> {
20
+ @override
21
+ Widget build(BuildContext context) {
22
+ final screenshot = ref.watch(latestScreenshotProvider);
23
+ final isDark = Theme.of(context).brightness == Brightness.dark;
24
+
25
+ return Scaffold(
26
+ appBar: AppBar(
27
+ title: const Text('Navigate'),
28
+ actions: [
29
+ IconButton(
30
+ icon: const Icon(Icons.refresh),
31
+ onPressed: _requestScreenshot,
32
+ tooltip: 'Refresh screenshot',
33
+ ),
34
+ ],
35
+ ),
36
+ body: Column(
37
+ children: [
38
+ // Screenshot display
39
+ Expanded(
40
+ child: screenshot != null
41
+ ? Padding(
42
+ padding: const EdgeInsets.all(8),
43
+ child: InteractiveViewer(
44
+ minScale: 1.0,
45
+ maxScale: 3.0,
46
+ child: Image.memory(
47
+ base64Decode(
48
+ screenshot.contains(',')
49
+ ? screenshot.split(',').last
50
+ : screenshot,
51
+ ),
52
+ fit: BoxFit.contain,
53
+ errorBuilder: (_, e, st) => const Center(
54
+ child: Text('Screenshot decode error'),
55
+ ),
56
+ ),
57
+ ),
58
+ )
59
+ : Center(
60
+ child: Column(
61
+ mainAxisSize: MainAxisSize.min,
62
+ children: [
63
+ Icon(
64
+ Icons.screenshot_monitor,
65
+ size: 48,
66
+ color: isDark
67
+ ? AppColors.darkTextTertiary
68
+ : Colors.grey.shade400,
69
+ ),
70
+ const SizedBox(height: 12),
71
+ Text(
72
+ 'No screenshot yet',
73
+ style: TextStyle(
74
+ color: isDark
75
+ ? AppColors.darkTextTertiary
76
+ : Colors.grey.shade500,
77
+ ),
78
+ ),
79
+ const SizedBox(height: 8),
80
+ TextButton(
81
+ onPressed: _requestScreenshot,
82
+ child: const Text('Request Screenshot'),
83
+ ),
84
+ ],
85
+ ),
86
+ ),
87
+ ),
88
+ // Key grid
89
+ Container(
90
+ padding: const EdgeInsets.all(12),
91
+ decoration: BoxDecoration(
92
+ color: isDark ? AppColors.darkSurface : AppColors.lightSurface,
93
+ border: Border(
94
+ top: BorderSide(
95
+ color: isDark ? Colors.white10 : Colors.black12,
96
+ ),
97
+ ),
98
+ ),
99
+ child: SafeArea(
100
+ top: false,
101
+ child: _buildKeyGrid(context),
102
+ ),
103
+ ),
104
+ ],
105
+ ),
106
+ );
107
+ }
108
+
109
+ Widget _buildKeyGrid(BuildContext context) {
110
+ return Column(
111
+ children: [
112
+ // Row 1: 0, Up, G
113
+ Row(
114
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
115
+ children: [
116
+ _keyButton('0', '0'),
117
+ _keyButton('\u2191', 'k', label: 'k'),
118
+ _keyButton('G', 'G'),
119
+ ],
120
+ ),
121
+ const SizedBox(height: 8),
122
+ // Row 2: Left, Down, Right
123
+ Row(
124
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
125
+ children: [
126
+ _keyButton('\u2190', 'h', label: 'h'),
127
+ _keyButton('\u2193', 'j', label: 'j'),
128
+ _keyButton('\u2192', 'l', label: 'l'),
129
+ ],
130
+ ),
131
+ const SizedBox(height: 8),
132
+ // Row 3: dd, Esc, Tab
133
+ Row(
134
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
135
+ children: [
136
+ _keyButton('dd', 'dd'),
137
+ _keyButton('Esc', 'Escape'),
138
+ _keyButton('Tab', 'Tab'),
139
+ ],
140
+ ),
141
+ const SizedBox(height: 8),
142
+ // Row 4: Enter (wide), ^C
143
+ Row(
144
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
145
+ children: [
146
+ Expanded(
147
+ flex: 2,
148
+ child: Padding(
149
+ padding: const EdgeInsets.symmetric(horizontal: 4),
150
+ child: _keyButton('Enter', 'Return', wide: true),
151
+ ),
152
+ ),
153
+ Expanded(
154
+ child: Padding(
155
+ padding: const EdgeInsets.symmetric(horizontal: 4),
156
+ child: _keyButton('^C', 'ctrl+c'),
157
+ ),
158
+ ),
159
+ ],
160
+ ),
161
+ ],
162
+ );
163
+ }
164
+
165
+ Widget _keyButton(String display, String key,
166
+ {String? label, bool wide = false}) {
167
+ final isDark = Theme.of(context).brightness == Brightness.dark;
168
+
169
+ return SizedBox(
170
+ width: wide ? null : 72,
171
+ height: 44,
172
+ child: Material(
173
+ color: isDark ? AppColors.darkInputBg : AppColors.lightInputBg,
174
+ borderRadius: BorderRadius.circular(8),
175
+ child: InkWell(
176
+ onTap: () => _sendKey(key),
177
+ borderRadius: BorderRadius.circular(8),
178
+ child: Center(
179
+ child: Text(
180
+ display,
181
+ style: TextStyle(
182
+ fontSize: 16,
183
+ fontWeight: FontWeight.w600,
184
+ color: isDark ? AppColors.darkTextPrimary : AppColors.lightTextPrimary,
185
+ ),
186
+ ),
187
+ ),
188
+ ),
189
+ ),
190
+ );
191
+ }
192
+
193
+ void _sendKey(String key) {
194
+ _haptic();
195
+
196
+ // Send via MQTT - the chat screen's MQTT service is in the provider
197
+ final activeSessionId = ref.read(activeSessionIdProvider);
198
+
199
+ // Send a key press to the AIBroker daemon via the MQTT service.
200
+ // navigateNotifierProvider bridges the navigate screen to the chat screen's MQTT service.
201
+
202
+ ref.read(navigateNotifierProvider)?.sendKey(key, activeSessionId);
203
+
204
+ // Request updated screenshot after key
205
+ Future.delayed(const Duration(milliseconds: 500), _requestScreenshot);
206
+ }
207
+
208
+ void _requestScreenshot() {
209
+ final activeSessionId = ref.read(activeSessionIdProvider);
210
+ ref.read(navigateNotifierProvider)?.requestScreenshot(activeSessionId);
211
+ }
212
+
213
+ Future<void> _haptic() async {
214
+ try {
215
+ final hasVibrator = await Vibration.hasVibrator();
216
+ if (hasVibrator) {
217
+ Vibration.vibrate(duration: 15);
218
+ }
219
+ } catch (_) {}
220
+ }
221
+}
222
+
lib/screens/settings_screen.dart
....@@ -0,0 +1,492 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:flutter_riverpod/flutter_riverpod.dart';
3
+import 'package:shared_preferences/shared_preferences.dart';
4
+
5
+import '../models/server_config.dart';
6
+import '../providers/providers.dart';
7
+import '../services/mqtt_service.dart' show ConnectionStatus;
8
+import '../services/purchase_service.dart';
9
+import '../services/wol_service.dart';
10
+import '../theme/app_theme.dart';
11
+import '../widgets/status_dot.dart';
12
+import 'trace_screen.dart';
13
+
14
+class SettingsScreen extends ConsumerStatefulWidget {
15
+ const SettingsScreen({super.key});
16
+
17
+ @override
18
+ ConsumerState<SettingsScreen> createState() => _SettingsScreenState();
19
+}
20
+
21
+class _SettingsScreenState extends ConsumerState<SettingsScreen> {
22
+ final _formKey = GlobalKey<FormState>();
23
+ late final TextEditingController _localHostController;
24
+ late final TextEditingController _vpnHostController;
25
+ late final TextEditingController _remoteHostController;
26
+ late final TextEditingController _portController;
27
+ late final TextEditingController _macController;
28
+ late final TextEditingController _mqttTokenController;
29
+ bool _isWaking = false;
30
+ bool _iapLoading = false;
31
+
32
+ @override
33
+ void initState() {
34
+ super.initState();
35
+ PurchaseService.instance.addListener(_onPurchaseChanged);
36
+ final config = ref.read(serverConfigProvider);
37
+ _localHostController =
38
+ TextEditingController(text: config?.localHost ?? '');
39
+ _vpnHostController =
40
+ TextEditingController(text: config?.vpnHost ?? '');
41
+ _remoteHostController =
42
+ TextEditingController(text: config?.host ?? '');
43
+ _portController =
44
+ TextEditingController(text: '${config?.port ?? 8765}');
45
+ _macController =
46
+ TextEditingController(text: config?.macAddress ?? '');
47
+ _mqttTokenController =
48
+ TextEditingController(text: config?.mqttToken ?? '');
49
+ }
50
+
51
+ @override
52
+ void dispose() {
53
+ PurchaseService.instance.removeListener(_onPurchaseChanged);
54
+ _localHostController.dispose();
55
+ _vpnHostController.dispose();
56
+ _remoteHostController.dispose();
57
+ _portController.dispose();
58
+ _macController.dispose();
59
+ _mqttTokenController.dispose();
60
+ super.dispose();
61
+ }
62
+
63
+ void _onPurchaseChanged() {
64
+ if (!mounted) return;
65
+ final isPro = PurchaseService.instance.isPro;
66
+ ref.read(isProProvider.notifier).state = isPro;
67
+ setState(() => _iapLoading = PurchaseService.instance.isLoading);
68
+ final error = PurchaseService.instance.errorMessage;
69
+ if (error != null && mounted) {
70
+ ScaffoldMessenger.of(context).showSnackBar(
71
+ SnackBar(content: Text(error)),
72
+ );
73
+ }
74
+ if (isPro && mounted) {
75
+ ScaffoldMessenger.of(context).showSnackBar(
76
+ const SnackBar(
77
+ content: Text('PAILot Pro activated. Enjoy unlimited sessions!'),
78
+ duration: Duration(seconds: 3),
79
+ ),
80
+ );
81
+ }
82
+ }
83
+
84
+ Future<void> _handleUpgrade() async {
85
+ setState(() => _iapLoading = true);
86
+ await PurchaseService.instance.purchaseFullAccess();
87
+ }
88
+
89
+ Future<void> _handleRestore() async {
90
+ setState(() => _iapLoading = true);
91
+ await PurchaseService.instance.restorePurchases();
92
+ if (mounted) {
93
+ ScaffoldMessenger.of(context).showSnackBar(
94
+ const SnackBar(
95
+ content: Text('Checking for previous purchases...'),
96
+ duration: Duration(seconds: 2),
97
+ ),
98
+ );
99
+ }
100
+ }
101
+
102
+ Future<void> _save() async {
103
+ if (!_formKey.currentState!.validate()) return;
104
+
105
+ final config = ServerConfig(
106
+ host: _remoteHostController.text.trim(),
107
+ port: int.tryParse(_portController.text.trim()) ?? 8765,
108
+ localHost: _localHostController.text.trim().isEmpty
109
+ ? null
110
+ : _localHostController.text.trim(),
111
+ vpnHost: _vpnHostController.text.trim().isEmpty
112
+ ? null
113
+ : _vpnHostController.text.trim(),
114
+ macAddress: _macController.text.trim().isEmpty
115
+ ? null
116
+ : _macController.text.trim(),
117
+ mqttToken: _mqttTokenController.text.trim().isEmpty
118
+ ? null
119
+ : _mqttTokenController.text.trim(),
120
+ );
121
+
122
+ await ref.read(serverConfigProvider.notifier).save(config);
123
+
124
+ if (mounted) {
125
+ ScaffoldMessenger.of(context).showSnackBar(
126
+ const SnackBar(
127
+ content: Text('Server configuration saved'),
128
+ duration: Duration(seconds: 2),
129
+ ),
130
+ );
131
+ }
132
+ }
133
+
134
+ Future<void> _wakeMac() async {
135
+ final mac = _macController.text.trim();
136
+ if (mac.isEmpty) {
137
+ ScaffoldMessenger.of(context).showSnackBar(
138
+ const SnackBar(content: Text('No MAC address configured')),
139
+ );
140
+ return;
141
+ }
142
+
143
+ setState(() => _isWaking = true);
144
+
145
+ try {
146
+ await WolService.wake(mac, localHost: _localHostController.text.trim());
147
+ if (mounted) {
148
+ ScaffoldMessenger.of(context).showSnackBar(
149
+ const SnackBar(content: Text('Wake-on-LAN packet sent')),
150
+ );
151
+ }
152
+ } catch (e) {
153
+ if (mounted) {
154
+ ScaffoldMessenger.of(context).showSnackBar(
155
+ SnackBar(content: Text('WoL failed: $e')),
156
+ );
157
+ }
158
+ } finally {
159
+ if (mounted) setState(() => _isWaking = false);
160
+ }
161
+ }
162
+
163
+ @override
164
+ Widget build(BuildContext context) {
165
+ final wsStatus = ref.watch(wsStatusProvider);
166
+ return Scaffold(
167
+ appBar: AppBar(
168
+ title: const Text('Settings'),
169
+ ),
170
+ body: SingleChildScrollView(
171
+ padding: const EdgeInsets.all(16),
172
+ child: Form(
173
+ key: _formKey,
174
+ child: Column(
175
+ crossAxisAlignment: CrossAxisAlignment.stretch,
176
+ children: [
177
+ // Connection status card
178
+ Card(
179
+ child: Padding(
180
+ padding: const EdgeInsets.all(16),
181
+ child: Row(
182
+ children: [
183
+ StatusDot(status: wsStatus),
184
+ const SizedBox(width: 12),
185
+ Expanded(
186
+ child: Column(
187
+ crossAxisAlignment: CrossAxisAlignment.start,
188
+ children: [
189
+ Text(
190
+ _statusText(wsStatus),
191
+ style: Theme.of(context).textTheme.bodyLarge,
192
+ ),
193
+ if (ref.watch(connectedViaProvider).isNotEmpty)
194
+ Text(
195
+ 'via ${ref.watch(connectedViaProvider)}',
196
+ style: TextStyle(
197
+ fontSize: 12,
198
+ color: Colors.grey.shade500,
199
+ ),
200
+ ),
201
+ ],
202
+ ),
203
+ ),
204
+ ],
205
+ ),
206
+ ),
207
+ ),
208
+ const SizedBox(height: 24),
209
+
210
+ // Local address
211
+ Text('Local Address',
212
+ style: Theme.of(context).textTheme.bodyMedium),
213
+ const SizedBox(height: 4),
214
+ TextFormField(
215
+ controller: _localHostController,
216
+ decoration: const InputDecoration(
217
+ hintText: '192.168.1.100',
218
+ ),
219
+ keyboardType: TextInputType.url,
220
+ validator: (v) {
221
+ if (v == null || v.trim().isEmpty) return null;
222
+ final ip = RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$');
223
+ return ip.hasMatch(v.trim()) ? null : 'Enter a valid IP address';
224
+ },
225
+ ),
226
+ const SizedBox(height: 16),
227
+
228
+ // VPN address
229
+ Text('VPN Address',
230
+ style: Theme.of(context).textTheme.bodyMedium),
231
+ const SizedBox(height: 4),
232
+ TextFormField(
233
+ controller: _vpnHostController,
234
+ decoration: const InputDecoration(
235
+ hintText: '10.8.0.1 (OpenVPN static IP)',
236
+ ),
237
+ keyboardType: TextInputType.url,
238
+ validator: (v) {
239
+ if (v == null || v.trim().isEmpty) return null;
240
+ final ip = RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$');
241
+ return ip.hasMatch(v.trim()) ? null : 'Enter a valid IP address';
242
+ },
243
+ ),
244
+ const SizedBox(height: 16),
245
+
246
+ // Remote address
247
+ Text('Remote Address',
248
+ style: Theme.of(context).textTheme.bodyMedium),
249
+ const SizedBox(height: 4),
250
+ TextFormField(
251
+ controller: _remoteHostController,
252
+ decoration: const InputDecoration(
253
+ hintText: 'your-server.example.com',
254
+ ),
255
+ keyboardType: TextInputType.url,
256
+ validator: (v) =>
257
+ (v == null || v.trim().isEmpty) ? 'Required' : null,
258
+ ),
259
+ const SizedBox(height: 16),
260
+
261
+ // Port
262
+ Text('Port', style: Theme.of(context).textTheme.bodyMedium),
263
+ const SizedBox(height: 4),
264
+ TextFormField(
265
+ controller: _portController,
266
+ decoration: const InputDecoration(
267
+ hintText: '8765',
268
+ ),
269
+ keyboardType: TextInputType.number,
270
+ validator: (v) {
271
+ if (v == null || v.trim().isEmpty) return 'Required';
272
+ final port = int.tryParse(v.trim());
273
+ if (port == null || port < 1 || port > 65535) {
274
+ return 'Port must be 1–65535';
275
+ }
276
+ return null;
277
+ },
278
+ ),
279
+ const SizedBox(height: 16),
280
+
281
+ // MAC address
282
+ Text('MAC Address (for Wake-on-LAN)',
283
+ style: Theme.of(context).textTheme.bodyMedium),
284
+ const SizedBox(height: 4),
285
+ TextFormField(
286
+ controller: _macController,
287
+ decoration: const InputDecoration(
288
+ hintText: 'AA:BB:CC:DD:EE:FF',
289
+ ),
290
+ validator: (v) {
291
+ if (v == null || v.trim().isEmpty) return null;
292
+ final mac = RegExp(
293
+ r'^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$');
294
+ return mac.hasMatch(v.trim())
295
+ ? null
296
+ : 'Enter a valid MAC address (AA:BB:CC:DD:EE:FF)';
297
+ },
298
+ ),
299
+ const SizedBox(height: 16),
300
+
301
+ // MQTT Token
302
+ Text('MQTT Token',
303
+ style: Theme.of(context).textTheme.bodyMedium),
304
+ const SizedBox(height: 4),
305
+ TextFormField(
306
+ controller: _mqttTokenController,
307
+ decoration: const InputDecoration(
308
+ hintText: 'Shared secret for MQTT auth',
309
+ ),
310
+ obscureText: true,
311
+ ),
312
+ const SizedBox(height: 24),
313
+
314
+ // Save button
315
+ ElevatedButton(
316
+ onPressed: _save,
317
+ style: ElevatedButton.styleFrom(
318
+ backgroundColor: AppColors.accent,
319
+ foregroundColor: Colors.white,
320
+ ),
321
+ child: const Text('Save Configuration'),
322
+ ),
323
+ const SizedBox(height: 12),
324
+
325
+ // Wake Mac button
326
+ OutlinedButton.icon(
327
+ onPressed: _isWaking ? null : _wakeMac,
328
+ icon: _isWaking
329
+ ? const SizedBox(
330
+ width: 16,
331
+ height: 16,
332
+ child: CircularProgressIndicator(strokeWidth: 2),
333
+ )
334
+ : const Icon(Icons.power_settings_new),
335
+ label: const Text('Wake Mac'),
336
+ ),
337
+ const SizedBox(height: 12),
338
+
339
+ // Reset TLS Trust button
340
+ OutlinedButton.icon(
341
+ onPressed: () async {
342
+ final confirmed = await showDialog<bool>(
343
+ context: context,
344
+ builder: (ctx) => AlertDialog(
345
+ title: const Text('Reset Server Trust?'),
346
+ content: const Text(
347
+ 'This clears the saved server certificate fingerprint. '
348
+ 'Use this if you reinstalled AIBroker or changed servers. '
349
+ 'The app will trust the next server it connects to.',
350
+ ),
351
+ actions: [
352
+ TextButton(
353
+ onPressed: () => Navigator.pop(ctx, false),
354
+ child: const Text('Cancel'),
355
+ ),
356
+ TextButton(
357
+ onPressed: () => Navigator.pop(ctx, true),
358
+ child: const Text('Reset', style: TextStyle(color: AppColors.error)),
359
+ ),
360
+ ],
361
+ ),
362
+ );
363
+ if (confirmed == true && mounted) {
364
+ // Access MqttService through the provider and reset trust
365
+ final prefs = await SharedPreferences.getInstance();
366
+ await prefs.remove('trustedCertFingerprint');
367
+ ScaffoldMessenger.of(context).showSnackBar(
368
+ const SnackBar(content: Text('Server trust reset. Reconnect to trust the new server.')),
369
+ );
370
+ }
371
+ },
372
+ icon: const Icon(Icons.shield_outlined),
373
+ label: const Text('Reset Server Trust'),
374
+ ),
375
+ const SizedBox(height: 12),
376
+
377
+ // Message Trace Log — for diagnosing message delivery problems
378
+ OutlinedButton.icon(
379
+ onPressed: () {
380
+ Navigator.of(context).push(
381
+ MaterialPageRoute<void>(
382
+ builder: (_) => const TraceScreen(),
383
+ ),
384
+ );
385
+ },
386
+ icon: const Icon(Icons.receipt_long_outlined),
387
+ label: const Text('Message Trace Log'),
388
+ ),
389
+ const SizedBox(height: 24),
390
+
391
+ // --- PAILot Pro ---
392
+ const Divider(),
393
+ const SizedBox(height: 8),
394
+ Row(
395
+ children: [
396
+ const Icon(Icons.star, size: 18),
397
+ const SizedBox(width: 8),
398
+ Text(
399
+ 'PAILot Pro',
400
+ style: Theme.of(context).textTheme.titleMedium,
401
+ ),
402
+ const Spacer(),
403
+ Consumer(
404
+ builder: (ctx, ref, _) {
405
+ final isPro = ref.watch(isProProvider);
406
+ return Chip(
407
+ label: Text(
408
+ isPro ? 'Active' : 'Free Tier',
409
+ style: TextStyle(
410
+ fontSize: 11,
411
+ color: isPro ? Colors.white : null,
412
+ ),
413
+ ),
414
+ backgroundColor: isPro ? AppColors.accent : null,
415
+ padding: EdgeInsets.zero,
416
+ visualDensity: VisualDensity.compact,
417
+ );
418
+ },
419
+ ),
420
+ ],
421
+ ),
422
+ const SizedBox(height: 4),
423
+ Text(
424
+ 'Free: 2 sessions, messages expire after 15 min\n'
425
+ 'Pro: unlimited sessions, messages persist forever',
426
+ style: Theme.of(context)
427
+ .textTheme
428
+ .bodySmall
429
+ ?.copyWith(color: Colors.grey.shade500),
430
+ ),
431
+ const SizedBox(height: 12),
432
+ Consumer(
433
+ builder: (ctx, ref, _) {
434
+ final isPro = ref.watch(isProProvider);
435
+ if (isPro) {
436
+ return const Center(
437
+ child: Text(
438
+ 'Full access active',
439
+ style: TextStyle(color: AppColors.accent),
440
+ ),
441
+ );
442
+ }
443
+ return Column(
444
+ crossAxisAlignment: CrossAxisAlignment.stretch,
445
+ children: [
446
+ ElevatedButton.icon(
447
+ onPressed: _iapLoading ? null : _handleUpgrade,
448
+ icon: _iapLoading
449
+ ? const SizedBox(
450
+ width: 16,
451
+ height: 16,
452
+ child:
453
+ CircularProgressIndicator(strokeWidth: 2),
454
+ )
455
+ : const Icon(Icons.upgrade),
456
+ label: const Text('Upgrade to Pro — \$4.99'),
457
+ style: ElevatedButton.styleFrom(
458
+ backgroundColor: AppColors.accent,
459
+ foregroundColor: Colors.white,
460
+ ),
461
+ ),
462
+ const SizedBox(height: 8),
463
+ OutlinedButton.icon(
464
+ onPressed: _iapLoading ? null : _handleRestore,
465
+ icon: const Icon(Icons.restore),
466
+ label: const Text('Restore Purchase'),
467
+ ),
468
+ ],
469
+ );
470
+ },
471
+ ),
472
+ const SizedBox(height: 12),
473
+ ],
474
+ ),
475
+ ),
476
+ ),
477
+ );
478
+ }
479
+
480
+ String _statusText(ConnectionStatus status) {
481
+ switch (status) {
482
+ case ConnectionStatus.connected:
483
+ return 'Connected';
484
+ case ConnectionStatus.connecting:
485
+ return 'Connecting...';
486
+ case ConnectionStatus.reconnecting:
487
+ return 'Reconnecting...';
488
+ case ConnectionStatus.disconnected:
489
+ return 'Disconnected';
490
+ }
491
+ }
492
+}
lib/screens/splash_screen.dart
....@@ -0,0 +1,311 @@
1
+import 'dart:math' as math;
2
+import 'package:flutter/material.dart';
3
+
4
+/// PAILot animated splash screen.
5
+///
6
+/// Phase 1 (~0-1500ms): The P logo reveals itself progressively from top to
7
+/// bottom, as if being drawn by an invisible pen.
8
+///
9
+/// Phase 2 (~1000-1700ms): A paper airplane flies in from the left, arcing
10
+/// across the P.
11
+///
12
+/// After animation completes the [onComplete] callback fires.
13
+class SplashScreen extends StatefulWidget {
14
+ final VoidCallback onComplete;
15
+
16
+ const SplashScreen({super.key, required this.onComplete});
17
+
18
+ @override
19
+ State<SplashScreen> createState() => _SplashScreenState();
20
+}
21
+
22
+class _SplashScreenState extends State<SplashScreen>
23
+ with TickerProviderStateMixin {
24
+ late final AnimationController _drawController;
25
+ late final AnimationController _planeController;
26
+ late final AnimationController _fadeController;
27
+
28
+ static const Duration _drawDuration = Duration(milliseconds: 1500);
29
+ static const Duration _planeDuration = Duration(milliseconds: 700);
30
+ static const Duration _fadeDuration = Duration(milliseconds: 300);
31
+
32
+ @override
33
+ void initState() {
34
+ super.initState();
35
+
36
+ _drawController =
37
+ AnimationController(vsync: this, duration: _drawDuration);
38
+ _planeController =
39
+ AnimationController(vsync: this, duration: _planeDuration);
40
+ _fadeController =
41
+ AnimationController(vsync: this, duration: _fadeDuration);
42
+
43
+ _startSequence();
44
+ }
45
+
46
+ Future<void> _startSequence() async {
47
+ await Future.delayed(const Duration(milliseconds: 50));
48
+ if (!mounted) return;
49
+
50
+ _drawController.forward();
51
+
52
+ await Future.delayed(const Duration(milliseconds: 1000));
53
+ if (!mounted) return;
54
+ _planeController.forward();
55
+
56
+ await Future.delayed(const Duration(milliseconds: 800));
57
+ if (!mounted) return;
58
+
59
+ await _fadeController.forward();
60
+ if (!mounted) return;
61
+ widget.onComplete();
62
+ }
63
+
64
+ @override
65
+ void dispose() {
66
+ _drawController.dispose();
67
+ _planeController.dispose();
68
+ _fadeController.dispose();
69
+ super.dispose();
70
+ }
71
+
72
+ @override
73
+ Widget build(BuildContext context) {
74
+ return Scaffold(
75
+ backgroundColor: const Color(0xFF111217),
76
+ body: FadeTransition(
77
+ opacity: Tween<double>(begin: 1.0, end: 0.0).animate(
78
+ CurvedAnimation(parent: _fadeController, curve: Curves.easeIn),
79
+ ),
80
+ child: Center(
81
+ child: Column(
82
+ mainAxisSize: MainAxisSize.min,
83
+ children: [
84
+ AnimatedBuilder(
85
+ animation:
86
+ Listenable.merge([_drawController, _planeController]),
87
+ builder: (context, child) {
88
+ return CustomPaint(
89
+ size: const Size(300, 300),
90
+ painter: _PLogoWithPlanePainter(
91
+ drawProgress: _drawController.value,
92
+ planeProgress: _planeController.value,
93
+ ),
94
+ );
95
+ },
96
+ ),
97
+ const SizedBox(height: 24),
98
+ AnimatedBuilder(
99
+ animation: _drawController,
100
+ builder: (context, child) {
101
+ return Opacity(
102
+ opacity: _drawController.value.clamp(0.0, 1.0),
103
+ child: const Text(
104
+ 'PAILot',
105
+ style: TextStyle(
106
+ color: Color(0xFF00C7FF),
107
+ fontSize: 28,
108
+ fontWeight: FontWeight.w300,
109
+ letterSpacing: 6,
110
+ ),
111
+ ),
112
+ );
113
+ },
114
+ ),
115
+ ],
116
+ ),
117
+ ),
118
+ ),
119
+ );
120
+ }
121
+}
122
+
123
+class _PLogoWithPlanePainter extends CustomPainter {
124
+ final double drawProgress;
125
+ final double planeProgress;
126
+
127
+ const _PLogoWithPlanePainter({
128
+ required this.drawProgress,
129
+ required this.planeProgress,
130
+ });
131
+
132
+ @override
133
+ void paint(Canvas canvas, Size size) {
134
+ const double svgW = 519.2;
135
+ const double svgH = 519.3;
136
+
137
+ final double scale = math.min(size.width / svgW, size.height / svgH);
138
+ final double offsetX = (size.width - svgW * scale) / 2;
139
+ final double offsetY = (size.height - svgH * scale) / 2;
140
+
141
+ canvas.save();
142
+ canvas.translate(offsetX, offsetY);
143
+ canvas.scale(scale, scale);
144
+
145
+ _drawPLogo(canvas);
146
+ _drawPlane(canvas);
147
+
148
+ canvas.restore();
149
+ }
150
+
151
+ void _drawPLogo(Canvas canvas) {
152
+ if (drawProgress <= 0) return;
153
+
154
+ final paths = _buildPPaths();
155
+
156
+ Rect bounds = paths.first.getBounds();
157
+ for (final p in paths.skip(1)) {
158
+ bounds = bounds.expandToInclude(p.getBounds());
159
+ }
160
+
161
+ final double revealY = bounds.top +
162
+ bounds.height * Curves.easeInOut.transform(drawProgress);
163
+
164
+ canvas.save();
165
+ canvas.clipRect(Rect.fromLTRB(
166
+ bounds.left - 10,
167
+ bounds.top - 10,
168
+ bounds.right + 10,
169
+ revealY + 6,
170
+ ));
171
+
172
+ final Paint gradientPaint = Paint()
173
+ ..shader = const LinearGradient(
174
+ begin: Alignment.topLeft,
175
+ end: Alignment.bottomRight,
176
+ colors: [Color(0xFF0000FF), Color(0xFF00C7FF)],
177
+ ).createShader(Rect.fromLTWH(0, 0, 519.2, 519.3))
178
+ ..style = PaintingStyle.fill
179
+ ..isAntiAlias = true;
180
+
181
+ for (final p in paths) {
182
+ canvas.drawPath(p, gradientPaint);
183
+ }
184
+
185
+ canvas.restore();
186
+ }
187
+
188
+ List<Path> _buildPPaths() {
189
+ final path1 = Path();
190
+ path1.moveTo(149.4, 68.3);
191
+ path1.lineTo(191.1, 155.4);
192
+ path1.lineTo(300.6, 151.2);
193
+ path1.cubicTo(301.3, 151.2, 302.0, 151.1, 302.7, 151.1);
194
+ path1.cubicTo(324.8, 151.1, 343.0, 169.0, 343.0, 191.4);
195
+ path1.cubicTo(343.0, 201.3, 339.4, 210.4, 333.5, 217.4);
196
+ path1.cubicTo(366.8, 193.1, 389.3, 153.8, 389.3, 109.5);
197
+ path1.cubicTo(389.3, 69.5, 371.7, 24.8, 343.9, 0.3);
198
+ path1.cubicTo(339.9, 0.0, 335.8, -0.1, 331.7, -0.1);
199
+ path1.lineTo(0, -0.1);
200
+ path1.lineTo(0, 5.4);
201
+ path1.cubicTo(0, 81.7, 59.8, 152.7, 134.9, 156.8);
202
+ path1.lineTo(107.3, 68.3);
203
+ path1.close();
204
+
205
+ final path2 = Path();
206
+ path2.moveTo(518.9, 175.6);
207
+ path2.cubicTo(515.9, 128.6, 495.7, 86.3, 464.4, 55.0);
208
+ path2.cubicTo(433.2, 23.8, 391.1, 3.6, 344.4, 0.5);
209
+ path2.cubicTo(344.3, 0.5, 344.2, 0.6, 344.3, 0.7);
210
+ path2.cubicTo(372.0, 25.2, 389.5, 69.8, 389.5, 109.6);
211
+ path2.cubicTo(389.5, 151.9, 364.4, 195.1, 333.7, 217.5);
212
+ path2.cubicTo(327.9, 224.3, 319.9, 229.2, 310.9, 231.0);
213
+ path2.cubicTo(293.9, 238.9, 275.2, 243.4, 255.9, 243.4);
214
+ path2.cubicTo(274.9, 243.4, 293.3, 239.1, 310.1, 231.4);
215
+ path2.cubicTo(310.2, 231.3, 310.2, 231.1, 310.0, 231.2);
216
+ path2.cubicTo(307.1, 231.7, 304.0, 231.9, 300.9, 231.8);
217
+ path2.lineTo(191.5, 227.6);
218
+ path2.lineTo(191.4, 227.7);
219
+ path2.lineTo(149.7, 314.7);
220
+ path2.lineTo(149.6, 314.8);
221
+ path2.lineTo(107.7, 314.8);
222
+ path2.cubicTo(107.6, 314.8, 107.6, 314.7, 107.6, 314.6);
223
+ path2.lineTo(135.1, 226.2);
224
+ path2.cubicTo(135.1, 226.1, 135.1, 226.0, 135.0, 226.0);
225
+ path2.cubicTo(59.7, 230.2, 0, 283.6, 0, 359.9);
226
+ path2.lineTo(0, 375.0);
227
+ path2.lineTo(0, 516.6);
228
+ path2.cubicTo(0, 516.7, 0.2, 516.8, 0.2, 516.6);
229
+ path2.cubicTo(29.6, 429.6, 111.9, 374.7, 208.9, 374.7);
230
+ path2.lineTo(298.2, 374.7);
231
+ path2.lineTo(298.4, 375.0);
232
+ path2.lineTo(329.8, 375.0);
233
+ path2.cubicTo(439.7, 375.0, 525.7, 285.2, 518.9, 175.6);
234
+ path2.close();
235
+
236
+ final path3 = Path();
237
+ path3.moveTo(208.9, 374.5);
238
+ path3.cubicTo(111.7, 374.5, 29.2, 429.6, 0, 517.0);
239
+ path3.lineTo(0, 519.2);
240
+ path3.lineTo(158.7, 519.2);
241
+ path3.lineTo(159.0, 417.6);
242
+ path3.cubicTo(158.8, 393.9, 178.0, 374.6, 201.7, 374.6);
243
+ path3.lineTo(298.4, 374.6);
244
+
245
+ return [path1, path2, path3];
246
+ }
247
+
248
+ void _drawPlane(Canvas canvas) {
249
+ if (planeProgress <= 0) return;
250
+
251
+ const double startX = -80.0, startY = 290.0;
252
+ const double ctrlX = 260.0, ctrlY = 100.0;
253
+ const double endX = 480.0, endY = 250.0;
254
+
255
+ final double t = planeProgress;
256
+ final double mt = 1.0 - t;
257
+
258
+ final double px = mt * mt * startX + 2 * mt * t * ctrlX + t * t * endX;
259
+ final double py = mt * mt * startY + 2 * mt * t * ctrlY + t * t * endY;
260
+
261
+ final double dx = 2 * mt * (ctrlX - startX) + 2 * t * (endX - ctrlX);
262
+ final double dy = 2 * mt * (ctrlY - startY) + 2 * t * (endY - ctrlY);
263
+ final double angle = math.atan2(dy, dx);
264
+
265
+ double alpha = 1.0;
266
+ if (t < 0.15) {
267
+ alpha = t / 0.15;
268
+ } else if (t > 0.9) {
269
+ alpha = (1.0 - t) / 0.1;
270
+ }
271
+
272
+ canvas.save();
273
+ canvas.translate(px, py);
274
+ canvas.rotate(angle);
275
+
276
+ const double s = 30.0;
277
+ final Paint bodyPaint = Paint()
278
+ ..color = Color.fromRGBO(0, 199, 255, alpha)
279
+ ..style = PaintingStyle.fill
280
+ ..isAntiAlias = true;
281
+ final Paint edgePaint = Paint()
282
+ ..color = Color.fromRGBO(255, 255, 255, alpha * 0.6)
283
+ ..style = PaintingStyle.stroke
284
+ ..strokeWidth = 1.5
285
+ ..isAntiAlias = true;
286
+
287
+ final Path plane = Path()
288
+ ..moveTo(s, 0)
289
+ ..lineTo(-s * 0.6, -s * 0.55)
290
+ ..lineTo(-s * 0.2, 0)
291
+ ..lineTo(-s * 0.6, s * 0.55)
292
+ ..close();
293
+
294
+ canvas.drawPath(plane, bodyPaint);
295
+ canvas.drawPath(plane, edgePaint);
296
+
297
+ canvas.drawLine(
298
+ Offset(s, 0),
299
+ Offset(-s * 0.2, 0),
300
+ Paint()
301
+ ..color = Color.fromRGBO(255, 255, 255, alpha * 0.4)
302
+ ..strokeWidth = 1.0,
303
+ );
304
+
305
+ canvas.restore();
306
+ }
307
+
308
+ @override
309
+ bool shouldRepaint(_PLogoWithPlanePainter old) =>
310
+ old.drawProgress != drawProgress || old.planeProgress != planeProgress;
311
+}
lib/screens/trace_screen.dart
....@@ -0,0 +1,254 @@
1
+import 'dart:convert';
2
+
3
+import 'package:flutter/material.dart';
4
+import 'package:mqtt_client/mqtt_client.dart';
5
+
6
+import '../services/mqtt_service.dart';
7
+import '../services/trace_service.dart';
8
+
9
+/// Displays the in-memory trace log for diagnosing message delivery problems.
10
+///
11
+/// Shows entries in reverse chronological order (newest first).
12
+/// Accessible from the Settings screen via "Message Trace Log".
13
+/// Works in both debug and release builds.
14
+class TraceScreen extends StatefulWidget {
15
+ /// Optional MQTT service reference so entries can be published to the server.
16
+ final MqttService? mqttService;
17
+
18
+ const TraceScreen({super.key, this.mqttService});
19
+
20
+ @override
21
+ State<TraceScreen> createState() => _TraceScreenState();
22
+}
23
+
24
+class _TraceScreenState extends State<TraceScreen> {
25
+ bool _sending = false;
26
+
27
+ List<TraceEntry> get _entries =>
28
+ TraceService.instance.entries.reversed.toList();
29
+
30
+ Future<void> _sendToServer() async {
31
+ final service = widget.mqttService;
32
+ if (service == null || !service.isConnected) {
33
+ if (mounted) {
34
+ ScaffoldMessenger.of(context).showSnackBar(
35
+ const SnackBar(content: Text('Not connected to server')),
36
+ );
37
+ }
38
+ return;
39
+ }
40
+
41
+ setState(() => _sending = true);
42
+
43
+ try {
44
+ final entries = TraceService.instance.entries;
45
+ final payload = jsonEncode({
46
+ 'type': 'trace_log',
47
+ 'source': 'pailot',
48
+ 'ts': DateTime.now().millisecondsSinceEpoch,
49
+ 'count': entries.length,
50
+ 'entries': entries
51
+ .map((e) => {
52
+ 'timestamp': e.timestamp.toIso8601String(),
53
+ 'event': e.event,
54
+ 'details': e.details,
55
+ })
56
+ .toList(),
57
+ });
58
+
59
+ // Build the MQTT payload
60
+ final builder = MqttClientPayloadBuilder();
61
+ builder.addString(payload);
62
+
63
+ // Publish on pailot/trace — daemon can subscribe/log this
64
+ service.send({
65
+ 'type': 'command',
66
+ 'command': 'trace_upload',
67
+ 'args': {
68
+ 'count': entries.length,
69
+ 'payload': payload,
70
+ },
71
+ });
72
+
73
+ if (mounted) {
74
+ ScaffoldMessenger.of(context).showSnackBar(
75
+ SnackBar(
76
+ content: Text('Sent ${entries.length} trace entries to server'),
77
+ ),
78
+ );
79
+ }
80
+ } catch (e) {
81
+ if (mounted) {
82
+ ScaffoldMessenger.of(context).showSnackBar(
83
+ SnackBar(content: Text('Send failed: $e')),
84
+ );
85
+ }
86
+ } finally {
87
+ if (mounted) setState(() => _sending = false);
88
+ }
89
+ }
90
+
91
+ void _clearLog() {
92
+ TraceService.instance.clear();
93
+ setState(() {});
94
+ }
95
+
96
+ Color _colorForEvent(String event) {
97
+ if (event.contains('error') || event.contains('fail') || event.contains('drop')) {
98
+ return Colors.red.shade300;
99
+ }
100
+ if (event.contains('dedup')) return Colors.orange.shade300;
101
+ if (event.contains('displayed') || event.contains('published')) {
102
+ return Colors.green.shade300;
103
+ }
104
+ if (event.contains('MQTT')) return Colors.blue.shade300;
105
+ if (event.contains('voice')) return Colors.purple.shade300;
106
+ return Colors.grey.shade400;
107
+ }
108
+
109
+ @override
110
+ Widget build(BuildContext context) {
111
+ final entries = _entries;
112
+
113
+ return Scaffold(
114
+ appBar: AppBar(
115
+ title: const Text('Message Trace Log'),
116
+ actions: [
117
+ IconButton(
118
+ icon: const Icon(Icons.delete_outline),
119
+ tooltip: 'Clear log',
120
+ onPressed: _clearLog,
121
+ ),
122
+ IconButton(
123
+ icon: _sending
124
+ ? const SizedBox(
125
+ width: 20,
126
+ height: 20,
127
+ child: CircularProgressIndicator(strokeWidth: 2),
128
+ )
129
+ : const Icon(Icons.upload_outlined),
130
+ tooltip: 'Send to server',
131
+ onPressed: _sending ? null : _sendToServer,
132
+ ),
133
+ ],
134
+ ),
135
+ body: entries.isEmpty
136
+ ? const Center(
137
+ child: Text(
138
+ 'No trace entries yet.\nSend a message to generate traces.',
139
+ textAlign: TextAlign.center,
140
+ style: TextStyle(color: Colors.grey),
141
+ ),
142
+ )
143
+ : Column(
144
+ children: [
145
+ Container(
146
+ color: Colors.black87,
147
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
148
+ child: Row(
149
+ children: [
150
+ Text(
151
+ '${entries.length} entries (newest first)',
152
+ style: const TextStyle(
153
+ fontSize: 11,
154
+ color: Colors.grey,
155
+ fontFamily: 'monospace',
156
+ ),
157
+ ),
158
+ const Spacer(),
159
+ const Text(
160
+ 'Tap to copy',
161
+ style: TextStyle(fontSize: 11, color: Colors.grey),
162
+ ),
163
+ ],
164
+ ),
165
+ ),
166
+ Expanded(
167
+ child: ListView.builder(
168
+ itemCount: entries.length,
169
+ itemBuilder: (context, index) {
170
+ final entry = entries[index];
171
+ final ts = entry.timestamp
172
+ .toIso8601String()
173
+ .substring(11, 23); // HH:mm:ss.mmm
174
+
175
+ return InkWell(
176
+ onTap: () {
177
+ // Copy full entry to clipboard on tap
178
+ final text = '$ts | ${entry.event} | ${entry.details}';
179
+ ScaffoldMessenger.of(context).showSnackBar(
180
+ SnackBar(
181
+ content: Text(
182
+ text,
183
+ maxLines: 2,
184
+ overflow: TextOverflow.ellipsis,
185
+ style: const TextStyle(fontFamily: 'monospace', fontSize: 11),
186
+ ),
187
+ duration: const Duration(seconds: 2),
188
+ ),
189
+ );
190
+ },
191
+ child: Container(
192
+ padding: const EdgeInsets.symmetric(
193
+ horizontal: 12,
194
+ vertical: 6,
195
+ ),
196
+ decoration: BoxDecoration(
197
+ border: Border(
198
+ bottom: BorderSide(
199
+ color: Colors.grey.shade800,
200
+ width: 0.5,
201
+ ),
202
+ ),
203
+ ),
204
+ child: Row(
205
+ crossAxisAlignment: CrossAxisAlignment.start,
206
+ children: [
207
+ Text(
208
+ ts,
209
+ style: const TextStyle(
210
+ fontFamily: 'monospace',
211
+ fontSize: 10,
212
+ color: Colors.grey,
213
+ ),
214
+ ),
215
+ const SizedBox(width: 8),
216
+ Expanded(
217
+ child: Column(
218
+ crossAxisAlignment: CrossAxisAlignment.start,
219
+ children: [
220
+ Text(
221
+ entry.event,
222
+ style: TextStyle(
223
+ fontFamily: 'monospace',
224
+ fontSize: 11,
225
+ fontWeight: FontWeight.bold,
226
+ color: _colorForEvent(entry.event),
227
+ ),
228
+ ),
229
+ if (entry.details.isNotEmpty)
230
+ Text(
231
+ entry.details,
232
+ style: const TextStyle(
233
+ fontFamily: 'monospace',
234
+ fontSize: 10,
235
+ color: Colors.grey,
236
+ ),
237
+ maxLines: 2,
238
+ overflow: TextOverflow.ellipsis,
239
+ ),
240
+ ],
241
+ ),
242
+ ),
243
+ ],
244
+ ),
245
+ ),
246
+ );
247
+ },
248
+ ),
249
+ ),
250
+ ],
251
+ ),
252
+ );
253
+ }
254
+}
lib/services/audio_service.dart
....@@ -0,0 +1,297 @@
1
+import 'dart:async';
2
+import 'dart:io';
3
+
4
+import 'package:audioplayers/audioplayers.dart';
5
+import 'package:flutter/widgets.dart';
6
+import 'package:path_provider/path_provider.dart';
7
+import 'package:record/record.dart';
8
+
9
+/// Manages audio recording (AAC) and playback (queue + singleton).
10
+///
11
+/// Incoming voice chunks are queued and played sequentially.
12
+/// Manual taps play a single file (or chain from that point).
13
+class AudioService {
14
+ AudioService._();
15
+
16
+ static final AudioRecorder _recorder = AudioRecorder();
17
+ static final AudioPlayer _player = AudioPlayer();
18
+ static bool _isRecording = false;
19
+ static String? _currentRecordingPath;
20
+
21
+ // Playback queue — file paths waiting to be played
22
+ static final List<String> _queue = [];
23
+ static bool _isPlaying = false;
24
+
25
+ // Callback when playback starts/stops — UI uses this to update play buttons
26
+ static void Function()? onPlaybackStateChanged;
27
+
28
+ // Autoplay suppression
29
+ static bool _isBackgrounded = false;
30
+
31
+ // Track last played temp file so it can be cleaned up when the track ends
32
+ static String? _lastPlaybackTempPath;
33
+
34
+ // Lifecycle observer stored so we can remove it in dispose()
35
+ static _LifecycleObserver? _lifecycleObserver;
36
+
37
+ /// Initialize the audio service and set up lifecycle observer.
38
+ static void init() {
39
+ _lifecycleObserver = _LifecycleObserver();
40
+ WidgetsBinding.instance.addObserver(_lifecycleObserver!);
41
+
42
+ // Configure audio session for background playback
43
+ _player.setAudioContext(AudioContext(
44
+ iOS: AudioContextIOS(
45
+ category: AVAudioSessionCategory.playback,
46
+ options: {AVAudioSessionOptions.mixWithOthers},
47
+ ),
48
+ android: const AudioContextAndroid(
49
+ isSpeakerphoneOn: false,
50
+ audioMode: AndroidAudioMode.normal,
51
+ audioFocus: AndroidAudioFocus.gain,
52
+ ),
53
+ ));
54
+
55
+ // When a track finishes, play the next in queue
56
+ _player.onPlayerComplete.listen((_) {
57
+ _onTrackComplete();
58
+ });
59
+ }
60
+
61
+ static void _onTrackComplete() {
62
+ // Clean up the temp file that just finished playing
63
+ final prev = _lastPlaybackTempPath;
64
+ _lastPlaybackTempPath = null;
65
+ if (prev != null) {
66
+ File(prev).delete().ignore();
67
+ }
68
+
69
+ if (_queue.isNotEmpty) {
70
+ _playNextInQueue();
71
+ } else {
72
+ _isPlaying = false;
73
+ onPlaybackStateChanged?.call();
74
+ }
75
+ }
76
+
77
+ static Future<void> _playNextInQueue() async {
78
+ if (_queue.isEmpty) {
79
+ _isPlaying = false;
80
+ onPlaybackStateChanged?.call();
81
+ return;
82
+ }
83
+
84
+ final path = _queue.removeAt(0);
85
+ _lastPlaybackTempPath = path;
86
+ try {
87
+ // Brief pause between tracks — iOS audio player needs time to reset
88
+ await _player.stop();
89
+ await Future.delayed(const Duration(milliseconds: 150));
90
+ await _player.play(DeviceFileSource(path));
91
+ _isPlaying = true;
92
+ onPlaybackStateChanged?.call();
93
+ debugPrint('AudioService: playing next from queue (remaining: ${_queue.length})');
94
+ } catch (e) {
95
+ debugPrint('AudioService: queue play failed: $e');
96
+ // Skip broken file, try next
97
+ _onTrackComplete();
98
+ }
99
+ }
100
+
101
+ // ── Recording ──
102
+
103
+ static bool get isRecording => _isRecording;
104
+ static bool get isBackgrounded => _isBackgrounded;
105
+
106
+ static Future<String?> startRecording() async {
107
+ if (_isRecording) return null;
108
+
109
+ final hasPermission = await _recorder.hasPermission();
110
+ if (!hasPermission) return null;
111
+
112
+ final dir = await getTemporaryDirectory();
113
+ final path =
114
+ '${dir.path}/recording_${DateTime.now().millisecondsSinceEpoch}.m4a';
115
+
116
+ await _recorder.start(
117
+ const RecordConfig(
118
+ encoder: AudioEncoder.aacLc,
119
+ bitRate: 128000,
120
+ sampleRate: 44100,
121
+ ),
122
+ path: path,
123
+ );
124
+
125
+ _isRecording = true;
126
+ _currentRecordingPath = path;
127
+ return path;
128
+ }
129
+
130
+ static Future<String?> stopRecording() async {
131
+ if (!_isRecording) return null;
132
+
133
+ final path = await _recorder.stop();
134
+ _isRecording = false;
135
+ _currentRecordingPath = null;
136
+ return path;
137
+ }
138
+
139
+ static Future<void> cancelRecording() async {
140
+ if (!_isRecording) return;
141
+
142
+ await _recorder.stop();
143
+ _isRecording = false;
144
+
145
+ if (_currentRecordingPath != null) {
146
+ try {
147
+ await File(_currentRecordingPath!).delete();
148
+ } catch (_) {}
149
+ _currentRecordingPath = null;
150
+ }
151
+ }
152
+
153
+ // ── Playback ──
154
+
155
+ /// Play a single file. Stops current playback and clears the queue.
156
+ static Future<void> playSingle(String source) async {
157
+ await stopPlayback();
158
+
159
+ if (source.startsWith('/')) {
160
+ await _player.play(DeviceFileSource(source));
161
+ // File path owned by caller — not tracked for deletion
162
+ } else {
163
+ // base64 data — write to temp file first
164
+ final path = await _base64ToFile(source);
165
+ if (path == null) return;
166
+ _lastPlaybackTempPath = path;
167
+ await _player.play(DeviceFileSource(path));
168
+ }
169
+ _isPlaying = true;
170
+ onPlaybackStateChanged?.call();
171
+ }
172
+
173
+ /// Play a base64-encoded audio blob. Stops current playback.
174
+ static Future<void> playBase64(String base64Audio) async {
175
+ await stopPlayback();
176
+ final path = await _base64ToFile(base64Audio);
177
+ if (path == null) return;
178
+
179
+ _lastPlaybackTempPath = path;
180
+ await _player.play(DeviceFileSource(path));
181
+ _isPlaying = true;
182
+ onPlaybackStateChanged?.call();
183
+ }
184
+
185
+ /// Queue a base64-encoded audio blob for sequential playback.
186
+ /// If nothing is playing, starts immediately.
187
+ /// If already playing, appends to queue — plays after current finishes.
188
+ static Future<void> queueBase64(String base64Audio) async {
189
+ final path = await _base64ToFile(base64Audio);
190
+ if (path == null) return;
191
+
192
+ if (_isPlaying) {
193
+ // Already playing — add to queue, plays when current finishes
194
+ _queue.add(path);
195
+ debugPrint('AudioService: queued (queue size: ${_queue.length})');
196
+ } else {
197
+ // Nothing playing — start immediately
198
+ _lastPlaybackTempPath = path;
199
+ try {
200
+ await _player.play(DeviceFileSource(path));
201
+ _isPlaying = true;
202
+ onPlaybackStateChanged?.call();
203
+ debugPrint('AudioService: playing immediately');
204
+ } catch (e) {
205
+ debugPrint('AudioService: play failed: $e');
206
+ _onTrackComplete();
207
+ }
208
+ }
209
+ }
210
+
211
+ /// Chain playback: play a list of sources sequentially.
212
+ /// First one plays immediately, rest are queued.
213
+ static Future<void> playChain(List<String> sources) async {
214
+ if (sources.isEmpty) return;
215
+ if (_isBackgrounded) return;
216
+
217
+ await stopPlayback();
218
+
219
+ // Queue all except the first
220
+ for (var i = 1; i < sources.length; i++) {
221
+ _queue.add(sources[i]);
222
+ }
223
+
224
+ // Play the first one
225
+ final first = sources[0];
226
+ if (first.startsWith('/')) {
227
+ await _player.play(DeviceFileSource(first));
228
+ } else {
229
+ final path = await _base64ToFile(first);
230
+ if (path == null) return;
231
+ await _player.play(DeviceFileSource(path));
232
+ }
233
+ _isPlaying = true;
234
+ onPlaybackStateChanged?.call();
235
+ }
236
+
237
+ /// Stop all playback and clear queue.
238
+ static Future<void> stopPlayback() async {
239
+ _queue.clear();
240
+ _isPlaying = false;
241
+ await _player.stop();
242
+ onPlaybackStateChanged?.call();
243
+ }
244
+
245
+ /// Whether audio is currently playing.
246
+ static bool get isPlaying => _isPlaying;
247
+
248
+ // ── Helpers ──
249
+
250
+ static Future<String?> _base64ToFile(String base64Audio) async {
251
+ final dir = await getTemporaryDirectory();
252
+ final path =
253
+ '${dir.path}/playback_${DateTime.now().millisecondsSinceEpoch}.m4a';
254
+ final bytes = _decodeBase64(base64Audio);
255
+ if (bytes == null) return null;
256
+ await File(path).writeAsBytes(bytes);
257
+ return path;
258
+ }
259
+
260
+ static List<int>? _decodeBase64(String b64) {
261
+ try {
262
+ final cleaned = b64.contains(',') ? b64.split(',').last : b64;
263
+ return List<int>.from(
264
+ Uri.parse('data:;base64,$cleaned').data!.contentAsBytes(),
265
+ );
266
+ } catch (_) {
267
+ return null;
268
+ }
269
+ }
270
+
271
+ static Future<void> dispose() async {
272
+ if (_lifecycleObserver != null) {
273
+ WidgetsBinding.instance.removeObserver(_lifecycleObserver!);
274
+ _lifecycleObserver = null;
275
+ }
276
+ await cancelRecording();
277
+ await stopPlayback();
278
+ _recorder.dispose();
279
+ _player.dispose();
280
+ }
281
+}
282
+
283
+class _LifecycleObserver extends WidgetsBindingObserver {
284
+ @override
285
+ void didChangeAppLifecycleState(AppLifecycleState state) {
286
+ switch (state) {
287
+ case AppLifecycleState.paused:
288
+ case AppLifecycleState.inactive:
289
+ case AppLifecycleState.detached:
290
+ AudioService._isBackgrounded = true;
291
+ case AppLifecycleState.resumed:
292
+ AudioService._isBackgrounded = false;
293
+ default:
294
+ break;
295
+ }
296
+ }
297
+}
lib/services/message_store.dart
....@@ -0,0 +1,302 @@
1
+import 'dart:convert';
2
+import 'dart:io';
3
+
4
+import 'package:flutter/services.dart';
5
+import 'package:path_provider/path_provider.dart';
6
+
7
+import '../models/message.dart';
8
+import 'trace_service.dart';
9
+
10
+/// Append-only log-based message persistence.
11
+///
12
+/// Layout:
13
+/// messages/log.jsonl — one JSON object per line, each a serialized Message
14
+/// messages/index.json — { "sessionId": [lineNumber, ...] }
15
+///
16
+/// All writes are synchronous (writeAsStringSync with FileMode.append) to
17
+/// prevent race conditions between concurrent addMessage / switchSession calls.
18
+class MessageStoreV2 {
19
+ MessageStoreV2._();
20
+
21
+ static const _backupChannel = MethodChannel('com.mnsoft.pailot/backup');
22
+
23
+ // In-memory index: sessionId -> list of 0-based line numbers in log.jsonl
24
+ static final Map<String, List<int>> _index = {};
25
+
26
+ // Number of lines currently in the log (= next line number to write)
27
+ static int _lineCount = 0;
28
+
29
+ // Flush the index to disk every N appends to amortise I/O
30
+ static const _indexFlushInterval = 20;
31
+ static int _appendsSinceFlush = 0;
32
+
33
+ static Directory? _baseDir;
34
+
35
+ // ------------------------------------------------------------------ init --
36
+
37
+ static Future<Directory> _getBaseDir() async {
38
+ if (_baseDir != null) return _baseDir!;
39
+ final appDir = await getApplicationDocumentsDirectory();
40
+ _baseDir = Directory('${appDir.path}/messages');
41
+ if (!_baseDir!.existsSync()) {
42
+ _baseDir!.createSync(recursive: true);
43
+ }
44
+ // Exclude from iCloud / iTunes backup (best-effort, iOS only).
45
+ if (Platform.isIOS) {
46
+ try {
47
+ await _backupChannel.invokeMethod<void>(
48
+ 'excludeFromBackup',
49
+ _baseDir!.path,
50
+ );
51
+ } catch (_) {}
52
+ }
53
+ return _baseDir!;
54
+ }
55
+
56
+ static String _logPath(Directory dir) => '${dir.path}/log.jsonl';
57
+ static String _indexPath(Directory dir) => '${dir.path}/index.json';
58
+
59
+ /// Called once at app startup. Reads log.jsonl and rebuilds the in-memory
60
+ /// index. Then calls compact() to trim old messages.
61
+ static Future<void> initialize() async {
62
+ try {
63
+ final dir = await _getBaseDir();
64
+ final logFile = File(_logPath(dir));
65
+ final indexFile = File(_indexPath(dir));
66
+
67
+ // Always rebuild index from log (the saved index.json may be stale
68
+ // if the app was killed before a flush).
69
+ if (logFile.existsSync()) {
70
+ final content = logFile.readAsStringSync();
71
+ _lineCount = content.isEmpty
72
+ ? 0
73
+ : content.trimRight().split('\n').length;
74
+ if (_lineCount > 0) {
75
+ await _rebuildIndex(logFile);
76
+ }
77
+ } else {
78
+ _lineCount = 0;
79
+ }
80
+
81
+ TraceService.instance.addTrace(
82
+ 'MsgStoreV2 INIT', '$_lineCount lines, ${_index.length} sessions');
83
+
84
+ // Compact on startup (keeps last 200 per session).
85
+ await compact();
86
+ } catch (e) {
87
+ TraceService.instance.addTrace('MsgStoreV2 INIT ERROR', '$e');
88
+ }
89
+ }
90
+
91
+ static Future<void> _rebuildIndex(File logFile) async {
92
+ _index.clear();
93
+ final lines = logFile.readAsLinesSync();
94
+ for (var i = 0; i < lines.length; i++) {
95
+ final line = lines[i].trim();
96
+ if (line.isEmpty) continue;
97
+ try {
98
+ final map = jsonDecode(line) as Map<String, dynamic>;
99
+ final sessionId = map['sessionId'] as String?;
100
+ if (sessionId != null) {
101
+ _index.putIfAbsent(sessionId, () => []).add(i);
102
+ }
103
+ } catch (_) {}
104
+ }
105
+ }
106
+
107
+ // --------------------------------------------------------------- append --
108
+
109
+ /// Append a message to the log. SYNCHRONOUS — no async gap, no race.
110
+ ///
111
+ /// Each line written includes a 'sessionId' field so the index can be
112
+ /// rebuilt from the log alone if needed.
113
+ static void append(String sessionId, Message message) {
114
+ try {
115
+ final dir = _baseDir;
116
+ if (dir == null) {
117
+ // initialize() hasn't been called yet — silently drop (shouldn't happen).
118
+ TraceService.instance
119
+ .addTrace('MsgStoreV2 APPEND WARN', 'baseDir null, dropping');
120
+ return;
121
+ }
122
+ final logFile = File(_logPath(dir));
123
+ final json = message.toJsonLight();
124
+ json['sessionId'] = sessionId;
125
+ final line = '${jsonEncode(json)}\n';
126
+
127
+ // Synchronous append — atomic single write, no read-modify-write.
128
+ logFile.writeAsStringSync(line, mode: FileMode.append);
129
+
130
+ // Update in-memory index.
131
+ final lineNum = _lineCount;
132
+ _index.putIfAbsent(sessionId, () => []).add(lineNum);
133
+ _lineCount++;
134
+
135
+ TraceService.instance.addTrace('MsgStoreV2 APPEND',
136
+ '${sessionId.substring(0, 8)} line=$lineNum total=$_lineCount idx=${_index[sessionId]?.length ?? 0}');
137
+
138
+ // Flush index after every append to prevent data loss on app kill.
139
+ _flushIndex(dir);
140
+ } catch (e) {
141
+ TraceService.instance.addTrace('MsgStoreV2 APPEND ERROR', '$e');
142
+ }
143
+ }
144
+
145
+ // -------------------------------------------------------------- load --
146
+
147
+ /// Load messages for a session. SYNCHRONOUS — reads from the log using the
148
+ /// in-memory index. Safe to call from switchSession without async gaps.
149
+ static List<Message> loadSession(String sessionId) {
150
+ try {
151
+ final dir = _baseDir;
152
+ if (dir == null) return [];
153
+ final logFile = File(_logPath(dir));
154
+ if (!logFile.existsSync()) return [];
155
+
156
+ final lineNumbers = _index[sessionId];
157
+ if (lineNumbers == null || lineNumbers.isEmpty) return [];
158
+
159
+ // Read all lines at once then pick the ones we need.
160
+ final allLines = logFile.readAsLinesSync();
161
+ TraceService.instance.addTrace('MsgStoreV2 LOAD detail',
162
+ '${sessionId.substring(0, 8)}: fileLines=${allLines.length} indexEntries=${lineNumbers.length} lineCount=$_lineCount');
163
+ final messages = <Message>[];
164
+
165
+ for (final n in lineNumbers) {
166
+ if (n >= allLines.length) continue;
167
+ final line = allLines[n].trim();
168
+ if (line.isEmpty) continue;
169
+ try {
170
+ final map = jsonDecode(line) as Map<String, dynamic>;
171
+ // Remove synthetic sessionId field before deserialising.
172
+ map.remove('sessionId');
173
+ final msg = _messageFromJson(map);
174
+ if (!msg.isEmptyVoice && !msg.isEmptyText) {
175
+ messages.add(msg);
176
+ }
177
+ } catch (_) {}
178
+ }
179
+
180
+ TraceService.instance.addTrace(
181
+ 'MsgStoreV2 LOAD', '${sessionId.substring(0, 8)}: ${messages.length} msgs');
182
+ return messages;
183
+ } catch (e) {
184
+ TraceService.instance
185
+ .addTrace('MsgStoreV2 LOAD ERROR', '${sessionId.substring(0, 8)}: $e');
186
+ return [];
187
+ }
188
+ }
189
+
190
+ // ------------------------------------------------------------- compact --
191
+
192
+ /// Rewrite the log keeping at most [keepPerSession] messages per session.
193
+ /// Called once on startup after initialize(). NOT called during normal use.
194
+ static Future<void> compact({int keepPerSession = 200}) async {
195
+ try {
196
+ final dir = await _getBaseDir();
197
+ final logFile = File(_logPath(dir));
198
+ if (!logFile.existsSync()) return;
199
+
200
+ final allLines = logFile.readAsLinesSync();
201
+ if (allLines.length < 500) return; // nothing worth compacting
202
+
203
+ // Build a set of line numbers to keep: last keepPerSession per session.
204
+ final keepLines = <int>{};
205
+ for (final entry in _index.entries) {
206
+ final lines = entry.value;
207
+ final start = lines.length > keepPerSession
208
+ ? lines.length - keepPerSession
209
+ : 0;
210
+ for (var i = start; i < lines.length; i++) {
211
+ keepLines.add(lines[i]);
212
+ }
213
+ }
214
+
215
+ if (keepLines.length == allLines.length) return; // nothing removed
216
+
217
+ // Rewrite the log with only the kept lines, rebuilding the index.
218
+ final newIndex = <String, List<int>>{};
219
+ final buffer = StringBuffer();
220
+ var newLine = 0;
221
+
222
+ for (var i = 0; i < allLines.length; i++) {
223
+ if (!keepLines.contains(i)) continue;
224
+ final line = allLines[i].trim();
225
+ if (line.isEmpty) continue;
226
+ buffer.write('$line\n');
227
+ // Extract sessionId for new index.
228
+ try {
229
+ final map = jsonDecode(line) as Map<String, dynamic>;
230
+ final sid = map['sessionId'] as String?;
231
+ if (sid != null) {
232
+ newIndex.putIfAbsent(sid, () => []).add(newLine);
233
+ }
234
+ } catch (_) {}
235
+ newLine++;
236
+ }
237
+
238
+ logFile.writeAsStringSync(buffer.toString());
239
+ _index
240
+ ..clear()
241
+ ..addAll(newIndex);
242
+ _lineCount = newLine;
243
+ _flushIndex(dir);
244
+
245
+ TraceService.instance.addTrace(
246
+ 'MsgStoreV2 COMPACT', '${allLines.length} → $newLine lines');
247
+ } catch (e) {
248
+ TraceService.instance.addTrace('MsgStoreV2 COMPACT ERROR', '$e');
249
+ }
250
+ }
251
+
252
+ // --------------------------------------------------------- index flush --
253
+
254
+ static void _flushIndex(Directory dir) {
255
+ try {
256
+ final indexMap = _index.map(
257
+ (k, v) => MapEntry(k, v));
258
+ File(_indexPath(dir))
259
+ .writeAsStringSync(jsonEncode(indexMap));
260
+ } catch (_) {}
261
+ }
262
+
263
+ /// Force-flush the index to disk (call on app suspend / session switch).
264
+ static void flushIndex() {
265
+ if (_baseDir != null) _flushIndex(_baseDir!);
266
+ }
267
+
268
+ // ------------------------------------------------- migration helper --
269
+
270
+ /// Deserialize a message, downgrading voice→text if audio is unavailable.
271
+ static Message _messageFromJson(Map<String, dynamic> json) {
272
+ final raw = Message.fromJson(json);
273
+ if (raw.type == MessageType.voice &&
274
+ (raw.audioUri == null || raw.audioUri!.isEmpty)) {
275
+ return Message(
276
+ id: raw.id,
277
+ role: raw.role,
278
+ type: MessageType.text,
279
+ content: raw.content,
280
+ timestamp: raw.timestamp,
281
+ status: raw.status,
282
+ duration: raw.duration,
283
+ );
284
+ }
285
+ return raw;
286
+ }
287
+
288
+ // --------------------------------------------------------- clear all --
289
+
290
+ /// Wipe everything (used from settings / debug).
291
+ static Future<void> clearAll() async {
292
+ try {
293
+ final dir = await _getBaseDir();
294
+ if (dir.existsSync()) {
295
+ dir.deleteSync(recursive: true);
296
+ dir.createSync(recursive: true);
297
+ }
298
+ _index.clear();
299
+ _lineCount = 0;
300
+ } catch (_) {}
301
+ }
302
+}
lib/services/mqtt_service.dart
....@@ -0,0 +1,811 @@
1
+import 'dart:async';
2
+import 'dart:convert';
3
+import 'dart:io';
4
+import 'dart:typed_data';
5
+import 'package:crypto/crypto.dart';
6
+
7
+import 'package:bonsoir/bonsoir.dart';
8
+import 'package:connectivity_plus/connectivity_plus.dart';
9
+import 'package:flutter/foundation.dart';
10
+import 'package:flutter/widgets.dart';
11
+import 'package:path_provider/path_provider.dart' as pp;
12
+import 'package:mqtt_client/mqtt_client.dart';
13
+import 'package:mqtt_client/mqtt_server_client.dart';
14
+import 'package:typed_data/typed_data.dart';
15
+import 'package:shared_preferences/shared_preferences.dart';
16
+import 'package:uuid/uuid.dart';
17
+
18
+import '../models/server_config.dart';
19
+import 'trace_service.dart';
20
+import 'wol_service.dart';
21
+
22
+/// Connection status for the MQTT client.
23
+enum ConnectionStatus {
24
+ disconnected,
25
+ connecting,
26
+ connected,
27
+ reconnecting,
28
+}
29
+
30
+// Debug log — writes to file only in debug builds, always prints via debugPrint.
31
+// Also adds entries to TraceService so they appear in the trace log viewer.
32
+Future<void> _mqttLog(String msg) async {
33
+ debugPrint('[MQTT] $msg');
34
+ TraceService.instance.addTrace('MQTT', msg);
35
+ if (!kDebugMode) return;
36
+ try {
37
+ final dir = await pp.getApplicationDocumentsDirectory();
38
+ final file = File('${dir.path}/mqtt_debug.log');
39
+ final ts = DateTime.now().toIso8601String().substring(11, 19);
40
+ await file.writeAsString('[$ts] $msg\n', mode: FileMode.append);
41
+ } catch (_) {}
42
+}
43
+
44
+/// MQTT client for PAILot.
45
+///
46
+/// Connects to the AIBroker daemon's embedded aedes broker.
47
+/// Subscribes to all pailot/ topics and dispatches messages
48
+/// through the onMessage callback interface.
49
+class MqttService with WidgetsBindingObserver {
50
+ MqttService({required this.config}) {
51
+ WidgetsBinding.instance.addObserver(this);
52
+ }
53
+
54
+ ServerConfig config;
55
+ MqttServerClient? _client;
56
+ ConnectionStatus _status = ConnectionStatus.disconnected;
57
+ bool _intentionalClose = false;
58
+ String? _clientId;
59
+ String? _lastDiscoveredHost;
60
+ StreamSubscription? _connectivitySub;
61
+ List<ConnectivityResult>? _lastConnectivity;
62
+ StreamSubscription? _updatesSub;
63
+
64
+ // Message deduplication
65
+ final Set<String> _seenMsgIds = {};
66
+ final List<String> _seenMsgIdOrder = [];
67
+
68
+ // (Per-session subscriptions removed — single pailot/out topic now)
69
+ static const int _maxSeenIds = 500;
70
+
71
+ // Callbacks
72
+ void Function(ConnectionStatus status)? onStatusChanged;
73
+ void Function(String detail)? onStatusDetail; // "Probing local...", "Scanning network..."
74
+ String? connectedHost; // The host we're currently connected to
75
+ String? connectedVia; // "Local", "VPN", "Remote", "Bonjour", "Scan"
76
+ void Function(Map<String, dynamic> message)? onMessage;
77
+ void Function()? onOpen;
78
+ void Function()? onClose;
79
+ void Function()? onReconnecting;
80
+ void Function()? onResume;
81
+ void Function(String error)? onError;
82
+
83
+ ConnectionStatus get status => _status;
84
+ bool get isConnected => _status == ConnectionStatus.connected;
85
+
86
+ void _setStatus(ConnectionStatus newStatus) {
87
+ if (_status == newStatus) return;
88
+ _status = newStatus;
89
+ onStatusChanged?.call(newStatus);
90
+ }
91
+
92
+ /// Get or create a persistent client ID for this device.
93
+ Future<String> _getClientId() async {
94
+ if (_clientId != null) return _clientId!;
95
+ final prefs = await SharedPreferences.getInstance();
96
+ var id = prefs.getString('mqtt_client_id');
97
+ // Regenerate if old format (too long for MQTT 3.1.1)
98
+ if (id == null || id.length > 23) {
99
+ // MQTT 3.1.1 client IDs: max 23 chars, alphanumeric
100
+ id = 'pailot${const Uuid().v4().replaceAll('-', '').substring(0, 16)}';
101
+ await prefs.setString('mqtt_client_id', id);
102
+ }
103
+ _clientId = id;
104
+ return id;
105
+ }
106
+
107
+ /// Force reconnect — disconnect and reconnect to last known host.
108
+ void forceReconnect() {
109
+ _mqttLog('MQTT: force reconnect requested');
110
+ final lastHost = connectedHost;
111
+ _client?.disconnect();
112
+ _client = null;
113
+ _setStatus(ConnectionStatus.reconnecting);
114
+ onReconnecting?.call();
115
+ if (lastHost != null) {
116
+ _fastReconnect(lastHost);
117
+ } else {
118
+ connect();
119
+ }
120
+ }
121
+
122
+ /// Fast reconnect to a known host — skips discovery, short timeout.
123
+ Future<void> _fastReconnect(String host) async {
124
+ _mqttLog('MQTT: fast reconnect to $host');
125
+ final clientId = await _getClientId();
126
+ if (await _tryConnect(host, clientId, timeout: 2000)) {
127
+ connectedHost = host;
128
+ return;
129
+ }
130
+ // Fast path failed — fall back to full connect
131
+ _mqttLog('MQTT: fast reconnect failed, full connect...');
132
+ connect();
133
+ }
134
+
135
+ /// Connect to the MQTT broker.
136
+ /// Tries local host first (2.5s timeout), then remote host.
137
+ Future<void> connect() async {
138
+ if (_status == ConnectionStatus.connected ||
139
+ _status == ConnectionStatus.connecting) {
140
+ return;
141
+ }
142
+
143
+ _intentionalClose = false;
144
+ _setStatus(ConnectionStatus.connecting);
145
+
146
+ // Network change detection disabled — was causing spurious reconnects.
147
+ // MQTT keepalive + auto-reconnect handles dead connections reliably.
148
+
149
+ // Load trusted cert fingerprint for TOFU verification
150
+ if (_trustedFingerprint == null) await _loadTrustedFingerprint();
151
+
152
+ // Send Wake-on-LAN if MAC configured
153
+ if (config.macAddress != null && config.macAddress!.isNotEmpty) {
154
+ try {
155
+ await WolService.wake(config.macAddress!, localHost: config.localHost);
156
+ } catch (_) {}
157
+ }
158
+
159
+ final clientId = await _getClientId();
160
+
161
+ // Phase 1: Race configured hosts (fast — just TLS probe, ~1s each)
162
+ final hosts = <String>[];
163
+ if (config.localHost != null && config.localHost!.isNotEmpty) hosts.add(config.localHost!);
164
+ if (_lastDiscoveredHost != null && !hosts.contains(_lastDiscoveredHost)) hosts.add(_lastDiscoveredHost!);
165
+ if (config.vpnHost != null && config.vpnHost!.isNotEmpty) hosts.add(config.vpnHost!);
166
+ if (config.host.isNotEmpty) hosts.add(config.host);
167
+ _mqttLog('MQTT: racing ${hosts.length} configured hosts: ${hosts.join(", ")}');
168
+ onStatusDetail?.call('Connecting...');
169
+
170
+ // Race: first probe to succeed wins, don't wait for others
171
+ String? winner;
172
+ if (hosts.isNotEmpty) {
173
+ final completer = Completer<String?>();
174
+ int pending = hosts.length;
175
+ for (final host in hosts) {
176
+ _probeHost(host, config.port).then((result) {
177
+ if (result != null && !completer.isCompleted) {
178
+ completer.complete(result);
179
+ } else {
180
+ pending--;
181
+ if (pending <= 0 && !completer.isCompleted) {
182
+ completer.complete(null); // All failed
183
+ }
184
+ }
185
+ });
186
+ }
187
+ winner = await completer.future.timeout(
188
+ const Duration(seconds: 3),
189
+ onTimeout: () => null,
190
+ );
191
+ }
192
+
193
+ // Phase 2: If configured hosts failed, try Bonjour/subnet discovery
194
+ if (winner == null && !_intentionalClose) {
195
+ _mqttLog('MQTT: configured hosts failed, trying discovery...');
196
+ onStatusDetail?.call('Scanning network...');
197
+ final discovered = await _discoverViaMdns();
198
+ if (discovered != null) {
199
+ _lastDiscoveredHost = discovered;
200
+ winner = discovered;
201
+ }
202
+ }
203
+
204
+ if (winner != null && !_intentionalClose) {
205
+ // Determine connection method label
206
+ if (winner == config.localHost) {
207
+ connectedVia = 'Local';
208
+ } else if (winner == config.vpnHost) {
209
+ connectedVia = 'VPN';
210
+ } else if (winner == config.host) {
211
+ connectedVia = 'Remote';
212
+ } else if (winner == _lastDiscoveredHost) {
213
+ connectedVia = 'Discovered';
214
+ } else {
215
+ connectedVia = winner;
216
+ }
217
+ connectedHost = winner;
218
+ _mqttLog('MQTT: winner: $winner ($connectedVia), connecting...');
219
+ onStatusDetail?.call('Connecting via $connectedVia...');
220
+ try {
221
+ if (await _tryConnect(winner, clientId, timeout: 5000)) return;
222
+ } catch (e) {
223
+ _mqttLog('MQTT: connect to $winner failed: $e');
224
+ connectedHost = null;
225
+ connectedVia = null;
226
+ }
227
+ }
228
+
229
+ // All hosts failed — retry after delay
230
+ _mqttLog('MQTT: all attempts failed, retrying in 5s');
231
+ onStatusDetail?.call('No server found, retrying...');
232
+ _setStatus(ConnectionStatus.reconnecting);
233
+ Future.delayed(const Duration(seconds: 5), () {
234
+ if (!_intentionalClose && _status != ConnectionStatus.connected) {
235
+ connect();
236
+ }
237
+ });
238
+ }
239
+
240
+ /// Discover AIBroker on local network via Bonjour/mDNS.
241
+ /// Falls back to subnet scan if Bonjour fails (iOS blocks mDNS on Personal Hotspot).
242
+ /// Returns the IP address or null if not found within timeout.
243
+ Future<String?> _discoverViaMdns({Duration timeout = const Duration(seconds: 3)}) async {
244
+ // Try Bonjour first
245
+ try {
246
+ final discovery = BonsoirDiscovery(type: '_mqtt._tcp');
247
+ await discovery.initialize();
248
+
249
+ final completer = Completer<String?>();
250
+ StreamSubscription? sub;
251
+
252
+ sub = discovery.eventStream?.listen((event) {
253
+ switch (event) {
254
+ case BonsoirDiscoveryServiceResolvedEvent():
255
+ final ip = event.service.host;
256
+ _mqttLog('MQTT: Bonjour resolved: ${event.service.name} at $ip:${event.service.port}');
257
+ if (ip != null && ip.isNotEmpty && !completer.isCompleted) {
258
+ completer.complete(ip);
259
+ }
260
+ case BonsoirDiscoveryServiceFoundEvent():
261
+ _mqttLog('MQTT: Bonjour found: ${event.service.name}');
262
+ default:
263
+ break;
264
+ }
265
+ });
266
+
267
+ await discovery.start();
268
+
269
+ final ip = await completer.future.timeout(timeout, onTimeout: () => null);
270
+
271
+ await sub?.cancel();
272
+ await discovery.stop();
273
+
274
+ if (ip != null) return ip;
275
+ } catch (e) {
276
+ _mqttLog('MQTT: Bonjour discovery error: $e');
277
+ }
278
+
279
+ // Fallback: scan local subnet for MQTT port (handles Personal Hotspot)
280
+ _mqttLog('MQTT: Bonjour failed, trying subnet scan...');
281
+ onStatusDetail?.call('Scanning local network...');
282
+ return _scanSubnetForMqtt();
283
+ }
284
+
285
+ /// Scan the local subnet for an MQTT broker by probing the configured port.
286
+ /// Useful when iOS Personal Hotspot blocks mDNS.
287
+ Future<String?> _scanSubnetForMqtt() async {
288
+ try {
289
+ // Get device's own IP to determine the subnet
290
+ final interfaces = await NetworkInterface.list(type: InternetAddressType.IPv4);
291
+ for (final iface in interfaces) {
292
+ for (final addr in iface.addresses) {
293
+ final parts = addr.address.split('.');
294
+ if (parts.length != 4) continue;
295
+ // Skip loopback
296
+ if (parts[0] == '127') continue;
297
+ // Only scan small subnets (hotspot = /28, max 14 hosts)
298
+ final subnet = '${parts[0]}.${parts[1]}.${parts[2]}';
299
+ _mqttLog('MQTT: scanning $subnet.0/24 on ${iface.name}');
300
+
301
+ // Probe in batches of 20 to avoid flooding the network.
302
+ // Early exit on first hit.
303
+ for (int batch = 1; batch <= 254; batch += 20) {
304
+ final end = (batch + 19).clamp(1, 254);
305
+ final futures = <Future<String?>>[];
306
+ for (int i = batch; i <= end; i++) {
307
+ final probe = '$subnet.$i';
308
+ if (probe == addr.address) continue;
309
+ futures.add(_probeHost(probe, config.port));
310
+ }
311
+ final results = await Future.wait(futures);
312
+ final found = results.firstWhere((r) => r != null, orElse: () => null);
313
+ if (found != null) {
314
+ _mqttLog('MQTT: subnet scan found broker at $found');
315
+ return found;
316
+ }
317
+ }
318
+ }
319
+ }
320
+ } catch (e) {
321
+ _mqttLog('MQTT: subnet scan error: $e');
322
+ }
323
+ return null;
324
+ }
325
+
326
+ // --- TOFU (Trust On First Use) certificate pinning ---
327
+
328
+ String? _trustedFingerprint; // Loaded from SharedPreferences at startup
329
+
330
+ /// Load the trusted cert fingerprint from storage.
331
+ Future<void> _loadTrustedFingerprint() async {
332
+ final prefs = await SharedPreferences.getInstance();
333
+ _trustedFingerprint = prefs.getString('trustedCertFingerprint');
334
+ if (_trustedFingerprint != null) {
335
+ _mqttLog('TOFU: loaded trusted fingerprint: ${_trustedFingerprint!.substring(0, 16)}...');
336
+ }
337
+ }
338
+
339
+ /// Compute SHA-256 fingerprint of a certificate's DER bytes.
340
+ String _certFingerprint(X509Certificate cert) {
341
+ final der = cert.der;
342
+ final digest = sha256.convert(der);
343
+ return digest.toString();
344
+ }
345
+
346
+ /// TOFU verification: accept on first use, reject if fingerprint changes.
347
+ bool _verifyCertTofu(dynamic certificate) {
348
+ if (certificate is! X509Certificate) return true; // Can't verify, accept
349
+
350
+ final fingerprint = _certFingerprint(certificate);
351
+
352
+ if (_trustedFingerprint == null) {
353
+ // First connection — trust and save
354
+ _trustedFingerprint = fingerprint;
355
+ SharedPreferences.getInstance().then((prefs) {
356
+ prefs.setString('trustedCertFingerprint', fingerprint);
357
+ });
358
+ _mqttLog('TOFU: first connection, saved fingerprint: ${fingerprint.substring(0, 16)}...');
359
+ return true;
360
+ }
361
+
362
+ if (_trustedFingerprint == fingerprint) {
363
+ return true; // Known cert, trusted
364
+ }
365
+
366
+ // Fingerprint mismatch — possible MITM or server reinstall
367
+ _mqttLog('TOFU: CERT MISMATCH! Expected ${_trustedFingerprint!.substring(0, 16)}... got ${fingerprint.substring(0, 16)}...');
368
+ // Reject the connection. User must reset trust in settings.
369
+ return false;
370
+ }
371
+
372
+ /// Reset the trusted cert fingerprint (e.g., after server reinstall).
373
+ Future<void> resetTrustedCert() async {
374
+ _trustedFingerprint = null;
375
+ final prefs = await SharedPreferences.getInstance();
376
+ await prefs.remove('trustedCertFingerprint');
377
+ _mqttLog('TOFU: trust reset');
378
+ }
379
+
380
+ /// Probe a single host:port with a TLS connection attempt (1s timeout).
381
+ /// Uses SecureSocket since the broker now requires TLS.
382
+ Future<String?> _probeHost(String host, int port) async {
383
+ try {
384
+ final socket = await SecureSocket.connect(
385
+ host,
386
+ port,
387
+ timeout: const Duration(milliseconds: 500),
388
+ onBadCertificate: (_) => true, // Accept self-signed cert during scan
389
+ );
390
+ await socket.close();
391
+ return host;
392
+ } catch (_) {
393
+ return null;
394
+ }
395
+ }
396
+
397
+ Future<bool> _tryConnect(String host, String clientId, {int timeout = 5000}) async {
398
+ try {
399
+ final client = MqttServerClient.withPort(host, clientId, config.port);
400
+ client.keepAlivePeriod = 120; // 2 min — iOS throttles bg network, short keepalive causes drops
401
+ client.autoReconnect = false; // Don't auto-reconnect during trial — enable after success
402
+ client.connectTimeoutPeriod = timeout;
403
+ // client.maxConnectionAttempts is final — can't set it
404
+ client.logging(on: false);
405
+
406
+ // TLS with TOFU (Trust On First Use) cert pinning.
407
+ // First connection: accept cert, save its SHA-256 fingerprint.
408
+ // Future connections: only accept certs matching the saved fingerprint.
409
+ client.secure = true;
410
+ client.securityContext = SecurityContext(withTrustedRoots: true);
411
+ client.onBadCertificate = (dynamic certificate) {
412
+ return _verifyCertTofu(certificate);
413
+ };
414
+
415
+ client.onConnected = _onConnected;
416
+ client.onDisconnected = _onDisconnected;
417
+ client.onAutoReconnect = _onAutoReconnect;
418
+ client.onAutoReconnected = _onAutoReconnected;
419
+
420
+ // Clean session: we handle offline delivery ourselves via catch_up protocol.
421
+ // Persistent sessions cause the broker to flood all queued QoS 1 messages
422
+ // on reconnect, which overwhelms the client with large voice payloads.
423
+ final connMessage = MqttConnectMessage()
424
+ .withClientIdentifier(clientId)
425
+ .startClean()
426
+ .authenticateAs('pailot', config.mqttToken ?? '');
427
+
428
+ client.connectionMessage = connMessage;
429
+
430
+ // Set _client BEFORE connect() so _onConnected can subscribe
431
+ _client = client;
432
+
433
+ _mqttLog('MQTT: connecting to $host:${config.port} as $clientId (timeout=${timeout}ms)');
434
+ final result = await client.connect().timeout(
435
+ Duration(milliseconds: timeout + 1000),
436
+ onTimeout: () {
437
+ _mqttLog('MQTT: connect timed out for $host');
438
+ return null;
439
+ },
440
+ );
441
+ _mqttLog('MQTT: connect result=${result?.state}');
442
+ if (result?.state == MqttConnectionState.connected) {
443
+ client.autoReconnect = true;
444
+ return true;
445
+ }
446
+ _client = null;
447
+ client.disconnect();
448
+ return false;
449
+ } catch (e) {
450
+ _mqttLog('MQTT: connect exception=$e');
451
+ return false;
452
+ }
453
+ }
454
+
455
+ void _onConnected() {
456
+ _mqttLog('MQTT: _onConnected fired');
457
+ _setStatus(ConnectionStatus.connected);
458
+ _subscribe();
459
+ _listenMessages();
460
+ onOpen?.call();
461
+ }
462
+
463
+ void _onDisconnected() {
464
+ _updatesSub?.cancel();
465
+ _updatesSub = null;
466
+
467
+ if (_intentionalClose) {
468
+ _setStatus(ConnectionStatus.disconnected);
469
+ onClose?.call();
470
+ } else {
471
+ _setStatus(ConnectionStatus.reconnecting);
472
+ onReconnecting?.call();
473
+ }
474
+ }
475
+
476
+ void _onAutoReconnect() {
477
+ _setStatus(ConnectionStatus.reconnecting);
478
+ onReconnecting?.call();
479
+ }
480
+
481
+ void _onAutoReconnected() {
482
+ _setStatus(ConnectionStatus.connected);
483
+ _subscribe();
484
+ _listenMessages();
485
+ onOpen?.call();
486
+ }
487
+
488
+ void _subscribe() {
489
+ final client = _client;
490
+ if (client == null) {
491
+ _mqttLog('MQTT: _subscribe called but client is null');
492
+ return;
493
+ }
494
+ // Single outbound topic — all messages carry sessionId in payload.
495
+ // Client routes messages to the correct session based on payload.
496
+ _mqttLog('MQTT: subscribing to topics...');
497
+ client.subscribe('pailot/out', MqttQos.atLeastOnce);
498
+ client.subscribe('pailot/sessions', MqttQos.atLeastOnce);
499
+ client.subscribe('pailot/status', MqttQos.atLeastOnce);
500
+ client.subscribe('pailot/projects', MqttQos.atLeastOnce);
501
+ client.subscribe('pailot/control/out', MqttQos.atLeastOnce);
502
+ }
503
+
504
+ void _listenMessages() {
505
+ _updatesSub?.cancel();
506
+ _updatesSub = _client?.updates?.listen(_onMqttMessage);
507
+ }
508
+
509
+ void _onMqttMessage(List<MqttReceivedMessage<MqttMessage>> messages) {
510
+ _mqttLog('MQTT: received ${messages.length} message(s)');
511
+ for (final msg in messages) {
512
+ _mqttLog('MQTT: topic=${msg.topic}');
513
+ final pubMsg = msg.payload as MqttPublishMessage;
514
+ final payload = MqttPublishPayload.bytesToStringAsString(
515
+ pubMsg.payload.message,
516
+ );
517
+
518
+ Map<String, dynamic> json;
519
+ try {
520
+ json = jsonDecode(payload) as Map<String, dynamic>;
521
+ } catch (_) {
522
+ continue; // Skip non-JSON
523
+ }
524
+
525
+ // Dedup by msgId
526
+ final msgId = json['msgId'] as String?;
527
+ if (msgId != null) {
528
+ if (_seenMsgIds.contains(msgId)) {
529
+ final seq = json['seq'];
530
+ final type = json['type'] as String? ?? '?';
531
+ TraceService.instance.addTrace(
532
+ 'MQTT deduped',
533
+ 'msgId=${msgId.substring(0, 8)} type=$type seq=$seq topic=${msg.topic}',
534
+ );
535
+ continue;
536
+ }
537
+ _seenMsgIds.add(msgId);
538
+ _seenMsgIdOrder.add(msgId);
539
+ _evictOldIds();
540
+ }
541
+
542
+ final seq = json['seq'];
543
+ final type = json['type'] as String? ?? '?';
544
+ TraceService.instance.addTrace(
545
+ 'MQTT received',
546
+ 'seq=$seq type=$type on ${msg.topic}',
547
+ );
548
+
549
+ // Dispatch: parse topic to enrich the message with routing info
550
+ _dispatchMessage(msg.topic, json);
551
+ }
552
+ }
553
+
554
+ /// Route incoming MQTT messages to the onMessage callback.
555
+ /// Translates MQTT topic structure into the flat message format
556
+ /// that chat_screen expects.
557
+ void _dispatchMessage(String topic, Map<String, dynamic> json) {
558
+ // pailot/sessions
559
+ if (topic == 'pailot/sessions') {
560
+ json['type'] = 'sessions';
561
+ onMessage?.call(json);
562
+ return;
563
+ }
564
+
565
+ // pailot/status
566
+ if (topic == 'pailot/status') {
567
+ json['type'] = 'status';
568
+ onMessage?.call(json);
569
+ return;
570
+ }
571
+
572
+ // pailot/projects
573
+ if (topic == 'pailot/projects') {
574
+ json['type'] = 'projects';
575
+ onMessage?.call(json);
576
+ return;
577
+ }
578
+
579
+ // pailot/control/out — command responses
580
+ if (topic == 'pailot/control/out') {
581
+ onMessage?.call(json);
582
+ return;
583
+ }
584
+
585
+ // pailot/out — ALL content messages (text, voice, image, typing, screenshot, transcript)
586
+ // Each message carries its type and sessionId in the payload.
587
+ if (topic == 'pailot/out') {
588
+ final type = json['type'] as String?;
589
+ // Normalize typing fields for chat_screen
590
+ if (type == 'typing') {
591
+ final active = json['active'] as bool? ?? true;
592
+ json['typing'] = active;
593
+ }
594
+ // Normalize screenshot fields
595
+ if (type == 'screenshot') {
596
+ json['data'] ??= json['imageBase64'];
597
+ }
598
+ onMessage?.call(json);
599
+ return;
600
+ }
601
+ }
602
+
603
+ void _evictOldIds() {
604
+ while (_seenMsgIdOrder.length > _maxSeenIds) {
605
+ final oldest = _seenMsgIdOrder.removeAt(0);
606
+ _seenMsgIds.remove(oldest);
607
+ }
608
+ }
609
+
610
+ /// Generate a UUID v4 for message IDs.
611
+ String _uuid() => const Uuid().v4();
612
+
613
+ /// Current timestamp in milliseconds.
614
+ int _now() => DateTime.now().millisecondsSinceEpoch;
615
+
616
+ /// Publish raw bytes to a topic. Used by TraceService for log streaming.
617
+ void publishRaw(String topic, Uint8Buffer payload, MqttQos qos) {
618
+ final client = _client;
619
+ if (client == null || client.connectionStatus?.state != MqttConnectionState.connected) return;
620
+ try {
621
+ client.publishMessage(topic, qos, payload);
622
+ } catch (_) {}
623
+ }
624
+
625
+ /// Publish a JSON payload to an MQTT topic.
626
+ void _publish(String topic, Map<String, dynamic> payload, MqttQos qos) {
627
+ final client = _client;
628
+ if (client == null || client.connectionStatus?.state != MqttConnectionState.connected) {
629
+ onError?.call('Not connected');
630
+ return;
631
+ }
632
+
633
+ try {
634
+ final builder = MqttClientPayloadBuilder();
635
+ builder.addString(jsonEncode(payload));
636
+ client.publishMessage(topic, qos, builder.payload!);
637
+ } catch (e) {
638
+ onError?.call('Send failed: $e');
639
+ }
640
+ }
641
+
642
+ /// Send a message — routes to the appropriate MQTT topic based on content.
643
+ void send(Map<String, dynamic> message) {
644
+ final type = message['type'] as String?;
645
+ final sessionId = message['sessionId'] as String?;
646
+
647
+ if (type == 'command' || (message.containsKey('command') && type == null)) {
648
+ // Command messages go to pailot/control/in
649
+ final command = message['command'] as String? ?? '';
650
+ final args = message['args'] as Map<String, dynamic>? ?? {};
651
+ final payload = <String, dynamic>{
652
+ 'msgId': _uuid(),
653
+ 'type': 'command',
654
+ 'command': command,
655
+ 'ts': _now(),
656
+ ...args,
657
+ };
658
+ _publish('pailot/control/in', payload, MqttQos.atLeastOnce);
659
+ return;
660
+ }
661
+
662
+ if (type == 'voice' && sessionId != null) {
663
+ // Voice message
664
+ _publish('pailot/$sessionId/in', {
665
+ 'msgId': _uuid(),
666
+ 'type': 'voice',
667
+ 'sessionId': sessionId,
668
+ 'audioBase64': message['audioBase64'] ?? '',
669
+ 'messageId': message['messageId'] ?? '',
670
+ 'ts': _now(),
671
+ }, MqttQos.atLeastOnce);
672
+ return;
673
+ }
674
+
675
+ if (type == 'image' && sessionId != null) {
676
+ _publish('pailot/$sessionId/in', {
677
+ 'msgId': _uuid(),
678
+ 'type': 'image',
679
+ 'sessionId': sessionId,
680
+ 'imageBase64': message['imageBase64'] ?? '',
681
+ 'mimeType': message['mimeType'] ?? 'image/jpeg',
682
+ 'caption': message['caption'] ?? '',
683
+ 'ts': _now(),
684
+ }, MqttQos.atLeastOnce);
685
+ return;
686
+ }
687
+
688
+ if (type == 'bundle' && sessionId != null) {
689
+ // Atomic multi-attachment message
690
+ _publish('pailot/$sessionId/in', {
691
+ 'msgId': _uuid(),
692
+ 'type': 'bundle',
693
+ 'sessionId': sessionId,
694
+ 'caption': message['caption'] ?? '',
695
+ if (message['audioBase64'] != null) 'audioBase64': message['audioBase64'],
696
+ if (message['voiceMessageId'] != null) 'voiceMessageId': message['voiceMessageId'],
697
+ 'attachments': message['attachments'] ?? [],
698
+ 'ts': _now(),
699
+ }, MqttQos.atLeastOnce);
700
+ return;
701
+ }
702
+
703
+ if (type == 'file' && sessionId != null) {
704
+ _publish('pailot/$sessionId/in', {
705
+ 'msgId': _uuid(),
706
+ 'type': 'file',
707
+ 'sessionId': sessionId,
708
+ 'fileBase64': message['fileBase64'] ?? '',
709
+ 'fileName': message['fileName'] ?? 'file',
710
+ 'mimeType': message['mimeType'] ?? 'application/octet-stream',
711
+ 'fileSize': message['fileSize'] ?? 0,
712
+ 'ts': _now(),
713
+ }, MqttQos.atLeastOnce);
714
+ return;
715
+ }
716
+
717
+ if (type == 'tts' && sessionId != null) {
718
+ // TTS request — route as command
719
+ _publish('pailot/control/in', {
720
+ 'msgId': _uuid(),
721
+ 'type': 'command',
722
+ 'command': 'tts',
723
+ 'text': message['text'] ?? '',
724
+ 'sessionId': sessionId,
725
+ 'ts': _now(),
726
+ }, MqttQos.atLeastOnce);
727
+ return;
728
+ }
729
+
730
+ // Default: plain text message (content + sessionId)
731
+ if (sessionId != null) {
732
+ final content = message['content'] as String? ?? '';
733
+ _publish('pailot/$sessionId/in', {
734
+ 'msgId': _uuid(),
735
+ 'type': 'text',
736
+ 'sessionId': sessionId,
737
+ 'content': content,
738
+ 'ts': _now(),
739
+ }, MqttQos.atLeastOnce);
740
+ return;
741
+ }
742
+
743
+ onError?.call('Cannot send message: missing sessionId');
744
+ }
745
+
746
+ /// Publish the APNs device token to the daemon for push notification delivery.
747
+ /// The daemon stores it in ~/.aibroker/apns-tokens.json and uses it when
748
+ /// no MQTT clients are connected (app is backgrounded or offline).
749
+ void sendDeviceToken(String token) {
750
+ final client = _client;
751
+ if (client == null || client.connectionStatus?.state != MqttConnectionState.connected) {
752
+ return;
753
+ }
754
+ try {
755
+ final builder = MqttClientPayloadBuilder();
756
+ builder.addString('{"token":"$token","ts":${DateTime.now().millisecondsSinceEpoch}}');
757
+ client.publishMessage('pailot/device/token', MqttQos.atLeastOnce, builder.payload!);
758
+ _mqttLog('Push: device token published to pailot/device/token');
759
+ } catch (e) {
760
+ _mqttLog('Push: failed to publish device token: $e');
761
+ }
762
+ }
763
+
764
+ /// Disconnect intentionally.
765
+ void disconnect() {
766
+ _intentionalClose = true;
767
+ _updatesSub?.cancel();
768
+ _updatesSub = null;
769
+ _connectivitySub?.cancel();
770
+ _connectivitySub = null;
771
+
772
+ try {
773
+ _client?.disconnect();
774
+ } catch (_) {}
775
+ _client = null;
776
+
777
+ _setStatus(ConnectionStatus.disconnected);
778
+ onClose?.call();
779
+ }
780
+
781
+ /// Update config and reconnect.
782
+ Future<void> updateConfig(ServerConfig newConfig) async {
783
+ config = newConfig;
784
+ disconnect();
785
+ await Future.delayed(const Duration(milliseconds: 100));
786
+ await connect();
787
+ }
788
+
789
+ /// Dispose all resources.
790
+ void dispose() {
791
+ WidgetsBinding.instance.removeObserver(this);
792
+ disconnect();
793
+ }
794
+
795
+ // App lifecycle integration
796
+ @override
797
+ void didChangeAppLifecycleState(AppLifecycleState state) {
798
+ switch (state) {
799
+ case AppLifecycleState.resumed:
800
+ if (_intentionalClose) break;
801
+ _mqttLog('MQTT: app resumed');
802
+ // Let autoReconnect handle dead connections (keepalive timeout).
803
+ // Just trigger catch_up to fetch missed messages and rebuild UI.
804
+ onResume?.call();
805
+ case AppLifecycleState.paused:
806
+ break;
807
+ default:
808
+ break;
809
+ }
810
+ }
811
+}
lib/services/navigate_notifier.dart
....@@ -0,0 +1,12 @@
1
+/// Bridge between NavigateScreen and ChatScreen's MQTT service.
2
+/// ChatScreen sets the [navigateNotifierProvider] when MQTT is initialized.
3
+/// NavigateScreen reads it to send key presses and screenshot requests.
4
+class NavigateNotifier {
5
+ final void Function(String key, String? sessionId) sendKey;
6
+ final void Function(String? sessionId) requestScreenshot;
7
+
8
+ NavigateNotifier({
9
+ required this.sendKey,
10
+ required this.requestScreenshot,
11
+ });
12
+}
lib/services/purchase_service.dart
....@@ -0,0 +1,209 @@
1
+import 'dart:async';
2
+
3
+import 'package:flutter/foundation.dart';
4
+import 'package:in_app_purchase/in_app_purchase.dart';
5
+import 'package:shared_preferences/shared_preferences.dart';
6
+
7
+/// Product ID for the one-time full-access purchase.
8
+const String kFullAccessProductId = 'com.tekmidian.pailot.fullaccess';
9
+
10
+/// Maximum sessions allowed on the free tier.
11
+const int kFreeTierMaxSessions = 2;
12
+
13
+/// Maximum message age for free-tier users (15 minutes).
14
+const Duration kFreeTierMessageTtl = Duration(minutes: 15);
15
+
16
+/// Shared preference key for caching purchase status locally.
17
+const String _kProCacheKey = 'pailot_is_pro';
18
+
19
+/// Service that manages the StoreKit 2 / in_app_purchase lifecycle.
20
+///
21
+/// Usage:
22
+/// final svc = PurchaseService();
23
+/// await svc.initialize();
24
+/// svc.addListener(() { ... });
25
+/// bool pro = svc.isPro;
26
+///
27
+/// Call [dispose] when done.
28
+class PurchaseService extends ChangeNotifier {
29
+ PurchaseService._();
30
+
31
+ static final PurchaseService instance = PurchaseService._();
32
+
33
+ bool _isPro = false;
34
+ bool _isLoading = false;
35
+ String? _errorMessage;
36
+
37
+ StreamSubscription<List<PurchaseDetails>>? _subscription;
38
+
39
+ /// Whether the user has purchased full access.
40
+ bool get isPro => _isPro;
41
+
42
+ /// True while a purchase or restore operation is in progress.
43
+ bool get isLoading => _isLoading;
44
+
45
+ /// Non-null if the last operation produced an error message.
46
+ String? get errorMessage => _errorMessage;
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // Lifecycle
50
+ // ---------------------------------------------------------------------------
51
+
52
+ /// Initialize the service. Call once at app startup.
53
+ Future<void> initialize() async {
54
+ // Restore cached value immediately so UI doesn't flicker.
55
+ // Default to true for dev/sideloaded builds (no StoreKit configured).
56
+ final prefs = await SharedPreferences.getInstance();
57
+ // Force pro for now — clear any stale false value from earlier testing
58
+ _isPro = true;
59
+ await prefs.setBool(_kProCacheKey, true);
60
+ notifyListeners();
61
+
62
+ // Check if IAP is available — may not be on dev/sideloaded builds
63
+ final available = await InAppPurchase.instance.isAvailable();
64
+ if (!available) {
65
+ debugPrint('[IAP] StoreKit not available — assuming pro (dev build)');
66
+ _isPro = true;
67
+ notifyListeners();
68
+ return;
69
+ }
70
+
71
+ // Listen for ongoing purchase updates.
72
+ final purchaseUpdated = InAppPurchase.instance.purchaseStream;
73
+ _subscription = purchaseUpdated.listen(
74
+ _handlePurchaseUpdates,
75
+ onError: (Object err) {
76
+ _errorMessage = err.toString();
77
+ notifyListeners();
78
+ },
79
+ );
80
+
81
+ // Verify with StoreKit on each launch (catches refunds / family sharing).
82
+ await restorePurchases(silent: true);
83
+ }
84
+
85
+ @override
86
+ void dispose() {
87
+ _subscription?.cancel();
88
+ super.dispose();
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Public API
93
+ // ---------------------------------------------------------------------------
94
+
95
+ /// Initiate the purchase flow for full access.
96
+ Future<void> purchaseFullAccess() async {
97
+ _errorMessage = null;
98
+ _isLoading = true;
99
+ notifyListeners();
100
+
101
+ try {
102
+ final bool available = await InAppPurchase.instance.isAvailable();
103
+ if (!available) {
104
+ _errorMessage = 'Store not available. Check your internet connection.';
105
+ _isLoading = false;
106
+ notifyListeners();
107
+ return;
108
+ }
109
+
110
+ final ProductDetailsResponse response = await InAppPurchase.instance
111
+ .queryProductDetails({kFullAccessProductId});
112
+
113
+ if (response.error != null || response.productDetails.isEmpty) {
114
+ _errorMessage =
115
+ 'Product not found. Please try again later.';
116
+ _isLoading = false;
117
+ notifyListeners();
118
+ return;
119
+ }
120
+
121
+ final ProductDetails product = response.productDetails.first;
122
+ final PurchaseParam param = PurchaseParam(productDetails: product);
123
+ await InAppPurchase.instance.buyNonConsumable(purchaseParam: param);
124
+ // Result arrives via purchaseStream — _isLoading cleared there.
125
+ } catch (e) {
126
+ _errorMessage = 'Purchase failed: $e';
127
+ _isLoading = false;
128
+ notifyListeners();
129
+ }
130
+ }
131
+
132
+ /// Restore previously completed purchases (also called on app launch).
133
+ Future<void> restorePurchases({bool silent = false}) async {
134
+ if (!silent) {
135
+ _errorMessage = null;
136
+ _isLoading = true;
137
+ notifyListeners();
138
+ }
139
+
140
+ try {
141
+ await InAppPurchase.instance.restorePurchases();
142
+ // Results arrive asynchronously via purchaseStream.
143
+ // For non-silent restores _isLoading is cleared there.
144
+ if (silent) {
145
+ // Give the stream a moment to deliver any results.
146
+ await Future<void>.delayed(const Duration(seconds: 2));
147
+ }
148
+ } catch (e) {
149
+ if (!silent) {
150
+ _errorMessage = 'Restore failed: $e';
151
+ _isLoading = false;
152
+ notifyListeners();
153
+ }
154
+ }
155
+ }
156
+
157
+ // ---------------------------------------------------------------------------
158
+ // Internal
159
+ // ---------------------------------------------------------------------------
160
+
161
+ Future<void> _handlePurchaseUpdates(
162
+ List<PurchaseDetails> purchases) async {
163
+ for (final PurchaseDetails purchase in purchases) {
164
+ if (purchase.productID != kFullAccessProductId) continue;
165
+
166
+ switch (purchase.status) {
167
+ case PurchaseStatus.purchased:
168
+ case PurchaseStatus.restored:
169
+ await _deliverPurchase(purchase);
170
+ break;
171
+
172
+ case PurchaseStatus.error:
173
+ _errorMessage = purchase.error?.message ?? 'Purchase failed.';
174
+ _isLoading = false;
175
+ notifyListeners();
176
+ break;
177
+
178
+ case PurchaseStatus.canceled:
179
+ _isLoading = false;
180
+ notifyListeners();
181
+ break;
182
+
183
+ case PurchaseStatus.pending:
184
+ // Show loading while pending (e.g. Ask to Buy).
185
+ _isLoading = true;
186
+ notifyListeners();
187
+ break;
188
+ }
189
+
190
+ // Complete the transaction to prevent it from being re-delivered.
191
+ if (purchase.pendingCompletePurchase) {
192
+ await InAppPurchase.instance.completePurchase(purchase);
193
+ }
194
+ }
195
+ }
196
+
197
+ Future<void> _deliverPurchase(PurchaseDetails purchase) async {
198
+ _isPro = true;
199
+ _isLoading = false;
200
+ _errorMessage = null;
201
+
202
+ // Persist so the next app launch restores from cache quickly.
203
+ final prefs = await SharedPreferences.getInstance();
204
+ await prefs.setBool(_kProCacheKey, true);
205
+
206
+ debugPrint('[Purchase] Full access granted for ${purchase.productID}');
207
+ notifyListeners();
208
+ }
209
+}
lib/services/push_service.dart
....@@ -0,0 +1,123 @@
1
+import 'package:flutter/foundation.dart';
2
+import 'package:flutter_app_badger/flutter_app_badger.dart';
3
+import 'package:push/push.dart';
4
+
5
+import 'mqtt_service.dart';
6
+
7
+/// Handles APNs push notification registration and token delivery to the daemon.
8
+///
9
+/// Flow:
10
+/// 1. [initialize] requests permission and registers for remote notifications.
11
+/// 2. On new token, the token is published to the daemon via MQTT on
12
+/// `pailot/device/token`.
13
+/// 3. On notification tap (app was killed), the [onNotificationTap] callback
14
+/// is called so the UI can navigate to the right session.
15
+class PushService {
16
+ PushService({required this.mqttService});
17
+
18
+ final MqttService mqttService;
19
+
20
+ /// Called when the user taps a push notification.
21
+ /// The [data] map contains any custom data from the notification payload
22
+ /// (e.g. `sessionId`).
23
+ void Function(Map<String, dynamic> data)? onNotificationTap;
24
+
25
+ String? _lastToken;
26
+
27
+ /// Initialize APNs: request permission and listen for tokens.
28
+ /// Safe to call multiple times — subsequent calls are no-ops if already done.
29
+ Future<void> initialize() async {
30
+ try {
31
+ // Request permission (returns bool on iOS)
32
+ final granted = await Push.instance.requestPermission(
33
+ alert: true,
34
+ badge: true,
35
+ sound: true,
36
+ );
37
+ debugPrint('[Push] permission granted: $granted');
38
+
39
+ // Register for remote notifications
40
+ Push.instance.registerForRemoteNotifications();
41
+
42
+ // Listen for new/refreshed tokens
43
+ Push.instance.addOnNewToken((token) {
44
+ debugPrint('[Push] new token: ${token.substring(0, 16)}...');
45
+ _lastToken = token;
46
+ _sendTokenToDaemon(token);
47
+ });
48
+
49
+ // If we already have a token (from a previous session), fetch and send it
50
+ final existingToken = await Push.instance.token;
51
+ if (existingToken != null) {
52
+ debugPrint('[Push] existing token: ${existingToken.substring(0, 16)}...');
53
+ _lastToken = existingToken;
54
+ _sendTokenToDaemon(existingToken);
55
+ }
56
+
57
+ // Handle notification tap that launched the app from terminated state.
58
+ // Returns Map<String?, Object?>? — extract custom data from it.
59
+ final terminatedPayload =
60
+ await Push.instance.notificationTapWhichLaunchedAppFromTerminated;
61
+ if (terminatedPayload != null) {
62
+ debugPrint('[Push] app launched from notification tap');
63
+ onNotificationTap?.call(_toStringMap(terminatedPayload));
64
+ }
65
+
66
+ // Handle notification taps while app is in background (suspended).
67
+ Push.instance.addOnNotificationTap((Map<String?, Object?> payload) {
68
+ debugPrint('[Push] notification tapped (background)');
69
+ onNotificationTap?.call(_toStringMap(payload));
70
+ });
71
+
72
+ debugPrint('[Push] initialized');
73
+ } catch (e) {
74
+ debugPrint('[Push] initialization error: $e');
75
+ }
76
+ }
77
+
78
+ /// Convert Map<String?, Object?> to Map<String, dynamic> for easier use.
79
+ Map<String, dynamic> _toStringMap(Map<String?, Object?> src) {
80
+ return {
81
+ for (final entry in src.entries)
82
+ if (entry.key != null) entry.key!: entry.value,
83
+ };
84
+ }
85
+
86
+ /// Re-send the last known token when MQTT reconnects, and clear badge.
87
+ void onMqttConnected() {
88
+ final token = _lastToken;
89
+ if (token != null) {
90
+ debugPrint('[Push] re-registering token after MQTT reconnect');
91
+ _sendTokenToDaemon(token);
92
+ }
93
+ clearBadge();
94
+ }
95
+
96
+ /// Clear the app icon badge number.
97
+ static void clearBadge() {
98
+ FlutterAppBadger.removeBadge();
99
+ }
100
+
101
+ /// Set the app icon badge to a specific count.
102
+ static void setBadge(int count) {
103
+ if (count <= 0) {
104
+ FlutterAppBadger.removeBadge();
105
+ } else {
106
+ FlutterAppBadger.updateBadgeCount(count);
107
+ }
108
+ }
109
+
110
+ /// Publish the device token to the daemon via MQTT.
111
+ void _sendTokenToDaemon(String token) {
112
+ if (!mqttService.isConnected) {
113
+ debugPrint('[Push] MQTT not connected, token will be sent on next reconnect');
114
+ return;
115
+ }
116
+ try {
117
+ mqttService.sendDeviceToken(token);
118
+ debugPrint('[Push] token sent to daemon: ${token.substring(0, 16)}...');
119
+ } catch (e) {
120
+ debugPrint('[Push] failed to send token: $e');
121
+ }
122
+ }
123
+}
lib/services/trace_service.dart
....@@ -0,0 +1,89 @@
1
+import 'dart:convert';
2
+
3
+import 'package:flutter/foundation.dart';
4
+import 'package:mqtt_client/mqtt_client.dart';
5
+import 'package:mqtt_client/mqtt_server_client.dart';
6
+
7
+import 'mqtt_service.dart';
8
+
9
+/// A single trace entry capturing a message-handling event.
10
+class TraceEntry {
11
+ final DateTime timestamp;
12
+ final String event;
13
+ final String details;
14
+
15
+ const TraceEntry({
16
+ required this.timestamp,
17
+ required this.event,
18
+ required this.details,
19
+ });
20
+
21
+ @override
22
+ String toString() =>
23
+ '[${timestamp.toIso8601String().substring(11, 23)}] $event — $details';
24
+}
25
+
26
+/// Singleton ring-buffer trace service.
27
+///
28
+/// Captures message-handling events from MQTT, chat screen, and other
29
+/// components. The buffer is capped at [maxEntries] (default 200).
30
+/// Works in both debug and release builds.
31
+///
32
+/// When an MqttService is attached via [attachMqtt], trace entries are
33
+/// automatically published to the server on `pailot/control/in` so they
34
+/// can be read from the daemon log.
35
+class TraceService {
36
+ TraceService._();
37
+ static final TraceService instance = TraceService._();
38
+
39
+ static const int maxEntries = 200;
40
+ final List<TraceEntry> _entries = [];
41
+ MqttService? _mqtt;
42
+
43
+ /// Attach an MQTT service for auto-publishing traces to the server.
44
+ void attachMqtt(MqttService mqtt) {
45
+ _mqtt = mqtt;
46
+ }
47
+
48
+ /// All entries, oldest first.
49
+ List<TraceEntry> get entries => List.unmodifiable(_entries);
50
+
51
+ /// Add a trace entry. Oldest entry is evicted once the buffer is full.
52
+ /// If MQTT is attached and connected, the entry is also published to the server.
53
+ void addTrace(String event, String details) {
54
+ _entries.add(TraceEntry(
55
+ timestamp: DateTime.now(),
56
+ event: event,
57
+ details: details,
58
+ ));
59
+ if (_entries.length > maxEntries) {
60
+ _entries.removeAt(0);
61
+ }
62
+ debugPrint('[TRACE] $event — $details');
63
+
64
+ // Auto-publish to server if MQTT is connected
65
+ _publishTrace(event, details);
66
+ }
67
+
68
+ void _publishTrace(String event, String details) {
69
+ final mqtt = _mqtt;
70
+ if (mqtt == null || !mqtt.isConnected) return;
71
+ try {
72
+ final payload = jsonEncode({
73
+ 'type': 'command',
74
+ 'command': 'app_trace',
75
+ 'event': event,
76
+ 'details': details,
77
+ 'ts': DateTime.now().millisecondsSinceEpoch,
78
+ });
79
+ final builder = MqttClientPayloadBuilder();
80
+ builder.addString(payload);
81
+ mqtt.publishRaw('pailot/control/in', builder.payload!, MqttQos.atMostOnce);
82
+ } catch (_) {
83
+ // Non-fatal — don't let trace logging break the app
84
+ }
85
+ }
86
+
87
+ /// Clear all entries.
88
+ void clear() => _entries.clear();
89
+}
lib/services/wol_service.dart
....@@ -0,0 +1,88 @@
1
+import 'dart:io';
2
+import 'dart:typed_data';
3
+
4
+/// Wake-on-LAN magic packet sender.
5
+class WolService {
6
+ WolService._();
7
+
8
+ /// Parse a MAC address string (colon or dash separated) to bytes.
9
+ static List<int>? _parseMac(String mac) {
10
+ final cleaned = mac.replaceAll(RegExp(r'[:\-]'), '');
11
+ if (cleaned.length != 12) return null;
12
+ final bytes = <int>[];
13
+ for (var i = 0; i < 12; i += 2) {
14
+ final byte = int.tryParse(cleaned.substring(i, i + 2), radix: 16);
15
+ if (byte == null) return null;
16
+ bytes.add(byte);
17
+ }
18
+ return bytes;
19
+ }
20
+
21
+ /// Build the magic packet: 6x 0xFF followed by MAC address repeated 16 times.
22
+ static Uint8List _buildPacket(List<int> macBytes) {
23
+ final packet = BytesBuilder();
24
+ // 6 bytes of 0xFF
25
+ for (var i = 0; i < 6; i++) {
26
+ packet.addByte(0xFF);
27
+ }
28
+ // MAC address repeated 16 times
29
+ for (var i = 0; i < 16; i++) {
30
+ packet.add(macBytes);
31
+ }
32
+ return packet.toBytes();
33
+ }
34
+
35
+ /// Derive subnet broadcast from an IP address (e.g., 192.168.1.100 → 192.168.1.255).
36
+ static String? _subnetBroadcast(String? ip) {
37
+ if (ip == null || ip.isEmpty) return null;
38
+ final parts = ip.split('.');
39
+ if (parts.length != 4) return null;
40
+ return '${parts[0]}.${parts[1]}.${parts[2]}.255';
41
+ }
42
+
43
+ /// Send a Wake-on-LAN packet for the given MAC address.
44
+ /// Broadcasts to 255.255.255.255 and subnet broadcast derived from localHost.
45
+ /// Sends on ports 7 and 9 for maximum compatibility.
46
+ static Future<void> wake(String macAddress, {String? localHost}) async {
47
+ final macBytes = _parseMac(macAddress);
48
+ if (macBytes == null) {
49
+ throw ArgumentError('Invalid MAC address: $macAddress');
50
+ }
51
+
52
+ final packet = _buildPacket(macBytes);
53
+
54
+ final socket = await RawDatagramSocket.bind(
55
+ InternetAddress.anyIPv4,
56
+ 0,
57
+ );
58
+ socket.broadcastEnabled = true;
59
+
60
+ final targets = <InternetAddress>[
61
+ InternetAddress('255.255.255.255'),
62
+ ];
63
+
64
+ // Add subnet broadcast derived from localHost
65
+ final subnet = _subnetBroadcast(localHost);
66
+ if (subnet != null) {
67
+ try {
68
+ targets.add(InternetAddress(subnet));
69
+ } catch (_) {}
70
+ }
71
+
72
+ // Send to all targets on both common WoL ports
73
+ for (final addr in targets) {
74
+ socket.send(packet, addr, 9);
75
+ socket.send(packet, addr, 7);
76
+ }
77
+
78
+ // Repeat for reliability
79
+ for (var i = 0; i < 3; i++) {
80
+ await Future.delayed(const Duration(milliseconds: 100));
81
+ for (final addr in targets) {
82
+ socket.send(packet, addr, 9);
83
+ }
84
+ }
85
+
86
+ socket.close();
87
+ }
88
+}
lib/theme/app_theme.dart
....@@ -0,0 +1,175 @@
1
+import 'package:flutter/material.dart';
2
+
3
+/// PAILot brand colors - teal/blue accent on dark backgrounds.
4
+class AppColors {
5
+ // Brand
6
+ static const Color accent = Color(0xFF4A9EFF);
7
+ static const Color accentDim = Color(0xFF2D6BB5);
8
+
9
+ // Dark mode
10
+ static const Color darkBg = Color(0xFF0A0A0F);
11
+ static const Color darkSurface = Color(0xFF1C1C2E);
12
+ static const Color darkCard = Color(0xFF1E1E2E);
13
+ static const Color darkInputBg = Color(0xFF2A2A3E);
14
+
15
+ // Bubbles
16
+ static const Color userBubble = Color(0xFF4A9EFF);
17
+ static const Color assistantBubble = Color(0xFF2A2A3E);
18
+ static const Color systemBubble = Color(0xFF1A1A2A);
19
+
20
+ // Light mode
21
+ static const Color lightBg = Color(0xFFF5F5FA);
22
+ static const Color lightSurface = Color(0xFFFFFFFF);
23
+ static const Color lightCard = Color(0xFFF0F0F8);
24
+ static const Color lightInputBg = Color(0xFFE8E8F0);
25
+ static const Color lightUserBubble = Color(0xFF4A9EFF);
26
+ static const Color lightAssistantBubble = Color(0xFFE8E8F0);
27
+
28
+ // Text
29
+ static const Color darkTextPrimary = Color(0xFFE0E0E0);
30
+ static const Color darkTextSecondary = Color(0xFFB0B0B0);
31
+ static const Color darkTextTertiary = Color(0xFF757575);
32
+ static const Color lightTextPrimary = Color(0xFF212121);
33
+ static const Color lightTextSecondary = Color(0xFF616161);
34
+
35
+ // Status
36
+ static const Color connected = Color(0xFF22C55E);
37
+ static const Color connecting = Color(0xFFEAB308);
38
+ static const Color disconnected = Color(0xFFEF4444);
39
+ static const Color compacting = Color(0xFF3B82F6);
40
+
41
+ // Recording
42
+ static const Color recording = Color(0xFFFF6B35);
43
+ static const Color recordingGlow = Color(0x40FF6B35);
44
+
45
+ // Misc
46
+ static const Color error = Color(0xFFEF4444);
47
+ static const Color success = Color(0xFF22C55E);
48
+ static const Color unreadBadge = Color(0xFFFF4444);
49
+}
50
+
51
+class AppTheme {
52
+ static ThemeData get darkTheme {
53
+ return ThemeData(
54
+ useMaterial3: true,
55
+ brightness: Brightness.dark,
56
+ colorScheme: ColorScheme.fromSeed(
57
+ seedColor: AppColors.accent,
58
+ brightness: Brightness.dark,
59
+ primary: AppColors.accent,
60
+ surface: AppColors.darkSurface,
61
+ ),
62
+ scaffoldBackgroundColor: AppColors.darkBg,
63
+ appBarTheme: const AppBarTheme(
64
+ backgroundColor: AppColors.darkSurface,
65
+ foregroundColor: Colors.white,
66
+ elevation: 0,
67
+ centerTitle: true,
68
+ ),
69
+ cardTheme: CardThemeData(
70
+ color: AppColors.darkCard,
71
+ elevation: 0,
72
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
73
+ margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
74
+ ),
75
+ drawerTheme: const DrawerThemeData(
76
+ backgroundColor: AppColors.darkSurface,
77
+ ),
78
+ elevatedButtonTheme: ElevatedButtonThemeData(
79
+ style: ElevatedButton.styleFrom(
80
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
81
+ padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
82
+ ),
83
+ ),
84
+ inputDecorationTheme: InputDecorationTheme(
85
+ filled: true,
86
+ fillColor: AppColors.darkInputBg,
87
+ border: OutlineInputBorder(
88
+ borderRadius: BorderRadius.circular(12),
89
+ borderSide: BorderSide.none,
90
+ ),
91
+ contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
92
+ ),
93
+ textTheme: const TextTheme(
94
+ headlineLarge: TextStyle(
95
+ fontSize: 28,
96
+ fontWeight: FontWeight.bold,
97
+ color: AppColors.darkTextPrimary),
98
+ headlineMedium: TextStyle(
99
+ fontSize: 22,
100
+ fontWeight: FontWeight.bold,
101
+ color: AppColors.darkTextPrimary),
102
+ titleLarge: TextStyle(
103
+ fontSize: 18,
104
+ fontWeight: FontWeight.w600,
105
+ color: AppColors.darkTextPrimary),
106
+ bodyLarge:
107
+ TextStyle(fontSize: 16, color: AppColors.darkTextPrimary),
108
+ bodyMedium:
109
+ TextStyle(fontSize: 14, color: AppColors.darkTextSecondary),
110
+ ),
111
+ );
112
+ }
113
+
114
+ static ThemeData get lightTheme {
115
+ return ThemeData(
116
+ useMaterial3: true,
117
+ brightness: Brightness.light,
118
+ colorScheme: ColorScheme.fromSeed(
119
+ seedColor: AppColors.accent,
120
+ brightness: Brightness.light,
121
+ primary: AppColors.accent,
122
+ surface: AppColors.lightSurface,
123
+ ),
124
+ scaffoldBackgroundColor: AppColors.lightBg,
125
+ appBarTheme: const AppBarTheme(
126
+ backgroundColor: AppColors.lightSurface,
127
+ foregroundColor: AppColors.lightTextPrimary,
128
+ elevation: 0,
129
+ centerTitle: true,
130
+ ),
131
+ cardTheme: CardThemeData(
132
+ color: AppColors.lightCard,
133
+ elevation: 0,
134
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
135
+ margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
136
+ ),
137
+ drawerTheme: const DrawerThemeData(
138
+ backgroundColor: AppColors.lightSurface,
139
+ ),
140
+ elevatedButtonTheme: ElevatedButtonThemeData(
141
+ style: ElevatedButton.styleFrom(
142
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
143
+ padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
144
+ ),
145
+ ),
146
+ inputDecorationTheme: InputDecorationTheme(
147
+ filled: true,
148
+ fillColor: AppColors.lightInputBg,
149
+ border: OutlineInputBorder(
150
+ borderRadius: BorderRadius.circular(12),
151
+ borderSide: BorderSide.none,
152
+ ),
153
+ contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
154
+ ),
155
+ textTheme: const TextTheme(
156
+ headlineLarge: TextStyle(
157
+ fontSize: 28,
158
+ fontWeight: FontWeight.bold,
159
+ color: AppColors.lightTextPrimary),
160
+ headlineMedium: TextStyle(
161
+ fontSize: 22,
162
+ fontWeight: FontWeight.bold,
163
+ color: AppColors.lightTextPrimary),
164
+ titleLarge: TextStyle(
165
+ fontSize: 18,
166
+ fontWeight: FontWeight.w600,
167
+ color: AppColors.lightTextPrimary),
168
+ bodyLarge:
169
+ TextStyle(fontSize: 16, color: AppColors.lightTextPrimary),
170
+ bodyMedium:
171
+ TextStyle(fontSize: 14, color: AppColors.lightTextSecondary),
172
+ ),
173
+ );
174
+ }
175
+}
lib/widgets/command_bar.dart
....@@ -0,0 +1,109 @@
1
+import 'package:flutter/material.dart';
2
+
3
+import '../theme/app_theme.dart';
4
+
5
+/// Row of command buttons: Screen, Navigate, Photo, Clear (+ Help in text mode).
6
+class CommandBar extends StatelessWidget {
7
+ final VoidCallback onScreen;
8
+ final VoidCallback onNavigate;
9
+ final VoidCallback onPhoto;
10
+ final VoidCallback onClear;
11
+ final VoidCallback? onHelp;
12
+ final bool showHelp;
13
+
14
+ const CommandBar({
15
+ super.key,
16
+ required this.onScreen,
17
+ required this.onNavigate,
18
+ required this.onPhoto,
19
+ required this.onClear,
20
+ this.onHelp,
21
+ this.showHelp = false,
22
+ });
23
+
24
+ @override
25
+ Widget build(BuildContext context) {
26
+ final isDark = Theme.of(context).brightness == Brightness.dark;
27
+
28
+ return Container(
29
+ padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
30
+ decoration: BoxDecoration(
31
+ color: isDark ? AppColors.darkSurface : AppColors.lightSurface,
32
+ ),
33
+ child: Row(
34
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
35
+ children: [
36
+ _CommandButton(
37
+ icon: Icons.screenshot_monitor,
38
+ label: 'Screen',
39
+ onTap: onScreen,
40
+ ),
41
+ _CommandButton(
42
+ icon: Icons.explore,
43
+ label: 'Navigate',
44
+ onTap: onNavigate,
45
+ ),
46
+ _CommandButton(
47
+ icon: Icons.attach_file,
48
+ label: 'Attach',
49
+ onTap: onPhoto,
50
+ ),
51
+ _CommandButton(
52
+ icon: Icons.delete_sweep,
53
+ label: 'Clear',
54
+ onTap: onClear,
55
+ ),
56
+ if (showHelp && onHelp != null)
57
+ _CommandButton(
58
+ icon: Icons.help_outline,
59
+ label: 'Help',
60
+ onTap: onHelp!,
61
+ ),
62
+ ],
63
+ ),
64
+ );
65
+ }
66
+}
67
+
68
+class _CommandButton extends StatelessWidget {
69
+ final IconData icon;
70
+ final String label;
71
+ final VoidCallback onTap;
72
+
73
+ const _CommandButton({
74
+ required this.icon,
75
+ required this.label,
76
+ required this.onTap,
77
+ });
78
+
79
+ @override
80
+ Widget build(BuildContext context) {
81
+ final isDark = Theme.of(context).brightness == Brightness.dark;
82
+
83
+ return InkWell(
84
+ onTap: onTap,
85
+ borderRadius: BorderRadius.circular(8),
86
+ child: Padding(
87
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
88
+ child: Column(
89
+ mainAxisSize: MainAxisSize.min,
90
+ children: [
91
+ Icon(
92
+ icon,
93
+ size: 22,
94
+ color: isDark ? AppColors.darkTextSecondary : AppColors.lightTextSecondary,
95
+ ),
96
+ const SizedBox(height: 2),
97
+ Text(
98
+ label,
99
+ style: TextStyle(
100
+ fontSize: 10,
101
+ color: isDark ? AppColors.darkTextTertiary : Colors.grey.shade600,
102
+ ),
103
+ ),
104
+ ],
105
+ ),
106
+ ),
107
+ );
108
+ }
109
+}
lib/widgets/image_viewer.dart
....@@ -0,0 +1,92 @@
1
+import 'dart:typed_data';
2
+
3
+import 'package:flutter/material.dart';
4
+import 'package:share_plus/share_plus.dart';
5
+import 'package:path_provider/path_provider.dart';
6
+import 'dart:io';
7
+
8
+/// Full-screen zoomable image viewer with share and close controls.
9
+class ImageViewer extends StatelessWidget {
10
+ final Uint8List imageBytes;
11
+
12
+ const ImageViewer({super.key, required this.imageBytes});
13
+
14
+ @override
15
+ Widget build(BuildContext context) {
16
+ return Scaffold(
17
+ backgroundColor: Colors.black,
18
+ body: SafeArea(
19
+ child: Stack(
20
+ children: [
21
+ // Zoomable image
22
+ Center(
23
+ child: InteractiveViewer(
24
+ minScale: 1.0,
25
+ maxScale: 5.0,
26
+ child: Image.memory(
27
+ imageBytes,
28
+ fit: BoxFit.contain,
29
+ ),
30
+ ),
31
+ ),
32
+ // Top bar with actions
33
+ Positioned(
34
+ top: 0,
35
+ left: 0,
36
+ right: 0,
37
+ child: Container(
38
+ padding:
39
+ const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
40
+ decoration: BoxDecoration(
41
+ gradient: LinearGradient(
42
+ begin: Alignment.topCenter,
43
+ end: Alignment.bottomCenter,
44
+ colors: [
45
+ Colors.black.withAlpha(180),
46
+ Colors.transparent,
47
+ ],
48
+ ),
49
+ ),
50
+ child: Row(
51
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
52
+ children: [
53
+ IconButton(
54
+ icon: const Icon(Icons.close, color: Colors.white),
55
+ onPressed: () => Navigator.pop(context),
56
+ ),
57
+ Row(
58
+ children: [
59
+ IconButton(
60
+ icon: const Icon(Icons.share, color: Colors.white),
61
+ onPressed: () => _share(context),
62
+ ),
63
+ ],
64
+ ),
65
+ ],
66
+ ),
67
+ ),
68
+ ),
69
+ ],
70
+ ),
71
+ ),
72
+ );
73
+ }
74
+
75
+ Future<void> _share(BuildContext context) async {
76
+ try {
77
+ final dir = await getTemporaryDirectory();
78
+ final file = File(
79
+ '${dir.path}/pailot_image_${DateTime.now().millisecondsSinceEpoch}.png');
80
+ await file.writeAsBytes(imageBytes);
81
+ await SharePlus.instance.share(
82
+ ShareParams(files: [XFile(file.path)]),
83
+ );
84
+ } catch (e) {
85
+ if (context.mounted) {
86
+ ScaffoldMessenger.of(context).showSnackBar(
87
+ SnackBar(content: Text('Share failed: $e')),
88
+ );
89
+ }
90
+ }
91
+ }
92
+}
lib/widgets/input_bar.dart
....@@ -0,0 +1,129 @@
1
+import 'package:flutter/material.dart';
2
+
3
+import '../providers/providers.dart';
4
+import '../theme/app_theme.dart';
5
+import 'voice_button.dart';
6
+
7
+/// Bottom input area: voice mode (replay | talk | Aa) or text mode (mic | text | send).
8
+class InputBar extends StatelessWidget {
9
+ final InputMode mode;
10
+ final bool isRecording;
11
+ final TextEditingController textController;
12
+ final VoidCallback onToggleMode;
13
+ final VoidCallback onRecordStart;
14
+ final VoidCallback onRecordStop;
15
+ final VoidCallback onRecordCancel;
16
+ final VoidCallback onReplay;
17
+ final VoidCallback onSendText;
18
+
19
+ const InputBar({
20
+ super.key,
21
+ required this.mode,
22
+ required this.isRecording,
23
+ required this.textController,
24
+ required this.onToggleMode,
25
+ required this.onRecordStart,
26
+ required this.onRecordStop,
27
+ required this.onRecordCancel,
28
+ required this.onReplay,
29
+ required this.onSendText,
30
+ });
31
+
32
+ @override
33
+ Widget build(BuildContext context) {
34
+ final isDark = Theme.of(context).brightness == Brightness.dark;
35
+
36
+ return Container(
37
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
38
+ decoration: BoxDecoration(
39
+ color: isDark ? AppColors.darkSurface : AppColors.lightSurface,
40
+ border: Border(
41
+ top: BorderSide(
42
+ color: isDark ? Colors.white10 : Colors.black12,
43
+ width: 0.5,
44
+ ),
45
+ ),
46
+ ),
47
+ child: SafeArea(
48
+ top: false,
49
+ child: mode == InputMode.voice
50
+ ? _buildVoiceMode(context)
51
+ : _buildTextMode(context),
52
+ ),
53
+ );
54
+ }
55
+
56
+ Widget _buildVoiceMode(BuildContext context) {
57
+ return Row(
58
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
59
+ children: [
60
+ // Replay button
61
+ IconButton(
62
+ icon: const Icon(Icons.replay, size: 28),
63
+ onPressed: onReplay,
64
+ tooltip: 'Replay last',
65
+ ),
66
+ // Talk button
67
+ VoiceButton(
68
+ isRecording: isRecording,
69
+ onTapStart: onRecordStart,
70
+ onTapStop: onRecordStop,
71
+ onCancel: onRecordCancel,
72
+ ),
73
+ // Toggle to text mode
74
+ IconButton(
75
+ icon: const Text(
76
+ 'Aa',
77
+ style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
78
+ ),
79
+ onPressed: onToggleMode,
80
+ tooltip: 'Text mode',
81
+ ),
82
+ ],
83
+ );
84
+ }
85
+
86
+ Widget _buildTextMode(BuildContext context) {
87
+ final isDark = Theme.of(context).brightness == Brightness.dark;
88
+
89
+ return Row(
90
+ children: [
91
+ // Toggle to voice mode
92
+ IconButton(
93
+ icon: const Icon(Icons.mic, size: 24),
94
+ onPressed: onToggleMode,
95
+ tooltip: 'Voice mode',
96
+ ),
97
+ const SizedBox(width: 8),
98
+ // Text field
99
+ Expanded(
100
+ child: TextField(
101
+ controller: textController,
102
+ decoration: InputDecoration(
103
+ hintText: 'Type a message...',
104
+ filled: true,
105
+ fillColor: isDark ? AppColors.darkInputBg : AppColors.lightInputBg,
106
+ border: OutlineInputBorder(
107
+ borderRadius: BorderRadius.circular(24),
108
+ borderSide: BorderSide.none,
109
+ ),
110
+ contentPadding:
111
+ const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
112
+ isDense: true,
113
+ ),
114
+ textInputAction: TextInputAction.newline,
115
+ maxLines: 4,
116
+ minLines: 1,
117
+ ),
118
+ ),
119
+ const SizedBox(width: 8),
120
+ // Send button
121
+ IconButton(
122
+ icon: const Icon(Icons.send, color: AppColors.accent),
123
+ onPressed: onSendText,
124
+ tooltip: 'Send',
125
+ ),
126
+ ],
127
+ );
128
+ }
129
+}
lib/widgets/message_bubble.dart
....@@ -0,0 +1,405 @@
1
+import 'dart:convert';
2
+import 'dart:math';
3
+import 'dart:typed_data';
4
+
5
+import 'package:flutter/material.dart';
6
+import 'package:flutter/services.dart';
7
+import 'package:flutter_markdown/flutter_markdown.dart';
8
+import 'package:url_launcher/url_launcher.dart';
9
+import 'package:intl/intl.dart';
10
+
11
+import '../models/message.dart';
12
+import '../theme/app_theme.dart';
13
+import 'image_viewer.dart';
14
+
15
+// Cache decoded image bytes to prevent flicker on widget rebuild
16
+final Map<String, Uint8List> _imageCache = {};
17
+
18
+/// Chat message bubble with support for text, voice, and image types.
19
+class MessageBubble extends StatelessWidget {
20
+ final Message message;
21
+ final VoidCallback? onPlay;
22
+ final VoidCallback? onChainPlay;
23
+ final VoidCallback? onDelete;
24
+ final bool isPlaying;
25
+
26
+ const MessageBubble({
27
+ super.key,
28
+ required this.message,
29
+ this.onPlay,
30
+ this.onChainPlay,
31
+ this.onDelete,
32
+ this.isPlaying = false,
33
+ });
34
+
35
+ bool get _isUser => message.role == MessageRole.user;
36
+ bool get _isSystem => message.role == MessageRole.system;
37
+
38
+ @override
39
+ Widget build(BuildContext context) {
40
+ if (_isSystem) return _buildSystem(context);
41
+
42
+ final isDark = Theme.of(context).brightness == Brightness.dark;
43
+
44
+ return Align(
45
+ alignment: _isUser ? Alignment.centerRight : Alignment.centerLeft,
46
+ child: GestureDetector(
47
+ onLongPress: () => _showContextMenu(context),
48
+ child: Container(
49
+ constraints: BoxConstraints(
50
+ maxWidth: MediaQuery.of(context).size.width * 0.78,
51
+ ),
52
+ margin: EdgeInsets.only(
53
+ left: _isUser ? 48 : 16,
54
+ right: _isUser ? 16 : 48,
55
+ bottom: 6,
56
+ ),
57
+ padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
58
+ decoration: BoxDecoration(
59
+ color: _isUser
60
+ ? (isDark ? AppColors.userBubble : AppColors.lightUserBubble)
61
+ : (isDark
62
+ ? AppColors.assistantBubble
63
+ : AppColors.lightAssistantBubble),
64
+ borderRadius: BorderRadius.only(
65
+ topLeft: const Radius.circular(16),
66
+ topRight: const Radius.circular(16),
67
+ bottomLeft: Radius.circular(_isUser ? 16 : 4),
68
+ bottomRight: Radius.circular(_isUser ? 4 : 16),
69
+ ),
70
+ ),
71
+ child: Column(
72
+ crossAxisAlignment: CrossAxisAlignment.start,
73
+ children: [
74
+ _buildContent(context),
75
+ const SizedBox(height: 4),
76
+ _buildFooter(context),
77
+ ],
78
+ ),
79
+ ),
80
+ ),
81
+ );
82
+ }
83
+
84
+ Widget _buildSystem(BuildContext context) {
85
+ final isDark = Theme.of(context).brightness == Brightness.dark;
86
+ return Center(
87
+ child: Container(
88
+ margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 32),
89
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
90
+ decoration: BoxDecoration(
91
+ color: isDark ? AppColors.systemBubble : Colors.grey.shade200,
92
+ borderRadius: BorderRadius.circular(12),
93
+ ),
94
+ child: Text(
95
+ message.content,
96
+ style: TextStyle(
97
+ fontSize: 12,
98
+ color: isDark ? AppColors.darkTextTertiary : Colors.grey.shade600,
99
+ fontStyle: FontStyle.italic,
100
+ ),
101
+ textAlign: TextAlign.center,
102
+ ),
103
+ ),
104
+ );
105
+ }
106
+
107
+ Widget _buildContent(BuildContext context) {
108
+ switch (message.type) {
109
+ case MessageType.text:
110
+ if (_isUser) {
111
+ return SelectableText(
112
+ message.content,
113
+ style: const TextStyle(
114
+ fontSize: 15,
115
+ color: Colors.white,
116
+ height: 1.4,
117
+ ),
118
+ );
119
+ }
120
+ return _buildMarkdown(context);
121
+
122
+ case MessageType.voice:
123
+ return _buildVoiceContent(context);
124
+
125
+ case MessageType.image:
126
+ return _buildImageContent(context);
127
+ }
128
+ }
129
+
130
+ Widget _buildMarkdown(BuildContext context) {
131
+ final isDark = Theme.of(context).brightness == Brightness.dark;
132
+ final textColor = isDark ? Colors.white : Colors.black87;
133
+ final codeBackground = isDark
134
+ ? Colors.white.withAlpha(20)
135
+ : Colors.black.withAlpha(15);
136
+
137
+ return MarkdownBody(
138
+ data: message.content,
139
+ selectable: true,
140
+ softLineBreak: true,
141
+ styleSheet: MarkdownStyleSheet(
142
+ p: TextStyle(fontSize: 15, height: 1.4, color: textColor),
143
+ h1: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: textColor),
144
+ h2: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: textColor),
145
+ h3: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: textColor),
146
+ strong: TextStyle(fontWeight: FontWeight.bold, color: textColor),
147
+ em: TextStyle(fontStyle: FontStyle.italic, color: textColor),
148
+ code: TextStyle(
149
+ fontSize: 13,
150
+ fontFamily: 'monospace',
151
+ color: textColor,
152
+ backgroundColor: codeBackground,
153
+ ),
154
+ codeblockDecoration: BoxDecoration(
155
+ color: codeBackground,
156
+ borderRadius: BorderRadius.circular(8),
157
+ ),
158
+ codeblockPadding: const EdgeInsets.all(10),
159
+ listBullet: TextStyle(fontSize: 15, color: textColor),
160
+ blockquoteDecoration: BoxDecoration(
161
+ border: Border(
162
+ left: BorderSide(color: AppColors.accent, width: 3),
163
+ ),
164
+ ),
165
+ blockquotePadding: const EdgeInsets.only(left: 12, top: 4, bottom: 4),
166
+ ),
167
+ onTapLink: (text, href, title) {
168
+ if (href != null) {
169
+ final uri = Uri.tryParse(href);
170
+ if (uri != null) {
171
+ launchUrl(uri, mode: LaunchMode.externalApplication);
172
+ }
173
+ }
174
+ },
175
+ );
176
+ }
177
+
178
+ Widget _buildVoiceContent(BuildContext context) {
179
+ final isDark = Theme.of(context).brightness == Brightness.dark;
180
+
181
+ return Column(
182
+ crossAxisAlignment: CrossAxisAlignment.start,
183
+ children: [
184
+ Row(
185
+ mainAxisSize: MainAxisSize.min,
186
+ children: [
187
+ // Play button
188
+ GestureDetector(
189
+ onTap: onPlay,
190
+ onDoubleTap: onChainPlay,
191
+ child: Container(
192
+ width: 36,
193
+ height: 36,
194
+ decoration: BoxDecoration(
195
+ color: _isUser
196
+ ? Colors.white.withAlpha(50)
197
+ : AppColors.accent.withAlpha(50),
198
+ shape: BoxShape.circle,
199
+ ),
200
+ child: Icon(
201
+ isPlaying ? Icons.pause : Icons.play_arrow,
202
+ color: _isUser ? Colors.white : AppColors.accent,
203
+ size: 20,
204
+ ),
205
+ ),
206
+ ),
207
+ const SizedBox(width: 8),
208
+ // Waveform bars
209
+ SizedBox(
210
+ width: 120,
211
+ height: 24,
212
+ child: Row(
213
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
214
+ children: List.generate(20, (i) {
215
+ final height = 4.0 + 16.0 * sin(i * 0.5).abs();
216
+ return Container(
217
+ width: 3,
218
+ height: height,
219
+ decoration: BoxDecoration(
220
+ color: _isUser
221
+ ? Colors.white.withAlpha(180)
222
+ : (isDark
223
+ ? AppColors.darkTextSecondary
224
+ : AppColors.lightTextSecondary),
225
+ borderRadius: BorderRadius.circular(2),
226
+ ),
227
+ );
228
+ }),
229
+ ),
230
+ ),
231
+ const SizedBox(width: 8),
232
+ // Duration
233
+ if (message.duration != null)
234
+ Text(
235
+ _formatDuration(message.duration!),
236
+ style: TextStyle(
237
+ fontSize: 12,
238
+ color: _isUser
239
+ ? Colors.white70
240
+ : (isDark
241
+ ? AppColors.darkTextTertiary
242
+ : AppColors.lightTextSecondary),
243
+ ),
244
+ ),
245
+ ],
246
+ ),
247
+ // Transcript
248
+ if (message.content.isNotEmpty) ...[
249
+ const SizedBox(height: 8),
250
+ if (_isUser)
251
+ SelectableText(
252
+ message.content,
253
+ style: TextStyle(
254
+ fontSize: 14,
255
+ color: Colors.white.withAlpha(220),
256
+ height: 1.3,
257
+ ),
258
+ )
259
+ else
260
+ _buildMarkdown(context),
261
+ ],
262
+ ],
263
+ );
264
+ }
265
+
266
+ Widget _buildImageContent(BuildContext context) {
267
+ if (message.imageBase64 == null || message.imageBase64!.isEmpty) {
268
+ return const Text('Image unavailable');
269
+ }
270
+
271
+ // Cache decoded bytes to prevent flicker on rebuild; evict oldest if over 50 entries
272
+ if (!_imageCache.containsKey(message.id)) {
273
+ if (_imageCache.length >= 50) {
274
+ _imageCache.remove(_imageCache.keys.first);
275
+ }
276
+ final raw = message.imageBase64!;
277
+ _imageCache[message.id] = Uint8List.fromList(base64Decode(
278
+ raw.contains(',') ? raw.split(',').last : raw,
279
+ ));
280
+ }
281
+ final bytes = _imageCache[message.id]!;
282
+
283
+ return Column(
284
+ crossAxisAlignment: CrossAxisAlignment.start,
285
+ children: [
286
+ GestureDetector(
287
+ onTap: () {
288
+ Navigator.of(context).push(
289
+ MaterialPageRoute(
290
+ builder: (_) => ImageViewer(imageBytes: bytes),
291
+ ),
292
+ );
293
+ },
294
+ child: ClipRRect(
295
+ borderRadius: BorderRadius.circular(8),
296
+ child: Image.memory(
297
+ bytes,
298
+ width: 260,
299
+ height: 180,
300
+ fit: BoxFit.cover,
301
+ gaplessPlayback: true,
302
+ errorBuilder: (_, e, st) => const SizedBox(
303
+ width: 260,
304
+ height: 60,
305
+ child: Center(child: Text('Image decode error')),
306
+ ),
307
+ ),
308
+ ),
309
+ ),
310
+ if (message.content.isNotEmpty) ...[
311
+ const SizedBox(height: 6),
312
+ Text(
313
+ message.content,
314
+ style: TextStyle(
315
+ fontSize: 14,
316
+ color: _isUser ? Colors.white.withAlpha(220) : null,
317
+ height: 1.3,
318
+ ),
319
+ ),
320
+ ],
321
+ ],
322
+ );
323
+ }
324
+
325
+ Widget _buildFooter(BuildContext context) {
326
+ final isDark = Theme.of(context).brightness == Brightness.dark;
327
+ final dt = DateTime.fromMillisecondsSinceEpoch(message.timestamp);
328
+ final time = DateFormat('dd.MM. HH:mm').format(dt);
329
+
330
+ return Row(
331
+ mainAxisSize: MainAxisSize.min,
332
+ children: [
333
+ Text(
334
+ time,
335
+ style: TextStyle(
336
+ fontSize: 11,
337
+ color: _isUser
338
+ ? Colors.white60
339
+ : (isDark
340
+ ? AppColors.darkTextTertiary
341
+ : Colors.grey.shade500),
342
+ ),
343
+ ),
344
+ if (message.status == MessageStatus.sending) ...[
345
+ const SizedBox(width: 4),
346
+ SizedBox(
347
+ width: 10,
348
+ height: 10,
349
+ child: CircularProgressIndicator(
350
+ strokeWidth: 1.5,
351
+ color: _isUser ? Colors.white60 : AppColors.accent,
352
+ ),
353
+ ),
354
+ ],
355
+ if (message.status == MessageStatus.error) ...[
356
+ const SizedBox(width: 4),
357
+ const Icon(Icons.error_outline, size: 14, color: AppColors.error),
358
+ ],
359
+ ],
360
+ );
361
+ }
362
+
363
+ void _showContextMenu(BuildContext context) {
364
+ showModalBottomSheet(
365
+ context: context,
366
+ builder: (ctx) => SafeArea(
367
+ child: Column(
368
+ mainAxisSize: MainAxisSize.min,
369
+ children: [
370
+ ListTile(
371
+ leading: const Icon(Icons.copy),
372
+ title: const Text('Copy'),
373
+ onTap: () {
374
+ Clipboard.setData(ClipboardData(text: message.content));
375
+ Navigator.pop(ctx);
376
+ ScaffoldMessenger.of(context).showSnackBar(
377
+ const SnackBar(
378
+ content: Text('Copied to clipboard'),
379
+ duration: Duration(seconds: 1),
380
+ ),
381
+ );
382
+ },
383
+ ),
384
+ if (onDelete != null)
385
+ ListTile(
386
+ leading: const Icon(Icons.delete_outline, color: AppColors.error),
387
+ title: const Text('Delete', style: TextStyle(color: AppColors.error)),
388
+ onTap: () {
389
+ Navigator.pop(ctx);
390
+ onDelete?.call();
391
+ },
392
+ ),
393
+ ],
394
+ ),
395
+ ),
396
+ );
397
+ }
398
+
399
+ String _formatDuration(int ms) {
400
+ final seconds = (ms / 1000).ceil();
401
+ final m = seconds ~/ 60;
402
+ final s = seconds % 60;
403
+ return '$m:${s.toString().padLeft(2, '0')}';
404
+ }
405
+}
lib/widgets/paywall_banner.dart
....@@ -0,0 +1,116 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:flutter_riverpod/flutter_riverpod.dart';
3
+
4
+import '../providers/providers.dart';
5
+import '../services/purchase_service.dart';
6
+import '../theme/app_theme.dart';
7
+
8
+/// Dismissible banner shown at the top of the chat screen when a free-tier
9
+/// limit has been reached. Tapping "Upgrade" initiates the IAP flow.
10
+class PaywallBanner extends ConsumerStatefulWidget {
11
+ const PaywallBanner({super.key});
12
+
13
+ @override
14
+ ConsumerState<PaywallBanner> createState() => _PaywallBannerState();
15
+}
16
+
17
+class _PaywallBannerState extends ConsumerState<PaywallBanner> {
18
+ bool _dismissed = false;
19
+
20
+ @override
21
+ Widget build(BuildContext context) {
22
+ final isPro = ref.watch(isProProvider);
23
+ if (isPro || _dismissed) return const SizedBox.shrink();
24
+
25
+ final sessions = ref.watch(sessionsProvider);
26
+ if (sessions.length <= kFreeTierMaxSessions) return const SizedBox.shrink();
27
+
28
+ return Material(
29
+ color: Colors.transparent,
30
+ child: Container(
31
+ margin: const EdgeInsets.fromLTRB(8, 4, 8, 0),
32
+ decoration: BoxDecoration(
33
+ color: AppColors.accent.withAlpha(230),
34
+ borderRadius: BorderRadius.circular(10),
35
+ ),
36
+ child: Padding(
37
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
38
+ child: Row(
39
+ children: [
40
+ const Icon(Icons.lock_outline, color: Colors.white, size: 18),
41
+ const SizedBox(width: 8),
42
+ Expanded(
43
+ child: Column(
44
+ crossAxisAlignment: CrossAxisAlignment.start,
45
+ mainAxisSize: MainAxisSize.min,
46
+ children: [
47
+ const Text(
48
+ 'PAILot Pro',
49
+ style: TextStyle(
50
+ color: Colors.white,
51
+ fontWeight: FontWeight.bold,
52
+ fontSize: 13,
53
+ ),
54
+ ),
55
+ const Text(
56
+ 'Unlimited sessions & persistent messages',
57
+ style: TextStyle(color: Colors.white70, fontSize: 11),
58
+ ),
59
+ ],
60
+ ),
61
+ ),
62
+ const SizedBox(width: 8),
63
+ TextButton(
64
+ onPressed: _handleRestore,
65
+ style: TextButton.styleFrom(
66
+ foregroundColor: Colors.white70,
67
+ padding: const EdgeInsets.symmetric(horizontal: 8),
68
+ minimumSize: Size.zero,
69
+ tapTargetSize: MaterialTapTargetSize.shrinkWrap,
70
+ ),
71
+ child: const Text('Restore', style: TextStyle(fontSize: 11)),
72
+ ),
73
+ ElevatedButton(
74
+ onPressed: _handleUpgrade,
75
+ style: ElevatedButton.styleFrom(
76
+ backgroundColor: Colors.white,
77
+ foregroundColor: AppColors.accent,
78
+ padding:
79
+ const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
80
+ minimumSize: Size.zero,
81
+ tapTargetSize: MaterialTapTargetSize.shrinkWrap,
82
+ textStyle: const TextStyle(
83
+ fontSize: 12,
84
+ fontWeight: FontWeight.bold,
85
+ ),
86
+ ),
87
+ child: const Text('Upgrade \$4.99'),
88
+ ),
89
+ const SizedBox(width: 4),
90
+ GestureDetector(
91
+ onTap: () => setState(() => _dismissed = true),
92
+ child: const Icon(Icons.close, color: Colors.white70, size: 16),
93
+ ),
94
+ ],
95
+ ),
96
+ ),
97
+ ),
98
+ );
99
+ }
100
+
101
+ Future<void> _handleUpgrade() async {
102
+ await PurchaseService.instance.purchaseFullAccess();
103
+ }
104
+
105
+ Future<void> _handleRestore() async {
106
+ await PurchaseService.instance.restorePurchases();
107
+ if (mounted) {
108
+ ScaffoldMessenger.of(context).showSnackBar(
109
+ const SnackBar(
110
+ content: Text('Checking for previous purchases...'),
111
+ duration: Duration(seconds: 2),
112
+ ),
113
+ );
114
+ }
115
+ }
116
+}
lib/widgets/session_drawer.dart
....@@ -0,0 +1,293 @@
1
+import 'package:flutter/material.dart';
2
+
3
+import '../models/session.dart';
4
+import '../services/purchase_service.dart';
5
+import '../theme/app_theme.dart';
6
+
7
+/// Side drawer showing session list with reordering, unread badges, and controls.
8
+class SessionDrawer extends StatelessWidget {
9
+ final List<Session> sessions;
10
+ final String? activeSessionId;
11
+ final Map<String, int> unreadCounts;
12
+ final bool isPro;
13
+ final void Function(Session session) onSelect;
14
+ final void Function(Session session) onRemove;
15
+ final void Function(Session session, String newName) onRename;
16
+ final void Function(int oldIndex, int newIndex) onReorder;
17
+ final VoidCallback onNewSession;
18
+ final VoidCallback onRefresh;
19
+ /// Called when the user taps the upgrade prompt in the drawer.
20
+ final VoidCallback? onUpgrade;
21
+
22
+ const SessionDrawer({
23
+ super.key,
24
+ required this.sessions,
25
+ required this.activeSessionId,
26
+ required this.unreadCounts,
27
+ required this.isPro,
28
+ required this.onSelect,
29
+ required this.onRemove,
30
+ required this.onRename,
31
+ required this.onReorder,
32
+ required this.onNewSession,
33
+ required this.onRefresh,
34
+ this.onUpgrade,
35
+ });
36
+
37
+ @override
38
+ Widget build(BuildContext context) {
39
+ final isDark = Theme.of(context).brightness == Brightness.dark;
40
+
41
+ return Drawer(
42
+ child: SafeArea(
43
+ child: Column(
44
+ children: [
45
+ // Header
46
+ Padding(
47
+ padding:
48
+ const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
49
+ child: Row(
50
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
51
+ children: [
52
+ Text(
53
+ 'Sessions',
54
+ style: Theme.of(context).textTheme.titleLarge,
55
+ ),
56
+ IconButton(
57
+ icon: const Icon(Icons.refresh, size: 22),
58
+ onPressed: onRefresh,
59
+ tooltip: 'Refresh sessions',
60
+ ),
61
+ ],
62
+ ),
63
+ ),
64
+ const Divider(height: 1),
65
+ // Session list
66
+ Expanded(
67
+ child: sessions.isEmpty
68
+ ? const Center(
69
+ child: Text(
70
+ 'No sessions',
71
+ style: TextStyle(color: AppColors.darkTextTertiary),
72
+ ),
73
+ )
74
+ : ReorderableListView.builder(
75
+ itemCount: sessions.length,
76
+ onReorder: onReorder,
77
+ buildDefaultDragHandles: false,
78
+ itemBuilder: (context, index) {
79
+ final session = sessions[index];
80
+ final isActive = session.id == activeSessionId;
81
+ final unread = unreadCounts[session.id] ?? 0;
82
+ // Sessions beyond the free limit are locked for free users.
83
+ // We still allow viewing them — just show the upgrade prompt.
84
+ final isLocked =
85
+ !isPro && index >= kFreeTierMaxSessions;
86
+
87
+ return Dismissible(
88
+ key: ValueKey(session.id),
89
+ direction: DismissDirection.endToStart,
90
+ background: Container(
91
+ color: AppColors.error,
92
+ alignment: Alignment.centerRight,
93
+ padding: const EdgeInsets.only(right: 16),
94
+ child: const Icon(Icons.delete,
95
+ color: Colors.white),
96
+ ),
97
+ confirmDismiss: (_) async {
98
+ return await showDialog<bool>(
99
+ context: context,
100
+ builder: (ctx) => AlertDialog(
101
+ title: const Text('Remove session?'),
102
+ content: Text(
103
+ 'Remove "${session.name}" from the list?'),
104
+ actions: [
105
+ TextButton(
106
+ onPressed: () =>
107
+ Navigator.pop(ctx, false),
108
+ child: const Text('Cancel'),
109
+ ),
110
+ TextButton(
111
+ onPressed: () =>
112
+ Navigator.pop(ctx, true),
113
+ child: const Text('Remove',
114
+ style: TextStyle(
115
+ color: AppColors.error)),
116
+ ),
117
+ ],
118
+ ),
119
+ );
120
+ },
121
+ onDismissed: (_) => onRemove(session),
122
+ child: ListTile(
123
+ key: ValueKey('tile_${session.id}'),
124
+ leading: isLocked
125
+ ? const Icon(Icons.lock_outline,
126
+ size: 20,
127
+ color: AppColors.darkTextTertiary)
128
+ : Text(
129
+ session.icon,
130
+ style: const TextStyle(fontSize: 20),
131
+ ),
132
+ title: GestureDetector(
133
+ onDoubleTap: isLocked
134
+ ? null
135
+ : () => _showRenameDialog(context, session),
136
+ child: Text(
137
+ session.name,
138
+ style: TextStyle(
139
+ fontWeight: isActive
140
+ ? FontWeight.bold
141
+ : FontWeight.normal,
142
+ color: isLocked
143
+ ? AppColors.darkTextTertiary
144
+ : isActive
145
+ ? AppColors.accent
146
+ : null,
147
+ ),
148
+ maxLines: 1,
149
+ overflow: TextOverflow.ellipsis,
150
+ ),
151
+ ),
152
+ trailing: isLocked
153
+ ? TextButton(
154
+ onPressed: () {
155
+ Navigator.pop(context);
156
+ onUpgrade?.call();
157
+ },
158
+ style: TextButton.styleFrom(
159
+ foregroundColor: AppColors.accent,
160
+ padding: const EdgeInsets.symmetric(
161
+ horizontal: 8),
162
+ minimumSize: Size.zero,
163
+ tapTargetSize:
164
+ MaterialTapTargetSize.shrinkWrap,
165
+ ),
166
+ child: const Text('Upgrade',
167
+ style: TextStyle(fontSize: 12)),
168
+ )
169
+ : Row(
170
+ mainAxisSize: MainAxisSize.min,
171
+ children: [
172
+ if (unread > 0)
173
+ Container(
174
+ padding: const EdgeInsets.symmetric(
175
+ horizontal: 6, vertical: 2),
176
+ decoration: BoxDecoration(
177
+ color: AppColors.unreadBadge,
178
+ borderRadius:
179
+ BorderRadius.circular(10),
180
+ ),
181
+ child: Text(
182
+ '$unread',
183
+ style: const TextStyle(
184
+ color: Colors.white,
185
+ fontSize: 11,
186
+ fontWeight: FontWeight.bold,
187
+ ),
188
+ ),
189
+ ),
190
+ const SizedBox(width: 4),
191
+ ReorderableDragStartListener(
192
+ index: index,
193
+ child: Icon(
194
+ Icons.drag_handle,
195
+ color: isDark
196
+ ? AppColors.darkTextTertiary
197
+ : Colors.grey.shade400,
198
+ size: 20,
199
+ ),
200
+ ),
201
+ ],
202
+ ),
203
+ selected: isActive,
204
+ selectedTileColor: isDark
205
+ ? Colors.white.withAlpha(10)
206
+ : Colors.blue.withAlpha(15),
207
+ onTap: isLocked
208
+ ? () {
209
+ Navigator.pop(context);
210
+ onUpgrade?.call();
211
+ }
212
+ : () {
213
+ onSelect(session);
214
+ Navigator.pop(context);
215
+ },
216
+ ),
217
+ );
218
+ },
219
+ ),
220
+ ),
221
+ // New session button (or upgrade prompt)
222
+ const Divider(height: 1),
223
+ Padding(
224
+ padding: const EdgeInsets.all(12),
225
+ child: SizedBox(
226
+ width: double.infinity,
227
+ child: !isPro &&
228
+ sessions.length >= kFreeTierMaxSessions
229
+ ? OutlinedButton.icon(
230
+ onPressed: () {
231
+ Navigator.pop(context);
232
+ onUpgrade?.call();
233
+ },
234
+ icon: const Icon(Icons.lock_outline, size: 18),
235
+ label: const Text('Upgrade for More Sessions'),
236
+ style: OutlinedButton.styleFrom(
237
+ foregroundColor: AppColors.accent,
238
+ side: const BorderSide(color: AppColors.accent),
239
+ ),
240
+ )
241
+ : ElevatedButton.icon(
242
+ onPressed: onNewSession,
243
+ icon: const Icon(Icons.add, size: 20),
244
+ label: const Text('New Session'),
245
+ style: ElevatedButton.styleFrom(
246
+ backgroundColor: AppColors.accent,
247
+ foregroundColor: Colors.white,
248
+ ),
249
+ ),
250
+ ),
251
+ ),
252
+ ],
253
+ ),
254
+ ),
255
+ );
256
+ }
257
+
258
+ void _showRenameDialog(BuildContext context, Session session) {
259
+ final controller = TextEditingController(text: session.name);
260
+ showDialog(
261
+ context: context,
262
+ builder: (ctx) => AlertDialog(
263
+ title: const Text('Rename session'),
264
+ content: TextField(
265
+ controller: controller,
266
+ autofocus: true,
267
+ decoration: const InputDecoration(hintText: 'Session name'),
268
+ onSubmitted: (value) {
269
+ if (value.isNotEmpty) {
270
+ onRename(session, value);
271
+ }
272
+ Navigator.pop(ctx);
273
+ },
274
+ ),
275
+ actions: [
276
+ TextButton(
277
+ onPressed: () => Navigator.pop(ctx),
278
+ child: const Text('Cancel'),
279
+ ),
280
+ TextButton(
281
+ onPressed: () {
282
+ if (controller.text.isNotEmpty) {
283
+ onRename(session, controller.text);
284
+ }
285
+ Navigator.pop(ctx);
286
+ },
287
+ child: const Text('Save'),
288
+ ),
289
+ ],
290
+ ),
291
+ ).then((_) => controller.dispose());
292
+ }
293
+}
lib/widgets/status_dot.dart
....@@ -0,0 +1,58 @@
1
+import 'package:flutter/material.dart';
2
+
3
+import '../services/mqtt_service.dart';
4
+import '../theme/app_theme.dart';
5
+
6
+/// 10px circle indicating MQTT connection status.
7
+class StatusDot extends StatelessWidget {
8
+ final ConnectionStatus status;
9
+
10
+ const StatusDot({super.key, required this.status});
11
+
12
+ Color get _color {
13
+ switch (status) {
14
+ case ConnectionStatus.connected:
15
+ return AppColors.connected;
16
+ case ConnectionStatus.connecting:
17
+ case ConnectionStatus.reconnecting:
18
+ return AppColors.connecting;
19
+ case ConnectionStatus.disconnected:
20
+ return AppColors.disconnected;
21
+ }
22
+ }
23
+
24
+ String get _tooltip {
25
+ switch (status) {
26
+ case ConnectionStatus.connected:
27
+ return 'Connected';
28
+ case ConnectionStatus.connecting:
29
+ return 'Connecting...';
30
+ case ConnectionStatus.reconnecting:
31
+ return 'Reconnecting...';
32
+ case ConnectionStatus.disconnected:
33
+ return 'Disconnected';
34
+ }
35
+ }
36
+
37
+ @override
38
+ Widget build(BuildContext context) {
39
+ return Tooltip(
40
+ message: _tooltip,
41
+ child: Container(
42
+ width: 10,
43
+ height: 10,
44
+ decoration: BoxDecoration(
45
+ color: _color,
46
+ shape: BoxShape.circle,
47
+ boxShadow: [
48
+ BoxShadow(
49
+ color: _color.withAlpha(100),
50
+ blurRadius: 4,
51
+ spreadRadius: 1,
52
+ ),
53
+ ],
54
+ ),
55
+ ),
56
+ );
57
+ }
58
+}
lib/widgets/toast_overlay.dart
....@@ -0,0 +1,185 @@
1
+import 'dart:async';
2
+
3
+import 'package:flutter/material.dart';
4
+
5
+import '../theme/app_theme.dart';
6
+
7
+/// Slide-in toast for cross-session incoming messages.
8
+class ToastOverlay extends StatefulWidget {
9
+ final String sessionName;
10
+ final String preview;
11
+ final VoidCallback onTap;
12
+ final VoidCallback onDismiss;
13
+
14
+ const ToastOverlay({
15
+ super.key,
16
+ required this.sessionName,
17
+ required this.preview,
18
+ required this.onTap,
19
+ required this.onDismiss,
20
+ });
21
+
22
+ @override
23
+ State<ToastOverlay> createState() => _ToastOverlayState();
24
+}
25
+
26
+class _ToastOverlayState extends State<ToastOverlay>
27
+ with SingleTickerProviderStateMixin {
28
+ late final AnimationController _controller;
29
+ late final Animation<Offset> _slideAnimation;
30
+ Timer? _autoDismiss;
31
+
32
+ @override
33
+ void initState() {
34
+ super.initState();
35
+ _controller = AnimationController(
36
+ vsync: this,
37
+ duration: const Duration(milliseconds: 300),
38
+ );
39
+ _slideAnimation = Tween<Offset>(
40
+ begin: const Offset(0, -1),
41
+ end: Offset.zero,
42
+ ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic));
43
+
44
+ _controller.forward();
45
+ _autoDismiss = Timer(const Duration(seconds: 4), _dismiss);
46
+ }
47
+
48
+ void _dismiss() {
49
+ _autoDismiss?.cancel();
50
+ _controller.reverse().then((_) {
51
+ widget.onDismiss();
52
+ });
53
+ }
54
+
55
+ @override
56
+ void dispose() {
57
+ _autoDismiss?.cancel();
58
+ _controller.dispose();
59
+ super.dispose();
60
+ }
61
+
62
+ @override
63
+ Widget build(BuildContext context) {
64
+ return SlideTransition(
65
+ position: _slideAnimation,
66
+ child: SafeArea(
67
+ bottom: false,
68
+ child: GestureDetector(
69
+ onTap: () {
70
+ _autoDismiss?.cancel();
71
+ widget.onTap();
72
+ },
73
+ onVerticalDragEnd: (details) {
74
+ if (details.primaryVelocity != null &&
75
+ details.primaryVelocity! < -100) {
76
+ _dismiss();
77
+ }
78
+ },
79
+ child: Container(
80
+ margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
81
+ padding: const EdgeInsets.all(12),
82
+ decoration: BoxDecoration(
83
+ color: AppColors.darkSurface,
84
+ borderRadius: BorderRadius.circular(12),
85
+ boxShadow: [
86
+ BoxShadow(
87
+ color: Colors.black.withAlpha(80),
88
+ blurRadius: 12,
89
+ offset: const Offset(0, 4),
90
+ ),
91
+ ],
92
+ ),
93
+ child: Row(
94
+ children: [
95
+ Container(
96
+ width: 36,
97
+ height: 36,
98
+ decoration: const BoxDecoration(
99
+ color: AppColors.accent,
100
+ shape: BoxShape.circle,
101
+ ),
102
+ child: const Icon(
103
+ Icons.chat_bubble_outline,
104
+ color: Colors.white,
105
+ size: 18,
106
+ ),
107
+ ),
108
+ const SizedBox(width: 12),
109
+ Expanded(
110
+ child: Column(
111
+ crossAxisAlignment: CrossAxisAlignment.start,
112
+ mainAxisSize: MainAxisSize.min,
113
+ children: [
114
+ Text(
115
+ widget.sessionName,
116
+ style: const TextStyle(
117
+ color: Colors.white,
118
+ fontWeight: FontWeight.w600,
119
+ fontSize: 13,
120
+ ),
121
+ ),
122
+ const SizedBox(height: 2),
123
+ Text(
124
+ widget.preview,
125
+ style: const TextStyle(
126
+ color: AppColors.darkTextSecondary,
127
+ fontSize: 12,
128
+ ),
129
+ maxLines: 2,
130
+ overflow: TextOverflow.ellipsis,
131
+ ),
132
+ ],
133
+ ),
134
+ ),
135
+ ],
136
+ ),
137
+ ),
138
+ ),
139
+ ),
140
+ );
141
+ }
142
+}
143
+
144
+/// Global toast manager for showing cross-session notifications.
145
+class ToastManager {
146
+ ToastManager._();
147
+
148
+ static OverlayEntry? _currentEntry;
149
+
150
+ static void show(
151
+ BuildContext context, {
152
+ required String sessionName,
153
+ required String preview,
154
+ required VoidCallback onTap,
155
+ }) {
156
+ dismiss();
157
+
158
+ _currentEntry = OverlayEntry(
159
+ builder: (ctx) => Positioned(
160
+ top: 0,
161
+ left: 0,
162
+ right: 0,
163
+ child: Material(
164
+ color: Colors.transparent,
165
+ child: ToastOverlay(
166
+ sessionName: sessionName,
167
+ preview: preview,
168
+ onTap: () {
169
+ dismiss();
170
+ onTap();
171
+ },
172
+ onDismiss: dismiss,
173
+ ),
174
+ ),
175
+ ),
176
+ );
177
+
178
+ Overlay.of(context).insert(_currentEntry!);
179
+ }
180
+
181
+ static void dismiss() {
182
+ _currentEntry?.remove();
183
+ _currentEntry = null;
184
+ }
185
+}
lib/widgets/typing_indicator.dart
....@@ -0,0 +1,89 @@
1
+import 'package:flutter/material.dart';
2
+
3
+import '../theme/app_theme.dart';
4
+
5
+/// Animated 3-dot typing indicator styled as an assistant bubble.
6
+class TypingIndicator extends StatefulWidget {
7
+ const TypingIndicator({super.key});
8
+
9
+ @override
10
+ State<TypingIndicator> createState() => _TypingIndicatorState();
11
+}
12
+
13
+class _TypingIndicatorState extends State<TypingIndicator>
14
+ with SingleTickerProviderStateMixin {
15
+ late final AnimationController _controller;
16
+
17
+ @override
18
+ void initState() {
19
+ super.initState();
20
+ _controller = AnimationController(
21
+ vsync: this,
22
+ duration: const Duration(milliseconds: 1200),
23
+ )..repeat();
24
+ }
25
+
26
+ @override
27
+ void dispose() {
28
+ _controller.dispose();
29
+ super.dispose();
30
+ }
31
+
32
+ @override
33
+ Widget build(BuildContext context) {
34
+ final isDark = Theme.of(context).brightness == Brightness.dark;
35
+
36
+ return Align(
37
+ alignment: Alignment.centerLeft,
38
+ child: Container(
39
+ margin: const EdgeInsets.only(left: 16, bottom: 8, right: 80),
40
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
41
+ decoration: BoxDecoration(
42
+ color: isDark ? AppColors.assistantBubble : AppColors.lightAssistantBubble,
43
+ borderRadius: const BorderRadius.only(
44
+ topLeft: Radius.circular(16),
45
+ topRight: Radius.circular(16),
46
+ bottomRight: Radius.circular(16),
47
+ bottomLeft: Radius.circular(4),
48
+ ),
49
+ ),
50
+ child: AnimatedBuilder(
51
+ animation: _controller,
52
+ builder: (context, _) {
53
+ return Row(
54
+ mainAxisSize: MainAxisSize.min,
55
+ children: List.generate(3, (i) {
56
+ final delay = i * 0.2;
57
+ final t = (_controller.value - delay).clamp(0.0, 1.0);
58
+ // Bounce: sin wave for smooth up/down
59
+ final offset = -4.0 * _bounce(t);
60
+ return Transform.translate(
61
+ offset: Offset(0, offset),
62
+ child: Container(
63
+ width: 8,
64
+ height: 8,
65
+ margin: EdgeInsets.only(right: i < 2 ? 4 : 0),
66
+ decoration: BoxDecoration(
67
+ color: isDark
68
+ ? AppColors.darkTextSecondary
69
+ : AppColors.lightTextSecondary,
70
+ shape: BoxShape.circle,
71
+ ),
72
+ ),
73
+ );
74
+ }),
75
+ );
76
+ },
77
+ ),
78
+ ),
79
+ );
80
+ }
81
+
82
+ double _bounce(double t) {
83
+ // Simple sine bounce
84
+ if (t <= 0 || t >= 1) return 0;
85
+ return (t < 0.5)
86
+ ? (t * 2) * (t * 2) // ease in
87
+ : 1 - ((t - 0.5) * 2) * ((t - 0.5) * 2); // ease out
88
+ }
89
+}
lib/widgets/voice_button.dart
....@@ -0,0 +1,138 @@
1
+import 'dart:async';
2
+
3
+import 'package:flutter/material.dart';
4
+import 'package:vibration/vibration.dart';
5
+
6
+import '../theme/app_theme.dart';
7
+
8
+/// Large circular talk button. Tap to toggle recording.
9
+/// Long-press while recording (600ms) cancels.
10
+class VoiceButton extends StatefulWidget {
11
+ final bool isRecording;
12
+ final VoidCallback onTapStart;
13
+ final VoidCallback onTapStop;
14
+ final VoidCallback onCancel;
15
+
16
+ const VoiceButton({
17
+ super.key,
18
+ required this.isRecording,
19
+ required this.onTapStart,
20
+ required this.onTapStop,
21
+ required this.onCancel,
22
+ });
23
+
24
+ @override
25
+ State<VoiceButton> createState() => _VoiceButtonState();
26
+}
27
+
28
+class _VoiceButtonState extends State<VoiceButton>
29
+ with SingleTickerProviderStateMixin {
30
+ late final AnimationController _pulseController;
31
+ Timer? _longPressTimer;
32
+
33
+ @override
34
+ void initState() {
35
+ super.initState();
36
+ _pulseController = AnimationController(
37
+ vsync: this,
38
+ duration: const Duration(milliseconds: 1500),
39
+ );
40
+ }
41
+
42
+ @override
43
+ void didUpdateWidget(VoiceButton oldWidget) {
44
+ super.didUpdateWidget(oldWidget);
45
+ if (widget.isRecording && !oldWidget.isRecording) {
46
+ _pulseController.repeat(reverse: true);
47
+ } else if (!widget.isRecording && oldWidget.isRecording) {
48
+ _pulseController.stop();
49
+ _pulseController.value = 0;
50
+ }
51
+ }
52
+
53
+ @override
54
+ void dispose() {
55
+ _pulseController.dispose();
56
+ _longPressTimer?.cancel();
57
+ super.dispose();
58
+ }
59
+
60
+ void _onTap() {
61
+ if (widget.isRecording) {
62
+ widget.onTapStop();
63
+ } else {
64
+ widget.onTapStart();
65
+ }
66
+ _haptic();
67
+ }
68
+
69
+ void _onLongPressStart(LongPressStartDetails _) {
70
+ if (widget.isRecording) {
71
+ _longPressTimer = Timer(const Duration(milliseconds: 600), () {
72
+ widget.onCancel();
73
+ _haptic();
74
+ });
75
+ }
76
+ }
77
+
78
+ void _onLongPressEnd(LongPressEndDetails _) {
79
+ _longPressTimer?.cancel();
80
+ }
81
+
82
+ Future<void> _haptic() async {
83
+ try {
84
+ final hasVibrator = await Vibration.hasVibrator();
85
+ if (hasVibrator) {
86
+ Vibration.vibrate(duration: 20);
87
+ }
88
+ } catch (_) {}
89
+ }
90
+
91
+ @override
92
+ Widget build(BuildContext context) {
93
+ return GestureDetector(
94
+ onTap: _onTap,
95
+ onLongPressStart: _onLongPressStart,
96
+ onLongPressEnd: _onLongPressEnd,
97
+ child: AnimatedBuilder(
98
+ animation: _pulseController,
99
+ builder: (context, child) {
100
+ final glowRadius = widget.isRecording
101
+ ? 8.0 + (_pulseController.value * 12.0)
102
+ : 0.0;
103
+
104
+ return Container(
105
+ width: 72,
106
+ height: 72,
107
+ decoration: BoxDecoration(
108
+ color: widget.isRecording
109
+ ? AppColors.recording
110
+ : AppColors.accent,
111
+ shape: BoxShape.circle,
112
+ boxShadow: widget.isRecording
113
+ ? [
114
+ BoxShadow(
115
+ color: AppColors.recordingGlow,
116
+ blurRadius: glowRadius,
117
+ spreadRadius: glowRadius / 2,
118
+ ),
119
+ ]
120
+ : [
121
+ BoxShadow(
122
+ color: AppColors.accent.withAlpha(60),
123
+ blurRadius: 8,
124
+ spreadRadius: 2,
125
+ ),
126
+ ],
127
+ ),
128
+ child: Icon(
129
+ widget.isRecording ? Icons.stop : Icons.mic,
130
+ color: Colors.white,
131
+ size: 32,
132
+ ),
133
+ );
134
+ },
135
+ ),
136
+ );
137
+ }
138
+}
linux/.gitignore
....@@ -0,0 +1 @@
1
+flutter/ephemeral
linux/CMakeLists.txt
....@@ -0,0 +1,128 @@
1
+# Project-level configuration.
2
+cmake_minimum_required(VERSION 3.13)
3
+project(runner LANGUAGES CXX)
4
+
5
+# The name of the executable created for the application. Change this to change
6
+# the on-disk name of your application.
7
+set(BINARY_NAME "pailot")
8
+# The unique GTK application identifier for this application. See:
9
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
10
+set(APPLICATION_ID "com.tekmidian.pailot")
11
+
12
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
13
+# versions of CMake.
14
+cmake_policy(SET CMP0063 NEW)
15
+
16
+# Load bundled libraries from the lib/ directory relative to the binary.
17
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
18
+
19
+# Root filesystem for cross-building.
20
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
21
+ set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
22
+ set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
23
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
24
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
25
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
26
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
27
+endif()
28
+
29
+# Define build configuration options.
30
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
31
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
32
+ STRING "Flutter build mode" FORCE)
33
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
34
+ "Debug" "Profile" "Release")
35
+endif()
36
+
37
+# Compilation settings that should be applied to most targets.
38
+#
39
+# Be cautious about adding new options here, as plugins use this function by
40
+# default. In most cases, you should add new options to specific targets instead
41
+# of modifying this function.
42
+function(APPLY_STANDARD_SETTINGS TARGET)
43
+ target_compile_features(${TARGET} PUBLIC cxx_std_14)
44
+ target_compile_options(${TARGET} PRIVATE -Wall -Werror)
45
+ target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
46
+ target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
47
+endfunction()
48
+
49
+# Flutter library and tool build rules.
50
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
51
+add_subdirectory(${FLUTTER_MANAGED_DIR})
52
+
53
+# System-level dependencies.
54
+find_package(PkgConfig REQUIRED)
55
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
56
+
57
+# Application build; see runner/CMakeLists.txt.
58
+add_subdirectory("runner")
59
+
60
+# Run the Flutter tool portions of the build. This must not be removed.
61
+add_dependencies(${BINARY_NAME} flutter_assemble)
62
+
63
+# Only the install-generated bundle's copy of the executable will launch
64
+# correctly, since the resources must in the right relative locations. To avoid
65
+# people trying to run the unbundled copy, put it in a subdirectory instead of
66
+# the default top-level location.
67
+set_target_properties(${BINARY_NAME}
68
+ PROPERTIES
69
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
70
+)
71
+
72
+
73
+# Generated plugin build rules, which manage building the plugins and adding
74
+# them to the application.
75
+include(flutter/generated_plugins.cmake)
76
+
77
+
78
+# === Installation ===
79
+# By default, "installing" just makes a relocatable bundle in the build
80
+# directory.
81
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
82
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
83
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
84
+endif()
85
+
86
+# Start with a clean build bundle directory every time.
87
+install(CODE "
88
+ file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
89
+ " COMPONENT Runtime)
90
+
91
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
92
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
93
+
94
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
95
+ COMPONENT Runtime)
96
+
97
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
98
+ COMPONENT Runtime)
99
+
100
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
101
+ COMPONENT Runtime)
102
+
103
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
104
+ install(FILES "${bundled_library}"
105
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
106
+ COMPONENT Runtime)
107
+endforeach(bundled_library)
108
+
109
+# Copy the native assets provided by the build.dart from all packages.
110
+set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
111
+install(DIRECTORY "${NATIVE_ASSETS_DIR}"
112
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
113
+ COMPONENT Runtime)
114
+
115
+# Fully re-copy the assets directory on each build to avoid having stale files
116
+# from a previous install.
117
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
118
+install(CODE "
119
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
120
+ " COMPONENT Runtime)
121
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
122
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
123
+
124
+# Install the AOT library on non-Debug builds only.
125
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
126
+ install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
127
+ COMPONENT Runtime)
128
+endif()
linux/flutter/CMakeLists.txt
....@@ -0,0 +1,88 @@
1
+# This file controls Flutter-level build steps. It should not be edited.
2
+cmake_minimum_required(VERSION 3.10)
3
+
4
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
5
+
6
+# Configuration provided via flutter tool.
7
+include(${EPHEMERAL_DIR}/generated_config.cmake)
8
+
9
+# TODO: Move the rest of this into files in ephemeral. See
10
+# https://github.com/flutter/flutter/issues/57146.
11
+
12
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
13
+# which isn't available in 3.10.
14
+function(list_prepend LIST_NAME PREFIX)
15
+ set(NEW_LIST "")
16
+ foreach(element ${${LIST_NAME}})
17
+ list(APPEND NEW_LIST "${PREFIX}${element}")
18
+ endforeach(element)
19
+ set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
20
+endfunction()
21
+
22
+# === Flutter Library ===
23
+# System-level dependencies.
24
+find_package(PkgConfig REQUIRED)
25
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
26
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
27
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
28
+
29
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
30
+
31
+# Published to parent scope for install step.
32
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
33
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
34
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
35
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
36
+
37
+list(APPEND FLUTTER_LIBRARY_HEADERS
38
+ "fl_basic_message_channel.h"
39
+ "fl_binary_codec.h"
40
+ "fl_binary_messenger.h"
41
+ "fl_dart_project.h"
42
+ "fl_engine.h"
43
+ "fl_json_message_codec.h"
44
+ "fl_json_method_codec.h"
45
+ "fl_message_codec.h"
46
+ "fl_method_call.h"
47
+ "fl_method_channel.h"
48
+ "fl_method_codec.h"
49
+ "fl_method_response.h"
50
+ "fl_plugin_registrar.h"
51
+ "fl_plugin_registry.h"
52
+ "fl_standard_message_codec.h"
53
+ "fl_standard_method_codec.h"
54
+ "fl_string_codec.h"
55
+ "fl_value.h"
56
+ "fl_view.h"
57
+ "flutter_linux.h"
58
+)
59
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
60
+add_library(flutter INTERFACE)
61
+target_include_directories(flutter INTERFACE
62
+ "${EPHEMERAL_DIR}"
63
+)
64
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
65
+target_link_libraries(flutter INTERFACE
66
+ PkgConfig::GTK
67
+ PkgConfig::GLIB
68
+ PkgConfig::GIO
69
+)
70
+add_dependencies(flutter flutter_assemble)
71
+
72
+# === Flutter tool backend ===
73
+# _phony_ is a non-existent file to force this command to run every time,
74
+# since currently there's no way to get a full input/output list from the
75
+# flutter tool.
76
+add_custom_command(
77
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
78
+ ${CMAKE_CURRENT_BINARY_DIR}/_phony_
79
+ COMMAND ${CMAKE_COMMAND} -E env
80
+ ${FLUTTER_TOOL_ENVIRONMENT}
81
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
82
+ ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
83
+ VERBATIM
84
+)
85
+add_custom_target(flutter_assemble DEPENDS
86
+ "${FLUTTER_LIBRARY}"
87
+ ${FLUTTER_LIBRARY_HEADERS}
88
+)
linux/flutter/generated_plugin_registrant.cc
....@@ -0,0 +1,31 @@
1
+//
2
+// Generated file. Do not edit.
3
+//
4
+
5
+// clang-format off
6
+
7
+#include "generated_plugin_registrant.h"
8
+
9
+#include <audioplayers_linux/audioplayers_linux_plugin.h>
10
+#include <file_selector_linux/file_selector_plugin.h>
11
+#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
12
+#include <record_linux/record_linux_plugin.h>
13
+#include <url_launcher_linux/url_launcher_plugin.h>
14
+
15
+void fl_register_plugins(FlPluginRegistry* registry) {
16
+ g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
17
+ fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
18
+ audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
19
+ g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
20
+ fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
21
+ file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
22
+ g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
23
+ fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
24
+ flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
25
+ g_autoptr(FlPluginRegistrar) record_linux_registrar =
26
+ fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin");
27
+ record_linux_plugin_register_with_registrar(record_linux_registrar);
28
+ g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
29
+ fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
30
+ url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
31
+}
linux/flutter/generated_plugin_registrant.h
....@@ -0,0 +1,15 @@
1
+//
2
+// Generated file. Do not edit.
3
+//
4
+
5
+// clang-format off
6
+
7
+#ifndef GENERATED_PLUGIN_REGISTRANT_
8
+#define GENERATED_PLUGIN_REGISTRANT_
9
+
10
+#include <flutter_linux/flutter_linux.h>
11
+
12
+// Registers Flutter plugins.
13
+void fl_register_plugins(FlPluginRegistry* registry);
14
+
15
+#endif // GENERATED_PLUGIN_REGISTRANT_
linux/flutter/generated_plugins.cmake
....@@ -0,0 +1,28 @@
1
+#
2
+# Generated file, do not edit.
3
+#
4
+
5
+list(APPEND FLUTTER_PLUGIN_LIST
6
+ audioplayers_linux
7
+ file_selector_linux
8
+ flutter_secure_storage_linux
9
+ record_linux
10
+ url_launcher_linux
11
+)
12
+
13
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
14
+)
15
+
16
+set(PLUGIN_BUNDLED_LIBRARIES)
17
+
18
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
19
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
20
+ target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
21
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
22
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
23
+endforeach(plugin)
24
+
25
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
26
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
27
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
28
+endforeach(ffi_plugin)
linux/runner/CMakeLists.txt
....@@ -0,0 +1,26 @@
1
+cmake_minimum_required(VERSION 3.13)
2
+project(runner LANGUAGES CXX)
3
+
4
+# Define the application target. To change its name, change BINARY_NAME in the
5
+# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
6
+# work.
7
+#
8
+# Any new source files that you add to the application should be added here.
9
+add_executable(${BINARY_NAME}
10
+ "main.cc"
11
+ "my_application.cc"
12
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
13
+)
14
+
15
+# Apply the standard set of build settings. This can be removed for applications
16
+# that need different build settings.
17
+apply_standard_settings(${BINARY_NAME})
18
+
19
+# Add preprocessor definitions for the application ID.
20
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
21
+
22
+# Add dependency libraries. Add any application-specific dependencies here.
23
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
24
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
25
+
26
+target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
linux/runner/main.cc
....@@ -0,0 +1,6 @@
1
+#include "my_application.h"
2
+
3
+int main(int argc, char** argv) {
4
+ g_autoptr(MyApplication) app = my_application_new();
5
+ return g_application_run(G_APPLICATION(app), argc, argv);
6
+}
linux/runner/my_application.cc
....@@ -0,0 +1,148 @@
1
+#include "my_application.h"
2
+
3
+#include <flutter_linux/flutter_linux.h>
4
+#ifdef GDK_WINDOWING_X11
5
+#include <gdk/gdkx.h>
6
+#endif
7
+
8
+#include "flutter/generated_plugin_registrant.h"
9
+
10
+struct _MyApplication {
11
+ GtkApplication parent_instance;
12
+ char** dart_entrypoint_arguments;
13
+};
14
+
15
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
16
+
17
+// Called when first Flutter frame received.
18
+static void first_frame_cb(MyApplication* self, FlView* view) {
19
+ gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view)));
20
+}
21
+
22
+// Implements GApplication::activate.
23
+static void my_application_activate(GApplication* application) {
24
+ MyApplication* self = MY_APPLICATION(application);
25
+ GtkWindow* window =
26
+ GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
27
+
28
+ // Use a header bar when running in GNOME as this is the common style used
29
+ // by applications and is the setup most users will be using (e.g. Ubuntu
30
+ // desktop).
31
+ // If running on X and not using GNOME then just use a traditional title bar
32
+ // in case the window manager does more exotic layout, e.g. tiling.
33
+ // If running on Wayland assume the header bar will work (may need changing
34
+ // if future cases occur).
35
+ gboolean use_header_bar = TRUE;
36
+#ifdef GDK_WINDOWING_X11
37
+ GdkScreen* screen = gtk_window_get_screen(window);
38
+ if (GDK_IS_X11_SCREEN(screen)) {
39
+ const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
40
+ if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
41
+ use_header_bar = FALSE;
42
+ }
43
+ }
44
+#endif
45
+ if (use_header_bar) {
46
+ GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
47
+ gtk_widget_show(GTK_WIDGET(header_bar));
48
+ gtk_header_bar_set_title(header_bar, "pailot");
49
+ gtk_header_bar_set_show_close_button(header_bar, TRUE);
50
+ gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
51
+ } else {
52
+ gtk_window_set_title(window, "pailot");
53
+ }
54
+
55
+ gtk_window_set_default_size(window, 1280, 720);
56
+
57
+ g_autoptr(FlDartProject) project = fl_dart_project_new();
58
+ fl_dart_project_set_dart_entrypoint_arguments(
59
+ project, self->dart_entrypoint_arguments);
60
+
61
+ FlView* view = fl_view_new(project);
62
+ GdkRGBA background_color;
63
+ // Background defaults to black, override it here if necessary, e.g. #00000000
64
+ // for transparent.
65
+ gdk_rgba_parse(&background_color, "#000000");
66
+ fl_view_set_background_color(view, &background_color);
67
+ gtk_widget_show(GTK_WIDGET(view));
68
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
69
+
70
+ // Show the window when Flutter renders.
71
+ // Requires the view to be realized so we can start rendering.
72
+ g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb),
73
+ self);
74
+ gtk_widget_realize(GTK_WIDGET(view));
75
+
76
+ fl_register_plugins(FL_PLUGIN_REGISTRY(view));
77
+
78
+ gtk_widget_grab_focus(GTK_WIDGET(view));
79
+}
80
+
81
+// Implements GApplication::local_command_line.
82
+static gboolean my_application_local_command_line(GApplication* application,
83
+ gchar*** arguments,
84
+ int* exit_status) {
85
+ MyApplication* self = MY_APPLICATION(application);
86
+ // Strip out the first argument as it is the binary name.
87
+ self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
88
+
89
+ g_autoptr(GError) error = nullptr;
90
+ if (!g_application_register(application, nullptr, &error)) {
91
+ g_warning("Failed to register: %s", error->message);
92
+ *exit_status = 1;
93
+ return TRUE;
94
+ }
95
+
96
+ g_application_activate(application);
97
+ *exit_status = 0;
98
+
99
+ return TRUE;
100
+}
101
+
102
+// Implements GApplication::startup.
103
+static void my_application_startup(GApplication* application) {
104
+ // MyApplication* self = MY_APPLICATION(object);
105
+
106
+ // Perform any actions required at application startup.
107
+
108
+ G_APPLICATION_CLASS(my_application_parent_class)->startup(application);
109
+}
110
+
111
+// Implements GApplication::shutdown.
112
+static void my_application_shutdown(GApplication* application) {
113
+ // MyApplication* self = MY_APPLICATION(object);
114
+
115
+ // Perform any actions required at application shutdown.
116
+
117
+ G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application);
118
+}
119
+
120
+// Implements GObject::dispose.
121
+static void my_application_dispose(GObject* object) {
122
+ MyApplication* self = MY_APPLICATION(object);
123
+ g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
124
+ G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
125
+}
126
+
127
+static void my_application_class_init(MyApplicationClass* klass) {
128
+ G_APPLICATION_CLASS(klass)->activate = my_application_activate;
129
+ G_APPLICATION_CLASS(klass)->local_command_line =
130
+ my_application_local_command_line;
131
+ G_APPLICATION_CLASS(klass)->startup = my_application_startup;
132
+ G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown;
133
+ G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
134
+}
135
+
136
+static void my_application_init(MyApplication* self) {}
137
+
138
+MyApplication* my_application_new() {
139
+ // Set the program name to the application ID, which helps various systems
140
+ // like GTK and desktop environments map this running application to its
141
+ // corresponding .desktop file. This ensures better integration by allowing
142
+ // the application to be recognized beyond its binary name.
143
+ g_set_prgname(APPLICATION_ID);
144
+
145
+ return MY_APPLICATION(g_object_new(my_application_get_type(),
146
+ "application-id", APPLICATION_ID, "flags",
147
+ G_APPLICATION_NON_UNIQUE, nullptr));
148
+}
linux/runner/my_application.h
....@@ -0,0 +1,21 @@
1
+#ifndef FLUTTER_MY_APPLICATION_H_
2
+#define FLUTTER_MY_APPLICATION_H_
3
+
4
+#include <gtk/gtk.h>
5
+
6
+G_DECLARE_FINAL_TYPE(MyApplication,
7
+ my_application,
8
+ MY,
9
+ APPLICATION,
10
+ GtkApplication)
11
+
12
+/**
13
+ * my_application_new:
14
+ *
15
+ * Creates a new Flutter-based application.
16
+ *
17
+ * Returns: a new #MyApplication.
18
+ */
19
+MyApplication* my_application_new();
20
+
21
+#endif // FLUTTER_MY_APPLICATION_H_
macos/.gitignore
....@@ -0,0 +1,7 @@
1
+# Flutter-related
2
+**/Flutter/ephemeral/
3
+**/Pods/
4
+
5
+# Xcode-related
6
+**/dgph
7
+**/xcuserdata/
macos/Flutter/Flutter-Debug.xcconfig
....@@ -0,0 +1,2 @@
1
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2
+#include "ephemeral/Flutter-Generated.xcconfig"
macos/Flutter/Flutter-Release.xcconfig
....@@ -0,0 +1,2 @@
1
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2
+#include "ephemeral/Flutter-Generated.xcconfig"
macos/Flutter/GeneratedPluginRegistrant.swift
....@@ -0,0 +1,38 @@
1
+//
2
+// Generated file. Do not edit.
3
+//
4
+
5
+import FlutterMacOS
6
+import Foundation
7
+
8
+import audioplayers_darwin
9
+import bonsoir_darwin
10
+import connectivity_plus
11
+import device_info_plus
12
+import file_picker
13
+import file_selector_macos
14
+import flutter_app_badger
15
+import flutter_secure_storage_macos
16
+import in_app_purchase_storekit
17
+import push
18
+import record_macos
19
+import share_plus
20
+import shared_preferences_foundation
21
+import url_launcher_macos
22
+
23
+func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
24
+ AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
25
+ SwiftBonsoirPlugin.register(with: registry.registrar(forPlugin: "SwiftBonsoirPlugin"))
26
+ ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
27
+ DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
28
+ FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
29
+ FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
30
+ FlutterAppBadgerPlugin.register(with: registry.registrar(forPlugin: "FlutterAppBadgerPlugin"))
31
+ FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
32
+ InAppPurchasePlugin.register(with: registry.registrar(forPlugin: "InAppPurchasePlugin"))
33
+ PushPlugin.register(with: registry.registrar(forPlugin: "PushPlugin"))
34
+ RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))
35
+ SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
36
+ SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
37
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
38
+}
macos/Podfile
....@@ -0,0 +1,42 @@
1
+platform :osx, '10.15'
2
+
3
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5
+
6
+project 'Runner', {
7
+ 'Debug' => :debug,
8
+ 'Profile' => :release,
9
+ 'Release' => :release,
10
+}
11
+
12
+def flutter_root
13
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14
+ unless File.exist?(generated_xcode_build_settings_path)
15
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16
+ end
17
+
18
+ File.foreach(generated_xcode_build_settings_path) do |line|
19
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
20
+ return matches[1].strip if matches
21
+ end
22
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23
+end
24
+
25
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26
+
27
+flutter_macos_podfile_setup
28
+
29
+target 'Runner' do
30
+ use_frameworks!
31
+
32
+ flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
33
+ target 'RunnerTests' do
34
+ inherit! :search_paths
35
+ end
36
+end
37
+
38
+post_install do |installer|
39
+ installer.pods_project.targets.each do |target|
40
+ flutter_additional_macos_build_settings(target)
41
+ end
42
+end
macos/Runner.xcodeproj/project.pbxproj
....@@ -0,0 +1,705 @@
1
+// !$*UTF8*$!
2
+{
3
+ archiveVersion = 1;
4
+ classes = {
5
+ };
6
+ objectVersion = 54;
7
+ objects = {
8
+
9
+/* Begin PBXAggregateTarget section */
10
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
11
+ isa = PBXAggregateTarget;
12
+ buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
13
+ buildPhases = (
14
+ 33CC111E2044C6BF0003C045 /* ShellScript */,
15
+ );
16
+ dependencies = (
17
+ );
18
+ name = "Flutter Assemble";
19
+ productName = FLX;
20
+ };
21
+/* End PBXAggregateTarget section */
22
+
23
+/* Begin PBXBuildFile section */
24
+ 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
25
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
26
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
27
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
28
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
29
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
30
+/* End PBXBuildFile section */
31
+
32
+/* Begin PBXContainerItemProxy section */
33
+ 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = {
34
+ isa = PBXContainerItemProxy;
35
+ containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
36
+ proxyType = 1;
37
+ remoteGlobalIDString = 33CC10EC2044A3C60003C045;
38
+ remoteInfo = Runner;
39
+ };
40
+ 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
41
+ isa = PBXContainerItemProxy;
42
+ containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
43
+ proxyType = 1;
44
+ remoteGlobalIDString = 33CC111A2044C6BA0003C045;
45
+ remoteInfo = FLX;
46
+ };
47
+/* End PBXContainerItemProxy section */
48
+
49
+/* Begin PBXCopyFilesBuildPhase section */
50
+ 33CC110E2044A8840003C045 /* Bundle Framework */ = {
51
+ isa = PBXCopyFilesBuildPhase;
52
+ buildActionMask = 2147483647;
53
+ dstPath = "";
54
+ dstSubfolderSpec = 10;
55
+ files = (
56
+ );
57
+ name = "Bundle Framework";
58
+ runOnlyForDeploymentPostprocessing = 0;
59
+ };
60
+/* End PBXCopyFilesBuildPhase section */
61
+
62
+/* Begin PBXFileReference section */
63
+ 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
64
+ 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
65
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
66
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
67
+ 33CC10ED2044A3C60003C045 /* pailot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "pailot.app"; sourceTree = BUILT_PRODUCTS_DIR; };
68
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
69
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
70
+ 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
71
+ 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
72
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
73
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
74
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
75
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
76
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
77
+ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
78
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
79
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
80
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
81
+/* End PBXFileReference section */
82
+
83
+/* Begin PBXFrameworksBuildPhase section */
84
+ 331C80D2294CF70F00263BE5 /* Frameworks */ = {
85
+ isa = PBXFrameworksBuildPhase;
86
+ buildActionMask = 2147483647;
87
+ files = (
88
+ );
89
+ runOnlyForDeploymentPostprocessing = 0;
90
+ };
91
+ 33CC10EA2044A3C60003C045 /* Frameworks */ = {
92
+ isa = PBXFrameworksBuildPhase;
93
+ buildActionMask = 2147483647;
94
+ files = (
95
+ );
96
+ runOnlyForDeploymentPostprocessing = 0;
97
+ };
98
+/* End PBXFrameworksBuildPhase section */
99
+
100
+/* Begin PBXGroup section */
101
+ 331C80D6294CF71000263BE5 /* RunnerTests */ = {
102
+ isa = PBXGroup;
103
+ children = (
104
+ 331C80D7294CF71000263BE5 /* RunnerTests.swift */,
105
+ );
106
+ path = RunnerTests;
107
+ sourceTree = "<group>";
108
+ };
109
+ 33BA886A226E78AF003329D5 /* Configs */ = {
110
+ isa = PBXGroup;
111
+ children = (
112
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */,
113
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
114
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
115
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
116
+ );
117
+ path = Configs;
118
+ sourceTree = "<group>";
119
+ };
120
+ 33CC10E42044A3C60003C045 = {
121
+ isa = PBXGroup;
122
+ children = (
123
+ 33FAB671232836740065AC1E /* Runner */,
124
+ 33CEB47122A05771004F2AC0 /* Flutter */,
125
+ 331C80D6294CF71000263BE5 /* RunnerTests */,
126
+ 33CC10EE2044A3C60003C045 /* Products */,
127
+ D73912EC22F37F3D000D13A0 /* Frameworks */,
128
+ );
129
+ sourceTree = "<group>";
130
+ };
131
+ 33CC10EE2044A3C60003C045 /* Products */ = {
132
+ isa = PBXGroup;
133
+ children = (
134
+ 33CC10ED2044A3C60003C045 /* pailot.app */,
135
+ 331C80D5294CF71000263BE5 /* RunnerTests.xctest */,
136
+ );
137
+ name = Products;
138
+ sourceTree = "<group>";
139
+ };
140
+ 33CC11242044D66E0003C045 /* Resources */ = {
141
+ isa = PBXGroup;
142
+ children = (
143
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */,
144
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */,
145
+ 33CC10F72044A3C60003C045 /* Info.plist */,
146
+ );
147
+ name = Resources;
148
+ path = ..;
149
+ sourceTree = "<group>";
150
+ };
151
+ 33CEB47122A05771004F2AC0 /* Flutter */ = {
152
+ isa = PBXGroup;
153
+ children = (
154
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
155
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
156
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
157
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
158
+ );
159
+ path = Flutter;
160
+ sourceTree = "<group>";
161
+ };
162
+ 33FAB671232836740065AC1E /* Runner */ = {
163
+ isa = PBXGroup;
164
+ children = (
165
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */,
166
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
167
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */,
168
+ 33E51914231749380026EE4D /* Release.entitlements */,
169
+ 33CC11242044D66E0003C045 /* Resources */,
170
+ 33BA886A226E78AF003329D5 /* Configs */,
171
+ );
172
+ path = Runner;
173
+ sourceTree = "<group>";
174
+ };
175
+ D73912EC22F37F3D000D13A0 /* Frameworks */ = {
176
+ isa = PBXGroup;
177
+ children = (
178
+ );
179
+ name = Frameworks;
180
+ sourceTree = "<group>";
181
+ };
182
+/* End PBXGroup section */
183
+
184
+/* Begin PBXNativeTarget section */
185
+ 331C80D4294CF70F00263BE5 /* RunnerTests */ = {
186
+ isa = PBXNativeTarget;
187
+ buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
188
+ buildPhases = (
189
+ 331C80D1294CF70F00263BE5 /* Sources */,
190
+ 331C80D2294CF70F00263BE5 /* Frameworks */,
191
+ 331C80D3294CF70F00263BE5 /* Resources */,
192
+ );
193
+ buildRules = (
194
+ );
195
+ dependencies = (
196
+ 331C80DA294CF71000263BE5 /* PBXTargetDependency */,
197
+ );
198
+ name = RunnerTests;
199
+ productName = RunnerTests;
200
+ productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */;
201
+ productType = "com.apple.product-type.bundle.unit-test";
202
+ };
203
+ 33CC10EC2044A3C60003C045 /* Runner */ = {
204
+ isa = PBXNativeTarget;
205
+ buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
206
+ buildPhases = (
207
+ 33CC10E92044A3C60003C045 /* Sources */,
208
+ 33CC10EA2044A3C60003C045 /* Frameworks */,
209
+ 33CC10EB2044A3C60003C045 /* Resources */,
210
+ 33CC110E2044A8840003C045 /* Bundle Framework */,
211
+ 3399D490228B24CF009A79C7 /* ShellScript */,
212
+ );
213
+ buildRules = (
214
+ );
215
+ dependencies = (
216
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */,
217
+ );
218
+ name = Runner;
219
+ productName = Runner;
220
+ productReference = 33CC10ED2044A3C60003C045 /* pailot.app */;
221
+ productType = "com.apple.product-type.application";
222
+ };
223
+/* End PBXNativeTarget section */
224
+
225
+/* Begin PBXProject section */
226
+ 33CC10E52044A3C60003C045 /* Project object */ = {
227
+ isa = PBXProject;
228
+ attributes = {
229
+ BuildIndependentTargetsInParallel = YES;
230
+ LastSwiftUpdateCheck = 0920;
231
+ LastUpgradeCheck = 1510;
232
+ ORGANIZATIONNAME = "";
233
+ TargetAttributes = {
234
+ 331C80D4294CF70F00263BE5 = {
235
+ CreatedOnToolsVersion = 14.0;
236
+ TestTargetID = 33CC10EC2044A3C60003C045;
237
+ };
238
+ 33CC10EC2044A3C60003C045 = {
239
+ CreatedOnToolsVersion = 9.2;
240
+ LastSwiftMigration = 1100;
241
+ ProvisioningStyle = Automatic;
242
+ SystemCapabilities = {
243
+ com.apple.Sandbox = {
244
+ enabled = 1;
245
+ };
246
+ };
247
+ };
248
+ 33CC111A2044C6BA0003C045 = {
249
+ CreatedOnToolsVersion = 9.2;
250
+ ProvisioningStyle = Manual;
251
+ };
252
+ };
253
+ };
254
+ buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
255
+ compatibilityVersion = "Xcode 9.3";
256
+ developmentRegion = en;
257
+ hasScannedForEncodings = 0;
258
+ knownRegions = (
259
+ en,
260
+ Base,
261
+ );
262
+ mainGroup = 33CC10E42044A3C60003C045;
263
+ productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
264
+ projectDirPath = "";
265
+ projectRoot = "";
266
+ targets = (
267
+ 33CC10EC2044A3C60003C045 /* Runner */,
268
+ 331C80D4294CF70F00263BE5 /* RunnerTests */,
269
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */,
270
+ );
271
+ };
272
+/* End PBXProject section */
273
+
274
+/* Begin PBXResourcesBuildPhase section */
275
+ 331C80D3294CF70F00263BE5 /* Resources */ = {
276
+ isa = PBXResourcesBuildPhase;
277
+ buildActionMask = 2147483647;
278
+ files = (
279
+ );
280
+ runOnlyForDeploymentPostprocessing = 0;
281
+ };
282
+ 33CC10EB2044A3C60003C045 /* Resources */ = {
283
+ isa = PBXResourcesBuildPhase;
284
+ buildActionMask = 2147483647;
285
+ files = (
286
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
287
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
288
+ );
289
+ runOnlyForDeploymentPostprocessing = 0;
290
+ };
291
+/* End PBXResourcesBuildPhase section */
292
+
293
+/* Begin PBXShellScriptBuildPhase section */
294
+ 3399D490228B24CF009A79C7 /* ShellScript */ = {
295
+ isa = PBXShellScriptBuildPhase;
296
+ alwaysOutOfDate = 1;
297
+ buildActionMask = 2147483647;
298
+ files = (
299
+ );
300
+ inputFileListPaths = (
301
+ );
302
+ inputPaths = (
303
+ );
304
+ outputFileListPaths = (
305
+ );
306
+ outputPaths = (
307
+ );
308
+ runOnlyForDeploymentPostprocessing = 0;
309
+ shellPath = /bin/sh;
310
+ shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
311
+ };
312
+ 33CC111E2044C6BF0003C045 /* ShellScript */ = {
313
+ isa = PBXShellScriptBuildPhase;
314
+ buildActionMask = 2147483647;
315
+ files = (
316
+ );
317
+ inputFileListPaths = (
318
+ Flutter/ephemeral/FlutterInputs.xcfilelist,
319
+ );
320
+ inputPaths = (
321
+ Flutter/ephemeral/tripwire,
322
+ );
323
+ outputFileListPaths = (
324
+ Flutter/ephemeral/FlutterOutputs.xcfilelist,
325
+ );
326
+ outputPaths = (
327
+ );
328
+ runOnlyForDeploymentPostprocessing = 0;
329
+ shellPath = /bin/sh;
330
+ shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
331
+ };
332
+/* End PBXShellScriptBuildPhase section */
333
+
334
+/* Begin PBXSourcesBuildPhase section */
335
+ 331C80D1294CF70F00263BE5 /* Sources */ = {
336
+ isa = PBXSourcesBuildPhase;
337
+ buildActionMask = 2147483647;
338
+ files = (
339
+ 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */,
340
+ );
341
+ runOnlyForDeploymentPostprocessing = 0;
342
+ };
343
+ 33CC10E92044A3C60003C045 /* Sources */ = {
344
+ isa = PBXSourcesBuildPhase;
345
+ buildActionMask = 2147483647;
346
+ files = (
347
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
348
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
349
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
350
+ );
351
+ runOnlyForDeploymentPostprocessing = 0;
352
+ };
353
+/* End PBXSourcesBuildPhase section */
354
+
355
+/* Begin PBXTargetDependency section */
356
+ 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = {
357
+ isa = PBXTargetDependency;
358
+ target = 33CC10EC2044A3C60003C045 /* Runner */;
359
+ targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */;
360
+ };
361
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
362
+ isa = PBXTargetDependency;
363
+ target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
364
+ targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
365
+ };
366
+/* End PBXTargetDependency section */
367
+
368
+/* Begin PBXVariantGroup section */
369
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
370
+ isa = PBXVariantGroup;
371
+ children = (
372
+ 33CC10F52044A3C60003C045 /* Base */,
373
+ );
374
+ name = MainMenu.xib;
375
+ path = Runner;
376
+ sourceTree = "<group>";
377
+ };
378
+/* End PBXVariantGroup section */
379
+
380
+/* Begin XCBuildConfiguration section */
381
+ 331C80DB294CF71000263BE5 /* Debug */ = {
382
+ isa = XCBuildConfiguration;
383
+ buildSettings = {
384
+ BUNDLE_LOADER = "$(TEST_HOST)";
385
+ CURRENT_PROJECT_VERSION = 1;
386
+ GENERATE_INFOPLIST_FILE = YES;
387
+ MARKETING_VERSION = 1.0;
388
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot.RunnerTests;
389
+ PRODUCT_NAME = "$(TARGET_NAME)";
390
+ SWIFT_VERSION = 5.0;
391
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pailot.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/pailot";
392
+ };
393
+ name = Debug;
394
+ };
395
+ 331C80DC294CF71000263BE5 /* Release */ = {
396
+ isa = XCBuildConfiguration;
397
+ buildSettings = {
398
+ BUNDLE_LOADER = "$(TEST_HOST)";
399
+ CURRENT_PROJECT_VERSION = 1;
400
+ GENERATE_INFOPLIST_FILE = YES;
401
+ MARKETING_VERSION = 1.0;
402
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot.RunnerTests;
403
+ PRODUCT_NAME = "$(TARGET_NAME)";
404
+ SWIFT_VERSION = 5.0;
405
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pailot.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/pailot";
406
+ };
407
+ name = Release;
408
+ };
409
+ 331C80DD294CF71000263BE5 /* Profile */ = {
410
+ isa = XCBuildConfiguration;
411
+ buildSettings = {
412
+ BUNDLE_LOADER = "$(TEST_HOST)";
413
+ CURRENT_PROJECT_VERSION = 1;
414
+ GENERATE_INFOPLIST_FILE = YES;
415
+ MARKETING_VERSION = 1.0;
416
+ PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot.RunnerTests;
417
+ PRODUCT_NAME = "$(TARGET_NAME)";
418
+ SWIFT_VERSION = 5.0;
419
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pailot.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/pailot";
420
+ };
421
+ name = Profile;
422
+ };
423
+ 338D0CE9231458BD00FA5F75 /* Profile */ = {
424
+ isa = XCBuildConfiguration;
425
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
426
+ buildSettings = {
427
+ ALWAYS_SEARCH_USER_PATHS = NO;
428
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
429
+ CLANG_ANALYZER_NONNULL = YES;
430
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
431
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
432
+ CLANG_CXX_LIBRARY = "libc++";
433
+ CLANG_ENABLE_MODULES = YES;
434
+ CLANG_ENABLE_OBJC_ARC = YES;
435
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
436
+ CLANG_WARN_BOOL_CONVERSION = YES;
437
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
438
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
439
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
440
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
441
+ CLANG_WARN_EMPTY_BODY = YES;
442
+ CLANG_WARN_ENUM_CONVERSION = YES;
443
+ CLANG_WARN_INFINITE_RECURSION = YES;
444
+ CLANG_WARN_INT_CONVERSION = YES;
445
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
446
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
447
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
448
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
449
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
450
+ CODE_SIGN_IDENTITY = "-";
451
+ COPY_PHASE_STRIP = NO;
452
+ DEAD_CODE_STRIPPING = YES;
453
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
454
+ ENABLE_NS_ASSERTIONS = NO;
455
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
456
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
457
+ GCC_C_LANGUAGE_STANDARD = gnu11;
458
+ GCC_NO_COMMON_BLOCKS = YES;
459
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
460
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
461
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
462
+ GCC_WARN_UNUSED_FUNCTION = YES;
463
+ GCC_WARN_UNUSED_VARIABLE = YES;
464
+ MACOSX_DEPLOYMENT_TARGET = 10.15;
465
+ MTL_ENABLE_DEBUG_INFO = NO;
466
+ SDKROOT = macosx;
467
+ SWIFT_COMPILATION_MODE = wholemodule;
468
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
469
+ };
470
+ name = Profile;
471
+ };
472
+ 338D0CEA231458BD00FA5F75 /* Profile */ = {
473
+ isa = XCBuildConfiguration;
474
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
475
+ buildSettings = {
476
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
477
+ CLANG_ENABLE_MODULES = YES;
478
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
479
+ CODE_SIGN_STYLE = Automatic;
480
+ COMBINE_HIDPI_IMAGES = YES;
481
+ INFOPLIST_FILE = Runner/Info.plist;
482
+ LD_RUNPATH_SEARCH_PATHS = (
483
+ "$(inherited)",
484
+ "@executable_path/../Frameworks",
485
+ );
486
+ PROVISIONING_PROFILE_SPECIFIER = "";
487
+ SWIFT_VERSION = 5.0;
488
+ };
489
+ name = Profile;
490
+ };
491
+ 338D0CEB231458BD00FA5F75 /* Profile */ = {
492
+ isa = XCBuildConfiguration;
493
+ buildSettings = {
494
+ CODE_SIGN_STYLE = Manual;
495
+ PRODUCT_NAME = "$(TARGET_NAME)";
496
+ };
497
+ name = Profile;
498
+ };
499
+ 33CC10F92044A3C60003C045 /* Debug */ = {
500
+ isa = XCBuildConfiguration;
501
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
502
+ buildSettings = {
503
+ ALWAYS_SEARCH_USER_PATHS = NO;
504
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
505
+ CLANG_ANALYZER_NONNULL = YES;
506
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
507
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
508
+ CLANG_CXX_LIBRARY = "libc++";
509
+ CLANG_ENABLE_MODULES = YES;
510
+ CLANG_ENABLE_OBJC_ARC = YES;
511
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
512
+ CLANG_WARN_BOOL_CONVERSION = YES;
513
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
514
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
515
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
516
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
517
+ CLANG_WARN_EMPTY_BODY = YES;
518
+ CLANG_WARN_ENUM_CONVERSION = YES;
519
+ CLANG_WARN_INFINITE_RECURSION = YES;
520
+ CLANG_WARN_INT_CONVERSION = YES;
521
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
522
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
523
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
524
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
525
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
526
+ CODE_SIGN_IDENTITY = "-";
527
+ COPY_PHASE_STRIP = NO;
528
+ DEAD_CODE_STRIPPING = YES;
529
+ DEBUG_INFORMATION_FORMAT = dwarf;
530
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
531
+ ENABLE_TESTABILITY = YES;
532
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
533
+ GCC_C_LANGUAGE_STANDARD = gnu11;
534
+ GCC_DYNAMIC_NO_PIC = NO;
535
+ GCC_NO_COMMON_BLOCKS = YES;
536
+ GCC_OPTIMIZATION_LEVEL = 0;
537
+ GCC_PREPROCESSOR_DEFINITIONS = (
538
+ "DEBUG=1",
539
+ "$(inherited)",
540
+ );
541
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
542
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
543
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
544
+ GCC_WARN_UNUSED_FUNCTION = YES;
545
+ GCC_WARN_UNUSED_VARIABLE = YES;
546
+ MACOSX_DEPLOYMENT_TARGET = 10.15;
547
+ MTL_ENABLE_DEBUG_INFO = YES;
548
+ ONLY_ACTIVE_ARCH = YES;
549
+ SDKROOT = macosx;
550
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
551
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
552
+ };
553
+ name = Debug;
554
+ };
555
+ 33CC10FA2044A3C60003C045 /* Release */ = {
556
+ isa = XCBuildConfiguration;
557
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
558
+ buildSettings = {
559
+ ALWAYS_SEARCH_USER_PATHS = NO;
560
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
561
+ CLANG_ANALYZER_NONNULL = YES;
562
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
563
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
564
+ CLANG_CXX_LIBRARY = "libc++";
565
+ CLANG_ENABLE_MODULES = YES;
566
+ CLANG_ENABLE_OBJC_ARC = YES;
567
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
568
+ CLANG_WARN_BOOL_CONVERSION = YES;
569
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
570
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
571
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
572
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
573
+ CLANG_WARN_EMPTY_BODY = YES;
574
+ CLANG_WARN_ENUM_CONVERSION = YES;
575
+ CLANG_WARN_INFINITE_RECURSION = YES;
576
+ CLANG_WARN_INT_CONVERSION = YES;
577
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
578
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
579
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
580
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
581
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
582
+ CODE_SIGN_IDENTITY = "-";
583
+ COPY_PHASE_STRIP = NO;
584
+ DEAD_CODE_STRIPPING = YES;
585
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
586
+ ENABLE_NS_ASSERTIONS = NO;
587
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
588
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
589
+ GCC_C_LANGUAGE_STANDARD = gnu11;
590
+ GCC_NO_COMMON_BLOCKS = YES;
591
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
592
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
593
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
594
+ GCC_WARN_UNUSED_FUNCTION = YES;
595
+ GCC_WARN_UNUSED_VARIABLE = YES;
596
+ MACOSX_DEPLOYMENT_TARGET = 10.15;
597
+ MTL_ENABLE_DEBUG_INFO = NO;
598
+ SDKROOT = macosx;
599
+ SWIFT_COMPILATION_MODE = wholemodule;
600
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
601
+ };
602
+ name = Release;
603
+ };
604
+ 33CC10FC2044A3C60003C045 /* Debug */ = {
605
+ isa = XCBuildConfiguration;
606
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
607
+ buildSettings = {
608
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
609
+ CLANG_ENABLE_MODULES = YES;
610
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
611
+ CODE_SIGN_STYLE = Automatic;
612
+ COMBINE_HIDPI_IMAGES = YES;
613
+ INFOPLIST_FILE = Runner/Info.plist;
614
+ LD_RUNPATH_SEARCH_PATHS = (
615
+ "$(inherited)",
616
+ "@executable_path/../Frameworks",
617
+ );
618
+ PROVISIONING_PROFILE_SPECIFIER = "";
619
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
620
+ SWIFT_VERSION = 5.0;
621
+ };
622
+ name = Debug;
623
+ };
624
+ 33CC10FD2044A3C60003C045 /* Release */ = {
625
+ isa = XCBuildConfiguration;
626
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
627
+ buildSettings = {
628
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
629
+ CLANG_ENABLE_MODULES = YES;
630
+ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
631
+ CODE_SIGN_STYLE = Automatic;
632
+ COMBINE_HIDPI_IMAGES = YES;
633
+ INFOPLIST_FILE = Runner/Info.plist;
634
+ LD_RUNPATH_SEARCH_PATHS = (
635
+ "$(inherited)",
636
+ "@executable_path/../Frameworks",
637
+ );
638
+ PROVISIONING_PROFILE_SPECIFIER = "";
639
+ SWIFT_VERSION = 5.0;
640
+ };
641
+ name = Release;
642
+ };
643
+ 33CC111C2044C6BA0003C045 /* Debug */ = {
644
+ isa = XCBuildConfiguration;
645
+ buildSettings = {
646
+ CODE_SIGN_STYLE = Manual;
647
+ PRODUCT_NAME = "$(TARGET_NAME)";
648
+ };
649
+ name = Debug;
650
+ };
651
+ 33CC111D2044C6BA0003C045 /* Release */ = {
652
+ isa = XCBuildConfiguration;
653
+ buildSettings = {
654
+ CODE_SIGN_STYLE = Automatic;
655
+ PRODUCT_NAME = "$(TARGET_NAME)";
656
+ };
657
+ name = Release;
658
+ };
659
+/* End XCBuildConfiguration section */
660
+
661
+/* Begin XCConfigurationList section */
662
+ 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
663
+ isa = XCConfigurationList;
664
+ buildConfigurations = (
665
+ 331C80DB294CF71000263BE5 /* Debug */,
666
+ 331C80DC294CF71000263BE5 /* Release */,
667
+ 331C80DD294CF71000263BE5 /* Profile */,
668
+ );
669
+ defaultConfigurationIsVisible = 0;
670
+ defaultConfigurationName = Release;
671
+ };
672
+ 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
673
+ isa = XCConfigurationList;
674
+ buildConfigurations = (
675
+ 33CC10F92044A3C60003C045 /* Debug */,
676
+ 33CC10FA2044A3C60003C045 /* Release */,
677
+ 338D0CE9231458BD00FA5F75 /* Profile */,
678
+ );
679
+ defaultConfigurationIsVisible = 0;
680
+ defaultConfigurationName = Release;
681
+ };
682
+ 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
683
+ isa = XCConfigurationList;
684
+ buildConfigurations = (
685
+ 33CC10FC2044A3C60003C045 /* Debug */,
686
+ 33CC10FD2044A3C60003C045 /* Release */,
687
+ 338D0CEA231458BD00FA5F75 /* Profile */,
688
+ );
689
+ defaultConfigurationIsVisible = 0;
690
+ defaultConfigurationName = Release;
691
+ };
692
+ 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
693
+ isa = XCConfigurationList;
694
+ buildConfigurations = (
695
+ 33CC111C2044C6BA0003C045 /* Debug */,
696
+ 33CC111D2044C6BA0003C045 /* Release */,
697
+ 338D0CEB231458BD00FA5F75 /* Profile */,
698
+ );
699
+ defaultConfigurationIsVisible = 0;
700
+ defaultConfigurationName = Release;
701
+ };
702
+/* End XCConfigurationList section */
703
+ };
704
+ rootObject = 33CC10E52044A3C60003C045 /* Project object */;
705
+}
macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+</dict>
8
+</plist>
macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
....@@ -0,0 +1,99 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+ LastUpgradeVersion = "1510"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
18
+ BuildableName = "pailot.app"
19
+ BlueprintName = "Runner"
20
+ ReferencedContainer = "container:Runner.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <MacroExpansion>
31
+ <BuildableReference
32
+ BuildableIdentifier = "primary"
33
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
34
+ BuildableName = "pailot.app"
35
+ BlueprintName = "Runner"
36
+ ReferencedContainer = "container:Runner.xcodeproj">
37
+ </BuildableReference>
38
+ </MacroExpansion>
39
+ <Testables>
40
+ <TestableReference
41
+ skipped = "NO"
42
+ parallelizable = "YES">
43
+ <BuildableReference
44
+ BuildableIdentifier = "primary"
45
+ BlueprintIdentifier = "331C80D4294CF70F00263BE5"
46
+ BuildableName = "RunnerTests.xctest"
47
+ BlueprintName = "RunnerTests"
48
+ ReferencedContainer = "container:Runner.xcodeproj">
49
+ </BuildableReference>
50
+ </TestableReference>
51
+ </Testables>
52
+ </TestAction>
53
+ <LaunchAction
54
+ buildConfiguration = "Debug"
55
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
56
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
57
+ launchStyle = "0"
58
+ useCustomWorkingDirectory = "NO"
59
+ ignoresPersistentStateOnLaunch = "NO"
60
+ debugDocumentVersioning = "YES"
61
+ debugServiceExtension = "internal"
62
+ enableGPUValidationMode = "1"
63
+ allowLocationSimulation = "YES">
64
+ <BuildableProductRunnable
65
+ runnableDebuggingMode = "0">
66
+ <BuildableReference
67
+ BuildableIdentifier = "primary"
68
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
69
+ BuildableName = "pailot.app"
70
+ BlueprintName = "Runner"
71
+ ReferencedContainer = "container:Runner.xcodeproj">
72
+ </BuildableReference>
73
+ </BuildableProductRunnable>
74
+ </LaunchAction>
75
+ <ProfileAction
76
+ buildConfiguration = "Profile"
77
+ shouldUseLaunchSchemeArgsEnv = "YES"
78
+ savedToolIdentifier = ""
79
+ useCustomWorkingDirectory = "NO"
80
+ debugDocumentVersioning = "YES">
81
+ <BuildableProductRunnable
82
+ runnableDebuggingMode = "0">
83
+ <BuildableReference
84
+ BuildableIdentifier = "primary"
85
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
86
+ BuildableName = "pailot.app"
87
+ BlueprintName = "Runner"
88
+ ReferencedContainer = "container:Runner.xcodeproj">
89
+ </BuildableReference>
90
+ </BuildableProductRunnable>
91
+ </ProfileAction>
92
+ <AnalyzeAction
93
+ buildConfiguration = "Debug">
94
+ </AnalyzeAction>
95
+ <ArchiveAction
96
+ buildConfiguration = "Release"
97
+ revealArchiveInOrganizer = "YES">
98
+ </ArchiveAction>
99
+</Scheme>
macos/Runner.xcworkspace/contents.xcworkspacedata
....@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "group:Runner.xcodeproj">
6
+ </FileRef>
7
+</Workspace>
macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+</dict>
8
+</plist>
macos/Runner/AppDelegate.swift
....@@ -0,0 +1,13 @@
1
+import Cocoa
2
+import FlutterMacOS
3
+
4
+@main
5
+class AppDelegate: FlutterAppDelegate {
6
+ override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7
+ return true
8
+ }
9
+
10
+ override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
11
+ return true
12
+ }
13
+}
macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
....@@ -0,0 +1,68 @@
1
+{
2
+ "images" : [
3
+ {
4
+ "size" : "16x16",
5
+ "idiom" : "mac",
6
+ "filename" : "app_icon_16.png",
7
+ "scale" : "1x"
8
+ },
9
+ {
10
+ "size" : "16x16",
11
+ "idiom" : "mac",
12
+ "filename" : "app_icon_32.png",
13
+ "scale" : "2x"
14
+ },
15
+ {
16
+ "size" : "32x32",
17
+ "idiom" : "mac",
18
+ "filename" : "app_icon_32.png",
19
+ "scale" : "1x"
20
+ },
21
+ {
22
+ "size" : "32x32",
23
+ "idiom" : "mac",
24
+ "filename" : "app_icon_64.png",
25
+ "scale" : "2x"
26
+ },
27
+ {
28
+ "size" : "128x128",
29
+ "idiom" : "mac",
30
+ "filename" : "app_icon_128.png",
31
+ "scale" : "1x"
32
+ },
33
+ {
34
+ "size" : "128x128",
35
+ "idiom" : "mac",
36
+ "filename" : "app_icon_256.png",
37
+ "scale" : "2x"
38
+ },
39
+ {
40
+ "size" : "256x256",
41
+ "idiom" : "mac",
42
+ "filename" : "app_icon_256.png",
43
+ "scale" : "1x"
44
+ },
45
+ {
46
+ "size" : "256x256",
47
+ "idiom" : "mac",
48
+ "filename" : "app_icon_512.png",
49
+ "scale" : "2x"
50
+ },
51
+ {
52
+ "size" : "512x512",
53
+ "idiom" : "mac",
54
+ "filename" : "app_icon_512.png",
55
+ "scale" : "1x"
56
+ },
57
+ {
58
+ "size" : "512x512",
59
+ "idiom" : "mac",
60
+ "filename" : "app_icon_1024.png",
61
+ "scale" : "2x"
62
+ }
63
+ ],
64
+ "info" : {
65
+ "version" : 1,
66
+ "author" : "xcode"
67
+ }
68
+}
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
Binary files differ
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
Binary files differ
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
Binary files differ
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
Binary files differ
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
Binary files differ
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
Binary files differ
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
Binary files differ
macos/Runner/Base.lproj/MainMenu.xib
....@@ -0,0 +1,343 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
3
+ <dependencies>
4
+ <deployment identifier="macosx"/>
5
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
6
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7
+ </dependencies>
8
+ <objects>
9
+ <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
10
+ <connections>
11
+ <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
12
+ </connections>
13
+ </customObject>
14
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
15
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
16
+ <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
17
+ <connections>
18
+ <outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
19
+ <outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
20
+ </connections>
21
+ </customObject>
22
+ <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
23
+ <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
24
+ <items>
25
+ <menuItem title="APP_NAME" id="1Xt-HY-uBw">
26
+ <modifierMask key="keyEquivalentModifierMask"/>
27
+ <menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
28
+ <items>
29
+ <menuItem title="About APP_NAME" id="5kV-Vb-QxS">
30
+ <modifierMask key="keyEquivalentModifierMask"/>
31
+ <connections>
32
+ <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
33
+ </connections>
34
+ </menuItem>
35
+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
36
+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
37
+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
38
+ <menuItem title="Services" id="NMo-om-nkz">
39
+ <modifierMask key="keyEquivalentModifierMask"/>
40
+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
41
+ </menuItem>
42
+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
43
+ <menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
44
+ <connections>
45
+ <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
46
+ </connections>
47
+ </menuItem>
48
+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
49
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
50
+ <connections>
51
+ <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
52
+ </connections>
53
+ </menuItem>
54
+ <menuItem title="Show All" id="Kd2-mp-pUS">
55
+ <modifierMask key="keyEquivalentModifierMask"/>
56
+ <connections>
57
+ <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
58
+ </connections>
59
+ </menuItem>
60
+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
61
+ <menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
62
+ <connections>
63
+ <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
64
+ </connections>
65
+ </menuItem>
66
+ </items>
67
+ </menu>
68
+ </menuItem>
69
+ <menuItem title="Edit" id="5QF-Oa-p0T">
70
+ <modifierMask key="keyEquivalentModifierMask"/>
71
+ <menu key="submenu" title="Edit" id="W48-6f-4Dl">
72
+ <items>
73
+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
74
+ <connections>
75
+ <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
76
+ </connections>
77
+ </menuItem>
78
+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
79
+ <connections>
80
+ <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
81
+ </connections>
82
+ </menuItem>
83
+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
84
+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
85
+ <connections>
86
+ <action selector="cut:" target="-1" id="YJe-68-I9s"/>
87
+ </connections>
88
+ </menuItem>
89
+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
90
+ <connections>
91
+ <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
92
+ </connections>
93
+ </menuItem>
94
+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
95
+ <connections>
96
+ <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
97
+ </connections>
98
+ </menuItem>
99
+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
100
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
101
+ <connections>
102
+ <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
103
+ </connections>
104
+ </menuItem>
105
+ <menuItem title="Delete" id="pa3-QI-u2k">
106
+ <modifierMask key="keyEquivalentModifierMask"/>
107
+ <connections>
108
+ <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
109
+ </connections>
110
+ </menuItem>
111
+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
112
+ <connections>
113
+ <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
114
+ </connections>
115
+ </menuItem>
116
+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
117
+ <menuItem title="Find" id="4EN-yA-p0u">
118
+ <modifierMask key="keyEquivalentModifierMask"/>
119
+ <menu key="submenu" title="Find" id="1b7-l0-nxx">
120
+ <items>
121
+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
122
+ <connections>
123
+ <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
124
+ </connections>
125
+ </menuItem>
126
+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
127
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
128
+ <connections>
129
+ <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
130
+ </connections>
131
+ </menuItem>
132
+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
133
+ <connections>
134
+ <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
135
+ </connections>
136
+ </menuItem>
137
+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
138
+ <connections>
139
+ <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
140
+ </connections>
141
+ </menuItem>
142
+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
143
+ <connections>
144
+ <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
145
+ </connections>
146
+ </menuItem>
147
+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
148
+ <connections>
149
+ <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
150
+ </connections>
151
+ </menuItem>
152
+ </items>
153
+ </menu>
154
+ </menuItem>
155
+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
156
+ <modifierMask key="keyEquivalentModifierMask"/>
157
+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
158
+ <items>
159
+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
160
+ <connections>
161
+ <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
162
+ </connections>
163
+ </menuItem>
164
+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
165
+ <connections>
166
+ <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
167
+ </connections>
168
+ </menuItem>
169
+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
170
+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
171
+ <modifierMask key="keyEquivalentModifierMask"/>
172
+ <connections>
173
+ <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
174
+ </connections>
175
+ </menuItem>
176
+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
177
+ <modifierMask key="keyEquivalentModifierMask"/>
178
+ <connections>
179
+ <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
180
+ </connections>
181
+ </menuItem>
182
+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
183
+ <modifierMask key="keyEquivalentModifierMask"/>
184
+ <connections>
185
+ <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
186
+ </connections>
187
+ </menuItem>
188
+ </items>
189
+ </menu>
190
+ </menuItem>
191
+ <menuItem title="Substitutions" id="9ic-FL-obx">
192
+ <modifierMask key="keyEquivalentModifierMask"/>
193
+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
194
+ <items>
195
+ <menuItem title="Show Substitutions" id="z6F-FW-3nz">
196
+ <modifierMask key="keyEquivalentModifierMask"/>
197
+ <connections>
198
+ <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
199
+ </connections>
200
+ </menuItem>
201
+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
202
+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
203
+ <modifierMask key="keyEquivalentModifierMask"/>
204
+ <connections>
205
+ <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
206
+ </connections>
207
+ </menuItem>
208
+ <menuItem title="Smart Quotes" id="hQb-2v-fYv">
209
+ <modifierMask key="keyEquivalentModifierMask"/>
210
+ <connections>
211
+ <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
212
+ </connections>
213
+ </menuItem>
214
+ <menuItem title="Smart Dashes" id="rgM-f4-ycn">
215
+ <modifierMask key="keyEquivalentModifierMask"/>
216
+ <connections>
217
+ <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
218
+ </connections>
219
+ </menuItem>
220
+ <menuItem title="Smart Links" id="cwL-P1-jid">
221
+ <modifierMask key="keyEquivalentModifierMask"/>
222
+ <connections>
223
+ <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
224
+ </connections>
225
+ </menuItem>
226
+ <menuItem title="Data Detectors" id="tRr-pd-1PS">
227
+ <modifierMask key="keyEquivalentModifierMask"/>
228
+ <connections>
229
+ <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
230
+ </connections>
231
+ </menuItem>
232
+ <menuItem title="Text Replacement" id="HFQ-gK-NFA">
233
+ <modifierMask key="keyEquivalentModifierMask"/>
234
+ <connections>
235
+ <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
236
+ </connections>
237
+ </menuItem>
238
+ </items>
239
+ </menu>
240
+ </menuItem>
241
+ <menuItem title="Transformations" id="2oI-Rn-ZJC">
242
+ <modifierMask key="keyEquivalentModifierMask"/>
243
+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
244
+ <items>
245
+ <menuItem title="Make Upper Case" id="vmV-6d-7jI">
246
+ <modifierMask key="keyEquivalentModifierMask"/>
247
+ <connections>
248
+ <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
249
+ </connections>
250
+ </menuItem>
251
+ <menuItem title="Make Lower Case" id="d9M-CD-aMd">
252
+ <modifierMask key="keyEquivalentModifierMask"/>
253
+ <connections>
254
+ <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
255
+ </connections>
256
+ </menuItem>
257
+ <menuItem title="Capitalize" id="UEZ-Bs-lqG">
258
+ <modifierMask key="keyEquivalentModifierMask"/>
259
+ <connections>
260
+ <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
261
+ </connections>
262
+ </menuItem>
263
+ </items>
264
+ </menu>
265
+ </menuItem>
266
+ <menuItem title="Speech" id="xrE-MZ-jX0">
267
+ <modifierMask key="keyEquivalentModifierMask"/>
268
+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
269
+ <items>
270
+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
271
+ <modifierMask key="keyEquivalentModifierMask"/>
272
+ <connections>
273
+ <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
274
+ </connections>
275
+ </menuItem>
276
+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
277
+ <modifierMask key="keyEquivalentModifierMask"/>
278
+ <connections>
279
+ <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
280
+ </connections>
281
+ </menuItem>
282
+ </items>
283
+ </menu>
284
+ </menuItem>
285
+ </items>
286
+ </menu>
287
+ </menuItem>
288
+ <menuItem title="View" id="H8h-7b-M4v">
289
+ <modifierMask key="keyEquivalentModifierMask"/>
290
+ <menu key="submenu" title="View" id="HyV-fh-RgO">
291
+ <items>
292
+ <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
293
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
294
+ <connections>
295
+ <action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
296
+ </connections>
297
+ </menuItem>
298
+ </items>
299
+ </menu>
300
+ </menuItem>
301
+ <menuItem title="Window" id="aUF-d1-5bR">
302
+ <modifierMask key="keyEquivalentModifierMask"/>
303
+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
304
+ <items>
305
+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
306
+ <connections>
307
+ <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
308
+ </connections>
309
+ </menuItem>
310
+ <menuItem title="Zoom" id="R4o-n2-Eq4">
311
+ <modifierMask key="keyEquivalentModifierMask"/>
312
+ <connections>
313
+ <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
314
+ </connections>
315
+ </menuItem>
316
+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
317
+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
318
+ <modifierMask key="keyEquivalentModifierMask"/>
319
+ <connections>
320
+ <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
321
+ </connections>
322
+ </menuItem>
323
+ </items>
324
+ </menu>
325
+ </menuItem>
326
+ <menuItem title="Help" id="EPT-qC-fAb">
327
+ <modifierMask key="keyEquivalentModifierMask"/>
328
+ <menu key="submenu" title="Help" systemMenu="help" id="rJ0-wn-3NY"/>
329
+ </menuItem>
330
+ </items>
331
+ <point key="canvasLocation" x="142" y="-258"/>
332
+ </menu>
333
+ <window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
334
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
335
+ <rect key="contentRect" x="335" y="390" width="800" height="600"/>
336
+ <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
337
+ <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
338
+ <rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
339
+ <autoresizingMask key="autoresizingMask"/>
340
+ </view>
341
+ </window>
342
+ </objects>
343
+</document>
macos/Runner/Configs/AppInfo.xcconfig
....@@ -0,0 +1,14 @@
1
+// Application-level settings for the Runner target.
2
+//
3
+// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4
+// future. If not, the values below would default to using the project name when this becomes a
5
+// 'flutter create' template.
6
+
7
+// The application's name. By default this is also the title of the Flutter window.
8
+PRODUCT_NAME = pailot
9
+
10
+// The application's bundle identifier
11
+PRODUCT_BUNDLE_IDENTIFIER = com.tekmidian.pailot
12
+
13
+// The copyright displayed in application information
14
+PRODUCT_COPYRIGHT = Copyright © 2026 com.tekmidian. All rights reserved.
macos/Runner/Configs/Debug.xcconfig
....@@ -0,0 +1,2 @@
1
+#include "../../Flutter/Flutter-Debug.xcconfig"
2
+#include "Warnings.xcconfig"
macos/Runner/Configs/Release.xcconfig
....@@ -0,0 +1,2 @@
1
+#include "../../Flutter/Flutter-Release.xcconfig"
2
+#include "Warnings.xcconfig"
macos/Runner/Configs/Warnings.xcconfig
....@@ -0,0 +1,13 @@
1
+WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2
+GCC_WARN_UNDECLARED_SELECTOR = YES
3
+CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4
+CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6
+CLANG_WARN_PRAGMA_PACK = YES
7
+CLANG_WARN_STRICT_PROTOTYPES = YES
8
+CLANG_WARN_COMMA = YES
9
+GCC_WARN_STRICT_SELECTOR_MATCH = YES
10
+CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12
+GCC_WARN_SHADOW = YES
13
+CLANG_WARN_UNREACHABLE_CODE = YES
macos/Runner/DebugProfile.entitlements
....@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>com.apple.security.app-sandbox</key>
6
+ <true/>
7
+ <key>com.apple.security.cs.allow-jit</key>
8
+ <true/>
9
+ <key>com.apple.security.network.server</key>
10
+ <true/>
11
+</dict>
12
+</plist>
macos/Runner/Info.plist
....@@ -0,0 +1,32 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIconFile</key>
10
+ <string></string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>$(PRODUCT_NAME)</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>APPL</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>$(FLUTTER_BUILD_NAME)</string>
21
+ <key>CFBundleVersion</key>
22
+ <string>$(FLUTTER_BUILD_NUMBER)</string>
23
+ <key>LSMinimumSystemVersion</key>
24
+ <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
25
+ <key>NSHumanReadableCopyright</key>
26
+ <string>$(PRODUCT_COPYRIGHT)</string>
27
+ <key>NSMainNibFile</key>
28
+ <string>MainMenu</string>
29
+ <key>NSPrincipalClass</key>
30
+ <string>NSApplication</string>
31
+</dict>
32
+</plist>
macos/Runner/MainFlutterWindow.swift
....@@ -0,0 +1,15 @@
1
+import Cocoa
2
+import FlutterMacOS
3
+
4
+class MainFlutterWindow: NSWindow {
5
+ override func awakeFromNib() {
6
+ let flutterViewController = FlutterViewController()
7
+ let windowFrame = self.frame
8
+ self.contentViewController = flutterViewController
9
+ self.setFrame(windowFrame, display: true)
10
+
11
+ RegisterGeneratedPlugins(registry: flutterViewController)
12
+
13
+ super.awakeFromNib()
14
+ }
15
+}
macos/Runner/Release.entitlements
....@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>com.apple.security.app-sandbox</key>
6
+ <true/>
7
+</dict>
8
+</plist>
macos/RunnerTests/RunnerTests.swift
....@@ -0,0 +1,12 @@
1
+import Cocoa
2
+import FlutterMacOS
3
+import XCTest
4
+
5
+class RunnerTests: XCTestCase {
6
+
7
+ func testExample() {
8
+ // If you add code to the Runner application, consider adding tests here.
9
+ // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10
+ }
11
+
12
+}
memory/MEMORY.md
deleted file mode 100644
....@@ -1,4 +0,0 @@
1
-# Memory
2
-
3
-Project-specific memory for PAI sessions.
4
-Add persistent notes, reminders, and context here.
metro.config.js
deleted file mode 100644
....@@ -1,5 +0,0 @@
1
-const { getDefaultConfig } = require("expo/metro-config");
2
-const { withNativeWind } = require("nativewind/metro");
3
-
4
-const config = getDefaultConfig(__dirname);
5
-module.exports = withNativeWind(config, { input: "./global.css" });
nativewind-env.d.ts
deleted file mode 100644
....@@ -1 +0,0 @@
1
-/// <reference types="nativewind/types" />
package-lock.json
deleted file mode 100644
....@@ -1,10201 +0,0 @@
1
-{
2
- "name": "pailot",
3
- "version": "1.0.0",
4
- "lockfileVersion": 3,
5
- "requires": true,
6
- "packages": {
7
- "": {
8
- "name": "pailot",
9
- "version": "1.0.0",
10
- "dependencies": {
11
- "@react-navigation/bottom-tabs": "^7.15.3",
12
- "@react-navigation/native": "^7.1.31",
13
- "expo": "~55.0.4",
14
- "expo-audio": "^55.0.8",
15
- "expo-constants": "~55.0.7",
16
- "expo-file-system": "~55.0.10",
17
- "expo-haptics": "~55.0.8",
18
- "expo-image-picker": "~55.0.11",
19
- "expo-linking": "~55.0.7",
20
- "expo-router": "~55.0.3",
21
- "expo-secure-store": "~55.0.8",
22
- "expo-sharing": "~55.0.11",
23
- "expo-splash-screen": "~55.0.10",
24
- "expo-status-bar": "~55.0.4",
25
- "expo-system-ui": "~55.0.9",
26
- "expo-web-browser": "~55.0.9",
27
- "nativewind": "^4",
28
- "react": "19.2.0",
29
- "react-dom": "^19.2.4",
30
- "react-native": "0.83.2",
31
- "react-native-draggable-flatlist": "^4.0.3",
32
- "react-native-gesture-handler": "~2.30.0",
33
- "react-native-reanimated": "4.2.1",
34
- "react-native-safe-area-context": "~5.6.2",
35
- "react-native-screens": "~4.23.0",
36
- "react-native-svg": "15.15.3",
37
- "react-native-udp": "^4.1.7",
38
- "react-native-web": "^0.21.0",
39
- "react-native-worklets": "0.7.2"
40
- },
41
- "devDependencies": {
42
- "@types/react": "~19.2.2",
43
- "babel-plugin-module-resolver": "^5.0.2",
44
- "babel-preset-expo": "^55.0.10",
45
- "tailwindcss": "^3.4.19",
46
- "typescript": "~5.9.2"
47
- }
48
- },
49
- "node_modules/@alloc/quick-lru": {
50
- "version": "5.2.0",
51
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
52
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
53
- "dev": true,
54
- "license": "MIT",
55
- "engines": {
56
- "node": ">=10"
57
- },
58
- "funding": {
59
- "url": "https://github.com/sponsors/sindresorhus"
60
- }
61
- },
62
- "node_modules/@babel/code-frame": {
63
- "version": "7.29.0",
64
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
65
- "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
66
- "license": "MIT",
67
- "dependencies": {
68
- "@babel/helper-validator-identifier": "^7.28.5",
69
- "js-tokens": "^4.0.0",
70
- "picocolors": "^1.1.1"
71
- },
72
- "engines": {
73
- "node": ">=6.9.0"
74
- }
75
- },
76
- "node_modules/@babel/compat-data": {
77
- "version": "7.29.0",
78
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
79
- "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
80
- "license": "MIT",
81
- "engines": {
82
- "node": ">=6.9.0"
83
- }
84
- },
85
- "node_modules/@babel/core": {
86
- "version": "7.29.0",
87
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
88
- "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
89
- "license": "MIT",
90
- "dependencies": {
91
- "@babel/code-frame": "^7.29.0",
92
- "@babel/generator": "^7.29.0",
93
- "@babel/helper-compilation-targets": "^7.28.6",
94
- "@babel/helper-module-transforms": "^7.28.6",
95
- "@babel/helpers": "^7.28.6",
96
- "@babel/parser": "^7.29.0",
97
- "@babel/template": "^7.28.6",
98
- "@babel/traverse": "^7.29.0",
99
- "@babel/types": "^7.29.0",
100
- "@jridgewell/remapping": "^2.3.5",
101
- "convert-source-map": "^2.0.0",
102
- "debug": "^4.1.0",
103
- "gensync": "^1.0.0-beta.2",
104
- "json5": "^2.2.3",
105
- "semver": "^6.3.1"
106
- },
107
- "engines": {
108
- "node": ">=6.9.0"
109
- },
110
- "funding": {
111
- "type": "opencollective",
112
- "url": "https://opencollective.com/babel"
113
- }
114
- },
115
- "node_modules/@babel/core/node_modules/semver": {
116
- "version": "6.3.1",
117
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
118
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
119
- "license": "ISC",
120
- "bin": {
121
- "semver": "bin/semver.js"
122
- }
123
- },
124
- "node_modules/@babel/generator": {
125
- "version": "7.29.1",
126
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
127
- "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
128
- "license": "MIT",
129
- "dependencies": {
130
- "@babel/parser": "^7.29.0",
131
- "@babel/types": "^7.29.0",
132
- "@jridgewell/gen-mapping": "^0.3.12",
133
- "@jridgewell/trace-mapping": "^0.3.28",
134
- "jsesc": "^3.0.2"
135
- },
136
- "engines": {
137
- "node": ">=6.9.0"
138
- }
139
- },
140
- "node_modules/@babel/helper-annotate-as-pure": {
141
- "version": "7.27.3",
142
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
143
- "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
144
- "license": "MIT",
145
- "dependencies": {
146
- "@babel/types": "^7.27.3"
147
- },
148
- "engines": {
149
- "node": ">=6.9.0"
150
- }
151
- },
152
- "node_modules/@babel/helper-compilation-targets": {
153
- "version": "7.28.6",
154
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
155
- "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
156
- "license": "MIT",
157
- "dependencies": {
158
- "@babel/compat-data": "^7.28.6",
159
- "@babel/helper-validator-option": "^7.27.1",
160
- "browserslist": "^4.24.0",
161
- "lru-cache": "^5.1.1",
162
- "semver": "^6.3.1"
163
- },
164
- "engines": {
165
- "node": ">=6.9.0"
166
- }
167
- },
168
- "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
169
- "version": "6.3.1",
170
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
171
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
172
- "license": "ISC",
173
- "bin": {
174
- "semver": "bin/semver.js"
175
- }
176
- },
177
- "node_modules/@babel/helper-create-class-features-plugin": {
178
- "version": "7.28.6",
179
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
180
- "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
181
- "license": "MIT",
182
- "dependencies": {
183
- "@babel/helper-annotate-as-pure": "^7.27.3",
184
- "@babel/helper-member-expression-to-functions": "^7.28.5",
185
- "@babel/helper-optimise-call-expression": "^7.27.1",
186
- "@babel/helper-replace-supers": "^7.28.6",
187
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
188
- "@babel/traverse": "^7.28.6",
189
- "semver": "^6.3.1"
190
- },
191
- "engines": {
192
- "node": ">=6.9.0"
193
- },
194
- "peerDependencies": {
195
- "@babel/core": "^7.0.0"
196
- }
197
- },
198
- "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
199
- "version": "6.3.1",
200
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
201
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
202
- "license": "ISC",
203
- "bin": {
204
- "semver": "bin/semver.js"
205
- }
206
- },
207
- "node_modules/@babel/helper-create-regexp-features-plugin": {
208
- "version": "7.28.5",
209
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz",
210
- "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==",
211
- "license": "MIT",
212
- "dependencies": {
213
- "@babel/helper-annotate-as-pure": "^7.27.3",
214
- "regexpu-core": "^6.3.1",
215
- "semver": "^6.3.1"
216
- },
217
- "engines": {
218
- "node": ">=6.9.0"
219
- },
220
- "peerDependencies": {
221
- "@babel/core": "^7.0.0"
222
- }
223
- },
224
- "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
225
- "version": "6.3.1",
226
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
227
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
228
- "license": "ISC",
229
- "bin": {
230
- "semver": "bin/semver.js"
231
- }
232
- },
233
- "node_modules/@babel/helper-define-polyfill-provider": {
234
- "version": "0.6.6",
235
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz",
236
- "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==",
237
- "license": "MIT",
238
- "dependencies": {
239
- "@babel/helper-compilation-targets": "^7.28.6",
240
- "@babel/helper-plugin-utils": "^7.28.6",
241
- "debug": "^4.4.3",
242
- "lodash.debounce": "^4.0.8",
243
- "resolve": "^1.22.11"
244
- },
245
- "peerDependencies": {
246
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
247
- }
248
- },
249
- "node_modules/@babel/helper-globals": {
250
- "version": "7.28.0",
251
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
252
- "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
253
- "license": "MIT",
254
- "engines": {
255
- "node": ">=6.9.0"
256
- }
257
- },
258
- "node_modules/@babel/helper-member-expression-to-functions": {
259
- "version": "7.28.5",
260
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
261
- "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
262
- "license": "MIT",
263
- "dependencies": {
264
- "@babel/traverse": "^7.28.5",
265
- "@babel/types": "^7.28.5"
266
- },
267
- "engines": {
268
- "node": ">=6.9.0"
269
- }
270
- },
271
- "node_modules/@babel/helper-module-imports": {
272
- "version": "7.28.6",
273
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
274
- "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
275
- "license": "MIT",
276
- "dependencies": {
277
- "@babel/traverse": "^7.28.6",
278
- "@babel/types": "^7.28.6"
279
- },
280
- "engines": {
281
- "node": ">=6.9.0"
282
- }
283
- },
284
- "node_modules/@babel/helper-module-transforms": {
285
- "version": "7.28.6",
286
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
287
- "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
288
- "license": "MIT",
289
- "dependencies": {
290
- "@babel/helper-module-imports": "^7.28.6",
291
- "@babel/helper-validator-identifier": "^7.28.5",
292
- "@babel/traverse": "^7.28.6"
293
- },
294
- "engines": {
295
- "node": ">=6.9.0"
296
- },
297
- "peerDependencies": {
298
- "@babel/core": "^7.0.0"
299
- }
300
- },
301
- "node_modules/@babel/helper-optimise-call-expression": {
302
- "version": "7.27.1",
303
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
304
- "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
305
- "license": "MIT",
306
- "dependencies": {
307
- "@babel/types": "^7.27.1"
308
- },
309
- "engines": {
310
- "node": ">=6.9.0"
311
- }
312
- },
313
- "node_modules/@babel/helper-plugin-utils": {
314
- "version": "7.28.6",
315
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
316
- "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
317
- "license": "MIT",
318
- "engines": {
319
- "node": ">=6.9.0"
320
- }
321
- },
322
- "node_modules/@babel/helper-remap-async-to-generator": {
323
- "version": "7.27.1",
324
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
325
- "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
326
- "license": "MIT",
327
- "dependencies": {
328
- "@babel/helper-annotate-as-pure": "^7.27.1",
329
- "@babel/helper-wrap-function": "^7.27.1",
330
- "@babel/traverse": "^7.27.1"
331
- },
332
- "engines": {
333
- "node": ">=6.9.0"
334
- },
335
- "peerDependencies": {
336
- "@babel/core": "^7.0.0"
337
- }
338
- },
339
- "node_modules/@babel/helper-replace-supers": {
340
- "version": "7.28.6",
341
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
342
- "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
343
- "license": "MIT",
344
- "dependencies": {
345
- "@babel/helper-member-expression-to-functions": "^7.28.5",
346
- "@babel/helper-optimise-call-expression": "^7.27.1",
347
- "@babel/traverse": "^7.28.6"
348
- },
349
- "engines": {
350
- "node": ">=6.9.0"
351
- },
352
- "peerDependencies": {
353
- "@babel/core": "^7.0.0"
354
- }
355
- },
356
- "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
357
- "version": "7.27.1",
358
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
359
- "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
360
- "license": "MIT",
361
- "dependencies": {
362
- "@babel/traverse": "^7.27.1",
363
- "@babel/types": "^7.27.1"
364
- },
365
- "engines": {
366
- "node": ">=6.9.0"
367
- }
368
- },
369
- "node_modules/@babel/helper-string-parser": {
370
- "version": "7.27.1",
371
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
372
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
373
- "license": "MIT",
374
- "engines": {
375
- "node": ">=6.9.0"
376
- }
377
- },
378
- "node_modules/@babel/helper-validator-identifier": {
379
- "version": "7.28.5",
380
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
381
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
382
- "license": "MIT",
383
- "engines": {
384
- "node": ">=6.9.0"
385
- }
386
- },
387
- "node_modules/@babel/helper-validator-option": {
388
- "version": "7.27.1",
389
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
390
- "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
391
- "license": "MIT",
392
- "engines": {
393
- "node": ">=6.9.0"
394
- }
395
- },
396
- "node_modules/@babel/helper-wrap-function": {
397
- "version": "7.28.6",
398
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz",
399
- "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==",
400
- "license": "MIT",
401
- "dependencies": {
402
- "@babel/template": "^7.28.6",
403
- "@babel/traverse": "^7.28.6",
404
- "@babel/types": "^7.28.6"
405
- },
406
- "engines": {
407
- "node": ">=6.9.0"
408
- }
409
- },
410
- "node_modules/@babel/helpers": {
411
- "version": "7.28.6",
412
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
413
- "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
414
- "license": "MIT",
415
- "dependencies": {
416
- "@babel/template": "^7.28.6",
417
- "@babel/types": "^7.28.6"
418
- },
419
- "engines": {
420
- "node": ">=6.9.0"
421
- }
422
- },
423
- "node_modules/@babel/parser": {
424
- "version": "7.29.0",
425
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
426
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
427
- "license": "MIT",
428
- "dependencies": {
429
- "@babel/types": "^7.29.0"
430
- },
431
- "bin": {
432
- "parser": "bin/babel-parser.js"
433
- },
434
- "engines": {
435
- "node": ">=6.0.0"
436
- }
437
- },
438
- "node_modules/@babel/plugin-proposal-decorators": {
439
- "version": "7.29.0",
440
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz",
441
- "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==",
442
- "license": "MIT",
443
- "dependencies": {
444
- "@babel/helper-create-class-features-plugin": "^7.28.6",
445
- "@babel/helper-plugin-utils": "^7.28.6",
446
- "@babel/plugin-syntax-decorators": "^7.28.6"
447
- },
448
- "engines": {
449
- "node": ">=6.9.0"
450
- },
451
- "peerDependencies": {
452
- "@babel/core": "^7.0.0-0"
453
- }
454
- },
455
- "node_modules/@babel/plugin-proposal-export-default-from": {
456
- "version": "7.27.1",
457
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz",
458
- "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==",
459
- "license": "MIT",
460
- "dependencies": {
461
- "@babel/helper-plugin-utils": "^7.27.1"
462
- },
463
- "engines": {
464
- "node": ">=6.9.0"
465
- },
466
- "peerDependencies": {
467
- "@babel/core": "^7.0.0-0"
468
- }
469
- },
470
- "node_modules/@babel/plugin-syntax-async-generators": {
471
- "version": "7.8.4",
472
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
473
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
474
- "license": "MIT",
475
- "dependencies": {
476
- "@babel/helper-plugin-utils": "^7.8.0"
477
- },
478
- "peerDependencies": {
479
- "@babel/core": "^7.0.0-0"
480
- }
481
- },
482
- "node_modules/@babel/plugin-syntax-bigint": {
483
- "version": "7.8.3",
484
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
485
- "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
486
- "license": "MIT",
487
- "dependencies": {
488
- "@babel/helper-plugin-utils": "^7.8.0"
489
- },
490
- "peerDependencies": {
491
- "@babel/core": "^7.0.0-0"
492
- }
493
- },
494
- "node_modules/@babel/plugin-syntax-class-properties": {
495
- "version": "7.12.13",
496
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
497
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
498
- "license": "MIT",
499
- "dependencies": {
500
- "@babel/helper-plugin-utils": "^7.12.13"
501
- },
502
- "peerDependencies": {
503
- "@babel/core": "^7.0.0-0"
504
- }
505
- },
506
- "node_modules/@babel/plugin-syntax-class-static-block": {
507
- "version": "7.14.5",
508
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
509
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
510
- "license": "MIT",
511
- "dependencies": {
512
- "@babel/helper-plugin-utils": "^7.14.5"
513
- },
514
- "engines": {
515
- "node": ">=6.9.0"
516
- },
517
- "peerDependencies": {
518
- "@babel/core": "^7.0.0-0"
519
- }
520
- },
521
- "node_modules/@babel/plugin-syntax-decorators": {
522
- "version": "7.28.6",
523
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz",
524
- "integrity": "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==",
525
- "license": "MIT",
526
- "dependencies": {
527
- "@babel/helper-plugin-utils": "^7.28.6"
528
- },
529
- "engines": {
530
- "node": ">=6.9.0"
531
- },
532
- "peerDependencies": {
533
- "@babel/core": "^7.0.0-0"
534
- }
535
- },
536
- "node_modules/@babel/plugin-syntax-dynamic-import": {
537
- "version": "7.8.3",
538
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
539
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
540
- "license": "MIT",
541
- "dependencies": {
542
- "@babel/helper-plugin-utils": "^7.8.0"
543
- },
544
- "peerDependencies": {
545
- "@babel/core": "^7.0.0-0"
546
- }
547
- },
548
- "node_modules/@babel/plugin-syntax-export-default-from": {
549
- "version": "7.28.6",
550
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.28.6.tgz",
551
- "integrity": "sha512-Svlx1fjJFnNz0LZeUaybRukSxZI3KkpApUmIRzEdXC5k8ErTOz0OD0kNrICi5Vc3GlpP5ZCeRyRO+mfWTSz+iQ==",
552
- "license": "MIT",
553
- "dependencies": {
554
- "@babel/helper-plugin-utils": "^7.28.6"
555
- },
556
- "engines": {
557
- "node": ">=6.9.0"
558
- },
559
- "peerDependencies": {
560
- "@babel/core": "^7.0.0-0"
561
- }
562
- },
563
- "node_modules/@babel/plugin-syntax-flow": {
564
- "version": "7.28.6",
565
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.28.6.tgz",
566
- "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==",
567
- "license": "MIT",
568
- "dependencies": {
569
- "@babel/helper-plugin-utils": "^7.28.6"
570
- },
571
- "engines": {
572
- "node": ">=6.9.0"
573
- },
574
- "peerDependencies": {
575
- "@babel/core": "^7.0.0-0"
576
- }
577
- },
578
- "node_modules/@babel/plugin-syntax-import-attributes": {
579
- "version": "7.28.6",
580
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
581
- "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
582
- "license": "MIT",
583
- "dependencies": {
584
- "@babel/helper-plugin-utils": "^7.28.6"
585
- },
586
- "engines": {
587
- "node": ">=6.9.0"
588
- },
589
- "peerDependencies": {
590
- "@babel/core": "^7.0.0-0"
591
- }
592
- },
593
- "node_modules/@babel/plugin-syntax-import-meta": {
594
- "version": "7.10.4",
595
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
596
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
597
- "license": "MIT",
598
- "dependencies": {
599
- "@babel/helper-plugin-utils": "^7.10.4"
600
- },
601
- "peerDependencies": {
602
- "@babel/core": "^7.0.0-0"
603
- }
604
- },
605
- "node_modules/@babel/plugin-syntax-json-strings": {
606
- "version": "7.8.3",
607
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
608
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
609
- "license": "MIT",
610
- "dependencies": {
611
- "@babel/helper-plugin-utils": "^7.8.0"
612
- },
613
- "peerDependencies": {
614
- "@babel/core": "^7.0.0-0"
615
- }
616
- },
617
- "node_modules/@babel/plugin-syntax-jsx": {
618
- "version": "7.28.6",
619
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz",
620
- "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==",
621
- "license": "MIT",
622
- "dependencies": {
623
- "@babel/helper-plugin-utils": "^7.28.6"
624
- },
625
- "engines": {
626
- "node": ">=6.9.0"
627
- },
628
- "peerDependencies": {
629
- "@babel/core": "^7.0.0-0"
630
- }
631
- },
632
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
633
- "version": "7.10.4",
634
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
635
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
636
- "license": "MIT",
637
- "dependencies": {
638
- "@babel/helper-plugin-utils": "^7.10.4"
639
- },
640
- "peerDependencies": {
641
- "@babel/core": "^7.0.0-0"
642
- }
643
- },
644
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
645
- "version": "7.8.3",
646
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
647
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
648
- "license": "MIT",
649
- "dependencies": {
650
- "@babel/helper-plugin-utils": "^7.8.0"
651
- },
652
- "peerDependencies": {
653
- "@babel/core": "^7.0.0-0"
654
- }
655
- },
656
- "node_modules/@babel/plugin-syntax-numeric-separator": {
657
- "version": "7.10.4",
658
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
659
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
660
- "license": "MIT",
661
- "dependencies": {
662
- "@babel/helper-plugin-utils": "^7.10.4"
663
- },
664
- "peerDependencies": {
665
- "@babel/core": "^7.0.0-0"
666
- }
667
- },
668
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
669
- "version": "7.8.3",
670
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
671
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
672
- "license": "MIT",
673
- "dependencies": {
674
- "@babel/helper-plugin-utils": "^7.8.0"
675
- },
676
- "peerDependencies": {
677
- "@babel/core": "^7.0.0-0"
678
- }
679
- },
680
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
681
- "version": "7.8.3",
682
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
683
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
684
- "license": "MIT",
685
- "dependencies": {
686
- "@babel/helper-plugin-utils": "^7.8.0"
687
- },
688
- "peerDependencies": {
689
- "@babel/core": "^7.0.0-0"
690
- }
691
- },
692
- "node_modules/@babel/plugin-syntax-optional-chaining": {
693
- "version": "7.8.3",
694
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
695
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
696
- "license": "MIT",
697
- "dependencies": {
698
- "@babel/helper-plugin-utils": "^7.8.0"
699
- },
700
- "peerDependencies": {
701
- "@babel/core": "^7.0.0-0"
702
- }
703
- },
704
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
705
- "version": "7.14.5",
706
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
707
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
708
- "license": "MIT",
709
- "dependencies": {
710
- "@babel/helper-plugin-utils": "^7.14.5"
711
- },
712
- "engines": {
713
- "node": ">=6.9.0"
714
- },
715
- "peerDependencies": {
716
- "@babel/core": "^7.0.0-0"
717
- }
718
- },
719
- "node_modules/@babel/plugin-syntax-top-level-await": {
720
- "version": "7.14.5",
721
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
722
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
723
- "license": "MIT",
724
- "dependencies": {
725
- "@babel/helper-plugin-utils": "^7.14.5"
726
- },
727
- "engines": {
728
- "node": ">=6.9.0"
729
- },
730
- "peerDependencies": {
731
- "@babel/core": "^7.0.0-0"
732
- }
733
- },
734
- "node_modules/@babel/plugin-syntax-typescript": {
735
- "version": "7.28.6",
736
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
737
- "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
738
- "license": "MIT",
739
- "dependencies": {
740
- "@babel/helper-plugin-utils": "^7.28.6"
741
- },
742
- "engines": {
743
- "node": ">=6.9.0"
744
- },
745
- "peerDependencies": {
746
- "@babel/core": "^7.0.0-0"
747
- }
748
- },
749
- "node_modules/@babel/plugin-transform-arrow-functions": {
750
- "version": "7.27.1",
751
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
752
- "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
753
- "license": "MIT",
754
- "dependencies": {
755
- "@babel/helper-plugin-utils": "^7.27.1"
756
- },
757
- "engines": {
758
- "node": ">=6.9.0"
759
- },
760
- "peerDependencies": {
761
- "@babel/core": "^7.0.0-0"
762
- }
763
- },
764
- "node_modules/@babel/plugin-transform-async-generator-functions": {
765
- "version": "7.29.0",
766
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz",
767
- "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==",
768
- "license": "MIT",
769
- "dependencies": {
770
- "@babel/helper-plugin-utils": "^7.28.6",
771
- "@babel/helper-remap-async-to-generator": "^7.27.1",
772
- "@babel/traverse": "^7.29.0"
773
- },
774
- "engines": {
775
- "node": ">=6.9.0"
776
- },
777
- "peerDependencies": {
778
- "@babel/core": "^7.0.0-0"
779
- }
780
- },
781
- "node_modules/@babel/plugin-transform-async-to-generator": {
782
- "version": "7.28.6",
783
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz",
784
- "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==",
785
- "license": "MIT",
786
- "dependencies": {
787
- "@babel/helper-module-imports": "^7.28.6",
788
- "@babel/helper-plugin-utils": "^7.28.6",
789
- "@babel/helper-remap-async-to-generator": "^7.27.1"
790
- },
791
- "engines": {
792
- "node": ">=6.9.0"
793
- },
794
- "peerDependencies": {
795
- "@babel/core": "^7.0.0-0"
796
- }
797
- },
798
- "node_modules/@babel/plugin-transform-block-scoping": {
799
- "version": "7.28.6",
800
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz",
801
- "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==",
802
- "license": "MIT",
803
- "dependencies": {
804
- "@babel/helper-plugin-utils": "^7.28.6"
805
- },
806
- "engines": {
807
- "node": ">=6.9.0"
808
- },
809
- "peerDependencies": {
810
- "@babel/core": "^7.0.0-0"
811
- }
812
- },
813
- "node_modules/@babel/plugin-transform-class-properties": {
814
- "version": "7.28.6",
815
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz",
816
- "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==",
817
- "license": "MIT",
818
- "dependencies": {
819
- "@babel/helper-create-class-features-plugin": "^7.28.6",
820
- "@babel/helper-plugin-utils": "^7.28.6"
821
- },
822
- "engines": {
823
- "node": ">=6.9.0"
824
- },
825
- "peerDependencies": {
826
- "@babel/core": "^7.0.0-0"
827
- }
828
- },
829
- "node_modules/@babel/plugin-transform-class-static-block": {
830
- "version": "7.28.6",
831
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz",
832
- "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==",
833
- "license": "MIT",
834
- "dependencies": {
835
- "@babel/helper-create-class-features-plugin": "^7.28.6",
836
- "@babel/helper-plugin-utils": "^7.28.6"
837
- },
838
- "engines": {
839
- "node": ">=6.9.0"
840
- },
841
- "peerDependencies": {
842
- "@babel/core": "^7.12.0"
843
- }
844
- },
845
- "node_modules/@babel/plugin-transform-classes": {
846
- "version": "7.28.6",
847
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz",
848
- "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==",
849
- "license": "MIT",
850
- "dependencies": {
851
- "@babel/helper-annotate-as-pure": "^7.27.3",
852
- "@babel/helper-compilation-targets": "^7.28.6",
853
- "@babel/helper-globals": "^7.28.0",
854
- "@babel/helper-plugin-utils": "^7.28.6",
855
- "@babel/helper-replace-supers": "^7.28.6",
856
- "@babel/traverse": "^7.28.6"
857
- },
858
- "engines": {
859
- "node": ">=6.9.0"
860
- },
861
- "peerDependencies": {
862
- "@babel/core": "^7.0.0-0"
863
- }
864
- },
865
- "node_modules/@babel/plugin-transform-computed-properties": {
866
- "version": "7.28.6",
867
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz",
868
- "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==",
869
- "license": "MIT",
870
- "dependencies": {
871
- "@babel/helper-plugin-utils": "^7.28.6",
872
- "@babel/template": "^7.28.6"
873
- },
874
- "engines": {
875
- "node": ">=6.9.0"
876
- },
877
- "peerDependencies": {
878
- "@babel/core": "^7.0.0-0"
879
- }
880
- },
881
- "node_modules/@babel/plugin-transform-destructuring": {
882
- "version": "7.28.5",
883
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
884
- "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
885
- "license": "MIT",
886
- "dependencies": {
887
- "@babel/helper-plugin-utils": "^7.27.1",
888
- "@babel/traverse": "^7.28.5"
889
- },
890
- "engines": {
891
- "node": ">=6.9.0"
892
- },
893
- "peerDependencies": {
894
- "@babel/core": "^7.0.0-0"
895
- }
896
- },
897
- "node_modules/@babel/plugin-transform-export-namespace-from": {
898
- "version": "7.27.1",
899
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
900
- "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
901
- "license": "MIT",
902
- "dependencies": {
903
- "@babel/helper-plugin-utils": "^7.27.1"
904
- },
905
- "engines": {
906
- "node": ">=6.9.0"
907
- },
908
- "peerDependencies": {
909
- "@babel/core": "^7.0.0-0"
910
- }
911
- },
912
- "node_modules/@babel/plugin-transform-flow-strip-types": {
913
- "version": "7.27.1",
914
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz",
915
- "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==",
916
- "license": "MIT",
917
- "dependencies": {
918
- "@babel/helper-plugin-utils": "^7.27.1",
919
- "@babel/plugin-syntax-flow": "^7.27.1"
920
- },
921
- "engines": {
922
- "node": ">=6.9.0"
923
- },
924
- "peerDependencies": {
925
- "@babel/core": "^7.0.0-0"
926
- }
927
- },
928
- "node_modules/@babel/plugin-transform-for-of": {
929
- "version": "7.27.1",
930
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
931
- "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
932
- "license": "MIT",
933
- "dependencies": {
934
- "@babel/helper-plugin-utils": "^7.27.1",
935
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
936
- },
937
- "engines": {
938
- "node": ">=6.9.0"
939
- },
940
- "peerDependencies": {
941
- "@babel/core": "^7.0.0-0"
942
- }
943
- },
944
- "node_modules/@babel/plugin-transform-function-name": {
945
- "version": "7.27.1",
946
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
947
- "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
948
- "license": "MIT",
949
- "dependencies": {
950
- "@babel/helper-compilation-targets": "^7.27.1",
951
- "@babel/helper-plugin-utils": "^7.27.1",
952
- "@babel/traverse": "^7.27.1"
953
- },
954
- "engines": {
955
- "node": ">=6.9.0"
956
- },
957
- "peerDependencies": {
958
- "@babel/core": "^7.0.0-0"
959
- }
960
- },
961
- "node_modules/@babel/plugin-transform-literals": {
962
- "version": "7.27.1",
963
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
964
- "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
965
- "license": "MIT",
966
- "dependencies": {
967
- "@babel/helper-plugin-utils": "^7.27.1"
968
- },
969
- "engines": {
970
- "node": ">=6.9.0"
971
- },
972
- "peerDependencies": {
973
- "@babel/core": "^7.0.0-0"
974
- }
975
- },
976
- "node_modules/@babel/plugin-transform-logical-assignment-operators": {
977
- "version": "7.28.6",
978
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz",
979
- "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==",
980
- "license": "MIT",
981
- "dependencies": {
982
- "@babel/helper-plugin-utils": "^7.28.6"
983
- },
984
- "engines": {
985
- "node": ">=6.9.0"
986
- },
987
- "peerDependencies": {
988
- "@babel/core": "^7.0.0-0"
989
- }
990
- },
991
- "node_modules/@babel/plugin-transform-modules-commonjs": {
992
- "version": "7.28.6",
993
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz",
994
- "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==",
995
- "license": "MIT",
996
- "dependencies": {
997
- "@babel/helper-module-transforms": "^7.28.6",
998
- "@babel/helper-plugin-utils": "^7.28.6"
999
- },
1000
- "engines": {
1001
- "node": ">=6.9.0"
1002
- },
1003
- "peerDependencies": {
1004
- "@babel/core": "^7.0.0-0"
1005
- }
1006
- },
1007
- "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
1008
- "version": "7.29.0",
1009
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz",
1010
- "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==",
1011
- "license": "MIT",
1012
- "dependencies": {
1013
- "@babel/helper-create-regexp-features-plugin": "^7.28.5",
1014
- "@babel/helper-plugin-utils": "^7.28.6"
1015
- },
1016
- "engines": {
1017
- "node": ">=6.9.0"
1018
- },
1019
- "peerDependencies": {
1020
- "@babel/core": "^7.0.0"
1021
- }
1022
- },
1023
- "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
1024
- "version": "7.28.6",
1025
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz",
1026
- "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==",
1027
- "license": "MIT",
1028
- "dependencies": {
1029
- "@babel/helper-plugin-utils": "^7.28.6"
1030
- },
1031
- "engines": {
1032
- "node": ">=6.9.0"
1033
- },
1034
- "peerDependencies": {
1035
- "@babel/core": "^7.0.0-0"
1036
- }
1037
- },
1038
- "node_modules/@babel/plugin-transform-numeric-separator": {
1039
- "version": "7.28.6",
1040
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz",
1041
- "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==",
1042
- "license": "MIT",
1043
- "dependencies": {
1044
- "@babel/helper-plugin-utils": "^7.28.6"
1045
- },
1046
- "engines": {
1047
- "node": ">=6.9.0"
1048
- },
1049
- "peerDependencies": {
1050
- "@babel/core": "^7.0.0-0"
1051
- }
1052
- },
1053
- "node_modules/@babel/plugin-transform-object-rest-spread": {
1054
- "version": "7.28.6",
1055
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz",
1056
- "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==",
1057
- "license": "MIT",
1058
- "dependencies": {
1059
- "@babel/helper-compilation-targets": "^7.28.6",
1060
- "@babel/helper-plugin-utils": "^7.28.6",
1061
- "@babel/plugin-transform-destructuring": "^7.28.5",
1062
- "@babel/plugin-transform-parameters": "^7.27.7",
1063
- "@babel/traverse": "^7.28.6"
1064
- },
1065
- "engines": {
1066
- "node": ">=6.9.0"
1067
- },
1068
- "peerDependencies": {
1069
- "@babel/core": "^7.0.0-0"
1070
- }
1071
- },
1072
- "node_modules/@babel/plugin-transform-optional-catch-binding": {
1073
- "version": "7.28.6",
1074
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz",
1075
- "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==",
1076
- "license": "MIT",
1077
- "dependencies": {
1078
- "@babel/helper-plugin-utils": "^7.28.6"
1079
- },
1080
- "engines": {
1081
- "node": ">=6.9.0"
1082
- },
1083
- "peerDependencies": {
1084
- "@babel/core": "^7.0.0-0"
1085
- }
1086
- },
1087
- "node_modules/@babel/plugin-transform-optional-chaining": {
1088
- "version": "7.28.6",
1089
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz",
1090
- "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==",
1091
- "license": "MIT",
1092
- "dependencies": {
1093
- "@babel/helper-plugin-utils": "^7.28.6",
1094
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
1095
- },
1096
- "engines": {
1097
- "node": ">=6.9.0"
1098
- },
1099
- "peerDependencies": {
1100
- "@babel/core": "^7.0.0-0"
1101
- }
1102
- },
1103
- "node_modules/@babel/plugin-transform-parameters": {
1104
- "version": "7.27.7",
1105
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
1106
- "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
1107
- "license": "MIT",
1108
- "dependencies": {
1109
- "@babel/helper-plugin-utils": "^7.27.1"
1110
- },
1111
- "engines": {
1112
- "node": ">=6.9.0"
1113
- },
1114
- "peerDependencies": {
1115
- "@babel/core": "^7.0.0-0"
1116
- }
1117
- },
1118
- "node_modules/@babel/plugin-transform-private-methods": {
1119
- "version": "7.28.6",
1120
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz",
1121
- "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==",
1122
- "license": "MIT",
1123
- "dependencies": {
1124
- "@babel/helper-create-class-features-plugin": "^7.28.6",
1125
- "@babel/helper-plugin-utils": "^7.28.6"
1126
- },
1127
- "engines": {
1128
- "node": ">=6.9.0"
1129
- },
1130
- "peerDependencies": {
1131
- "@babel/core": "^7.0.0-0"
1132
- }
1133
- },
1134
- "node_modules/@babel/plugin-transform-private-property-in-object": {
1135
- "version": "7.28.6",
1136
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz",
1137
- "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==",
1138
- "license": "MIT",
1139
- "dependencies": {
1140
- "@babel/helper-annotate-as-pure": "^7.27.3",
1141
- "@babel/helper-create-class-features-plugin": "^7.28.6",
1142
- "@babel/helper-plugin-utils": "^7.28.6"
1143
- },
1144
- "engines": {
1145
- "node": ">=6.9.0"
1146
- },
1147
- "peerDependencies": {
1148
- "@babel/core": "^7.0.0-0"
1149
- }
1150
- },
1151
- "node_modules/@babel/plugin-transform-react-display-name": {
1152
- "version": "7.28.0",
1153
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz",
1154
- "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==",
1155
- "license": "MIT",
1156
- "dependencies": {
1157
- "@babel/helper-plugin-utils": "^7.27.1"
1158
- },
1159
- "engines": {
1160
- "node": ">=6.9.0"
1161
- },
1162
- "peerDependencies": {
1163
- "@babel/core": "^7.0.0-0"
1164
- }
1165
- },
1166
- "node_modules/@babel/plugin-transform-react-jsx": {
1167
- "version": "7.28.6",
1168
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz",
1169
- "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==",
1170
- "license": "MIT",
1171
- "dependencies": {
1172
- "@babel/helper-annotate-as-pure": "^7.27.3",
1173
- "@babel/helper-module-imports": "^7.28.6",
1174
- "@babel/helper-plugin-utils": "^7.28.6",
1175
- "@babel/plugin-syntax-jsx": "^7.28.6",
1176
- "@babel/types": "^7.28.6"
1177
- },
1178
- "engines": {
1179
- "node": ">=6.9.0"
1180
- },
1181
- "peerDependencies": {
1182
- "@babel/core": "^7.0.0-0"
1183
- }
1184
- },
1185
- "node_modules/@babel/plugin-transform-react-jsx-development": {
1186
- "version": "7.27.1",
1187
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz",
1188
- "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==",
1189
- "license": "MIT",
1190
- "dependencies": {
1191
- "@babel/plugin-transform-react-jsx": "^7.27.1"
1192
- },
1193
- "engines": {
1194
- "node": ">=6.9.0"
1195
- },
1196
- "peerDependencies": {
1197
- "@babel/core": "^7.0.0-0"
1198
- }
1199
- },
1200
- "node_modules/@babel/plugin-transform-react-jsx-self": {
1201
- "version": "7.27.1",
1202
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
1203
- "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
1204
- "license": "MIT",
1205
- "dependencies": {
1206
- "@babel/helper-plugin-utils": "^7.27.1"
1207
- },
1208
- "engines": {
1209
- "node": ">=6.9.0"
1210
- },
1211
- "peerDependencies": {
1212
- "@babel/core": "^7.0.0-0"
1213
- }
1214
- },
1215
- "node_modules/@babel/plugin-transform-react-jsx-source": {
1216
- "version": "7.27.1",
1217
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
1218
- "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
1219
- "license": "MIT",
1220
- "dependencies": {
1221
- "@babel/helper-plugin-utils": "^7.27.1"
1222
- },
1223
- "engines": {
1224
- "node": ">=6.9.0"
1225
- },
1226
- "peerDependencies": {
1227
- "@babel/core": "^7.0.0-0"
1228
- }
1229
- },
1230
- "node_modules/@babel/plugin-transform-react-pure-annotations": {
1231
- "version": "7.27.1",
1232
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz",
1233
- "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==",
1234
- "license": "MIT",
1235
- "dependencies": {
1236
- "@babel/helper-annotate-as-pure": "^7.27.1",
1237
- "@babel/helper-plugin-utils": "^7.27.1"
1238
- },
1239
- "engines": {
1240
- "node": ">=6.9.0"
1241
- },
1242
- "peerDependencies": {
1243
- "@babel/core": "^7.0.0-0"
1244
- }
1245
- },
1246
- "node_modules/@babel/plugin-transform-regenerator": {
1247
- "version": "7.29.0",
1248
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz",
1249
- "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==",
1250
- "license": "MIT",
1251
- "dependencies": {
1252
- "@babel/helper-plugin-utils": "^7.28.6"
1253
- },
1254
- "engines": {
1255
- "node": ">=6.9.0"
1256
- },
1257
- "peerDependencies": {
1258
- "@babel/core": "^7.0.0-0"
1259
- }
1260
- },
1261
- "node_modules/@babel/plugin-transform-runtime": {
1262
- "version": "7.29.0",
1263
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz",
1264
- "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==",
1265
- "license": "MIT",
1266
- "dependencies": {
1267
- "@babel/helper-module-imports": "^7.28.6",
1268
- "@babel/helper-plugin-utils": "^7.28.6",
1269
- "babel-plugin-polyfill-corejs2": "^0.4.14",
1270
- "babel-plugin-polyfill-corejs3": "^0.13.0",
1271
- "babel-plugin-polyfill-regenerator": "^0.6.5",
1272
- "semver": "^6.3.1"
1273
- },
1274
- "engines": {
1275
- "node": ">=6.9.0"
1276
- },
1277
- "peerDependencies": {
1278
- "@babel/core": "^7.0.0-0"
1279
- }
1280
- },
1281
- "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
1282
- "version": "6.3.1",
1283
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1284
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
1285
- "license": "ISC",
1286
- "bin": {
1287
- "semver": "bin/semver.js"
1288
- }
1289
- },
1290
- "node_modules/@babel/plugin-transform-shorthand-properties": {
1291
- "version": "7.27.1",
1292
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
1293
- "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
1294
- "license": "MIT",
1295
- "dependencies": {
1296
- "@babel/helper-plugin-utils": "^7.27.1"
1297
- },
1298
- "engines": {
1299
- "node": ">=6.9.0"
1300
- },
1301
- "peerDependencies": {
1302
- "@babel/core": "^7.0.0-0"
1303
- }
1304
- },
1305
- "node_modules/@babel/plugin-transform-spread": {
1306
- "version": "7.28.6",
1307
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz",
1308
- "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==",
1309
- "license": "MIT",
1310
- "dependencies": {
1311
- "@babel/helper-plugin-utils": "^7.28.6",
1312
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
1313
- },
1314
- "engines": {
1315
- "node": ">=6.9.0"
1316
- },
1317
- "peerDependencies": {
1318
- "@babel/core": "^7.0.0-0"
1319
- }
1320
- },
1321
- "node_modules/@babel/plugin-transform-sticky-regex": {
1322
- "version": "7.27.1",
1323
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
1324
- "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
1325
- "license": "MIT",
1326
- "dependencies": {
1327
- "@babel/helper-plugin-utils": "^7.27.1"
1328
- },
1329
- "engines": {
1330
- "node": ">=6.9.0"
1331
- },
1332
- "peerDependencies": {
1333
- "@babel/core": "^7.0.0-0"
1334
- }
1335
- },
1336
- "node_modules/@babel/plugin-transform-template-literals": {
1337
- "version": "7.27.1",
1338
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
1339
- "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
1340
- "license": "MIT",
1341
- "dependencies": {
1342
- "@babel/helper-plugin-utils": "^7.27.1"
1343
- },
1344
- "engines": {
1345
- "node": ">=6.9.0"
1346
- },
1347
- "peerDependencies": {
1348
- "@babel/core": "^7.0.0-0"
1349
- }
1350
- },
1351
- "node_modules/@babel/plugin-transform-typescript": {
1352
- "version": "7.28.6",
1353
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz",
1354
- "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==",
1355
- "license": "MIT",
1356
- "dependencies": {
1357
- "@babel/helper-annotate-as-pure": "^7.27.3",
1358
- "@babel/helper-create-class-features-plugin": "^7.28.6",
1359
- "@babel/helper-plugin-utils": "^7.28.6",
1360
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
1361
- "@babel/plugin-syntax-typescript": "^7.28.6"
1362
- },
1363
- "engines": {
1364
- "node": ">=6.9.0"
1365
- },
1366
- "peerDependencies": {
1367
- "@babel/core": "^7.0.0-0"
1368
- }
1369
- },
1370
- "node_modules/@babel/plugin-transform-unicode-regex": {
1371
- "version": "7.27.1",
1372
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
1373
- "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
1374
- "license": "MIT",
1375
- "dependencies": {
1376
- "@babel/helper-create-regexp-features-plugin": "^7.27.1",
1377
- "@babel/helper-plugin-utils": "^7.27.1"
1378
- },
1379
- "engines": {
1380
- "node": ">=6.9.0"
1381
- },
1382
- "peerDependencies": {
1383
- "@babel/core": "^7.0.0-0"
1384
- }
1385
- },
1386
- "node_modules/@babel/preset-react": {
1387
- "version": "7.28.5",
1388
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz",
1389
- "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==",
1390
- "license": "MIT",
1391
- "dependencies": {
1392
- "@babel/helper-plugin-utils": "^7.27.1",
1393
- "@babel/helper-validator-option": "^7.27.1",
1394
- "@babel/plugin-transform-react-display-name": "^7.28.0",
1395
- "@babel/plugin-transform-react-jsx": "^7.27.1",
1396
- "@babel/plugin-transform-react-jsx-development": "^7.27.1",
1397
- "@babel/plugin-transform-react-pure-annotations": "^7.27.1"
1398
- },
1399
- "engines": {
1400
- "node": ">=6.9.0"
1401
- },
1402
- "peerDependencies": {
1403
- "@babel/core": "^7.0.0-0"
1404
- }
1405
- },
1406
- "node_modules/@babel/preset-typescript": {
1407
- "version": "7.28.5",
1408
- "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz",
1409
- "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==",
1410
- "license": "MIT",
1411
- "dependencies": {
1412
- "@babel/helper-plugin-utils": "^7.27.1",
1413
- "@babel/helper-validator-option": "^7.27.1",
1414
- "@babel/plugin-syntax-jsx": "^7.27.1",
1415
- "@babel/plugin-transform-modules-commonjs": "^7.27.1",
1416
- "@babel/plugin-transform-typescript": "^7.28.5"
1417
- },
1418
- "engines": {
1419
- "node": ">=6.9.0"
1420
- },
1421
- "peerDependencies": {
1422
- "@babel/core": "^7.0.0-0"
1423
- }
1424
- },
1425
- "node_modules/@babel/runtime": {
1426
- "version": "7.28.6",
1427
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
1428
- "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
1429
- "license": "MIT",
1430
- "engines": {
1431
- "node": ">=6.9.0"
1432
- }
1433
- },
1434
- "node_modules/@babel/template": {
1435
- "version": "7.28.6",
1436
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
1437
- "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
1438
- "license": "MIT",
1439
- "dependencies": {
1440
- "@babel/code-frame": "^7.28.6",
1441
- "@babel/parser": "^7.28.6",
1442
- "@babel/types": "^7.28.6"
1443
- },
1444
- "engines": {
1445
- "node": ">=6.9.0"
1446
- }
1447
- },
1448
- "node_modules/@babel/traverse": {
1449
- "version": "7.29.0",
1450
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
1451
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
1452
- "license": "MIT",
1453
- "dependencies": {
1454
- "@babel/code-frame": "^7.29.0",
1455
- "@babel/generator": "^7.29.0",
1456
- "@babel/helper-globals": "^7.28.0",
1457
- "@babel/parser": "^7.29.0",
1458
- "@babel/template": "^7.28.6",
1459
- "@babel/types": "^7.29.0",
1460
- "debug": "^4.3.1"
1461
- },
1462
- "engines": {
1463
- "node": ">=6.9.0"
1464
- }
1465
- },
1466
- "node_modules/@babel/traverse--for-generate-function-map": {
1467
- "name": "@babel/traverse",
1468
- "version": "7.29.0",
1469
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
1470
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
1471
- "license": "MIT",
1472
- "dependencies": {
1473
- "@babel/code-frame": "^7.29.0",
1474
- "@babel/generator": "^7.29.0",
1475
- "@babel/helper-globals": "^7.28.0",
1476
- "@babel/parser": "^7.29.0",
1477
- "@babel/template": "^7.28.6",
1478
- "@babel/types": "^7.29.0",
1479
- "debug": "^4.3.1"
1480
- },
1481
- "engines": {
1482
- "node": ">=6.9.0"
1483
- }
1484
- },
1485
- "node_modules/@babel/types": {
1486
- "version": "7.29.0",
1487
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
1488
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
1489
- "license": "MIT",
1490
- "dependencies": {
1491
- "@babel/helper-string-parser": "^7.27.1",
1492
- "@babel/helper-validator-identifier": "^7.28.5"
1493
- },
1494
- "engines": {
1495
- "node": ">=6.9.0"
1496
- }
1497
- },
1498
- "node_modules/@egjs/hammerjs": {
1499
- "version": "2.0.17",
1500
- "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
1501
- "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
1502
- "license": "MIT",
1503
- "dependencies": {
1504
- "@types/hammerjs": "^2.0.36"
1505
- },
1506
- "engines": {
1507
- "node": ">=0.8.0"
1508
- }
1509
- },
1510
- "node_modules/@expo-google-fonts/material-symbols": {
1511
- "version": "0.4.24",
1512
- "resolved": "https://registry.npmjs.org/@expo-google-fonts/material-symbols/-/material-symbols-0.4.24.tgz",
1513
- "integrity": "sha512-1bJ63Yv2Bn8SN2MjrlbwLwUhnC8COOeejd15H88WjCtw5iNErqEPaBnpvmYyqciVYwudGo5drUIdY9C/5yPGbg==",
1514
- "license": "MIT AND Apache-2.0"
1515
- },
1516
- "node_modules/@expo/code-signing-certificates": {
1517
- "version": "0.0.6",
1518
- "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz",
1519
- "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==",
1520
- "license": "MIT",
1521
- "dependencies": {
1522
- "node-forge": "^1.3.3"
1523
- }
1524
- },
1525
- "node_modules/@expo/config": {
1526
- "version": "55.0.8",
1527
- "resolved": "https://registry.npmjs.org/@expo/config/-/config-55.0.8.tgz",
1528
- "integrity": "sha512-D7RYYHfErCgEllGxNwdYdkgzLna7zkzUECBV3snbUpf7RvIpB5l1LpCgzuVoc5KVew5h7N1Tn4LnT/tBSUZsQg==",
1529
- "license": "MIT",
1530
- "dependencies": {
1531
- "@expo/config-plugins": "~55.0.6",
1532
- "@expo/config-types": "^55.0.5",
1533
- "@expo/json-file": "^10.0.12",
1534
- "@expo/require-utils": "^55.0.2",
1535
- "deepmerge": "^4.3.1",
1536
- "getenv": "^2.0.0",
1537
- "glob": "^13.0.0",
1538
- "resolve-from": "^5.0.0",
1539
- "resolve-workspace-root": "^2.0.0",
1540
- "semver": "^7.6.0",
1541
- "slugify": "^1.3.4"
1542
- }
1543
- },
1544
- "node_modules/@expo/config-plugins": {
1545
- "version": "55.0.6",
1546
- "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-55.0.6.tgz",
1547
- "integrity": "sha512-cIox6FjZlFaaX40rbQ3DvP9e87S5X85H9uw+BAxJE5timkMhuByy3GAlOsj1h96EyzSiol7Q6YIGgY1Jiz4M+A==",
1548
- "license": "MIT",
1549
- "dependencies": {
1550
- "@expo/config-types": "^55.0.5",
1551
- "@expo/json-file": "~10.0.12",
1552
- "@expo/plist": "^0.5.2",
1553
- "@expo/sdk-runtime-versions": "^1.0.0",
1554
- "chalk": "^4.1.2",
1555
- "debug": "^4.3.5",
1556
- "getenv": "^2.0.0",
1557
- "glob": "^13.0.0",
1558
- "resolve-from": "^5.0.0",
1559
- "semver": "^7.5.4",
1560
- "slugify": "^1.6.6",
1561
- "xcode": "^3.0.1",
1562
- "xml2js": "0.6.0"
1563
- }
1564
- },
1565
- "node_modules/@expo/config-types": {
1566
- "version": "55.0.5",
1567
- "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-55.0.5.tgz",
1568
- "integrity": "sha512-sCmSUZG4mZ/ySXvfyyBdhjivz8Q539X1NondwDdYG7s3SBsk+wsgPJzYsqgAG/P9+l0xWjUD2F+kQ1cAJ6NNLg==",
1569
- "license": "MIT"
1570
- },
1571
- "node_modules/@expo/devcert": {
1572
- "version": "1.2.1",
1573
- "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz",
1574
- "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==",
1575
- "license": "MIT",
1576
- "dependencies": {
1577
- "@expo/sudo-prompt": "^9.3.1",
1578
- "debug": "^3.1.0"
1579
- }
1580
- },
1581
- "node_modules/@expo/devcert/node_modules/debug": {
1582
- "version": "3.2.7",
1583
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
1584
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
1585
- "license": "MIT",
1586
- "dependencies": {
1587
- "ms": "^2.1.1"
1588
- }
1589
- },
1590
- "node_modules/@expo/devtools": {
1591
- "version": "55.0.2",
1592
- "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-55.0.2.tgz",
1593
- "integrity": "sha512-4VsFn9MUriocyuhyA+ycJP3TJhUsOFHDc270l9h3LhNpXMf6wvIdGcA0QzXkZtORXmlDybWXRP2KT1k36HcQkA==",
1594
- "license": "MIT",
1595
- "dependencies": {
1596
- "chalk": "^4.1.2"
1597
- },
1598
- "peerDependencies": {
1599
- "react": "*",
1600
- "react-native": "*"
1601
- },
1602
- "peerDependenciesMeta": {
1603
- "react": {
1604
- "optional": true
1605
- },
1606
- "react-native": {
1607
- "optional": true
1608
- }
1609
- }
1610
- },
1611
- "node_modules/@expo/dom-webview": {
1612
- "version": "55.0.3",
1613
- "resolved": "https://registry.npmjs.org/@expo/dom-webview/-/dom-webview-55.0.3.tgz",
1614
- "integrity": "sha512-bY4/rfcZ0f43DvOtMn8/kmPlmo01tex5hRoc5hKbwBwQjqWQuQt0ACwu7akR9IHI4j0WNG48eL6cZB6dZUFrzg==",
1615
- "license": "MIT",
1616
- "peerDependencies": {
1617
- "expo": "*",
1618
- "react": "*",
1619
- "react-native": "*"
1620
- }
1621
- },
1622
- "node_modules/@expo/env": {
1623
- "version": "2.1.1",
1624
- "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.1.1.tgz",
1625
- "integrity": "sha512-rVvHC4I6xlPcg+mAO09ydUi2Wjv1ZytpLmHOSzvXzBAz9mMrJggqCe4s4dubjJvi/Ino/xQCLhbaLCnTtLpikg==",
1626
- "license": "MIT",
1627
- "dependencies": {
1628
- "chalk": "^4.0.0",
1629
- "debug": "^4.3.4",
1630
- "getenv": "^2.0.0"
1631
- },
1632
- "engines": {
1633
- "node": ">=20.12.0"
1634
- }
1635
- },
1636
- "node_modules/@expo/fingerprint": {
1637
- "version": "0.16.5",
1638
- "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.16.5.tgz",
1639
- "integrity": "sha512-mLrcymtgkW9IJ/G1e8MH1Xt2VIb1MOS86ePY0ePcnV3nVyJqm7gfa/AXD1Hk+eZXvf8XhioYz6QZaamBdEzR3A==",
1640
- "license": "MIT",
1641
- "dependencies": {
1642
- "@expo/env": "^2.0.11",
1643
- "@expo/spawn-async": "^1.7.2",
1644
- "arg": "^5.0.2",
1645
- "chalk": "^4.1.2",
1646
- "debug": "^4.3.4",
1647
- "getenv": "^2.0.0",
1648
- "glob": "^13.0.0",
1649
- "ignore": "^5.3.1",
1650
- "minimatch": "^10.2.2",
1651
- "resolve-from": "^5.0.0",
1652
- "semver": "^7.6.0"
1653
- },
1654
- "bin": {
1655
- "fingerprint": "bin/cli.js"
1656
- }
1657
- },
1658
- "node_modules/@expo/image-utils": {
1659
- "version": "0.8.12",
1660
- "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.12.tgz",
1661
- "integrity": "sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==",
1662
- "license": "MIT",
1663
- "dependencies": {
1664
- "@expo/spawn-async": "^1.7.2",
1665
- "chalk": "^4.0.0",
1666
- "getenv": "^2.0.0",
1667
- "jimp-compact": "0.16.1",
1668
- "parse-png": "^2.1.0",
1669
- "resolve-from": "^5.0.0",
1670
- "semver": "^7.6.0"
1671
- }
1672
- },
1673
- "node_modules/@expo/json-file": {
1674
- "version": "10.0.12",
1675
- "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.12.tgz",
1676
- "integrity": "sha512-inbDycp1rMAelAofg7h/mMzIe+Owx6F7pur3XdQ3EPTy00tme+4P6FWgHKUcjN8dBSrnbRNpSyh5/shzHyVCyQ==",
1677
- "license": "MIT",
1678
- "dependencies": {
1679
- "@babel/code-frame": "^7.20.0",
1680
- "json5": "^2.2.3"
1681
- }
1682
- },
1683
- "node_modules/@expo/local-build-cache-provider": {
1684
- "version": "55.0.6",
1685
- "resolved": "https://registry.npmjs.org/@expo/local-build-cache-provider/-/local-build-cache-provider-55.0.6.tgz",
1686
- "integrity": "sha512-4kfdv48sKzokijMqi07fINYA9/XprshmPgSLf8i69XgzIv2YdRyBbb70SzrufB7PDneFoltz8N83icW8gOOj1g==",
1687
- "license": "MIT",
1688
- "dependencies": {
1689
- "@expo/config": "~55.0.8",
1690
- "chalk": "^4.1.2"
1691
- }
1692
- },
1693
- "node_modules/@expo/log-box": {
1694
- "version": "55.0.7",
1695
- "resolved": "https://registry.npmjs.org/@expo/log-box/-/log-box-55.0.7.tgz",
1696
- "integrity": "sha512-m7V1k2vlMp4NOj3fopjOg4zl/ANXyTRF3HMTMep2GZAKsPiDzgOQ41nm8CaU50/HlDIGXlCObss07gOn20UpHQ==",
1697
- "license": "MIT",
1698
- "dependencies": {
1699
- "@expo/dom-webview": "^55.0.3",
1700
- "anser": "^1.4.9",
1701
- "stacktrace-parser": "^0.1.10"
1702
- },
1703
- "peerDependencies": {
1704
- "@expo/dom-webview": "^55.0.3",
1705
- "expo": "*",
1706
- "react": "*",
1707
- "react-native": "*"
1708
- }
1709
- },
1710
- "node_modules/@expo/metro": {
1711
- "version": "54.2.0",
1712
- "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.2.0.tgz",
1713
- "integrity": "sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w==",
1714
- "license": "MIT",
1715
- "dependencies": {
1716
- "metro": "0.83.3",
1717
- "metro-babel-transformer": "0.83.3",
1718
- "metro-cache": "0.83.3",
1719
- "metro-cache-key": "0.83.3",
1720
- "metro-config": "0.83.3",
1721
- "metro-core": "0.83.3",
1722
- "metro-file-map": "0.83.3",
1723
- "metro-minify-terser": "0.83.3",
1724
- "metro-resolver": "0.83.3",
1725
- "metro-runtime": "0.83.3",
1726
- "metro-source-map": "0.83.3",
1727
- "metro-symbolicate": "0.83.3",
1728
- "metro-transform-plugins": "0.83.3",
1729
- "metro-transform-worker": "0.83.3"
1730
- }
1731
- },
1732
- "node_modules/@expo/osascript": {
1733
- "version": "2.4.2",
1734
- "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.4.2.tgz",
1735
- "integrity": "sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw==",
1736
- "license": "MIT",
1737
- "dependencies": {
1738
- "@expo/spawn-async": "^1.7.2"
1739
- },
1740
- "engines": {
1741
- "node": ">=12"
1742
- }
1743
- },
1744
- "node_modules/@expo/package-manager": {
1745
- "version": "1.10.3",
1746
- "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.10.3.tgz",
1747
- "integrity": "sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A==",
1748
- "license": "MIT",
1749
- "dependencies": {
1750
- "@expo/json-file": "^10.0.12",
1751
- "@expo/spawn-async": "^1.7.2",
1752
- "chalk": "^4.0.0",
1753
- "npm-package-arg": "^11.0.0",
1754
- "ora": "^3.4.0",
1755
- "resolve-workspace-root": "^2.0.0"
1756
- }
1757
- },
1758
- "node_modules/@expo/plist": {
1759
- "version": "0.5.2",
1760
- "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.5.2.tgz",
1761
- "integrity": "sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g==",
1762
- "license": "MIT",
1763
- "dependencies": {
1764
- "@xmldom/xmldom": "^0.8.8",
1765
- "base64-js": "^1.5.1",
1766
- "xmlbuilder": "^15.1.1"
1767
- }
1768
- },
1769
- "node_modules/@expo/prebuild-config": {
1770
- "version": "55.0.8",
1771
- "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-55.0.8.tgz",
1772
- "integrity": "sha512-VJNJiOmmZgyDnR7JMmc3B8Z0ZepZ17I8Wtw+wAH/2+UCUsFg588XU+bwgYcFGw+is28kwGjY46z43kfufpxOnA==",
1773
- "license": "MIT",
1774
- "dependencies": {
1775
- "@expo/config": "~55.0.8",
1776
- "@expo/config-plugins": "~55.0.6",
1777
- "@expo/config-types": "^55.0.5",
1778
- "@expo/image-utils": "^0.8.12",
1779
- "@expo/json-file": "^10.0.12",
1780
- "@react-native/normalize-colors": "0.83.2",
1781
- "debug": "^4.3.1",
1782
- "resolve-from": "^5.0.0",
1783
- "semver": "^7.6.0",
1784
- "xml2js": "0.6.0"
1785
- },
1786
- "peerDependencies": {
1787
- "expo": "*"
1788
- }
1789
- },
1790
- "node_modules/@expo/require-utils": {
1791
- "version": "55.0.2",
1792
- "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-55.0.2.tgz",
1793
- "integrity": "sha512-dV5oCShQ1umKBKagMMT4B/N+SREsQe3lU4Zgmko5AO0rxKV0tynZT6xXs+e2JxuqT4Rz997atg7pki0BnZb4uw==",
1794
- "license": "MIT",
1795
- "dependencies": {
1796
- "@babel/code-frame": "^7.20.0",
1797
- "@babel/core": "^7.25.2",
1798
- "@babel/plugin-transform-modules-commonjs": "^7.24.8"
1799
- },
1800
- "peerDependencies": {
1801
- "typescript": "^5.0.0 || ^5.0.0-0"
1802
- },
1803
- "peerDependenciesMeta": {
1804
- "typescript": {
1805
- "optional": true
1806
- }
1807
- }
1808
- },
1809
- "node_modules/@expo/schema-utils": {
1810
- "version": "55.0.2",
1811
- "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-55.0.2.tgz",
1812
- "integrity": "sha512-QZ5WKbJOWkCrMq0/kfhV9ry8te/OaS34YgLVpG8u9y2gix96TlpRTbxM/YATjNcUR2s4fiQmPCOxkGtog4i37g==",
1813
- "license": "MIT"
1814
- },
1815
- "node_modules/@expo/sdk-runtime-versions": {
1816
- "version": "1.0.0",
1817
- "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
1818
- "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==",
1819
- "license": "MIT"
1820
- },
1821
- "node_modules/@expo/spawn-async": {
1822
- "version": "1.7.2",
1823
- "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz",
1824
- "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==",
1825
- "license": "MIT",
1826
- "dependencies": {
1827
- "cross-spawn": "^7.0.3"
1828
- },
1829
- "engines": {
1830
- "node": ">=12"
1831
- }
1832
- },
1833
- "node_modules/@expo/sudo-prompt": {
1834
- "version": "9.3.2",
1835
- "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz",
1836
- "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
1837
- "license": "MIT"
1838
- },
1839
- "node_modules/@expo/ws-tunnel": {
1840
- "version": "1.0.6",
1841
- "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz",
1842
- "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==",
1843
- "license": "MIT"
1844
- },
1845
- "node_modules/@expo/xcpretty": {
1846
- "version": "4.4.1",
1847
- "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz",
1848
- "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==",
1849
- "license": "BSD-3-Clause",
1850
- "dependencies": {
1851
- "@babel/code-frame": "^7.20.0",
1852
- "chalk": "^4.1.0",
1853
- "js-yaml": "^4.1.0"
1854
- },
1855
- "bin": {
1856
- "excpretty": "build/cli.js"
1857
- }
1858
- },
1859
- "node_modules/@expo/xcpretty/node_modules/argparse": {
1860
- "version": "2.0.1",
1861
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1862
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1863
- "license": "Python-2.0"
1864
- },
1865
- "node_modules/@expo/xcpretty/node_modules/js-yaml": {
1866
- "version": "4.1.1",
1867
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
1868
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
1869
- "license": "MIT",
1870
- "dependencies": {
1871
- "argparse": "^2.0.1"
1872
- },
1873
- "bin": {
1874
- "js-yaml": "bin/js-yaml.js"
1875
- }
1876
- },
1877
- "node_modules/@isaacs/ttlcache": {
1878
- "version": "1.4.1",
1879
- "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz",
1880
- "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==",
1881
- "license": "ISC",
1882
- "engines": {
1883
- "node": ">=12"
1884
- }
1885
- },
1886
- "node_modules/@istanbuljs/load-nyc-config": {
1887
- "version": "1.1.0",
1888
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
1889
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
1890
- "license": "ISC",
1891
- "dependencies": {
1892
- "camelcase": "^5.3.1",
1893
- "find-up": "^4.1.0",
1894
- "get-package-type": "^0.1.0",
1895
- "js-yaml": "^3.13.1",
1896
- "resolve-from": "^5.0.0"
1897
- },
1898
- "engines": {
1899
- "node": ">=8"
1900
- }
1901
- },
1902
- "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": {
1903
- "version": "5.3.1",
1904
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
1905
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
1906
- "license": "MIT",
1907
- "engines": {
1908
- "node": ">=6"
1909
- }
1910
- },
1911
- "node_modules/@istanbuljs/schema": {
1912
- "version": "0.1.3",
1913
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
1914
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
1915
- "license": "MIT",
1916
- "engines": {
1917
- "node": ">=8"
1918
- }
1919
- },
1920
- "node_modules/@jest/create-cache-key-function": {
1921
- "version": "29.7.0",
1922
- "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
1923
- "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
1924
- "license": "MIT",
1925
- "dependencies": {
1926
- "@jest/types": "^29.6.3"
1927
- },
1928
- "engines": {
1929
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1930
- }
1931
- },
1932
- "node_modules/@jest/environment": {
1933
- "version": "29.7.0",
1934
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
1935
- "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
1936
- "license": "MIT",
1937
- "dependencies": {
1938
- "@jest/fake-timers": "^29.7.0",
1939
- "@jest/types": "^29.6.3",
1940
- "@types/node": "*",
1941
- "jest-mock": "^29.7.0"
1942
- },
1943
- "engines": {
1944
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1945
- }
1946
- },
1947
- "node_modules/@jest/fake-timers": {
1948
- "version": "29.7.0",
1949
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
1950
- "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
1951
- "license": "MIT",
1952
- "dependencies": {
1953
- "@jest/types": "^29.6.3",
1954
- "@sinonjs/fake-timers": "^10.0.2",
1955
- "@types/node": "*",
1956
- "jest-message-util": "^29.7.0",
1957
- "jest-mock": "^29.7.0",
1958
- "jest-util": "^29.7.0"
1959
- },
1960
- "engines": {
1961
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1962
- }
1963
- },
1964
- "node_modules/@jest/schemas": {
1965
- "version": "29.6.3",
1966
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
1967
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
1968
- "license": "MIT",
1969
- "dependencies": {
1970
- "@sinclair/typebox": "^0.27.8"
1971
- },
1972
- "engines": {
1973
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1974
- }
1975
- },
1976
- "node_modules/@jest/transform": {
1977
- "version": "29.7.0",
1978
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
1979
- "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
1980
- "license": "MIT",
1981
- "dependencies": {
1982
- "@babel/core": "^7.11.6",
1983
- "@jest/types": "^29.6.3",
1984
- "@jridgewell/trace-mapping": "^0.3.18",
1985
- "babel-plugin-istanbul": "^6.1.1",
1986
- "chalk": "^4.0.0",
1987
- "convert-source-map": "^2.0.0",
1988
- "fast-json-stable-stringify": "^2.1.0",
1989
- "graceful-fs": "^4.2.9",
1990
- "jest-haste-map": "^29.7.0",
1991
- "jest-regex-util": "^29.6.3",
1992
- "jest-util": "^29.7.0",
1993
- "micromatch": "^4.0.4",
1994
- "pirates": "^4.0.4",
1995
- "slash": "^3.0.0",
1996
- "write-file-atomic": "^4.0.2"
1997
- },
1998
- "engines": {
1999
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
2000
- }
2001
- },
2002
- "node_modules/@jest/types": {
2003
- "version": "29.6.3",
2004
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
2005
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
2006
- "license": "MIT",
2007
- "dependencies": {
2008
- "@jest/schemas": "^29.6.3",
2009
- "@types/istanbul-lib-coverage": "^2.0.0",
2010
- "@types/istanbul-reports": "^3.0.0",
2011
- "@types/node": "*",
2012
- "@types/yargs": "^17.0.8",
2013
- "chalk": "^4.0.0"
2014
- },
2015
- "engines": {
2016
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
2017
- }
2018
- },
2019
- "node_modules/@jridgewell/gen-mapping": {
2020
- "version": "0.3.13",
2021
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
2022
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
2023
- "license": "MIT",
2024
- "dependencies": {
2025
- "@jridgewell/sourcemap-codec": "^1.5.0",
2026
- "@jridgewell/trace-mapping": "^0.3.24"
2027
- }
2028
- },
2029
- "node_modules/@jridgewell/remapping": {
2030
- "version": "2.3.5",
2031
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
2032
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
2033
- "license": "MIT",
2034
- "dependencies": {
2035
- "@jridgewell/gen-mapping": "^0.3.5",
2036
- "@jridgewell/trace-mapping": "^0.3.24"
2037
- }
2038
- },
2039
- "node_modules/@jridgewell/resolve-uri": {
2040
- "version": "3.1.2",
2041
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
2042
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
2043
- "license": "MIT",
2044
- "engines": {
2045
- "node": ">=6.0.0"
2046
- }
2047
- },
2048
- "node_modules/@jridgewell/source-map": {
2049
- "version": "0.3.11",
2050
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
2051
- "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
2052
- "license": "MIT",
2053
- "dependencies": {
2054
- "@jridgewell/gen-mapping": "^0.3.5",
2055
- "@jridgewell/trace-mapping": "^0.3.25"
2056
- }
2057
- },
2058
- "node_modules/@jridgewell/sourcemap-codec": {
2059
- "version": "1.5.5",
2060
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
2061
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
2062
- "license": "MIT"
2063
- },
2064
- "node_modules/@jridgewell/trace-mapping": {
2065
- "version": "0.3.31",
2066
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
2067
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
2068
- "license": "MIT",
2069
- "dependencies": {
2070
- "@jridgewell/resolve-uri": "^3.1.0",
2071
- "@jridgewell/sourcemap-codec": "^1.4.14"
2072
- }
2073
- },
2074
- "node_modules/@nodelib/fs.scandir": {
2075
- "version": "2.1.5",
2076
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
2077
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
2078
- "dev": true,
2079
- "license": "MIT",
2080
- "dependencies": {
2081
- "@nodelib/fs.stat": "2.0.5",
2082
- "run-parallel": "^1.1.9"
2083
- },
2084
- "engines": {
2085
- "node": ">= 8"
2086
- }
2087
- },
2088
- "node_modules/@nodelib/fs.stat": {
2089
- "version": "2.0.5",
2090
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
2091
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
2092
- "dev": true,
2093
- "license": "MIT",
2094
- "engines": {
2095
- "node": ">= 8"
2096
- }
2097
- },
2098
- "node_modules/@nodelib/fs.walk": {
2099
- "version": "1.2.8",
2100
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
2101
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
2102
- "dev": true,
2103
- "license": "MIT",
2104
- "dependencies": {
2105
- "@nodelib/fs.scandir": "2.1.5",
2106
- "fastq": "^1.6.0"
2107
- },
2108
- "engines": {
2109
- "node": ">= 8"
2110
- }
2111
- },
2112
- "node_modules/@radix-ui/primitive": {
2113
- "version": "1.1.3",
2114
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
2115
- "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
2116
- "license": "MIT"
2117
- },
2118
- "node_modules/@radix-ui/react-collection": {
2119
- "version": "1.1.7",
2120
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
2121
- "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
2122
- "license": "MIT",
2123
- "dependencies": {
2124
- "@radix-ui/react-compose-refs": "1.1.2",
2125
- "@radix-ui/react-context": "1.1.2",
2126
- "@radix-ui/react-primitive": "2.1.3",
2127
- "@radix-ui/react-slot": "1.2.3"
2128
- },
2129
- "peerDependencies": {
2130
- "@types/react": "*",
2131
- "@types/react-dom": "*",
2132
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2133
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2134
- },
2135
- "peerDependenciesMeta": {
2136
- "@types/react": {
2137
- "optional": true
2138
- },
2139
- "@types/react-dom": {
2140
- "optional": true
2141
- }
2142
- }
2143
- },
2144
- "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
2145
- "version": "1.2.3",
2146
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
2147
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
2148
- "license": "MIT",
2149
- "dependencies": {
2150
- "@radix-ui/react-compose-refs": "1.1.2"
2151
- },
2152
- "peerDependencies": {
2153
- "@types/react": "*",
2154
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2155
- },
2156
- "peerDependenciesMeta": {
2157
- "@types/react": {
2158
- "optional": true
2159
- }
2160
- }
2161
- },
2162
- "node_modules/@radix-ui/react-compose-refs": {
2163
- "version": "1.1.2",
2164
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
2165
- "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
2166
- "license": "MIT",
2167
- "peerDependencies": {
2168
- "@types/react": "*",
2169
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2170
- },
2171
- "peerDependenciesMeta": {
2172
- "@types/react": {
2173
- "optional": true
2174
- }
2175
- }
2176
- },
2177
- "node_modules/@radix-ui/react-context": {
2178
- "version": "1.1.2",
2179
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
2180
- "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
2181
- "license": "MIT",
2182
- "peerDependencies": {
2183
- "@types/react": "*",
2184
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2185
- },
2186
- "peerDependenciesMeta": {
2187
- "@types/react": {
2188
- "optional": true
2189
- }
2190
- }
2191
- },
2192
- "node_modules/@radix-ui/react-dialog": {
2193
- "version": "1.1.15",
2194
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
2195
- "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
2196
- "license": "MIT",
2197
- "dependencies": {
2198
- "@radix-ui/primitive": "1.1.3",
2199
- "@radix-ui/react-compose-refs": "1.1.2",
2200
- "@radix-ui/react-context": "1.1.2",
2201
- "@radix-ui/react-dismissable-layer": "1.1.11",
2202
- "@radix-ui/react-focus-guards": "1.1.3",
2203
- "@radix-ui/react-focus-scope": "1.1.7",
2204
- "@radix-ui/react-id": "1.1.1",
2205
- "@radix-ui/react-portal": "1.1.9",
2206
- "@radix-ui/react-presence": "1.1.5",
2207
- "@radix-ui/react-primitive": "2.1.3",
2208
- "@radix-ui/react-slot": "1.2.3",
2209
- "@radix-ui/react-use-controllable-state": "1.2.2",
2210
- "aria-hidden": "^1.2.4",
2211
- "react-remove-scroll": "^2.6.3"
2212
- },
2213
- "peerDependencies": {
2214
- "@types/react": "*",
2215
- "@types/react-dom": "*",
2216
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2217
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2218
- },
2219
- "peerDependenciesMeta": {
2220
- "@types/react": {
2221
- "optional": true
2222
- },
2223
- "@types/react-dom": {
2224
- "optional": true
2225
- }
2226
- }
2227
- },
2228
- "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
2229
- "version": "1.2.3",
2230
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
2231
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
2232
- "license": "MIT",
2233
- "dependencies": {
2234
- "@radix-ui/react-compose-refs": "1.1.2"
2235
- },
2236
- "peerDependencies": {
2237
- "@types/react": "*",
2238
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2239
- },
2240
- "peerDependenciesMeta": {
2241
- "@types/react": {
2242
- "optional": true
2243
- }
2244
- }
2245
- },
2246
- "node_modules/@radix-ui/react-direction": {
2247
- "version": "1.1.1",
2248
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
2249
- "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
2250
- "license": "MIT",
2251
- "peerDependencies": {
2252
- "@types/react": "*",
2253
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2254
- },
2255
- "peerDependenciesMeta": {
2256
- "@types/react": {
2257
- "optional": true
2258
- }
2259
- }
2260
- },
2261
- "node_modules/@radix-ui/react-dismissable-layer": {
2262
- "version": "1.1.11",
2263
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
2264
- "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
2265
- "license": "MIT",
2266
- "dependencies": {
2267
- "@radix-ui/primitive": "1.1.3",
2268
- "@radix-ui/react-compose-refs": "1.1.2",
2269
- "@radix-ui/react-primitive": "2.1.3",
2270
- "@radix-ui/react-use-callback-ref": "1.1.1",
2271
- "@radix-ui/react-use-escape-keydown": "1.1.1"
2272
- },
2273
- "peerDependencies": {
2274
- "@types/react": "*",
2275
- "@types/react-dom": "*",
2276
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2277
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2278
- },
2279
- "peerDependenciesMeta": {
2280
- "@types/react": {
2281
- "optional": true
2282
- },
2283
- "@types/react-dom": {
2284
- "optional": true
2285
- }
2286
- }
2287
- },
2288
- "node_modules/@radix-ui/react-focus-guards": {
2289
- "version": "1.1.3",
2290
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
2291
- "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
2292
- "license": "MIT",
2293
- "peerDependencies": {
2294
- "@types/react": "*",
2295
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2296
- },
2297
- "peerDependenciesMeta": {
2298
- "@types/react": {
2299
- "optional": true
2300
- }
2301
- }
2302
- },
2303
- "node_modules/@radix-ui/react-focus-scope": {
2304
- "version": "1.1.7",
2305
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
2306
- "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
2307
- "license": "MIT",
2308
- "dependencies": {
2309
- "@radix-ui/react-compose-refs": "1.1.2",
2310
- "@radix-ui/react-primitive": "2.1.3",
2311
- "@radix-ui/react-use-callback-ref": "1.1.1"
2312
- },
2313
- "peerDependencies": {
2314
- "@types/react": "*",
2315
- "@types/react-dom": "*",
2316
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2317
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2318
- },
2319
- "peerDependenciesMeta": {
2320
- "@types/react": {
2321
- "optional": true
2322
- },
2323
- "@types/react-dom": {
2324
- "optional": true
2325
- }
2326
- }
2327
- },
2328
- "node_modules/@radix-ui/react-id": {
2329
- "version": "1.1.1",
2330
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
2331
- "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
2332
- "license": "MIT",
2333
- "dependencies": {
2334
- "@radix-ui/react-use-layout-effect": "1.1.1"
2335
- },
2336
- "peerDependencies": {
2337
- "@types/react": "*",
2338
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2339
- },
2340
- "peerDependenciesMeta": {
2341
- "@types/react": {
2342
- "optional": true
2343
- }
2344
- }
2345
- },
2346
- "node_modules/@radix-ui/react-portal": {
2347
- "version": "1.1.9",
2348
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
2349
- "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
2350
- "license": "MIT",
2351
- "dependencies": {
2352
- "@radix-ui/react-primitive": "2.1.3",
2353
- "@radix-ui/react-use-layout-effect": "1.1.1"
2354
- },
2355
- "peerDependencies": {
2356
- "@types/react": "*",
2357
- "@types/react-dom": "*",
2358
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2359
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2360
- },
2361
- "peerDependenciesMeta": {
2362
- "@types/react": {
2363
- "optional": true
2364
- },
2365
- "@types/react-dom": {
2366
- "optional": true
2367
- }
2368
- }
2369
- },
2370
- "node_modules/@radix-ui/react-presence": {
2371
- "version": "1.1.5",
2372
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
2373
- "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
2374
- "license": "MIT",
2375
- "dependencies": {
2376
- "@radix-ui/react-compose-refs": "1.1.2",
2377
- "@radix-ui/react-use-layout-effect": "1.1.1"
2378
- },
2379
- "peerDependencies": {
2380
- "@types/react": "*",
2381
- "@types/react-dom": "*",
2382
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2383
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2384
- },
2385
- "peerDependenciesMeta": {
2386
- "@types/react": {
2387
- "optional": true
2388
- },
2389
- "@types/react-dom": {
2390
- "optional": true
2391
- }
2392
- }
2393
- },
2394
- "node_modules/@radix-ui/react-primitive": {
2395
- "version": "2.1.3",
2396
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
2397
- "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
2398
- "license": "MIT",
2399
- "dependencies": {
2400
- "@radix-ui/react-slot": "1.2.3"
2401
- },
2402
- "peerDependencies": {
2403
- "@types/react": "*",
2404
- "@types/react-dom": "*",
2405
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2406
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2407
- },
2408
- "peerDependenciesMeta": {
2409
- "@types/react": {
2410
- "optional": true
2411
- },
2412
- "@types/react-dom": {
2413
- "optional": true
2414
- }
2415
- }
2416
- },
2417
- "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
2418
- "version": "1.2.3",
2419
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
2420
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
2421
- "license": "MIT",
2422
- "dependencies": {
2423
- "@radix-ui/react-compose-refs": "1.1.2"
2424
- },
2425
- "peerDependencies": {
2426
- "@types/react": "*",
2427
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2428
- },
2429
- "peerDependenciesMeta": {
2430
- "@types/react": {
2431
- "optional": true
2432
- }
2433
- }
2434
- },
2435
- "node_modules/@radix-ui/react-roving-focus": {
2436
- "version": "1.1.11",
2437
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
2438
- "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
2439
- "license": "MIT",
2440
- "dependencies": {
2441
- "@radix-ui/primitive": "1.1.3",
2442
- "@radix-ui/react-collection": "1.1.7",
2443
- "@radix-ui/react-compose-refs": "1.1.2",
2444
- "@radix-ui/react-context": "1.1.2",
2445
- "@radix-ui/react-direction": "1.1.1",
2446
- "@radix-ui/react-id": "1.1.1",
2447
- "@radix-ui/react-primitive": "2.1.3",
2448
- "@radix-ui/react-use-callback-ref": "1.1.1",
2449
- "@radix-ui/react-use-controllable-state": "1.2.2"
2450
- },
2451
- "peerDependencies": {
2452
- "@types/react": "*",
2453
- "@types/react-dom": "*",
2454
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2455
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2456
- },
2457
- "peerDependenciesMeta": {
2458
- "@types/react": {
2459
- "optional": true
2460
- },
2461
- "@types/react-dom": {
2462
- "optional": true
2463
- }
2464
- }
2465
- },
2466
- "node_modules/@radix-ui/react-slot": {
2467
- "version": "1.2.4",
2468
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
2469
- "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
2470
- "license": "MIT",
2471
- "dependencies": {
2472
- "@radix-ui/react-compose-refs": "1.1.2"
2473
- },
2474
- "peerDependencies": {
2475
- "@types/react": "*",
2476
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2477
- },
2478
- "peerDependenciesMeta": {
2479
- "@types/react": {
2480
- "optional": true
2481
- }
2482
- }
2483
- },
2484
- "node_modules/@radix-ui/react-use-callback-ref": {
2485
- "version": "1.1.1",
2486
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
2487
- "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
2488
- "license": "MIT",
2489
- "peerDependencies": {
2490
- "@types/react": "*",
2491
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2492
- },
2493
- "peerDependenciesMeta": {
2494
- "@types/react": {
2495
- "optional": true
2496
- }
2497
- }
2498
- },
2499
- "node_modules/@radix-ui/react-use-controllable-state": {
2500
- "version": "1.2.2",
2501
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
2502
- "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
2503
- "license": "MIT",
2504
- "dependencies": {
2505
- "@radix-ui/react-use-effect-event": "0.0.2",
2506
- "@radix-ui/react-use-layout-effect": "1.1.1"
2507
- },
2508
- "peerDependencies": {
2509
- "@types/react": "*",
2510
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2511
- },
2512
- "peerDependenciesMeta": {
2513
- "@types/react": {
2514
- "optional": true
2515
- }
2516
- }
2517
- },
2518
- "node_modules/@radix-ui/react-use-effect-event": {
2519
- "version": "0.0.2",
2520
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
2521
- "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
2522
- "license": "MIT",
2523
- "dependencies": {
2524
- "@radix-ui/react-use-layout-effect": "1.1.1"
2525
- },
2526
- "peerDependencies": {
2527
- "@types/react": "*",
2528
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2529
- },
2530
- "peerDependenciesMeta": {
2531
- "@types/react": {
2532
- "optional": true
2533
- }
2534
- }
2535
- },
2536
- "node_modules/@radix-ui/react-use-escape-keydown": {
2537
- "version": "1.1.1",
2538
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
2539
- "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
2540
- "license": "MIT",
2541
- "dependencies": {
2542
- "@radix-ui/react-use-callback-ref": "1.1.1"
2543
- },
2544
- "peerDependencies": {
2545
- "@types/react": "*",
2546
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2547
- },
2548
- "peerDependenciesMeta": {
2549
- "@types/react": {
2550
- "optional": true
2551
- }
2552
- }
2553
- },
2554
- "node_modules/@radix-ui/react-use-layout-effect": {
2555
- "version": "1.1.1",
2556
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
2557
- "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
2558
- "license": "MIT",
2559
- "peerDependencies": {
2560
- "@types/react": "*",
2561
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2562
- },
2563
- "peerDependenciesMeta": {
2564
- "@types/react": {
2565
- "optional": true
2566
- }
2567
- }
2568
- },
2569
- "node_modules/@react-native/assets-registry": {
2570
- "version": "0.83.2",
2571
- "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.83.2.tgz",
2572
- "integrity": "sha512-9I5l3pGAKnlpQ15uVkeB9Mgjvt3cZEaEc8EDtdexvdtZvLSjtwBzgourrOW4yZUijbjJr8h3YO2Y0q+THwUHTA==",
2573
- "license": "MIT",
2574
- "engines": {
2575
- "node": ">= 20.19.4"
2576
- }
2577
- },
2578
- "node_modules/@react-native/babel-plugin-codegen": {
2579
- "version": "0.83.2",
2580
- "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.83.2.tgz",
2581
- "integrity": "sha512-XbcN/BEa64pVlb0Hb/E/Ph2SepjVN/FcNKrJcQvtaKZA6mBSO8pW8Eircdlr61/KBH94LihHbQoQDzkQFpeaTg==",
2582
- "license": "MIT",
2583
- "dependencies": {
2584
- "@babel/traverse": "^7.25.3",
2585
- "@react-native/codegen": "0.83.2"
2586
- },
2587
- "engines": {
2588
- "node": ">= 20.19.4"
2589
- }
2590
- },
2591
- "node_modules/@react-native/babel-preset": {
2592
- "version": "0.83.2",
2593
- "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.83.2.tgz",
2594
- "integrity": "sha512-X/RAXDfe6W+om/Fw1i6htTxQXFhBJ2jgNOWx3WpI3KbjeIWbq7ib6vrpTeIAW2NUMg+K3mML1NzgD4dpZeqdjA==",
2595
- "license": "MIT",
2596
- "dependencies": {
2597
- "@babel/core": "^7.25.2",
2598
- "@babel/plugin-proposal-export-default-from": "^7.24.7",
2599
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
2600
- "@babel/plugin-syntax-export-default-from": "^7.24.7",
2601
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
2602
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
2603
- "@babel/plugin-transform-arrow-functions": "^7.24.7",
2604
- "@babel/plugin-transform-async-generator-functions": "^7.25.4",
2605
- "@babel/plugin-transform-async-to-generator": "^7.24.7",
2606
- "@babel/plugin-transform-block-scoping": "^7.25.0",
2607
- "@babel/plugin-transform-class-properties": "^7.25.4",
2608
- "@babel/plugin-transform-classes": "^7.25.4",
2609
- "@babel/plugin-transform-computed-properties": "^7.24.7",
2610
- "@babel/plugin-transform-destructuring": "^7.24.8",
2611
- "@babel/plugin-transform-flow-strip-types": "^7.25.2",
2612
- "@babel/plugin-transform-for-of": "^7.24.7",
2613
- "@babel/plugin-transform-function-name": "^7.25.1",
2614
- "@babel/plugin-transform-literals": "^7.25.2",
2615
- "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
2616
- "@babel/plugin-transform-modules-commonjs": "^7.24.8",
2617
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
2618
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
2619
- "@babel/plugin-transform-numeric-separator": "^7.24.7",
2620
- "@babel/plugin-transform-object-rest-spread": "^7.24.7",
2621
- "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
2622
- "@babel/plugin-transform-optional-chaining": "^7.24.8",
2623
- "@babel/plugin-transform-parameters": "^7.24.7",
2624
- "@babel/plugin-transform-private-methods": "^7.24.7",
2625
- "@babel/plugin-transform-private-property-in-object": "^7.24.7",
2626
- "@babel/plugin-transform-react-display-name": "^7.24.7",
2627
- "@babel/plugin-transform-react-jsx": "^7.25.2",
2628
- "@babel/plugin-transform-react-jsx-self": "^7.24.7",
2629
- "@babel/plugin-transform-react-jsx-source": "^7.24.7",
2630
- "@babel/plugin-transform-regenerator": "^7.24.7",
2631
- "@babel/plugin-transform-runtime": "^7.24.7",
2632
- "@babel/plugin-transform-shorthand-properties": "^7.24.7",
2633
- "@babel/plugin-transform-spread": "^7.24.7",
2634
- "@babel/plugin-transform-sticky-regex": "^7.24.7",
2635
- "@babel/plugin-transform-typescript": "^7.25.2",
2636
- "@babel/plugin-transform-unicode-regex": "^7.24.7",
2637
- "@babel/template": "^7.25.0",
2638
- "@react-native/babel-plugin-codegen": "0.83.2",
2639
- "babel-plugin-syntax-hermes-parser": "0.32.0",
2640
- "babel-plugin-transform-flow-enums": "^0.0.2",
2641
- "react-refresh": "^0.14.0"
2642
- },
2643
- "engines": {
2644
- "node": ">= 20.19.4"
2645
- },
2646
- "peerDependencies": {
2647
- "@babel/core": "*"
2648
- }
2649
- },
2650
- "node_modules/@react-native/codegen": {
2651
- "version": "0.83.2",
2652
- "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.83.2.tgz",
2653
- "integrity": "sha512-9uK6X1miCXqtL4c759l74N/XbQeneWeQVjoV7SD2CGJuW7ZefxaoYenwGPs7rMoCdtS6wuIyR3hXQ+uWEBGYXA==",
2654
- "license": "MIT",
2655
- "dependencies": {
2656
- "@babel/core": "^7.25.2",
2657
- "@babel/parser": "^7.25.3",
2658
- "glob": "^7.1.1",
2659
- "hermes-parser": "0.32.0",
2660
- "invariant": "^2.2.4",
2661
- "nullthrows": "^1.1.1",
2662
- "yargs": "^17.6.2"
2663
- },
2664
- "engines": {
2665
- "node": ">= 20.19.4"
2666
- },
2667
- "peerDependencies": {
2668
- "@babel/core": "*"
2669
- }
2670
- },
2671
- "node_modules/@react-native/codegen/node_modules/balanced-match": {
2672
- "version": "1.0.2",
2673
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
2674
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
2675
- "license": "MIT"
2676
- },
2677
- "node_modules/@react-native/codegen/node_modules/brace-expansion": {
2678
- "version": "1.1.12",
2679
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
2680
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
2681
- "license": "MIT",
2682
- "dependencies": {
2683
- "balanced-match": "^1.0.0",
2684
- "concat-map": "0.0.1"
2685
- }
2686
- },
2687
- "node_modules/@react-native/codegen/node_modules/glob": {
2688
- "version": "7.2.3",
2689
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
2690
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
2691
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
2692
- "license": "ISC",
2693
- "dependencies": {
2694
- "fs.realpath": "^1.0.0",
2695
- "inflight": "^1.0.4",
2696
- "inherits": "2",
2697
- "minimatch": "^3.1.1",
2698
- "once": "^1.3.0",
2699
- "path-is-absolute": "^1.0.0"
2700
- },
2701
- "engines": {
2702
- "node": "*"
2703
- },
2704
- "funding": {
2705
- "url": "https://github.com/sponsors/isaacs"
2706
- }
2707
- },
2708
- "node_modules/@react-native/codegen/node_modules/minimatch": {
2709
- "version": "3.1.5",
2710
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
2711
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
2712
- "license": "ISC",
2713
- "dependencies": {
2714
- "brace-expansion": "^1.1.7"
2715
- },
2716
- "engines": {
2717
- "node": "*"
2718
- }
2719
- },
2720
- "node_modules/@react-native/community-cli-plugin": {
2721
- "version": "0.83.2",
2722
- "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.83.2.tgz",
2723
- "integrity": "sha512-sTEF0eiUKtmImEP07Qo5c3Khvm1LIVX1Qyb6zWUqPL6W3MqFiXutZvKBjqLz6p49Szx8cplQLoXfLHT0bcDXKg==",
2724
- "license": "MIT",
2725
- "dependencies": {
2726
- "@react-native/dev-middleware": "0.83.2",
2727
- "debug": "^4.4.0",
2728
- "invariant": "^2.2.4",
2729
- "metro": "^0.83.3",
2730
- "metro-config": "^0.83.3",
2731
- "metro-core": "^0.83.3",
2732
- "semver": "^7.1.3"
2733
- },
2734
- "engines": {
2735
- "node": ">= 20.19.4"
2736
- },
2737
- "peerDependencies": {
2738
- "@react-native-community/cli": "*",
2739
- "@react-native/metro-config": "*"
2740
- },
2741
- "peerDependenciesMeta": {
2742
- "@react-native-community/cli": {
2743
- "optional": true
2744
- },
2745
- "@react-native/metro-config": {
2746
- "optional": true
2747
- }
2748
- }
2749
- },
2750
- "node_modules/@react-native/debugger-frontend": {
2751
- "version": "0.83.2",
2752
- "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.83.2.tgz",
2753
- "integrity": "sha512-t4fYfa7xopbUF5S4+ihNEwgaq4wLZLKLY0Ms8z72lkMteVd3bOX2Foxa8E2wTfRvdhPOkSpOsTeNDmD8ON4DoQ==",
2754
- "license": "BSD-3-Clause",
2755
- "engines": {
2756
- "node": ">= 20.19.4"
2757
- }
2758
- },
2759
- "node_modules/@react-native/debugger-shell": {
2760
- "version": "0.83.2",
2761
- "resolved": "https://registry.npmjs.org/@react-native/debugger-shell/-/debugger-shell-0.83.2.tgz",
2762
- "integrity": "sha512-z9go6NJMsLSDJT5MW6VGugRsZHjYvUTwxtsVc3uLt4U9W6T3J6FWI2wHpXIzd2dUkXRfAiRQ3Zi8ZQQ8fRFg9A==",
2763
- "license": "MIT",
2764
- "dependencies": {
2765
- "cross-spawn": "^7.0.6",
2766
- "fb-dotslash": "0.5.8"
2767
- },
2768
- "engines": {
2769
- "node": ">= 20.19.4"
2770
- }
2771
- },
2772
- "node_modules/@react-native/dev-middleware": {
2773
- "version": "0.83.2",
2774
- "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.83.2.tgz",
2775
- "integrity": "sha512-Zi4EVaAm28+icD19NN07Gh8Pqg/84QQu+jn4patfWKNkcToRFP5vPEbbp0eLOGWS+BVB1d1Fn5lvMrJsBbFcOg==",
2776
- "license": "MIT",
2777
- "dependencies": {
2778
- "@isaacs/ttlcache": "^1.4.1",
2779
- "@react-native/debugger-frontend": "0.83.2",
2780
- "@react-native/debugger-shell": "0.83.2",
2781
- "chrome-launcher": "^0.15.2",
2782
- "chromium-edge-launcher": "^0.2.0",
2783
- "connect": "^3.6.5",
2784
- "debug": "^4.4.0",
2785
- "invariant": "^2.2.4",
2786
- "nullthrows": "^1.1.1",
2787
- "open": "^7.0.3",
2788
- "serve-static": "^1.16.2",
2789
- "ws": "^7.5.10"
2790
- },
2791
- "engines": {
2792
- "node": ">= 20.19.4"
2793
- }
2794
- },
2795
- "node_modules/@react-native/gradle-plugin": {
2796
- "version": "0.83.2",
2797
- "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.83.2.tgz",
2798
- "integrity": "sha512-PqN11fXRAU+uJ0inZY1HWYlwJOXHOhF4SPyeHBBxjajKpm2PGunmvFWwkmBjmmUkP/CNO0ezTUudV0oj+2wiHQ==",
2799
- "license": "MIT",
2800
- "engines": {
2801
- "node": ">= 20.19.4"
2802
- }
2803
- },
2804
- "node_modules/@react-native/js-polyfills": {
2805
- "version": "0.83.2",
2806
- "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.83.2.tgz",
2807
- "integrity": "sha512-dk6fIY2OrKW/2Nk2HydfYNrQau8g6LOtd7NVBrgaqa+lvuRyIML5iimShP5qPqQnx2ofHuzjFw+Ya0b5Q7nDbA==",
2808
- "license": "MIT",
2809
- "engines": {
2810
- "node": ">= 20.19.4"
2811
- }
2812
- },
2813
- "node_modules/@react-native/normalize-colors": {
2814
- "version": "0.83.2",
2815
- "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.83.2.tgz",
2816
- "integrity": "sha512-gkZAb9LoVVzNuYzzOviH7DiPTXQoZPHuiTH2+O2+VWNtOkiznjgvqpwYAhg58a5zfRq5GXlbBdf5mzRj5+3Y5Q==",
2817
- "license": "MIT"
2818
- },
2819
- "node_modules/@react-navigation/bottom-tabs": {
2820
- "version": "7.15.3",
2821
- "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.15.3.tgz",
2822
- "integrity": "sha512-CIaHk5TuLeYlDgR1eij38kEbrQU5dAQxQZCC4Xv1wFZ/RRxppBopRMLzv2Il529a7mic6xG33OHcr9aEdOzq+A==",
2823
- "license": "MIT",
2824
- "dependencies": {
2825
- "@react-navigation/elements": "^2.9.8",
2826
- "color": "^4.2.3",
2827
- "sf-symbols-typescript": "^2.1.0"
2828
- },
2829
- "peerDependencies": {
2830
- "@react-navigation/native": "^7.1.31",
2831
- "react": ">= 18.2.0",
2832
- "react-native": "*",
2833
- "react-native-safe-area-context": ">= 4.0.0",
2834
- "react-native-screens": ">= 4.0.0"
2835
- }
2836
- },
2837
- "node_modules/@react-navigation/core": {
2838
- "version": "7.15.1",
2839
- "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.15.1.tgz",
2840
- "integrity": "sha512-Fqr6qxfZJIC4ewho7LtTa9zz6hcOzohX7D1lcDfrkGaYkS5xBwEZViGNxCJK/czUc74ua8NThyrObQFjB6Q/RQ==",
2841
- "license": "MIT",
2842
- "dependencies": {
2843
- "@react-navigation/routers": "^7.5.3",
2844
- "escape-string-regexp": "^4.0.0",
2845
- "fast-deep-equal": "^3.1.3",
2846
- "nanoid": "^3.3.11",
2847
- "query-string": "^7.1.3",
2848
- "react-is": "^19.1.0",
2849
- "use-latest-callback": "^0.2.4",
2850
- "use-sync-external-store": "^1.5.0"
2851
- },
2852
- "peerDependencies": {
2853
- "react": ">= 18.2.0"
2854
- }
2855
- },
2856
- "node_modules/@react-navigation/core/node_modules/react-is": {
2857
- "version": "19.2.4",
2858
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz",
2859
- "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==",
2860
- "license": "MIT"
2861
- },
2862
- "node_modules/@react-navigation/elements": {
2863
- "version": "2.9.8",
2864
- "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.8.tgz",
2865
- "integrity": "sha512-3gpwUmVnDJYvK9nFmAA/YXw0hmT/C/lZx8RkRMK+ux9l1T+32EWnQFnn34Wa1BMDX8HN2r64yrlW93DIzKI7Uw==",
2866
- "license": "MIT",
2867
- "dependencies": {
2868
- "color": "^4.2.3",
2869
- "use-latest-callback": "^0.2.4",
2870
- "use-sync-external-store": "^1.5.0"
2871
- },
2872
- "peerDependencies": {
2873
- "@react-native-masked-view/masked-view": ">= 0.2.0",
2874
- "@react-navigation/native": "^7.1.31",
2875
- "react": ">= 18.2.0",
2876
- "react-native": "*",
2877
- "react-native-safe-area-context": ">= 4.0.0"
2878
- },
2879
- "peerDependenciesMeta": {
2880
- "@react-native-masked-view/masked-view": {
2881
- "optional": true
2882
- }
2883
- }
2884
- },
2885
- "node_modules/@react-navigation/native": {
2886
- "version": "7.1.31",
2887
- "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.31.tgz",
2888
- "integrity": "sha512-+YCUwtfDgsux59Q0LDHc3Zid9ih93ecUCFWZOH6/+eNoUGnWx77wjS6ZfvBO/7E+EiIup11IVShDzCHR4of8hw==",
2889
- "license": "MIT",
2890
- "dependencies": {
2891
- "@react-navigation/core": "^7.15.1",
2892
- "escape-string-regexp": "^4.0.0",
2893
- "fast-deep-equal": "^3.1.3",
2894
- "nanoid": "^3.3.11",
2895
- "use-latest-callback": "^0.2.4"
2896
- },
2897
- "peerDependencies": {
2898
- "react": ">= 18.2.0",
2899
- "react-native": "*"
2900
- }
2901
- },
2902
- "node_modules/@react-navigation/native-stack": {
2903
- "version": "7.14.2",
2904
- "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.14.2.tgz",
2905
- "integrity": "sha512-/nKxFAFSUSGV+NSXrXXcWEcGAHdyp8RyWjoGMDzVPdBhjCLblVSgHWx5y4mm+k0de9V1pkjsftUaroP7rQckzw==",
2906
- "license": "MIT",
2907
- "dependencies": {
2908
- "@react-navigation/elements": "^2.9.8",
2909
- "color": "^4.2.3",
2910
- "sf-symbols-typescript": "^2.1.0",
2911
- "warn-once": "^0.1.1"
2912
- },
2913
- "peerDependencies": {
2914
- "@react-navigation/native": "^7.1.31",
2915
- "react": ">= 18.2.0",
2916
- "react-native": "*",
2917
- "react-native-safe-area-context": ">= 4.0.0",
2918
- "react-native-screens": ">= 4.0.0"
2919
- }
2920
- },
2921
- "node_modules/@react-navigation/routers": {
2922
- "version": "7.5.3",
2923
- "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.3.tgz",
2924
- "integrity": "sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg==",
2925
- "license": "MIT",
2926
- "dependencies": {
2927
- "nanoid": "^3.3.11"
2928
- }
2929
- },
2930
- "node_modules/@sinclair/typebox": {
2931
- "version": "0.27.10",
2932
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz",
2933
- "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==",
2934
- "license": "MIT"
2935
- },
2936
- "node_modules/@sinonjs/commons": {
2937
- "version": "3.0.1",
2938
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
2939
- "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
2940
- "license": "BSD-3-Clause",
2941
- "dependencies": {
2942
- "type-detect": "4.0.8"
2943
- }
2944
- },
2945
- "node_modules/@sinonjs/fake-timers": {
2946
- "version": "10.3.0",
2947
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
2948
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
2949
- "license": "BSD-3-Clause",
2950
- "dependencies": {
2951
- "@sinonjs/commons": "^3.0.0"
2952
- }
2953
- },
2954
- "node_modules/@types/babel__core": {
2955
- "version": "7.20.5",
2956
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
2957
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
2958
- "license": "MIT",
2959
- "dependencies": {
2960
- "@babel/parser": "^7.20.7",
2961
- "@babel/types": "^7.20.7",
2962
- "@types/babel__generator": "*",
2963
- "@types/babel__template": "*",
2964
- "@types/babel__traverse": "*"
2965
- }
2966
- },
2967
- "node_modules/@types/babel__generator": {
2968
- "version": "7.27.0",
2969
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
2970
- "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
2971
- "license": "MIT",
2972
- "dependencies": {
2973
- "@babel/types": "^7.0.0"
2974
- }
2975
- },
2976
- "node_modules/@types/babel__template": {
2977
- "version": "7.4.4",
2978
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
2979
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
2980
- "license": "MIT",
2981
- "dependencies": {
2982
- "@babel/parser": "^7.1.0",
2983
- "@babel/types": "^7.0.0"
2984
- }
2985
- },
2986
- "node_modules/@types/babel__traverse": {
2987
- "version": "7.28.0",
2988
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
2989
- "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
2990
- "license": "MIT",
2991
- "dependencies": {
2992
- "@babel/types": "^7.28.2"
2993
- }
2994
- },
2995
- "node_modules/@types/graceful-fs": {
2996
- "version": "4.1.9",
2997
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
2998
- "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
2999
- "license": "MIT",
3000
- "dependencies": {
3001
- "@types/node": "*"
3002
- }
3003
- },
3004
- "node_modules/@types/hammerjs": {
3005
- "version": "2.0.46",
3006
- "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz",
3007
- "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==",
3008
- "license": "MIT"
3009
- },
3010
- "node_modules/@types/istanbul-lib-coverage": {
3011
- "version": "2.0.6",
3012
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
3013
- "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
3014
- "license": "MIT"
3015
- },
3016
- "node_modules/@types/istanbul-lib-report": {
3017
- "version": "3.0.3",
3018
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
3019
- "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
3020
- "license": "MIT",
3021
- "dependencies": {
3022
- "@types/istanbul-lib-coverage": "*"
3023
- }
3024
- },
3025
- "node_modules/@types/istanbul-reports": {
3026
- "version": "3.0.4",
3027
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
3028
- "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
3029
- "license": "MIT",
3030
- "dependencies": {
3031
- "@types/istanbul-lib-report": "*"
3032
- }
3033
- },
3034
- "node_modules/@types/node": {
3035
- "version": "25.3.3",
3036
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz",
3037
- "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==",
3038
- "license": "MIT",
3039
- "dependencies": {
3040
- "undici-types": "~7.18.0"
3041
- }
3042
- },
3043
- "node_modules/@types/react": {
3044
- "version": "19.2.14",
3045
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
3046
- "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
3047
- "dev": true,
3048
- "license": "MIT",
3049
- "dependencies": {
3050
- "csstype": "^3.2.2"
3051
- }
3052
- },
3053
- "node_modules/@types/stack-utils": {
3054
- "version": "2.0.3",
3055
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
3056
- "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
3057
- "license": "MIT"
3058
- },
3059
- "node_modules/@types/yargs": {
3060
- "version": "17.0.35",
3061
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
3062
- "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
3063
- "license": "MIT",
3064
- "dependencies": {
3065
- "@types/yargs-parser": "*"
3066
- }
3067
- },
3068
- "node_modules/@types/yargs-parser": {
3069
- "version": "21.0.3",
3070
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
3071
- "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
3072
- "license": "MIT"
3073
- },
3074
- "node_modules/@ungap/structured-clone": {
3075
- "version": "1.3.0",
3076
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
3077
- "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
3078
- "license": "ISC"
3079
- },
3080
- "node_modules/@xmldom/xmldom": {
3081
- "version": "0.8.11",
3082
- "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
3083
- "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==",
3084
- "license": "MIT",
3085
- "engines": {
3086
- "node": ">=10.0.0"
3087
- }
3088
- },
3089
- "node_modules/abort-controller": {
3090
- "version": "3.0.0",
3091
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
3092
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
3093
- "license": "MIT",
3094
- "dependencies": {
3095
- "event-target-shim": "^5.0.0"
3096
- },
3097
- "engines": {
3098
- "node": ">=6.5"
3099
- }
3100
- },
3101
- "node_modules/accepts": {
3102
- "version": "1.3.8",
3103
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
3104
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
3105
- "license": "MIT",
3106
- "dependencies": {
3107
- "mime-types": "~2.1.34",
3108
- "negotiator": "0.6.3"
3109
- },
3110
- "engines": {
3111
- "node": ">= 0.6"
3112
- }
3113
- },
3114
- "node_modules/acorn": {
3115
- "version": "8.16.0",
3116
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
3117
- "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
3118
- "license": "MIT",
3119
- "bin": {
3120
- "acorn": "bin/acorn"
3121
- },
3122
- "engines": {
3123
- "node": ">=0.4.0"
3124
- }
3125
- },
3126
- "node_modules/agent-base": {
3127
- "version": "7.1.4",
3128
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
3129
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
3130
- "license": "MIT",
3131
- "engines": {
3132
- "node": ">= 14"
3133
- }
3134
- },
3135
- "node_modules/anser": {
3136
- "version": "1.4.10",
3137
- "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz",
3138
- "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==",
3139
- "license": "MIT"
3140
- },
3141
- "node_modules/ansi-escapes": {
3142
- "version": "4.3.2",
3143
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
3144
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
3145
- "license": "MIT",
3146
- "dependencies": {
3147
- "type-fest": "^0.21.3"
3148
- },
3149
- "engines": {
3150
- "node": ">=8"
3151
- },
3152
- "funding": {
3153
- "url": "https://github.com/sponsors/sindresorhus"
3154
- }
3155
- },
3156
- "node_modules/ansi-escapes/node_modules/type-fest": {
3157
- "version": "0.21.3",
3158
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
3159
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
3160
- "license": "(MIT OR CC0-1.0)",
3161
- "engines": {
3162
- "node": ">=10"
3163
- },
3164
- "funding": {
3165
- "url": "https://github.com/sponsors/sindresorhus"
3166
- }
3167
- },
3168
- "node_modules/ansi-regex": {
3169
- "version": "5.0.1",
3170
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
3171
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
3172
- "license": "MIT",
3173
- "engines": {
3174
- "node": ">=8"
3175
- }
3176
- },
3177
- "node_modules/ansi-styles": {
3178
- "version": "4.3.0",
3179
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
3180
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
3181
- "license": "MIT",
3182
- "dependencies": {
3183
- "color-convert": "^2.0.1"
3184
- },
3185
- "engines": {
3186
- "node": ">=8"
3187
- },
3188
- "funding": {
3189
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
3190
- }
3191
- },
3192
- "node_modules/any-promise": {
3193
- "version": "1.3.0",
3194
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
3195
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
3196
- "dev": true,
3197
- "license": "MIT"
3198
- },
3199
- "node_modules/anymatch": {
3200
- "version": "3.1.3",
3201
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
3202
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
3203
- "license": "ISC",
3204
- "dependencies": {
3205
- "normalize-path": "^3.0.0",
3206
- "picomatch": "^2.0.4"
3207
- },
3208
- "engines": {
3209
- "node": ">= 8"
3210
- }
3211
- },
3212
- "node_modules/arg": {
3213
- "version": "5.0.2",
3214
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
3215
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
3216
- "license": "MIT"
3217
- },
3218
- "node_modules/argparse": {
3219
- "version": "1.0.10",
3220
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
3221
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
3222
- "license": "MIT",
3223
- "dependencies": {
3224
- "sprintf-js": "~1.0.2"
3225
- }
3226
- },
3227
- "node_modules/aria-hidden": {
3228
- "version": "1.2.6",
3229
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
3230
- "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
3231
- "license": "MIT",
3232
- "dependencies": {
3233
- "tslib": "^2.0.0"
3234
- },
3235
- "engines": {
3236
- "node": ">=10"
3237
- }
3238
- },
3239
- "node_modules/array-timsort": {
3240
- "version": "1.0.3",
3241
- "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
3242
- "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
3243
- "license": "MIT"
3244
- },
3245
- "node_modules/asap": {
3246
- "version": "2.0.6",
3247
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
3248
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
3249
- "license": "MIT"
3250
- },
3251
- "node_modules/babel-jest": {
3252
- "version": "29.7.0",
3253
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
3254
- "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
3255
- "license": "MIT",
3256
- "dependencies": {
3257
- "@jest/transform": "^29.7.0",
3258
- "@types/babel__core": "^7.1.14",
3259
- "babel-plugin-istanbul": "^6.1.1",
3260
- "babel-preset-jest": "^29.6.3",
3261
- "chalk": "^4.0.0",
3262
- "graceful-fs": "^4.2.9",
3263
- "slash": "^3.0.0"
3264
- },
3265
- "engines": {
3266
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
3267
- },
3268
- "peerDependencies": {
3269
- "@babel/core": "^7.8.0"
3270
- }
3271
- },
3272
- "node_modules/babel-plugin-istanbul": {
3273
- "version": "6.1.1",
3274
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
3275
- "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
3276
- "license": "BSD-3-Clause",
3277
- "dependencies": {
3278
- "@babel/helper-plugin-utils": "^7.0.0",
3279
- "@istanbuljs/load-nyc-config": "^1.0.0",
3280
- "@istanbuljs/schema": "^0.1.2",
3281
- "istanbul-lib-instrument": "^5.0.4",
3282
- "test-exclude": "^6.0.0"
3283
- },
3284
- "engines": {
3285
- "node": ">=8"
3286
- }
3287
- },
3288
- "node_modules/babel-plugin-jest-hoist": {
3289
- "version": "29.6.3",
3290
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
3291
- "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
3292
- "license": "MIT",
3293
- "dependencies": {
3294
- "@babel/template": "^7.3.3",
3295
- "@babel/types": "^7.3.3",
3296
- "@types/babel__core": "^7.1.14",
3297
- "@types/babel__traverse": "^7.0.6"
3298
- },
3299
- "engines": {
3300
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
3301
- }
3302
- },
3303
- "node_modules/babel-plugin-module-resolver": {
3304
- "version": "5.0.2",
3305
- "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz",
3306
- "integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==",
3307
- "dev": true,
3308
- "license": "MIT",
3309
- "dependencies": {
3310
- "find-babel-config": "^2.1.1",
3311
- "glob": "^9.3.3",
3312
- "pkg-up": "^3.1.0",
3313
- "reselect": "^4.1.7",
3314
- "resolve": "^1.22.8"
3315
- }
3316
- },
3317
- "node_modules/babel-plugin-module-resolver/node_modules/balanced-match": {
3318
- "version": "1.0.2",
3319
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
3320
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
3321
- "dev": true,
3322
- "license": "MIT"
3323
- },
3324
- "node_modules/babel-plugin-module-resolver/node_modules/brace-expansion": {
3325
- "version": "2.0.2",
3326
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
3327
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
3328
- "dev": true,
3329
- "license": "MIT",
3330
- "dependencies": {
3331
- "balanced-match": "^1.0.0"
3332
- }
3333
- },
3334
- "node_modules/babel-plugin-module-resolver/node_modules/glob": {
3335
- "version": "9.3.5",
3336
- "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
3337
- "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
3338
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
3339
- "dev": true,
3340
- "license": "ISC",
3341
- "dependencies": {
3342
- "fs.realpath": "^1.0.0",
3343
- "minimatch": "^8.0.2",
3344
- "minipass": "^4.2.4",
3345
- "path-scurry": "^1.6.1"
3346
- },
3347
- "engines": {
3348
- "node": ">=16 || 14 >=14.17"
3349
- },
3350
- "funding": {
3351
- "url": "https://github.com/sponsors/isaacs"
3352
- }
3353
- },
3354
- "node_modules/babel-plugin-module-resolver/node_modules/lru-cache": {
3355
- "version": "10.4.3",
3356
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
3357
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
3358
- "dev": true,
3359
- "license": "ISC"
3360
- },
3361
- "node_modules/babel-plugin-module-resolver/node_modules/minimatch": {
3362
- "version": "8.0.7",
3363
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.7.tgz",
3364
- "integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==",
3365
- "dev": true,
3366
- "license": "ISC",
3367
- "dependencies": {
3368
- "brace-expansion": "^2.0.1"
3369
- },
3370
- "engines": {
3371
- "node": ">=16 || 14 >=14.17"
3372
- },
3373
- "funding": {
3374
- "url": "https://github.com/sponsors/isaacs"
3375
- }
3376
- },
3377
- "node_modules/babel-plugin-module-resolver/node_modules/minipass": {
3378
- "version": "4.2.8",
3379
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
3380
- "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
3381
- "dev": true,
3382
- "license": "ISC",
3383
- "engines": {
3384
- "node": ">=8"
3385
- }
3386
- },
3387
- "node_modules/babel-plugin-module-resolver/node_modules/path-scurry": {
3388
- "version": "1.11.1",
3389
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
3390
- "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
3391
- "dev": true,
3392
- "license": "BlueOak-1.0.0",
3393
- "dependencies": {
3394
- "lru-cache": "^10.2.0",
3395
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
3396
- },
3397
- "engines": {
3398
- "node": ">=16 || 14 >=14.18"
3399
- },
3400
- "funding": {
3401
- "url": "https://github.com/sponsors/isaacs"
3402
- }
3403
- },
3404
- "node_modules/babel-plugin-module-resolver/node_modules/path-scurry/node_modules/minipass": {
3405
- "version": "7.1.3",
3406
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
3407
- "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
3408
- "dev": true,
3409
- "license": "BlueOak-1.0.0",
3410
- "engines": {
3411
- "node": ">=16 || 14 >=14.17"
3412
- }
3413
- },
3414
- "node_modules/babel-plugin-polyfill-corejs2": {
3415
- "version": "0.4.15",
3416
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz",
3417
- "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==",
3418
- "license": "MIT",
3419
- "dependencies": {
3420
- "@babel/compat-data": "^7.28.6",
3421
- "@babel/helper-define-polyfill-provider": "^0.6.6",
3422
- "semver": "^6.3.1"
3423
- },
3424
- "peerDependencies": {
3425
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
3426
- }
3427
- },
3428
- "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
3429
- "version": "6.3.1",
3430
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
3431
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
3432
- "license": "ISC",
3433
- "bin": {
3434
- "semver": "bin/semver.js"
3435
- }
3436
- },
3437
- "node_modules/babel-plugin-polyfill-corejs3": {
3438
- "version": "0.13.0",
3439
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz",
3440
- "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==",
3441
- "license": "MIT",
3442
- "dependencies": {
3443
- "@babel/helper-define-polyfill-provider": "^0.6.5",
3444
- "core-js-compat": "^3.43.0"
3445
- },
3446
- "peerDependencies": {
3447
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
3448
- }
3449
- },
3450
- "node_modules/babel-plugin-polyfill-regenerator": {
3451
- "version": "0.6.6",
3452
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz",
3453
- "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==",
3454
- "license": "MIT",
3455
- "dependencies": {
3456
- "@babel/helper-define-polyfill-provider": "^0.6.6"
3457
- },
3458
- "peerDependencies": {
3459
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
3460
- }
3461
- },
3462
- "node_modules/babel-plugin-react-compiler": {
3463
- "version": "1.0.0",
3464
- "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz",
3465
- "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==",
3466
- "license": "MIT",
3467
- "dependencies": {
3468
- "@babel/types": "^7.26.0"
3469
- }
3470
- },
3471
- "node_modules/babel-plugin-react-native-web": {
3472
- "version": "0.21.2",
3473
- "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz",
3474
- "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==",
3475
- "license": "MIT"
3476
- },
3477
- "node_modules/babel-plugin-syntax-hermes-parser": {
3478
- "version": "0.32.0",
3479
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.32.0.tgz",
3480
- "integrity": "sha512-m5HthL++AbyeEA2FcdwOLfVFvWYECOBObLHNqdR8ceY4TsEdn4LdX2oTvbB2QJSSElE2AWA/b2MXZ/PF/CqLZg==",
3481
- "license": "MIT",
3482
- "dependencies": {
3483
- "hermes-parser": "0.32.0"
3484
- }
3485
- },
3486
- "node_modules/babel-plugin-transform-flow-enums": {
3487
- "version": "0.0.2",
3488
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz",
3489
- "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==",
3490
- "license": "MIT",
3491
- "dependencies": {
3492
- "@babel/plugin-syntax-flow": "^7.12.1"
3493
- }
3494
- },
3495
- "node_modules/babel-preset-current-node-syntax": {
3496
- "version": "1.2.0",
3497
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
3498
- "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
3499
- "license": "MIT",
3500
- "dependencies": {
3501
- "@babel/plugin-syntax-async-generators": "^7.8.4",
3502
- "@babel/plugin-syntax-bigint": "^7.8.3",
3503
- "@babel/plugin-syntax-class-properties": "^7.12.13",
3504
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
3505
- "@babel/plugin-syntax-import-attributes": "^7.24.7",
3506
- "@babel/plugin-syntax-import-meta": "^7.10.4",
3507
- "@babel/plugin-syntax-json-strings": "^7.8.3",
3508
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
3509
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
3510
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
3511
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
3512
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
3513
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
3514
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
3515
- "@babel/plugin-syntax-top-level-await": "^7.14.5"
3516
- },
3517
- "peerDependencies": {
3518
- "@babel/core": "^7.0.0 || ^8.0.0-0"
3519
- }
3520
- },
3521
- "node_modules/babel-preset-expo": {
3522
- "version": "55.0.10",
3523
- "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-55.0.10.tgz",
3524
- "integrity": "sha512-aRtW7qJKohGU2V0LUJ6IeP7py3+kVUo9zcc8+v1Kix8jGGuIvqvpo9S6W1Fmn9VFP2DBwkFDLiyzkCZS85urVA==",
3525
- "license": "MIT",
3526
- "dependencies": {
3527
- "@babel/generator": "^7.20.5",
3528
- "@babel/helper-module-imports": "^7.25.9",
3529
- "@babel/plugin-proposal-decorators": "^7.12.9",
3530
- "@babel/plugin-proposal-export-default-from": "^7.24.7",
3531
- "@babel/plugin-syntax-export-default-from": "^7.24.7",
3532
- "@babel/plugin-transform-class-static-block": "^7.27.1",
3533
- "@babel/plugin-transform-export-namespace-from": "^7.25.9",
3534
- "@babel/plugin-transform-flow-strip-types": "^7.25.2",
3535
- "@babel/plugin-transform-modules-commonjs": "^7.24.8",
3536
- "@babel/plugin-transform-object-rest-spread": "^7.24.7",
3537
- "@babel/plugin-transform-parameters": "^7.24.7",
3538
- "@babel/plugin-transform-private-methods": "^7.24.7",
3539
- "@babel/plugin-transform-private-property-in-object": "^7.24.7",
3540
- "@babel/plugin-transform-runtime": "^7.24.7",
3541
- "@babel/preset-react": "^7.22.15",
3542
- "@babel/preset-typescript": "^7.23.0",
3543
- "@react-native/babel-preset": "0.83.2",
3544
- "babel-plugin-react-compiler": "^1.0.0",
3545
- "babel-plugin-react-native-web": "~0.21.0",
3546
- "babel-plugin-syntax-hermes-parser": "^0.32.0",
3547
- "babel-plugin-transform-flow-enums": "^0.0.2",
3548
- "debug": "^4.3.4",
3549
- "resolve-from": "^5.0.0"
3550
- },
3551
- "peerDependencies": {
3552
- "@babel/runtime": "^7.20.0",
3553
- "expo": "*",
3554
- "expo-widgets": "^55.0.2",
3555
- "react-refresh": ">=0.14.0 <1.0.0"
3556
- },
3557
- "peerDependenciesMeta": {
3558
- "@babel/runtime": {
3559
- "optional": true
3560
- },
3561
- "expo": {
3562
- "optional": true
3563
- },
3564
- "expo-widgets": {
3565
- "optional": true
3566
- }
3567
- }
3568
- },
3569
- "node_modules/babel-preset-jest": {
3570
- "version": "29.6.3",
3571
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
3572
- "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
3573
- "license": "MIT",
3574
- "dependencies": {
3575
- "babel-plugin-jest-hoist": "^29.6.3",
3576
- "babel-preset-current-node-syntax": "^1.0.0"
3577
- },
3578
- "engines": {
3579
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
3580
- },
3581
- "peerDependencies": {
3582
- "@babel/core": "^7.0.0"
3583
- }
3584
- },
3585
- "node_modules/balanced-match": {
3586
- "version": "4.0.4",
3587
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
3588
- "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
3589
- "license": "MIT",
3590
- "engines": {
3591
- "node": "18 || 20 || >=22"
3592
- }
3593
- },
3594
- "node_modules/base64-js": {
3595
- "version": "1.5.1",
3596
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
3597
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
3598
- "funding": [
3599
- {
3600
- "type": "github",
3601
- "url": "https://github.com/sponsors/feross"
3602
- },
3603
- {
3604
- "type": "patreon",
3605
- "url": "https://www.patreon.com/feross"
3606
- },
3607
- {
3608
- "type": "consulting",
3609
- "url": "https://feross.org/support"
3610
- }
3611
- ],
3612
- "license": "MIT"
3613
- },
3614
- "node_modules/baseline-browser-mapping": {
3615
- "version": "2.10.0",
3616
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz",
3617
- "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==",
3618
- "license": "Apache-2.0",
3619
- "bin": {
3620
- "baseline-browser-mapping": "dist/cli.cjs"
3621
- },
3622
- "engines": {
3623
- "node": ">=6.0.0"
3624
- }
3625
- },
3626
- "node_modules/better-opn": {
3627
- "version": "3.0.2",
3628
- "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
3629
- "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==",
3630
- "license": "MIT",
3631
- "dependencies": {
3632
- "open": "^8.0.4"
3633
- },
3634
- "engines": {
3635
- "node": ">=12.0.0"
3636
- }
3637
- },
3638
- "node_modules/better-opn/node_modules/open": {
3639
- "version": "8.4.2",
3640
- "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
3641
- "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
3642
- "license": "MIT",
3643
- "dependencies": {
3644
- "define-lazy-prop": "^2.0.0",
3645
- "is-docker": "^2.1.1",
3646
- "is-wsl": "^2.2.0"
3647
- },
3648
- "engines": {
3649
- "node": ">=12"
3650
- },
3651
- "funding": {
3652
- "url": "https://github.com/sponsors/sindresorhus"
3653
- }
3654
- },
3655
- "node_modules/big-integer": {
3656
- "version": "1.6.52",
3657
- "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
3658
- "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
3659
- "license": "Unlicense",
3660
- "engines": {
3661
- "node": ">=0.6"
3662
- }
3663
- },
3664
- "node_modules/binary-extensions": {
3665
- "version": "2.3.0",
3666
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
3667
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
3668
- "dev": true,
3669
- "license": "MIT",
3670
- "engines": {
3671
- "node": ">=8"
3672
- },
3673
- "funding": {
3674
- "url": "https://github.com/sponsors/sindresorhus"
3675
- }
3676
- },
3677
- "node_modules/boolbase": {
3678
- "version": "1.0.0",
3679
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
3680
- "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
3681
- "license": "ISC"
3682
- },
3683
- "node_modules/bplist-creator": {
3684
- "version": "0.1.0",
3685
- "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz",
3686
- "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==",
3687
- "license": "MIT",
3688
- "dependencies": {
3689
- "stream-buffers": "2.2.x"
3690
- }
3691
- },
3692
- "node_modules/bplist-parser": {
3693
- "version": "0.3.1",
3694
- "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz",
3695
- "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==",
3696
- "license": "MIT",
3697
- "dependencies": {
3698
- "big-integer": "1.6.x"
3699
- },
3700
- "engines": {
3701
- "node": ">= 5.10.0"
3702
- }
3703
- },
3704
- "node_modules/brace-expansion": {
3705
- "version": "5.0.4",
3706
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
3707
- "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
3708
- "license": "MIT",
3709
- "dependencies": {
3710
- "balanced-match": "^4.0.2"
3711
- },
3712
- "engines": {
3713
- "node": "18 || 20 || >=22"
3714
- }
3715
- },
3716
- "node_modules/braces": {
3717
- "version": "3.0.3",
3718
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
3719
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
3720
- "license": "MIT",
3721
- "dependencies": {
3722
- "fill-range": "^7.1.1"
3723
- },
3724
- "engines": {
3725
- "node": ">=8"
3726
- }
3727
- },
3728
- "node_modules/browserslist": {
3729
- "version": "4.28.1",
3730
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
3731
- "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
3732
- "funding": [
3733
- {
3734
- "type": "opencollective",
3735
- "url": "https://opencollective.com/browserslist"
3736
- },
3737
- {
3738
- "type": "tidelift",
3739
- "url": "https://tidelift.com/funding/github/npm/browserslist"
3740
- },
3741
- {
3742
- "type": "github",
3743
- "url": "https://github.com/sponsors/ai"
3744
- }
3745
- ],
3746
- "license": "MIT",
3747
- "dependencies": {
3748
- "baseline-browser-mapping": "^2.9.0",
3749
- "caniuse-lite": "^1.0.30001759",
3750
- "electron-to-chromium": "^1.5.263",
3751
- "node-releases": "^2.0.27",
3752
- "update-browserslist-db": "^1.2.0"
3753
- },
3754
- "bin": {
3755
- "browserslist": "cli.js"
3756
- },
3757
- "engines": {
3758
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
3759
- }
3760
- },
3761
- "node_modules/bser": {
3762
- "version": "2.1.1",
3763
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
3764
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
3765
- "license": "Apache-2.0",
3766
- "dependencies": {
3767
- "node-int64": "^0.4.0"
3768
- }
3769
- },
3770
- "node_modules/buffer": {
3771
- "version": "5.7.1",
3772
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
3773
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
3774
- "funding": [
3775
- {
3776
- "type": "github",
3777
- "url": "https://github.com/sponsors/feross"
3778
- },
3779
- {
3780
- "type": "patreon",
3781
- "url": "https://www.patreon.com/feross"
3782
- },
3783
- {
3784
- "type": "consulting",
3785
- "url": "https://feross.org/support"
3786
- }
3787
- ],
3788
- "license": "MIT",
3789
- "dependencies": {
3790
- "base64-js": "^1.3.1",
3791
- "ieee754": "^1.1.13"
3792
- }
3793
- },
3794
- "node_modules/buffer-from": {
3795
- "version": "1.1.2",
3796
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
3797
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
3798
- "license": "MIT"
3799
- },
3800
- "node_modules/bytes": {
3801
- "version": "3.1.2",
3802
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
3803
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
3804
- "license": "MIT",
3805
- "engines": {
3806
- "node": ">= 0.8"
3807
- }
3808
- },
3809
- "node_modules/camelcase": {
3810
- "version": "6.3.0",
3811
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
3812
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
3813
- "license": "MIT",
3814
- "engines": {
3815
- "node": ">=10"
3816
- },
3817
- "funding": {
3818
- "url": "https://github.com/sponsors/sindresorhus"
3819
- }
3820
- },
3821
- "node_modules/camelcase-css": {
3822
- "version": "2.0.1",
3823
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
3824
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
3825
- "dev": true,
3826
- "license": "MIT",
3827
- "engines": {
3828
- "node": ">= 6"
3829
- }
3830
- },
3831
- "node_modules/caniuse-lite": {
3832
- "version": "1.0.30001775",
3833
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz",
3834
- "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==",
3835
- "funding": [
3836
- {
3837
- "type": "opencollective",
3838
- "url": "https://opencollective.com/browserslist"
3839
- },
3840
- {
3841
- "type": "tidelift",
3842
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
3843
- },
3844
- {
3845
- "type": "github",
3846
- "url": "https://github.com/sponsors/ai"
3847
- }
3848
- ],
3849
- "license": "CC-BY-4.0"
3850
- },
3851
- "node_modules/chalk": {
3852
- "version": "4.1.2",
3853
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
3854
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
3855
- "license": "MIT",
3856
- "dependencies": {
3857
- "ansi-styles": "^4.1.0",
3858
- "supports-color": "^7.1.0"
3859
- },
3860
- "engines": {
3861
- "node": ">=10"
3862
- },
3863
- "funding": {
3864
- "url": "https://github.com/chalk/chalk?sponsor=1"
3865
- }
3866
- },
3867
- "node_modules/chokidar": {
3868
- "version": "3.6.0",
3869
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
3870
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
3871
- "dev": true,
3872
- "license": "MIT",
3873
- "dependencies": {
3874
- "anymatch": "~3.1.2",
3875
- "braces": "~3.0.2",
3876
- "glob-parent": "~5.1.2",
3877
- "is-binary-path": "~2.1.0",
3878
- "is-glob": "~4.0.1",
3879
- "normalize-path": "~3.0.0",
3880
- "readdirp": "~3.6.0"
3881
- },
3882
- "engines": {
3883
- "node": ">= 8.10.0"
3884
- },
3885
- "funding": {
3886
- "url": "https://paulmillr.com/funding/"
3887
- },
3888
- "optionalDependencies": {
3889
- "fsevents": "~2.3.2"
3890
- }
3891
- },
3892
- "node_modules/chokidar/node_modules/glob-parent": {
3893
- "version": "5.1.2",
3894
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
3895
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
3896
- "dev": true,
3897
- "license": "ISC",
3898
- "dependencies": {
3899
- "is-glob": "^4.0.1"
3900
- },
3901
- "engines": {
3902
- "node": ">= 6"
3903
- }
3904
- },
3905
- "node_modules/chrome-launcher": {
3906
- "version": "0.15.2",
3907
- "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz",
3908
- "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==",
3909
- "license": "Apache-2.0",
3910
- "dependencies": {
3911
- "@types/node": "*",
3912
- "escape-string-regexp": "^4.0.0",
3913
- "is-wsl": "^2.2.0",
3914
- "lighthouse-logger": "^1.0.0"
3915
- },
3916
- "bin": {
3917
- "print-chrome-path": "bin/print-chrome-path.js"
3918
- },
3919
- "engines": {
3920
- "node": ">=12.13.0"
3921
- }
3922
- },
3923
- "node_modules/chromium-edge-launcher": {
3924
- "version": "0.2.0",
3925
- "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz",
3926
- "integrity": "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==",
3927
- "license": "Apache-2.0",
3928
- "dependencies": {
3929
- "@types/node": "*",
3930
- "escape-string-regexp": "^4.0.0",
3931
- "is-wsl": "^2.2.0",
3932
- "lighthouse-logger": "^1.0.0",
3933
- "mkdirp": "^1.0.4",
3934
- "rimraf": "^3.0.2"
3935
- }
3936
- },
3937
- "node_modules/ci-info": {
3938
- "version": "2.0.0",
3939
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
3940
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
3941
- "license": "MIT"
3942
- },
3943
- "node_modules/cli-cursor": {
3944
- "version": "2.1.0",
3945
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
3946
- "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
3947
- "license": "MIT",
3948
- "dependencies": {
3949
- "restore-cursor": "^2.0.0"
3950
- },
3951
- "engines": {
3952
- "node": ">=4"
3953
- }
3954
- },
3955
- "node_modules/cli-spinners": {
3956
- "version": "2.9.2",
3957
- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
3958
- "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
3959
- "license": "MIT",
3960
- "engines": {
3961
- "node": ">=6"
3962
- },
3963
- "funding": {
3964
- "url": "https://github.com/sponsors/sindresorhus"
3965
- }
3966
- },
3967
- "node_modules/client-only": {
3968
- "version": "0.0.1",
3969
- "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
3970
- "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
3971
- "license": "MIT"
3972
- },
3973
- "node_modules/cliui": {
3974
- "version": "8.0.1",
3975
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
3976
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
3977
- "license": "ISC",
3978
- "dependencies": {
3979
- "string-width": "^4.2.0",
3980
- "strip-ansi": "^6.0.1",
3981
- "wrap-ansi": "^7.0.0"
3982
- },
3983
- "engines": {
3984
- "node": ">=12"
3985
- }
3986
- },
3987
- "node_modules/clone": {
3988
- "version": "1.0.4",
3989
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
3990
- "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
3991
- "license": "MIT",
3992
- "engines": {
3993
- "node": ">=0.8"
3994
- }
3995
- },
3996
- "node_modules/color": {
3997
- "version": "4.2.3",
3998
- "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
3999
- "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
4000
- "license": "MIT",
4001
- "dependencies": {
4002
- "color-convert": "^2.0.1",
4003
- "color-string": "^1.9.0"
4004
- },
4005
- "engines": {
4006
- "node": ">=12.5.0"
4007
- }
4008
- },
4009
- "node_modules/color-convert": {
4010
- "version": "2.0.1",
4011
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
4012
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
4013
- "license": "MIT",
4014
- "dependencies": {
4015
- "color-name": "~1.1.4"
4016
- },
4017
- "engines": {
4018
- "node": ">=7.0.0"
4019
- }
4020
- },
4021
- "node_modules/color-name": {
4022
- "version": "1.1.4",
4023
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
4024
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
4025
- "license": "MIT"
4026
- },
4027
- "node_modules/color-string": {
4028
- "version": "1.9.1",
4029
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
4030
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
4031
- "license": "MIT",
4032
- "dependencies": {
4033
- "color-name": "^1.0.0",
4034
- "simple-swizzle": "^0.2.2"
4035
- }
4036
- },
4037
- "node_modules/commander": {
4038
- "version": "7.2.0",
4039
- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
4040
- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
4041
- "license": "MIT",
4042
- "engines": {
4043
- "node": ">= 10"
4044
- }
4045
- },
4046
- "node_modules/comment-json": {
4047
- "version": "4.6.1",
4048
- "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.6.1.tgz",
4049
- "integrity": "sha512-kdBIsBGqD/sAeqvzeOhBvO/bhtpbfbIU/2lw7bp182FV1cVlY7gr1Jf3Q1I+NOsCk8e4gF5Sl9iYH5cNvVmx5w==",
4050
- "license": "MIT",
4051
- "dependencies": {
4052
- "array-timsort": "^1.0.3",
4053
- "core-util-is": "^1.0.3",
4054
- "esprima": "^4.0.1"
4055
- },
4056
- "engines": {
4057
- "node": ">= 6"
4058
- }
4059
- },
4060
- "node_modules/compressible": {
4061
- "version": "2.0.18",
4062
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
4063
- "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
4064
- "license": "MIT",
4065
- "dependencies": {
4066
- "mime-db": ">= 1.43.0 < 2"
4067
- },
4068
- "engines": {
4069
- "node": ">= 0.6"
4070
- }
4071
- },
4072
- "node_modules/compression": {
4073
- "version": "1.8.1",
4074
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
4075
- "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
4076
- "license": "MIT",
4077
- "dependencies": {
4078
- "bytes": "3.1.2",
4079
- "compressible": "~2.0.18",
4080
- "debug": "2.6.9",
4081
- "negotiator": "~0.6.4",
4082
- "on-headers": "~1.1.0",
4083
- "safe-buffer": "5.2.1",
4084
- "vary": "~1.1.2"
4085
- },
4086
- "engines": {
4087
- "node": ">= 0.8.0"
4088
- }
4089
- },
4090
- "node_modules/compression/node_modules/debug": {
4091
- "version": "2.6.9",
4092
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
4093
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
4094
- "license": "MIT",
4095
- "dependencies": {
4096
- "ms": "2.0.0"
4097
- }
4098
- },
4099
- "node_modules/compression/node_modules/ms": {
4100
- "version": "2.0.0",
4101
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
4102
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
4103
- "license": "MIT"
4104
- },
4105
- "node_modules/compression/node_modules/negotiator": {
4106
- "version": "0.6.4",
4107
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
4108
- "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
4109
- "license": "MIT",
4110
- "engines": {
4111
- "node": ">= 0.6"
4112
- }
4113
- },
4114
- "node_modules/concat-map": {
4115
- "version": "0.0.1",
4116
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
4117
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
4118
- "license": "MIT"
4119
- },
4120
- "node_modules/connect": {
4121
- "version": "3.7.0",
4122
- "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
4123
- "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
4124
- "license": "MIT",
4125
- "dependencies": {
4126
- "debug": "2.6.9",
4127
- "finalhandler": "1.1.2",
4128
- "parseurl": "~1.3.3",
4129
- "utils-merge": "1.0.1"
4130
- },
4131
- "engines": {
4132
- "node": ">= 0.10.0"
4133
- }
4134
- },
4135
- "node_modules/connect/node_modules/debug": {
4136
- "version": "2.6.9",
4137
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
4138
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
4139
- "license": "MIT",
4140
- "dependencies": {
4141
- "ms": "2.0.0"
4142
- }
4143
- },
4144
- "node_modules/connect/node_modules/ms": {
4145
- "version": "2.0.0",
4146
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
4147
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
4148
- "license": "MIT"
4149
- },
4150
- "node_modules/convert-source-map": {
4151
- "version": "2.0.0",
4152
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
4153
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
4154
- "license": "MIT"
4155
- },
4156
- "node_modules/core-js-compat": {
4157
- "version": "3.48.0",
4158
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz",
4159
- "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==",
4160
- "license": "MIT",
4161
- "dependencies": {
4162
- "browserslist": "^4.28.1"
4163
- },
4164
- "funding": {
4165
- "type": "opencollective",
4166
- "url": "https://opencollective.com/core-js"
4167
- }
4168
- },
4169
- "node_modules/core-util-is": {
4170
- "version": "1.0.3",
4171
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
4172
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
4173
- "license": "MIT"
4174
- },
4175
- "node_modules/cross-fetch": {
4176
- "version": "3.2.0",
4177
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
4178
- "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
4179
- "license": "MIT",
4180
- "dependencies": {
4181
- "node-fetch": "^2.7.0"
4182
- }
4183
- },
4184
- "node_modules/cross-spawn": {
4185
- "version": "7.0.6",
4186
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
4187
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
4188
- "license": "MIT",
4189
- "dependencies": {
4190
- "path-key": "^3.1.0",
4191
- "shebang-command": "^2.0.0",
4192
- "which": "^2.0.1"
4193
- },
4194
- "engines": {
4195
- "node": ">= 8"
4196
- }
4197
- },
4198
- "node_modules/css-in-js-utils": {
4199
- "version": "3.1.0",
4200
- "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz",
4201
- "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==",
4202
- "license": "MIT",
4203
- "dependencies": {
4204
- "hyphenate-style-name": "^1.0.3"
4205
- }
4206
- },
4207
- "node_modules/css-select": {
4208
- "version": "5.2.2",
4209
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
4210
- "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
4211
- "license": "BSD-2-Clause",
4212
- "dependencies": {
4213
- "boolbase": "^1.0.0",
4214
- "css-what": "^6.1.0",
4215
- "domhandler": "^5.0.2",
4216
- "domutils": "^3.0.1",
4217
- "nth-check": "^2.0.1"
4218
- },
4219
- "funding": {
4220
- "url": "https://github.com/sponsors/fb55"
4221
- }
4222
- },
4223
- "node_modules/css-tree": {
4224
- "version": "1.1.3",
4225
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
4226
- "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
4227
- "license": "MIT",
4228
- "dependencies": {
4229
- "mdn-data": "2.0.14",
4230
- "source-map": "^0.6.1"
4231
- },
4232
- "engines": {
4233
- "node": ">=8.0.0"
4234
- }
4235
- },
4236
- "node_modules/css-tree/node_modules/source-map": {
4237
- "version": "0.6.1",
4238
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
4239
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
4240
- "license": "BSD-3-Clause",
4241
- "engines": {
4242
- "node": ">=0.10.0"
4243
- }
4244
- },
4245
- "node_modules/css-what": {
4246
- "version": "6.2.2",
4247
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
4248
- "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
4249
- "license": "BSD-2-Clause",
4250
- "engines": {
4251
- "node": ">= 6"
4252
- },
4253
- "funding": {
4254
- "url": "https://github.com/sponsors/fb55"
4255
- }
4256
- },
4257
- "node_modules/cssesc": {
4258
- "version": "3.0.0",
4259
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
4260
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
4261
- "dev": true,
4262
- "license": "MIT",
4263
- "bin": {
4264
- "cssesc": "bin/cssesc"
4265
- },
4266
- "engines": {
4267
- "node": ">=4"
4268
- }
4269
- },
4270
- "node_modules/csstype": {
4271
- "version": "3.2.3",
4272
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
4273
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
4274
- "dev": true,
4275
- "license": "MIT"
4276
- },
4277
- "node_modules/debug": {
4278
- "version": "4.4.3",
4279
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
4280
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
4281
- "license": "MIT",
4282
- "dependencies": {
4283
- "ms": "^2.1.3"
4284
- },
4285
- "engines": {
4286
- "node": ">=6.0"
4287
- },
4288
- "peerDependenciesMeta": {
4289
- "supports-color": {
4290
- "optional": true
4291
- }
4292
- }
4293
- },
4294
- "node_modules/decode-uri-component": {
4295
- "version": "0.2.2",
4296
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
4297
- "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
4298
- "license": "MIT",
4299
- "engines": {
4300
- "node": ">=0.10"
4301
- }
4302
- },
4303
- "node_modules/deepmerge": {
4304
- "version": "4.3.1",
4305
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
4306
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
4307
- "license": "MIT",
4308
- "engines": {
4309
- "node": ">=0.10.0"
4310
- }
4311
- },
4312
- "node_modules/defaults": {
4313
- "version": "1.0.4",
4314
- "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
4315
- "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
4316
- "license": "MIT",
4317
- "dependencies": {
4318
- "clone": "^1.0.2"
4319
- },
4320
- "funding": {
4321
- "url": "https://github.com/sponsors/sindresorhus"
4322
- }
4323
- },
4324
- "node_modules/define-lazy-prop": {
4325
- "version": "2.0.0",
4326
- "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
4327
- "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
4328
- "license": "MIT",
4329
- "engines": {
4330
- "node": ">=8"
4331
- }
4332
- },
4333
- "node_modules/depd": {
4334
- "version": "2.0.0",
4335
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
4336
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
4337
- "license": "MIT",
4338
- "engines": {
4339
- "node": ">= 0.8"
4340
- }
4341
- },
4342
- "node_modules/destroy": {
4343
- "version": "1.2.0",
4344
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
4345
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
4346
- "license": "MIT",
4347
- "engines": {
4348
- "node": ">= 0.8",
4349
- "npm": "1.2.8000 || >= 1.4.16"
4350
- }
4351
- },
4352
- "node_modules/detect-libc": {
4353
- "version": "2.1.2",
4354
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
4355
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
4356
- "license": "Apache-2.0",
4357
- "engines": {
4358
- "node": ">=8"
4359
- }
4360
- },
4361
- "node_modules/detect-node-es": {
4362
- "version": "1.1.0",
4363
- "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
4364
- "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
4365
- "license": "MIT"
4366
- },
4367
- "node_modules/didyoumean": {
4368
- "version": "1.2.2",
4369
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
4370
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
4371
- "dev": true,
4372
- "license": "Apache-2.0"
4373
- },
4374
- "node_modules/dlv": {
4375
- "version": "1.1.3",
4376
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
4377
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
4378
- "dev": true,
4379
- "license": "MIT"
4380
- },
4381
- "node_modules/dnssd-advertise": {
4382
- "version": "1.1.3",
4383
- "resolved": "https://registry.npmjs.org/dnssd-advertise/-/dnssd-advertise-1.1.3.tgz",
4384
- "integrity": "sha512-XENsHi3MBzWOCAXif3yZvU1Ah0l+nhJj1sjWL6TnOAYKvGiFhbTx32xHN7+wLMLUOCj7Nr0evADWG4R8JtqCDA==",
4385
- "license": "MIT"
4386
- },
4387
- "node_modules/dom-serializer": {
4388
- "version": "2.0.0",
4389
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
4390
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
4391
- "license": "MIT",
4392
- "dependencies": {
4393
- "domelementtype": "^2.3.0",
4394
- "domhandler": "^5.0.2",
4395
- "entities": "^4.2.0"
4396
- },
4397
- "funding": {
4398
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
4399
- }
4400
- },
4401
- "node_modules/domelementtype": {
4402
- "version": "2.3.0",
4403
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
4404
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
4405
- "funding": [
4406
- {
4407
- "type": "github",
4408
- "url": "https://github.com/sponsors/fb55"
4409
- }
4410
- ],
4411
- "license": "BSD-2-Clause"
4412
- },
4413
- "node_modules/domhandler": {
4414
- "version": "5.0.3",
4415
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
4416
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
4417
- "license": "BSD-2-Clause",
4418
- "dependencies": {
4419
- "domelementtype": "^2.3.0"
4420
- },
4421
- "engines": {
4422
- "node": ">= 4"
4423
- },
4424
- "funding": {
4425
- "url": "https://github.com/fb55/domhandler?sponsor=1"
4426
- }
4427
- },
4428
- "node_modules/domutils": {
4429
- "version": "3.2.2",
4430
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
4431
- "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
4432
- "license": "BSD-2-Clause",
4433
- "dependencies": {
4434
- "dom-serializer": "^2.0.0",
4435
- "domelementtype": "^2.3.0",
4436
- "domhandler": "^5.0.3"
4437
- },
4438
- "funding": {
4439
- "url": "https://github.com/fb55/domutils?sponsor=1"
4440
- }
4441
- },
4442
- "node_modules/ee-first": {
4443
- "version": "1.1.1",
4444
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
4445
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
4446
- "license": "MIT"
4447
- },
4448
- "node_modules/electron-to-chromium": {
4449
- "version": "1.5.302",
4450
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz",
4451
- "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==",
4452
- "license": "ISC"
4453
- },
4454
- "node_modules/emoji-regex": {
4455
- "version": "8.0.0",
4456
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
4457
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
4458
- "license": "MIT"
4459
- },
4460
- "node_modules/encodeurl": {
4461
- "version": "1.0.2",
4462
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
4463
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
4464
- "license": "MIT",
4465
- "engines": {
4466
- "node": ">= 0.8"
4467
- }
4468
- },
4469
- "node_modules/entities": {
4470
- "version": "4.5.0",
4471
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
4472
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
4473
- "license": "BSD-2-Clause",
4474
- "engines": {
4475
- "node": ">=0.12"
4476
- },
4477
- "funding": {
4478
- "url": "https://github.com/fb55/entities?sponsor=1"
4479
- }
4480
- },
4481
- "node_modules/error-stack-parser": {
4482
- "version": "2.1.4",
4483
- "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
4484
- "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
4485
- "license": "MIT",
4486
- "dependencies": {
4487
- "stackframe": "^1.3.4"
4488
- }
4489
- },
4490
- "node_modules/escalade": {
4491
- "version": "3.2.0",
4492
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
4493
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
4494
- "license": "MIT",
4495
- "engines": {
4496
- "node": ">=6"
4497
- }
4498
- },
4499
- "node_modules/escape-html": {
4500
- "version": "1.0.3",
4501
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
4502
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
4503
- "license": "MIT"
4504
- },
4505
- "node_modules/escape-string-regexp": {
4506
- "version": "4.0.0",
4507
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
4508
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
4509
- "license": "MIT",
4510
- "engines": {
4511
- "node": ">=10"
4512
- },
4513
- "funding": {
4514
- "url": "https://github.com/sponsors/sindresorhus"
4515
- }
4516
- },
4517
- "node_modules/esprima": {
4518
- "version": "4.0.1",
4519
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
4520
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
4521
- "license": "BSD-2-Clause",
4522
- "bin": {
4523
- "esparse": "bin/esparse.js",
4524
- "esvalidate": "bin/esvalidate.js"
4525
- },
4526
- "engines": {
4527
- "node": ">=4"
4528
- }
4529
- },
4530
- "node_modules/etag": {
4531
- "version": "1.8.1",
4532
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
4533
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
4534
- "license": "MIT",
4535
- "engines": {
4536
- "node": ">= 0.6"
4537
- }
4538
- },
4539
- "node_modules/event-target-shim": {
4540
- "version": "5.0.1",
4541
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
4542
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
4543
- "license": "MIT",
4544
- "engines": {
4545
- "node": ">=6"
4546
- }
4547
- },
4548
- "node_modules/events": {
4549
- "version": "3.3.0",
4550
- "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
4551
- "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
4552
- "license": "MIT",
4553
- "engines": {
4554
- "node": ">=0.8.x"
4555
- }
4556
- },
4557
- "node_modules/expo": {
4558
- "version": "55.0.4",
4559
- "resolved": "https://registry.npmjs.org/expo/-/expo-55.0.4.tgz",
4560
- "integrity": "sha512-cbQBPYwmH6FRvh942KR8mSdEcrVdsIMkjdHthtf59zlpzgrk28FabhOdL/Pc9WuS+CsIP3EIQbZqmLkTjv6qPg==",
4561
- "license": "MIT",
4562
- "dependencies": {
4563
- "@babel/runtime": "^7.20.0",
4564
- "@expo/cli": "55.0.14",
4565
- "@expo/config": "~55.0.8",
4566
- "@expo/config-plugins": "~55.0.6",
4567
- "@expo/devtools": "55.0.2",
4568
- "@expo/fingerprint": "0.16.5",
4569
- "@expo/local-build-cache-provider": "55.0.6",
4570
- "@expo/log-box": "55.0.7",
4571
- "@expo/metro": "~54.2.0",
4572
- "@expo/metro-config": "55.0.9",
4573
- "@expo/vector-icons": "^15.0.2",
4574
- "@ungap/structured-clone": "^1.3.0",
4575
- "babel-preset-expo": "~55.0.10",
4576
- "expo-asset": "~55.0.8",
4577
- "expo-constants": "~55.0.7",
4578
- "expo-file-system": "~55.0.10",
4579
- "expo-font": "~55.0.4",
4580
- "expo-keep-awake": "~55.0.4",
4581
- "expo-modules-autolinking": "55.0.8",
4582
- "expo-modules-core": "55.0.13",
4583
- "pretty-format": "^29.7.0",
4584
- "react-refresh": "^0.14.2",
4585
- "whatwg-url-minimum": "^0.1.1"
4586
- },
4587
- "bin": {
4588
- "expo": "bin/cli",
4589
- "expo-modules-autolinking": "bin/autolinking",
4590
- "fingerprint": "bin/fingerprint"
4591
- },
4592
- "peerDependencies": {
4593
- "@expo/dom-webview": "*",
4594
- "@expo/metro-runtime": "*",
4595
- "react": "*",
4596
- "react-native": "*",
4597
- "react-native-webview": "*"
4598
- },
4599
- "peerDependenciesMeta": {
4600
- "@expo/dom-webview": {
4601
- "optional": true
4602
- },
4603
- "@expo/metro-runtime": {
4604
- "optional": true
4605
- },
4606
- "react-native-webview": {
4607
- "optional": true
4608
- }
4609
- }
4610
- },
4611
- "node_modules/expo-audio": {
4612
- "version": "55.0.8",
4613
- "resolved": "https://registry.npmjs.org/expo-audio/-/expo-audio-55.0.8.tgz",
4614
- "integrity": "sha512-X61pQSikE2rsP2ZTMFUMThOmgGyYEHcmZpGVMrKJgcYtRCFKuctB/z69dFQPoumL+zTz8qlBoGohjkHVvA9P8A==",
4615
- "license": "MIT",
4616
- "peerDependencies": {
4617
- "expo": "*",
4618
- "expo-asset": "*",
4619
- "react": "*",
4620
- "react-native": "*"
4621
- }
4622
- },
4623
- "node_modules/expo-constants": {
4624
- "version": "55.0.7",
4625
- "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-55.0.7.tgz",
4626
- "integrity": "sha512-kdcO4TsQRRqt0USvjaY5vgQMO9H52K3kBZ/ejC7F6rz70mv08GoowrZ1CYOr5O4JpPDRlIpQfZJUucaS/c+KWQ==",
4627
- "license": "MIT",
4628
- "dependencies": {
4629
- "@expo/config": "~55.0.8",
4630
- "@expo/env": "~2.1.1"
4631
- },
4632
- "peerDependencies": {
4633
- "expo": "*",
4634
- "react-native": "*"
4635
- }
4636
- },
4637
- "node_modules/expo-file-system": {
4638
- "version": "55.0.10",
4639
- "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-55.0.10.tgz",
4640
- "integrity": "sha512-ysFdVdUgtfj2ApY0Cn+pBg+yK4xp+SNwcaH8j2B91JJQ4OXJmnyCSmrNZYz7J4mdYVuv2GzxIP+N/IGlHQG3Yw==",
4641
- "license": "MIT",
4642
- "peerDependencies": {
4643
- "expo": "*",
4644
- "react-native": "*"
4645
- }
4646
- },
4647
- "node_modules/expo-font": {
4648
- "version": "55.0.4",
4649
- "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-55.0.4.tgz",
4650
- "integrity": "sha512-ZKeGTFffPygvY5dM/9ATM2p7QDkhsaHopH7wFAWgP2lKzqUMS9B/RxCvw5CaObr9Ro7x9YptyeRKX2HmgmMfrg==",
4651
- "license": "MIT",
4652
- "dependencies": {
4653
- "fontfaceobserver": "^2.1.0"
4654
- },
4655
- "peerDependencies": {
4656
- "expo": "*",
4657
- "react": "*",
4658
- "react-native": "*"
4659
- }
4660
- },
4661
- "node_modules/expo-glass-effect": {
4662
- "version": "55.0.7",
4663
- "resolved": "https://registry.npmjs.org/expo-glass-effect/-/expo-glass-effect-55.0.7.tgz",
4664
- "integrity": "sha512-G7Q9rUaEY0YC36fGE6irDljfsfvzz/y49zagARAKvSJSyQMUSrhR25WOr5LK5Cw7gQNNBEy9U1ctlr7yCay/fQ==",
4665
- "license": "MIT",
4666
- "peerDependencies": {
4667
- "expo": "*",
4668
- "react": "*",
4669
- "react-native": "*"
4670
- }
4671
- },
4672
- "node_modules/expo-haptics": {
4673
- "version": "55.0.8",
4674
- "resolved": "https://registry.npmjs.org/expo-haptics/-/expo-haptics-55.0.8.tgz",
4675
- "integrity": "sha512-yVR6EsQwl1WuhFITc0PpfI/7dsBdjK/F2YA8xB80UUW9iTa+Tqz21FpH4n/vtbargpzFxkhl5WNYMa419+QWFQ==",
4676
- "license": "MIT",
4677
- "peerDependencies": {
4678
- "expo": "*"
4679
- }
4680
- },
4681
- "node_modules/expo-image": {
4682
- "version": "55.0.5",
4683
- "resolved": "https://registry.npmjs.org/expo-image/-/expo-image-55.0.5.tgz",
4684
- "integrity": "sha512-oejmMwy5O9EtC8po9NxkcurWHqND6p8xuJaj9FGNo8NXLt9e+w3cKWx7HuPzkH5y3qFXQ9Od+z+I/wxEci36fw==",
4685
- "license": "MIT",
4686
- "dependencies": {
4687
- "sf-symbols-typescript": "^2.2.0"
4688
- },
4689
- "peerDependencies": {
4690
- "expo": "*",
4691
- "react": "*",
4692
- "react-native": "*",
4693
- "react-native-web": "*"
4694
- },
4695
- "peerDependenciesMeta": {
4696
- "react-native-web": {
4697
- "optional": true
4698
- }
4699
- }
4700
- },
4701
- "node_modules/expo-image-loader": {
4702
- "version": "55.0.0",
4703
- "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-55.0.0.tgz",
4704
- "integrity": "sha512-NOjp56wDrfuA5aiNAybBIjqIn1IxKeGJ8CECWZncQ/GzjZfyTYAHTCyeApYkdKkMBLHINzI4BbTGSlbCa0fXXQ==",
4705
- "license": "MIT",
4706
- "peerDependencies": {
4707
- "expo": "*"
4708
- }
4709
- },
4710
- "node_modules/expo-image-picker": {
4711
- "version": "55.0.11",
4712
- "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-55.0.11.tgz",
4713
- "integrity": "sha512-geJklIGdAR2N16iSk86oyJe7QgX5RpqDX1FjKpxO53fF4D0eBmg5Irm6gRwT0b+DHP1kJevZgzzbVJsRAV362g==",
4714
- "license": "MIT",
4715
- "dependencies": {
4716
- "expo-image-loader": "~55.0.0"
4717
- },
4718
- "peerDependencies": {
4719
- "expo": "*"
4720
- }
4721
- },
4722
- "node_modules/expo-linking": {
4723
- "version": "55.0.7",
4724
- "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-55.0.7.tgz",
4725
- "integrity": "sha512-MiGCedere1vzQTEi2aGrkzd7eh/rPSz4w6F3GMBuAJzYl+/0VhIuyhozpEGrueyDIXWfzaUVOcn3SfxVi+kwQQ==",
4726
- "license": "MIT",
4727
- "dependencies": {
4728
- "expo-constants": "~55.0.7",
4729
- "invariant": "^2.2.4"
4730
- },
4731
- "peerDependencies": {
4732
- "react": "*",
4733
- "react-native": "*"
4734
- }
4735
- },
4736
- "node_modules/expo-modules-autolinking": {
4737
- "version": "55.0.8",
4738
- "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-55.0.8.tgz",
4739
- "integrity": "sha512-nrWB1pkNp7bR8ECUTgYUiJ2Pyh6AvxCBXZ+lyPlfl1TzEIGhwU1Yqr+d78eJDueXaW+9zKeE0HqrTZoLS3ve4A==",
4740
- "license": "MIT",
4741
- "dependencies": {
4742
- "@expo/require-utils": "^55.0.2",
4743
- "@expo/spawn-async": "^1.7.2",
4744
- "chalk": "^4.1.0",
4745
- "commander": "^7.2.0"
4746
- },
4747
- "bin": {
4748
- "expo-modules-autolinking": "bin/expo-modules-autolinking.js"
4749
- }
4750
- },
4751
- "node_modules/expo-modules-core": {
4752
- "version": "55.0.13",
4753
- "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-55.0.13.tgz",
4754
- "integrity": "sha512-DYLQTOJAR7jD3M9S0sH9myZaPEtShdicHrPiWcupIXMeMkQxFzErx+adUI8gZPy4AU45BgeGgtaogRfT25iLfw==",
4755
- "license": "MIT",
4756
- "dependencies": {
4757
- "invariant": "^2.2.4"
4758
- },
4759
- "peerDependencies": {
4760
- "react": "*",
4761
- "react-native": "*"
4762
- }
4763
- },
4764
- "node_modules/expo-router": {
4765
- "version": "55.0.3",
4766
- "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-55.0.3.tgz",
4767
- "integrity": "sha512-B3MQAeZq9B2SS5kgEybGqXYR0AY7QYM7fQ5E4bJwtvZLJjWPmWhDALhBpD26ovK/i1k0fi9VgW47FKJODxM5Jg==",
4768
- "license": "MIT",
4769
- "dependencies": {
4770
- "@expo/metro-runtime": "^55.0.6",
4771
- "@expo/schema-utils": "^55.0.2",
4772
- "@radix-ui/react-slot": "^1.2.0",
4773
- "@radix-ui/react-tabs": "^1.1.12",
4774
- "@react-navigation/bottom-tabs": "^7.10.1",
4775
- "@react-navigation/native": "^7.1.28",
4776
- "@react-navigation/native-stack": "^7.10.1",
4777
- "client-only": "^0.0.1",
4778
- "debug": "^4.3.4",
4779
- "escape-string-regexp": "^4.0.0",
4780
- "expo-glass-effect": "^55.0.7",
4781
- "expo-image": "^55.0.5",
4782
- "expo-server": "^55.0.6",
4783
- "expo-symbols": "^55.0.4",
4784
- "fast-deep-equal": "^3.1.3",
4785
- "invariant": "^2.2.4",
4786
- "nanoid": "^3.3.8",
4787
- "query-string": "^7.1.3",
4788
- "react-fast-compare": "^3.2.2",
4789
- "react-native-is-edge-to-edge": "^1.2.1",
4790
- "semver": "~7.6.3",
4791
- "server-only": "^0.0.1",
4792
- "sf-symbols-typescript": "^2.1.0",
4793
- "shallowequal": "^1.1.0",
4794
- "use-latest-callback": "^0.2.1",
4795
- "vaul": "^1.1.2"
4796
- },
4797
- "peerDependencies": {
4798
- "@expo/log-box": "55.0.7",
4799
- "@expo/metro-runtime": "^55.0.6",
4800
- "@react-navigation/drawer": "^7.7.2",
4801
- "@testing-library/react-native": ">= 13.2.0",
4802
- "expo": "*",
4803
- "expo-constants": "^55.0.7",
4804
- "expo-linking": "^55.0.7",
4805
- "react": "*",
4806
- "react-dom": "*",
4807
- "react-native": "*",
4808
- "react-native-gesture-handler": "*",
4809
- "react-native-reanimated": "*",
4810
- "react-native-safe-area-context": ">= 5.4.0",
4811
- "react-native-screens": "*",
4812
- "react-native-web": "*",
4813
- "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4"
4814
- },
4815
- "peerDependenciesMeta": {
4816
- "@react-navigation/drawer": {
4817
- "optional": true
4818
- },
4819
- "@testing-library/react-native": {
4820
- "optional": true
4821
- },
4822
- "react-dom": {
4823
- "optional": true
4824
- },
4825
- "react-native-gesture-handler": {
4826
- "optional": true
4827
- },
4828
- "react-native-reanimated": {
4829
- "optional": true
4830
- },
4831
- "react-native-web": {
4832
- "optional": true
4833
- },
4834
- "react-server-dom-webpack": {
4835
- "optional": true
4836
- }
4837
- }
4838
- },
4839
- "node_modules/expo-router/node_modules/@expo/metro-runtime": {
4840
- "version": "55.0.6",
4841
- "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-55.0.6.tgz",
4842
- "integrity": "sha512-l8VvgKN9md+URjeQDB+DnHVmvpcWI6zFLH6yv7GTv4sfRDKyaZ5zDXYjTP1phYdgW6ea2NrRtCGNIxylWhsgtg==",
4843
- "license": "MIT",
4844
- "dependencies": {
4845
- "@expo/log-box": "55.0.7",
4846
- "anser": "^1.4.9",
4847
- "pretty-format": "^29.7.0",
4848
- "stacktrace-parser": "^0.1.10",
4849
- "whatwg-fetch": "^3.0.0"
4850
- },
4851
- "peerDependencies": {
4852
- "expo": "*",
4853
- "react": "*",
4854
- "react-dom": "*",
4855
- "react-native": "*"
4856
- },
4857
- "peerDependenciesMeta": {
4858
- "react-dom": {
4859
- "optional": true
4860
- }
4861
- }
4862
- },
4863
- "node_modules/expo-router/node_modules/@radix-ui/react-tabs": {
4864
- "version": "1.1.13",
4865
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
4866
- "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
4867
- "license": "MIT",
4868
- "dependencies": {
4869
- "@radix-ui/primitive": "1.1.3",
4870
- "@radix-ui/react-context": "1.1.2",
4871
- "@radix-ui/react-direction": "1.1.1",
4872
- "@radix-ui/react-id": "1.1.1",
4873
- "@radix-ui/react-presence": "1.1.5",
4874
- "@radix-ui/react-primitive": "2.1.3",
4875
- "@radix-ui/react-roving-focus": "1.1.11",
4876
- "@radix-ui/react-use-controllable-state": "1.2.2"
4877
- },
4878
- "peerDependencies": {
4879
- "@types/react": "*",
4880
- "@types/react-dom": "*",
4881
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
4882
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
4883
- },
4884
- "peerDependenciesMeta": {
4885
- "@types/react": {
4886
- "optional": true
4887
- },
4888
- "@types/react-dom": {
4889
- "optional": true
4890
- }
4891
- }
4892
- },
4893
- "node_modules/expo-router/node_modules/semver": {
4894
- "version": "7.6.3",
4895
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
4896
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
4897
- "license": "ISC",
4898
- "bin": {
4899
- "semver": "bin/semver.js"
4900
- },
4901
- "engines": {
4902
- "node": ">=10"
4903
- }
4904
- },
4905
- "node_modules/expo-secure-store": {
4906
- "version": "55.0.8",
4907
- "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-55.0.8.tgz",
4908
- "integrity": "sha512-8w9tQe8U6oRo5YIzqCqVhRrOnfoODNDoitBtLXEx+zS6WLUnkRq5kH7ViJuOgiM7PzLr9pvAliRiDOKyvFbTuQ==",
4909
- "license": "MIT",
4910
- "peerDependencies": {
4911
- "expo": "*"
4912
- }
4913
- },
4914
- "node_modules/expo-server": {
4915
- "version": "55.0.6",
4916
- "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-55.0.6.tgz",
4917
- "integrity": "sha512-xI72FTm469FfuuBL2R5aNtthgH+GR7ygOpsx/KcPS0K8AZaZd7VjtEExbzn9/qyyYkWW3T+3dAmCDKOMX8gdmQ==",
4918
- "license": "MIT",
4919
- "engines": {
4920
- "node": ">=20.16.0"
4921
- }
4922
- },
4923
- "node_modules/expo-sharing": {
4924
- "version": "55.0.11",
4925
- "resolved": "https://registry.npmjs.org/expo-sharing/-/expo-sharing-55.0.11.tgz",
4926
- "integrity": "sha512-YlVez832W0sYR2KJY4Dr8ON9aC+Wp8a/r40eQyhoHT9Tetkr2KBM7tWLT0CGKRuTTnrqJL1C51UacLkHJ9zmNA==",
4927
- "license": "MIT",
4928
- "dependencies": {
4929
- "@expo/config-plugins": "^55.0.6",
4930
- "@expo/config-types": "^55.0.5",
4931
- "@expo/plist": "^0.5.2"
4932
- },
4933
- "peerDependencies": {
4934
- "expo": "*",
4935
- "react": "*",
4936
- "react-native": "*"
4937
- }
4938
- },
4939
- "node_modules/expo-splash-screen": {
4940
- "version": "55.0.10",
4941
- "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-55.0.10.tgz",
4942
- "integrity": "sha512-RN5qqrxudxFlRIjLFr/Ifmt+mUCLRc0gs66PekP6flzNS/JYEuoCbwJ+NmUwwJtPA+vyy60DYiky0QmS98ydmQ==",
4943
- "license": "MIT",
4944
- "dependencies": {
4945
- "@expo/prebuild-config": "^55.0.8"
4946
- },
4947
- "peerDependencies": {
4948
- "expo": "*"
4949
- }
4950
- },
4951
- "node_modules/expo-status-bar": {
4952
- "version": "55.0.4",
4953
- "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-55.0.4.tgz",
4954
- "integrity": "sha512-BPDjUXKqv1F9j2YNGLRZfkBEZXIEEpqj+t81y4c+4fdSN3Pos7goIHXgcl2ozbKQLgKRZQyNZQtbUgh5UjHYUQ==",
4955
- "license": "MIT",
4956
- "dependencies": {
4957
- "react-native-is-edge-to-edge": "^1.2.1"
4958
- },
4959
- "peerDependencies": {
4960
- "react": "*",
4961
- "react-native": "*"
4962
- }
4963
- },
4964
- "node_modules/expo-symbols": {
4965
- "version": "55.0.4",
4966
- "resolved": "https://registry.npmjs.org/expo-symbols/-/expo-symbols-55.0.4.tgz",
4967
- "integrity": "sha512-w9rxPlpta3gks0G4Tvpq/qQdiMp4R/XOeOzyjSruYUQakmsWbQBKA+Sd/fCVXs7qFJSvVTOGXiOhZm+YJRYZVg==",
4968
- "license": "MIT",
4969
- "dependencies": {
4970
- "@expo-google-fonts/material-symbols": "^0.4.1",
4971
- "sf-symbols-typescript": "^2.0.0"
4972
- },
4973
- "peerDependencies": {
4974
- "expo": "*",
4975
- "expo-font": "*",
4976
- "react": "*",
4977
- "react-native": "*"
4978
- }
4979
- },
4980
- "node_modules/expo-system-ui": {
4981
- "version": "55.0.9",
4982
- "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-55.0.9.tgz",
4983
- "integrity": "sha512-8ygP1B0uFAFI8s7eHY2IcGnE83GhFeZYwHBr/fQ4dSXnc7iVT9zp2PvyTyiDiibQ69dBG+fauMQ4KlPcOO51kQ==",
4984
- "license": "MIT",
4985
- "dependencies": {
4986
- "@react-native/normalize-colors": "0.83.2",
4987
- "debug": "^4.3.2"
4988
- },
4989
- "peerDependencies": {
4990
- "expo": "*",
4991
- "react-native": "*",
4992
- "react-native-web": "*"
4993
- },
4994
- "peerDependenciesMeta": {
4995
- "react-native-web": {
4996
- "optional": true
4997
- }
4998
- }
4999
- },
5000
- "node_modules/expo-web-browser": {
5001
- "version": "55.0.9",
5002
- "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-55.0.9.tgz",
5003
- "integrity": "sha512-PvAVsG401QmZabtTsYh1cYcpPiqvBPs8oiOkSrp0jIXnneiM466HxmeNtvo+fNxqJ2nwOBz9qLPiWRO91VBfsQ==",
5004
- "license": "MIT",
5005
- "peerDependencies": {
5006
- "expo": "*",
5007
- "react-native": "*"
5008
- }
5009
- },
5010
- "node_modules/expo/node_modules/@expo/cli": {
5011
- "version": "55.0.14",
5012
- "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-55.0.14.tgz",
5013
- "integrity": "sha512-glXPSjjLCIz+KX/ezqLTGIF9eTE1lexiCxunvB3loRZNnGeBDGW3eF++cuPKudW26jeC6bqZkcqBG7Lp0Sp9qg==",
5014
- "license": "MIT",
5015
- "dependencies": {
5016
- "@expo/code-signing-certificates": "^0.0.6",
5017
- "@expo/config": "~55.0.8",
5018
- "@expo/config-plugins": "~55.0.6",
5019
- "@expo/devcert": "^1.2.1",
5020
- "@expo/env": "~2.1.1",
5021
- "@expo/image-utils": "^0.8.12",
5022
- "@expo/json-file": "^10.0.12",
5023
- "@expo/log-box": "55.0.7",
5024
- "@expo/metro": "~54.2.0",
5025
- "@expo/metro-config": "~55.0.9",
5026
- "@expo/osascript": "^2.4.2",
5027
- "@expo/package-manager": "^1.10.3",
5028
- "@expo/plist": "^0.5.2",
5029
- "@expo/prebuild-config": "^55.0.8",
5030
- "@expo/require-utils": "^55.0.2",
5031
- "@expo/router-server": "^55.0.9",
5032
- "@expo/schema-utils": "^55.0.2",
5033
- "@expo/spawn-async": "^1.7.2",
5034
- "@expo/ws-tunnel": "^1.0.1",
5035
- "@expo/xcpretty": "^4.4.0",
5036
- "@react-native/dev-middleware": "0.83.2",
5037
- "accepts": "^1.3.8",
5038
- "arg": "^5.0.2",
5039
- "better-opn": "~3.0.2",
5040
- "bplist-creator": "0.1.0",
5041
- "bplist-parser": "^0.3.1",
5042
- "chalk": "^4.0.0",
5043
- "ci-info": "^3.3.0",
5044
- "compression": "^1.7.4",
5045
- "connect": "^3.7.0",
5046
- "debug": "^4.3.4",
5047
- "dnssd-advertise": "^1.1.3",
5048
- "expo-server": "^55.0.6",
5049
- "fetch-nodeshim": "^0.4.6",
5050
- "getenv": "^2.0.0",
5051
- "glob": "^13.0.0",
5052
- "lan-network": "^0.2.0",
5053
- "multitars": "^0.2.3",
5054
- "node-forge": "^1.3.3",
5055
- "npm-package-arg": "^11.0.0",
5056
- "ora": "^3.4.0",
5057
- "picomatch": "^4.0.3",
5058
- "pretty-format": "^29.7.0",
5059
- "progress": "^2.0.3",
5060
- "prompts": "^2.3.2",
5061
- "resolve-from": "^5.0.0",
5062
- "semver": "^7.6.0",
5063
- "send": "^0.19.0",
5064
- "slugify": "^1.3.4",
5065
- "source-map-support": "~0.5.21",
5066
- "stacktrace-parser": "^0.1.10",
5067
- "structured-headers": "^0.4.1",
5068
- "terminal-link": "^2.1.1",
5069
- "toqr": "^0.1.1",
5070
- "wrap-ansi": "^7.0.0",
5071
- "ws": "^8.12.1",
5072
- "zod": "^3.25.76"
5073
- },
5074
- "bin": {
5075
- "expo-internal": "build/bin/cli"
5076
- },
5077
- "peerDependencies": {
5078
- "expo": "*",
5079
- "expo-router": "*",
5080
- "react-native": "*"
5081
- },
5082
- "peerDependenciesMeta": {
5083
- "expo-router": {
5084
- "optional": true
5085
- },
5086
- "react-native": {
5087
- "optional": true
5088
- }
5089
- }
5090
- },
5091
- "node_modules/expo/node_modules/@expo/cli/node_modules/@expo/router-server": {
5092
- "version": "55.0.9",
5093
- "resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-55.0.9.tgz",
5094
- "integrity": "sha512-LcCFi+P1qfZOsw0DO4JwNKRxtWt4u2bjTYj0PUe4WVf9NVG/NfUetAXYRbBS6P+gupfM6SC+/bdzdqCWQh7j8g==",
5095
- "license": "MIT",
5096
- "dependencies": {
5097
- "debug": "^4.3.4"
5098
- },
5099
- "peerDependencies": {
5100
- "@expo/metro-runtime": "^55.0.6",
5101
- "expo": "*",
5102
- "expo-constants": "^55.0.7",
5103
- "expo-font": "^55.0.4",
5104
- "expo-router": "*",
5105
- "expo-server": "^55.0.6",
5106
- "react": "*",
5107
- "react-dom": "*",
5108
- "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1"
5109
- },
5110
- "peerDependenciesMeta": {
5111
- "@expo/metro-runtime": {
5112
- "optional": true
5113
- },
5114
- "expo-router": {
5115
- "optional": true
5116
- },
5117
- "react-dom": {
5118
- "optional": true
5119
- },
5120
- "react-server-dom-webpack": {
5121
- "optional": true
5122
- }
5123
- }
5124
- },
5125
- "node_modules/expo/node_modules/@expo/metro-config": {
5126
- "version": "55.0.9",
5127
- "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-55.0.9.tgz",
5128
- "integrity": "sha512-ZJFEfat/+dLUhFyFFWrzMjAqAwwUaJ3RD42QNqR7jh+RVYkAf6XYLynb5qrKJTHI1EcOx4KoO1717yXYYRFDBA==",
5129
- "license": "MIT",
5130
- "dependencies": {
5131
- "@babel/code-frame": "^7.20.0",
5132
- "@babel/core": "^7.20.0",
5133
- "@babel/generator": "^7.20.5",
5134
- "@expo/config": "~55.0.8",
5135
- "@expo/env": "~2.1.1",
5136
- "@expo/json-file": "~10.0.12",
5137
- "@expo/metro": "~54.2.0",
5138
- "@expo/spawn-async": "^1.7.2",
5139
- "browserslist": "^4.25.0",
5140
- "chalk": "^4.1.0",
5141
- "debug": "^4.3.2",
5142
- "getenv": "^2.0.0",
5143
- "glob": "^13.0.0",
5144
- "hermes-parser": "^0.32.0",
5145
- "jsc-safe-url": "^0.2.4",
5146
- "lightningcss": "^1.30.1",
5147
- "picomatch": "^4.0.3",
5148
- "postcss": "~8.4.32",
5149
- "resolve-from": "^5.0.0"
5150
- },
5151
- "peerDependencies": {
5152
- "expo": "*"
5153
- },
5154
- "peerDependenciesMeta": {
5155
- "expo": {
5156
- "optional": true
5157
- }
5158
- }
5159
- },
5160
- "node_modules/expo/node_modules/@expo/vector-icons": {
5161
- "version": "15.1.1",
5162
- "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz",
5163
- "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==",
5164
- "license": "MIT",
5165
- "peerDependencies": {
5166
- "expo-font": ">=14.0.4",
5167
- "react": "*",
5168
- "react-native": "*"
5169
- }
5170
- },
5171
- "node_modules/expo/node_modules/ci-info": {
5172
- "version": "3.9.0",
5173
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
5174
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
5175
- "funding": [
5176
- {
5177
- "type": "github",
5178
- "url": "https://github.com/sponsors/sibiraj-s"
5179
- }
5180
- ],
5181
- "license": "MIT",
5182
- "engines": {
5183
- "node": ">=8"
5184
- }
5185
- },
5186
- "node_modules/expo/node_modules/expo-asset": {
5187
- "version": "55.0.8",
5188
- "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-55.0.8.tgz",
5189
- "integrity": "sha512-yEz2svDX67R0yiW2skx6dJmcE0q7sj9ECpGMcxBExMCbctc+nMoZCnjUuhzPl5vhClUsO5HFFXS5vIGmf1bgHQ==",
5190
- "license": "MIT",
5191
- "dependencies": {
5192
- "@expo/image-utils": "^0.8.12",
5193
- "expo-constants": "~55.0.7"
5194
- },
5195
- "peerDependencies": {
5196
- "expo": "*",
5197
- "react": "*",
5198
- "react-native": "*"
5199
- }
5200
- },
5201
- "node_modules/expo/node_modules/expo-keep-awake": {
5202
- "version": "55.0.4",
5203
- "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-55.0.4.tgz",
5204
- "integrity": "sha512-vwfdMtMS5Fxaon8gC0AiE70SpxTsHJ+rjeoVJl8kdfdbxczF7OIaVmfjFJ5Gfigd/WZiLqxhfZk34VAkXF4PNg==",
5205
- "license": "MIT",
5206
- "peerDependencies": {
5207
- "expo": "*",
5208
- "react": "*"
5209
- }
5210
- },
5211
- "node_modules/expo/node_modules/picomatch": {
5212
- "version": "4.0.3",
5213
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
5214
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
5215
- "license": "MIT",
5216
- "engines": {
5217
- "node": ">=12"
5218
- },
5219
- "funding": {
5220
- "url": "https://github.com/sponsors/jonschlinkert"
5221
- }
5222
- },
5223
- "node_modules/expo/node_modules/ws": {
5224
- "version": "8.19.0",
5225
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
5226
- "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
5227
- "license": "MIT",
5228
- "engines": {
5229
- "node": ">=10.0.0"
5230
- },
5231
- "peerDependencies": {
5232
- "bufferutil": "^4.0.1",
5233
- "utf-8-validate": ">=5.0.2"
5234
- },
5235
- "peerDependenciesMeta": {
5236
- "bufferutil": {
5237
- "optional": true
5238
- },
5239
- "utf-8-validate": {
5240
- "optional": true
5241
- }
5242
- }
5243
- },
5244
- "node_modules/exponential-backoff": {
5245
- "version": "3.1.3",
5246
- "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
5247
- "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
5248
- "license": "Apache-2.0"
5249
- },
5250
- "node_modules/fast-deep-equal": {
5251
- "version": "3.1.3",
5252
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
5253
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
5254
- "license": "MIT"
5255
- },
5256
- "node_modules/fast-glob": {
5257
- "version": "3.3.3",
5258
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
5259
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
5260
- "dev": true,
5261
- "license": "MIT",
5262
- "dependencies": {
5263
- "@nodelib/fs.stat": "^2.0.2",
5264
- "@nodelib/fs.walk": "^1.2.3",
5265
- "glob-parent": "^5.1.2",
5266
- "merge2": "^1.3.0",
5267
- "micromatch": "^4.0.8"
5268
- },
5269
- "engines": {
5270
- "node": ">=8.6.0"
5271
- }
5272
- },
5273
- "node_modules/fast-glob/node_modules/glob-parent": {
5274
- "version": "5.1.2",
5275
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
5276
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
5277
- "dev": true,
5278
- "license": "ISC",
5279
- "dependencies": {
5280
- "is-glob": "^4.0.1"
5281
- },
5282
- "engines": {
5283
- "node": ">= 6"
5284
- }
5285
- },
5286
- "node_modules/fast-json-stable-stringify": {
5287
- "version": "2.1.0",
5288
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
5289
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
5290
- "license": "MIT"
5291
- },
5292
- "node_modules/fastq": {
5293
- "version": "1.20.1",
5294
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
5295
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
5296
- "dev": true,
5297
- "license": "ISC",
5298
- "dependencies": {
5299
- "reusify": "^1.0.4"
5300
- }
5301
- },
5302
- "node_modules/fb-dotslash": {
5303
- "version": "0.5.8",
5304
- "resolved": "https://registry.npmjs.org/fb-dotslash/-/fb-dotslash-0.5.8.tgz",
5305
- "integrity": "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==",
5306
- "license": "(MIT OR Apache-2.0)",
5307
- "bin": {
5308
- "dotslash": "bin/dotslash"
5309
- },
5310
- "engines": {
5311
- "node": ">=20"
5312
- }
5313
- },
5314
- "node_modules/fb-watchman": {
5315
- "version": "2.0.2",
5316
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
5317
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
5318
- "license": "Apache-2.0",
5319
- "dependencies": {
5320
- "bser": "2.1.1"
5321
- }
5322
- },
5323
- "node_modules/fbjs": {
5324
- "version": "3.0.5",
5325
- "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
5326
- "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
5327
- "license": "MIT",
5328
- "dependencies": {
5329
- "cross-fetch": "^3.1.5",
5330
- "fbjs-css-vars": "^1.0.0",
5331
- "loose-envify": "^1.0.0",
5332
- "object-assign": "^4.1.0",
5333
- "promise": "^7.1.1",
5334
- "setimmediate": "^1.0.5",
5335
- "ua-parser-js": "^1.0.35"
5336
- }
5337
- },
5338
- "node_modules/fbjs-css-vars": {
5339
- "version": "1.0.2",
5340
- "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
5341
- "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
5342
- "license": "MIT"
5343
- },
5344
- "node_modules/fbjs/node_modules/promise": {
5345
- "version": "7.3.1",
5346
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
5347
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
5348
- "license": "MIT",
5349
- "dependencies": {
5350
- "asap": "~2.0.3"
5351
- }
5352
- },
5353
- "node_modules/fetch-nodeshim": {
5354
- "version": "0.4.8",
5355
- "resolved": "https://registry.npmjs.org/fetch-nodeshim/-/fetch-nodeshim-0.4.8.tgz",
5356
- "integrity": "sha512-YW5vG33rabBq6JpYosLNoXoaMN69/WH26MeeX2hkDVjN6UlvRGq3Wkazl9H0kisH95aMu/HtHL64JUvv/+Nv/g==",
5357
- "license": "MIT"
5358
- },
5359
- "node_modules/fill-range": {
5360
- "version": "7.1.1",
5361
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
5362
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
5363
- "license": "MIT",
5364
- "dependencies": {
5365
- "to-regex-range": "^5.0.1"
5366
- },
5367
- "engines": {
5368
- "node": ">=8"
5369
- }
5370
- },
5371
- "node_modules/filter-obj": {
5372
- "version": "1.1.0",
5373
- "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
5374
- "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
5375
- "license": "MIT",
5376
- "engines": {
5377
- "node": ">=0.10.0"
5378
- }
5379
- },
5380
- "node_modules/finalhandler": {
5381
- "version": "1.1.2",
5382
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
5383
- "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
5384
- "license": "MIT",
5385
- "dependencies": {
5386
- "debug": "2.6.9",
5387
- "encodeurl": "~1.0.2",
5388
- "escape-html": "~1.0.3",
5389
- "on-finished": "~2.3.0",
5390
- "parseurl": "~1.3.3",
5391
- "statuses": "~1.5.0",
5392
- "unpipe": "~1.0.0"
5393
- },
5394
- "engines": {
5395
- "node": ">= 0.8"
5396
- }
5397
- },
5398
- "node_modules/finalhandler/node_modules/debug": {
5399
- "version": "2.6.9",
5400
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
5401
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
5402
- "license": "MIT",
5403
- "dependencies": {
5404
- "ms": "2.0.0"
5405
- }
5406
- },
5407
- "node_modules/finalhandler/node_modules/ms": {
5408
- "version": "2.0.0",
5409
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
5410
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
5411
- "license": "MIT"
5412
- },
5413
- "node_modules/find-babel-config": {
5414
- "version": "2.1.2",
5415
- "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.2.tgz",
5416
- "integrity": "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==",
5417
- "dev": true,
5418
- "license": "MIT",
5419
- "dependencies": {
5420
- "json5": "^2.2.3"
5421
- }
5422
- },
5423
- "node_modules/find-up": {
5424
- "version": "4.1.0",
5425
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
5426
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
5427
- "license": "MIT",
5428
- "dependencies": {
5429
- "locate-path": "^5.0.0",
5430
- "path-exists": "^4.0.0"
5431
- },
5432
- "engines": {
5433
- "node": ">=8"
5434
- }
5435
- },
5436
- "node_modules/flow-enums-runtime": {
5437
- "version": "0.0.6",
5438
- "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz",
5439
- "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==",
5440
- "license": "MIT"
5441
- },
5442
- "node_modules/fontfaceobserver": {
5443
- "version": "2.3.0",
5444
- "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
5445
- "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==",
5446
- "license": "BSD-2-Clause"
5447
- },
5448
- "node_modules/fresh": {
5449
- "version": "0.5.2",
5450
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
5451
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
5452
- "license": "MIT",
5453
- "engines": {
5454
- "node": ">= 0.6"
5455
- }
5456
- },
5457
- "node_modules/fs.realpath": {
5458
- "version": "1.0.0",
5459
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
5460
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
5461
- "license": "ISC"
5462
- },
5463
- "node_modules/fsevents": {
5464
- "version": "2.3.3",
5465
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
5466
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
5467
- "hasInstallScript": true,
5468
- "license": "MIT",
5469
- "optional": true,
5470
- "os": [
5471
- "darwin"
5472
- ],
5473
- "engines": {
5474
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
5475
- }
5476
- },
5477
- "node_modules/function-bind": {
5478
- "version": "1.1.2",
5479
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
5480
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
5481
- "license": "MIT",
5482
- "funding": {
5483
- "url": "https://github.com/sponsors/ljharb"
5484
- }
5485
- },
5486
- "node_modules/gensync": {
5487
- "version": "1.0.0-beta.2",
5488
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
5489
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
5490
- "license": "MIT",
5491
- "engines": {
5492
- "node": ">=6.9.0"
5493
- }
5494
- },
5495
- "node_modules/get-caller-file": {
5496
- "version": "2.0.5",
5497
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
5498
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
5499
- "license": "ISC",
5500
- "engines": {
5501
- "node": "6.* || 8.* || >= 10.*"
5502
- }
5503
- },
5504
- "node_modules/get-nonce": {
5505
- "version": "1.0.1",
5506
- "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
5507
- "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
5508
- "license": "MIT",
5509
- "engines": {
5510
- "node": ">=6"
5511
- }
5512
- },
5513
- "node_modules/get-package-type": {
5514
- "version": "0.1.0",
5515
- "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
5516
- "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
5517
- "license": "MIT",
5518
- "engines": {
5519
- "node": ">=8.0.0"
5520
- }
5521
- },
5522
- "node_modules/getenv": {
5523
- "version": "2.0.0",
5524
- "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz",
5525
- "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==",
5526
- "license": "MIT",
5527
- "engines": {
5528
- "node": ">=6"
5529
- }
5530
- },
5531
- "node_modules/glob": {
5532
- "version": "13.0.6",
5533
- "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
5534
- "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
5535
- "license": "BlueOak-1.0.0",
5536
- "dependencies": {
5537
- "minimatch": "^10.2.2",
5538
- "minipass": "^7.1.3",
5539
- "path-scurry": "^2.0.2"
5540
- },
5541
- "engines": {
5542
- "node": "18 || 20 || >=22"
5543
- },
5544
- "funding": {
5545
- "url": "https://github.com/sponsors/isaacs"
5546
- }
5547
- },
5548
- "node_modules/glob-parent": {
5549
- "version": "6.0.2",
5550
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
5551
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
5552
- "dev": true,
5553
- "license": "ISC",
5554
- "dependencies": {
5555
- "is-glob": "^4.0.3"
5556
- },
5557
- "engines": {
5558
- "node": ">=10.13.0"
5559
- }
5560
- },
5561
- "node_modules/graceful-fs": {
5562
- "version": "4.2.11",
5563
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
5564
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
5565
- "license": "ISC"
5566
- },
5567
- "node_modules/has-flag": {
5568
- "version": "4.0.0",
5569
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
5570
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
5571
- "license": "MIT",
5572
- "engines": {
5573
- "node": ">=8"
5574
- }
5575
- },
5576
- "node_modules/hasown": {
5577
- "version": "2.0.2",
5578
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
5579
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
5580
- "license": "MIT",
5581
- "dependencies": {
5582
- "function-bind": "^1.1.2"
5583
- },
5584
- "engines": {
5585
- "node": ">= 0.4"
5586
- }
5587
- },
5588
- "node_modules/hermes-compiler": {
5589
- "version": "0.14.1",
5590
- "resolved": "https://registry.npmjs.org/hermes-compiler/-/hermes-compiler-0.14.1.tgz",
5591
- "integrity": "sha512-+RPPQlayoZ9n6/KXKt5SFILWXCGJ/LV5d24L5smXrvTDrPS4L6dSctPczXauuvzFP3QEJbD1YO7Z3Ra4a+4IhA==",
5592
- "license": "MIT"
5593
- },
5594
- "node_modules/hermes-estree": {
5595
- "version": "0.32.0",
5596
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz",
5597
- "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==",
5598
- "license": "MIT"
5599
- },
5600
- "node_modules/hermes-parser": {
5601
- "version": "0.32.0",
5602
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz",
5603
- "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==",
5604
- "license": "MIT",
5605
- "dependencies": {
5606
- "hermes-estree": "0.32.0"
5607
- }
5608
- },
5609
- "node_modules/hoist-non-react-statics": {
5610
- "version": "3.3.2",
5611
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
5612
- "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
5613
- "license": "BSD-3-Clause",
5614
- "dependencies": {
5615
- "react-is": "^16.7.0"
5616
- }
5617
- },
5618
- "node_modules/hoist-non-react-statics/node_modules/react-is": {
5619
- "version": "16.13.1",
5620
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
5621
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
5622
- "license": "MIT"
5623
- },
5624
- "node_modules/hosted-git-info": {
5625
- "version": "7.0.2",
5626
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
5627
- "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
5628
- "license": "ISC",
5629
- "dependencies": {
5630
- "lru-cache": "^10.0.1"
5631
- },
5632
- "engines": {
5633
- "node": "^16.14.0 || >=18.0.0"
5634
- }
5635
- },
5636
- "node_modules/hosted-git-info/node_modules/lru-cache": {
5637
- "version": "10.4.3",
5638
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
5639
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
5640
- "license": "ISC"
5641
- },
5642
- "node_modules/http-errors": {
5643
- "version": "2.0.1",
5644
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
5645
- "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
5646
- "license": "MIT",
5647
- "dependencies": {
5648
- "depd": "~2.0.0",
5649
- "inherits": "~2.0.4",
5650
- "setprototypeof": "~1.2.0",
5651
- "statuses": "~2.0.2",
5652
- "toidentifier": "~1.0.1"
5653
- },
5654
- "engines": {
5655
- "node": ">= 0.8"
5656
- },
5657
- "funding": {
5658
- "type": "opencollective",
5659
- "url": "https://opencollective.com/express"
5660
- }
5661
- },
5662
- "node_modules/http-errors/node_modules/statuses": {
5663
- "version": "2.0.2",
5664
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
5665
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
5666
- "license": "MIT",
5667
- "engines": {
5668
- "node": ">= 0.8"
5669
- }
5670
- },
5671
- "node_modules/https-proxy-agent": {
5672
- "version": "7.0.6",
5673
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
5674
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
5675
- "license": "MIT",
5676
- "dependencies": {
5677
- "agent-base": "^7.1.2",
5678
- "debug": "4"
5679
- },
5680
- "engines": {
5681
- "node": ">= 14"
5682
- }
5683
- },
5684
- "node_modules/hyphenate-style-name": {
5685
- "version": "1.1.0",
5686
- "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
5687
- "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==",
5688
- "license": "BSD-3-Clause"
5689
- },
5690
- "node_modules/ieee754": {
5691
- "version": "1.2.1",
5692
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
5693
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
5694
- "funding": [
5695
- {
5696
- "type": "github",
5697
- "url": "https://github.com/sponsors/feross"
5698
- },
5699
- {
5700
- "type": "patreon",
5701
- "url": "https://www.patreon.com/feross"
5702
- },
5703
- {
5704
- "type": "consulting",
5705
- "url": "https://feross.org/support"
5706
- }
5707
- ],
5708
- "license": "BSD-3-Clause"
5709
- },
5710
- "node_modules/ignore": {
5711
- "version": "5.3.2",
5712
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
5713
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
5714
- "license": "MIT",
5715
- "engines": {
5716
- "node": ">= 4"
5717
- }
5718
- },
5719
- "node_modules/image-size": {
5720
- "version": "1.2.1",
5721
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
5722
- "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
5723
- "license": "MIT",
5724
- "dependencies": {
5725
- "queue": "6.0.2"
5726
- },
5727
- "bin": {
5728
- "image-size": "bin/image-size.js"
5729
- },
5730
- "engines": {
5731
- "node": ">=16.x"
5732
- }
5733
- },
5734
- "node_modules/imurmurhash": {
5735
- "version": "0.1.4",
5736
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
5737
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
5738
- "license": "MIT",
5739
- "engines": {
5740
- "node": ">=0.8.19"
5741
- }
5742
- },
5743
- "node_modules/inflight": {
5744
- "version": "1.0.6",
5745
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
5746
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
5747
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
5748
- "license": "ISC",
5749
- "dependencies": {
5750
- "once": "^1.3.0",
5751
- "wrappy": "1"
5752
- }
5753
- },
5754
- "node_modules/inherits": {
5755
- "version": "2.0.4",
5756
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
5757
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
5758
- "license": "ISC"
5759
- },
5760
- "node_modules/inline-style-prefixer": {
5761
- "version": "7.0.1",
5762
- "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz",
5763
- "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==",
5764
- "license": "MIT",
5765
- "dependencies": {
5766
- "css-in-js-utils": "^3.1.0"
5767
- }
5768
- },
5769
- "node_modules/invariant": {
5770
- "version": "2.2.4",
5771
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
5772
- "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
5773
- "license": "MIT",
5774
- "dependencies": {
5775
- "loose-envify": "^1.0.0"
5776
- }
5777
- },
5778
- "node_modules/is-arrayish": {
5779
- "version": "0.3.4",
5780
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
5781
- "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
5782
- "license": "MIT"
5783
- },
5784
- "node_modules/is-binary-path": {
5785
- "version": "2.1.0",
5786
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
5787
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
5788
- "dev": true,
5789
- "license": "MIT",
5790
- "dependencies": {
5791
- "binary-extensions": "^2.0.0"
5792
- },
5793
- "engines": {
5794
- "node": ">=8"
5795
- }
5796
- },
5797
- "node_modules/is-core-module": {
5798
- "version": "2.16.1",
5799
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
5800
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
5801
- "license": "MIT",
5802
- "dependencies": {
5803
- "hasown": "^2.0.2"
5804
- },
5805
- "engines": {
5806
- "node": ">= 0.4"
5807
- },
5808
- "funding": {
5809
- "url": "https://github.com/sponsors/ljharb"
5810
- }
5811
- },
5812
- "node_modules/is-docker": {
5813
- "version": "2.2.1",
5814
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
5815
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
5816
- "license": "MIT",
5817
- "bin": {
5818
- "is-docker": "cli.js"
5819
- },
5820
- "engines": {
5821
- "node": ">=8"
5822
- },
5823
- "funding": {
5824
- "url": "https://github.com/sponsors/sindresorhus"
5825
- }
5826
- },
5827
- "node_modules/is-extglob": {
5828
- "version": "2.1.1",
5829
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
5830
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
5831
- "dev": true,
5832
- "license": "MIT",
5833
- "engines": {
5834
- "node": ">=0.10.0"
5835
- }
5836
- },
5837
- "node_modules/is-fullwidth-code-point": {
5838
- "version": "3.0.0",
5839
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
5840
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
5841
- "license": "MIT",
5842
- "engines": {
5843
- "node": ">=8"
5844
- }
5845
- },
5846
- "node_modules/is-glob": {
5847
- "version": "4.0.3",
5848
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
5849
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
5850
- "dev": true,
5851
- "license": "MIT",
5852
- "dependencies": {
5853
- "is-extglob": "^2.1.1"
5854
- },
5855
- "engines": {
5856
- "node": ">=0.10.0"
5857
- }
5858
- },
5859
- "node_modules/is-number": {
5860
- "version": "7.0.0",
5861
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
5862
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
5863
- "license": "MIT",
5864
- "engines": {
5865
- "node": ">=0.12.0"
5866
- }
5867
- },
5868
- "node_modules/is-wsl": {
5869
- "version": "2.2.0",
5870
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
5871
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
5872
- "license": "MIT",
5873
- "dependencies": {
5874
- "is-docker": "^2.0.0"
5875
- },
5876
- "engines": {
5877
- "node": ">=8"
5878
- }
5879
- },
5880
- "node_modules/isexe": {
5881
- "version": "2.0.0",
5882
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
5883
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
5884
- "license": "ISC"
5885
- },
5886
- "node_modules/istanbul-lib-coverage": {
5887
- "version": "3.2.2",
5888
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
5889
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
5890
- "license": "BSD-3-Clause",
5891
- "engines": {
5892
- "node": ">=8"
5893
- }
5894
- },
5895
- "node_modules/istanbul-lib-instrument": {
5896
- "version": "5.2.1",
5897
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
5898
- "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
5899
- "license": "BSD-3-Clause",
5900
- "dependencies": {
5901
- "@babel/core": "^7.12.3",
5902
- "@babel/parser": "^7.14.7",
5903
- "@istanbuljs/schema": "^0.1.2",
5904
- "istanbul-lib-coverage": "^3.2.0",
5905
- "semver": "^6.3.0"
5906
- },
5907
- "engines": {
5908
- "node": ">=8"
5909
- }
5910
- },
5911
- "node_modules/istanbul-lib-instrument/node_modules/semver": {
5912
- "version": "6.3.1",
5913
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
5914
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
5915
- "license": "ISC",
5916
- "bin": {
5917
- "semver": "bin/semver.js"
5918
- }
5919
- },
5920
- "node_modules/jest-environment-node": {
5921
- "version": "29.7.0",
5922
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
5923
- "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
5924
- "license": "MIT",
5925
- "dependencies": {
5926
- "@jest/environment": "^29.7.0",
5927
- "@jest/fake-timers": "^29.7.0",
5928
- "@jest/types": "^29.6.3",
5929
- "@types/node": "*",
5930
- "jest-mock": "^29.7.0",
5931
- "jest-util": "^29.7.0"
5932
- },
5933
- "engines": {
5934
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
5935
- }
5936
- },
5937
- "node_modules/jest-get-type": {
5938
- "version": "29.6.3",
5939
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
5940
- "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
5941
- "license": "MIT",
5942
- "engines": {
5943
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
5944
- }
5945
- },
5946
- "node_modules/jest-haste-map": {
5947
- "version": "29.7.0",
5948
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
5949
- "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
5950
- "license": "MIT",
5951
- "dependencies": {
5952
- "@jest/types": "^29.6.3",
5953
- "@types/graceful-fs": "^4.1.3",
5954
- "@types/node": "*",
5955
- "anymatch": "^3.0.3",
5956
- "fb-watchman": "^2.0.0",
5957
- "graceful-fs": "^4.2.9",
5958
- "jest-regex-util": "^29.6.3",
5959
- "jest-util": "^29.7.0",
5960
- "jest-worker": "^29.7.0",
5961
- "micromatch": "^4.0.4",
5962
- "walker": "^1.0.8"
5963
- },
5964
- "engines": {
5965
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
5966
- },
5967
- "optionalDependencies": {
5968
- "fsevents": "^2.3.2"
5969
- }
5970
- },
5971
- "node_modules/jest-message-util": {
5972
- "version": "29.7.0",
5973
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
5974
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
5975
- "license": "MIT",
5976
- "dependencies": {
5977
- "@babel/code-frame": "^7.12.13",
5978
- "@jest/types": "^29.6.3",
5979
- "@types/stack-utils": "^2.0.0",
5980
- "chalk": "^4.0.0",
5981
- "graceful-fs": "^4.2.9",
5982
- "micromatch": "^4.0.4",
5983
- "pretty-format": "^29.7.0",
5984
- "slash": "^3.0.0",
5985
- "stack-utils": "^2.0.3"
5986
- },
5987
- "engines": {
5988
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
5989
- }
5990
- },
5991
- "node_modules/jest-mock": {
5992
- "version": "29.7.0",
5993
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
5994
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
5995
- "license": "MIT",
5996
- "dependencies": {
5997
- "@jest/types": "^29.6.3",
5998
- "@types/node": "*",
5999
- "jest-util": "^29.7.0"
6000
- },
6001
- "engines": {
6002
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
6003
- }
6004
- },
6005
- "node_modules/jest-regex-util": {
6006
- "version": "29.6.3",
6007
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
6008
- "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
6009
- "license": "MIT",
6010
- "engines": {
6011
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
6012
- }
6013
- },
6014
- "node_modules/jest-util": {
6015
- "version": "29.7.0",
6016
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
6017
- "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
6018
- "license": "MIT",
6019
- "dependencies": {
6020
- "@jest/types": "^29.6.3",
6021
- "@types/node": "*",
6022
- "chalk": "^4.0.0",
6023
- "ci-info": "^3.2.0",
6024
- "graceful-fs": "^4.2.9",
6025
- "picomatch": "^2.2.3"
6026
- },
6027
- "engines": {
6028
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
6029
- }
6030
- },
6031
- "node_modules/jest-util/node_modules/ci-info": {
6032
- "version": "3.9.0",
6033
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
6034
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
6035
- "funding": [
6036
- {
6037
- "type": "github",
6038
- "url": "https://github.com/sponsors/sibiraj-s"
6039
- }
6040
- ],
6041
- "license": "MIT",
6042
- "engines": {
6043
- "node": ">=8"
6044
- }
6045
- },
6046
- "node_modules/jest-validate": {
6047
- "version": "29.7.0",
6048
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
6049
- "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
6050
- "license": "MIT",
6051
- "dependencies": {
6052
- "@jest/types": "^29.6.3",
6053
- "camelcase": "^6.2.0",
6054
- "chalk": "^4.0.0",
6055
- "jest-get-type": "^29.6.3",
6056
- "leven": "^3.1.0",
6057
- "pretty-format": "^29.7.0"
6058
- },
6059
- "engines": {
6060
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
6061
- }
6062
- },
6063
- "node_modules/jest-worker": {
6064
- "version": "29.7.0",
6065
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
6066
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
6067
- "license": "MIT",
6068
- "dependencies": {
6069
- "@types/node": "*",
6070
- "jest-util": "^29.7.0",
6071
- "merge-stream": "^2.0.0",
6072
- "supports-color": "^8.0.0"
6073
- },
6074
- "engines": {
6075
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
6076
- }
6077
- },
6078
- "node_modules/jest-worker/node_modules/supports-color": {
6079
- "version": "8.1.1",
6080
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
6081
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
6082
- "license": "MIT",
6083
- "dependencies": {
6084
- "has-flag": "^4.0.0"
6085
- },
6086
- "engines": {
6087
- "node": ">=10"
6088
- },
6089
- "funding": {
6090
- "url": "https://github.com/chalk/supports-color?sponsor=1"
6091
- }
6092
- },
6093
- "node_modules/jimp-compact": {
6094
- "version": "0.16.1",
6095
- "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz",
6096
- "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==",
6097
- "license": "MIT"
6098
- },
6099
- "node_modules/jiti": {
6100
- "version": "1.21.7",
6101
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
6102
- "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
6103
- "dev": true,
6104
- "license": "MIT",
6105
- "bin": {
6106
- "jiti": "bin/jiti.js"
6107
- }
6108
- },
6109
- "node_modules/js-tokens": {
6110
- "version": "4.0.0",
6111
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
6112
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
6113
- "license": "MIT"
6114
- },
6115
- "node_modules/js-yaml": {
6116
- "version": "3.14.2",
6117
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
6118
- "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
6119
- "license": "MIT",
6120
- "dependencies": {
6121
- "argparse": "^1.0.7",
6122
- "esprima": "^4.0.0"
6123
- },
6124
- "bin": {
6125
- "js-yaml": "bin/js-yaml.js"
6126
- }
6127
- },
6128
- "node_modules/jsc-safe-url": {
6129
- "version": "0.2.4",
6130
- "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz",
6131
- "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==",
6132
- "license": "0BSD"
6133
- },
6134
- "node_modules/jsesc": {
6135
- "version": "3.1.0",
6136
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
6137
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
6138
- "license": "MIT",
6139
- "bin": {
6140
- "jsesc": "bin/jsesc"
6141
- },
6142
- "engines": {
6143
- "node": ">=6"
6144
- }
6145
- },
6146
- "node_modules/json5": {
6147
- "version": "2.2.3",
6148
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
6149
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
6150
- "license": "MIT",
6151
- "bin": {
6152
- "json5": "lib/cli.js"
6153
- },
6154
- "engines": {
6155
- "node": ">=6"
6156
- }
6157
- },
6158
- "node_modules/kleur": {
6159
- "version": "3.0.3",
6160
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
6161
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
6162
- "license": "MIT",
6163
- "engines": {
6164
- "node": ">=6"
6165
- }
6166
- },
6167
- "node_modules/lan-network": {
6168
- "version": "0.2.0",
6169
- "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.2.0.tgz",
6170
- "integrity": "sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw==",
6171
- "license": "MIT",
6172
- "bin": {
6173
- "lan-network": "dist/lan-network-cli.js"
6174
- }
6175
- },
6176
- "node_modules/leven": {
6177
- "version": "3.1.0",
6178
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
6179
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
6180
- "license": "MIT",
6181
- "engines": {
6182
- "node": ">=6"
6183
- }
6184
- },
6185
- "node_modules/lighthouse-logger": {
6186
- "version": "1.4.2",
6187
- "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
6188
- "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==",
6189
- "license": "Apache-2.0",
6190
- "dependencies": {
6191
- "debug": "^2.6.9",
6192
- "marky": "^1.2.2"
6193
- }
6194
- },
6195
- "node_modules/lighthouse-logger/node_modules/debug": {
6196
- "version": "2.6.9",
6197
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
6198
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
6199
- "license": "MIT",
6200
- "dependencies": {
6201
- "ms": "2.0.0"
6202
- }
6203
- },
6204
- "node_modules/lighthouse-logger/node_modules/ms": {
6205
- "version": "2.0.0",
6206
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
6207
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
6208
- "license": "MIT"
6209
- },
6210
- "node_modules/lightningcss": {
6211
- "version": "1.31.1",
6212
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz",
6213
- "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==",
6214
- "license": "MPL-2.0",
6215
- "dependencies": {
6216
- "detect-libc": "^2.0.3"
6217
- },
6218
- "engines": {
6219
- "node": ">= 12.0.0"
6220
- },
6221
- "funding": {
6222
- "type": "opencollective",
6223
- "url": "https://opencollective.com/parcel"
6224
- },
6225
- "optionalDependencies": {
6226
- "lightningcss-android-arm64": "1.31.1",
6227
- "lightningcss-darwin-arm64": "1.31.1",
6228
- "lightningcss-darwin-x64": "1.31.1",
6229
- "lightningcss-freebsd-x64": "1.31.1",
6230
- "lightningcss-linux-arm-gnueabihf": "1.31.1",
6231
- "lightningcss-linux-arm64-gnu": "1.31.1",
6232
- "lightningcss-linux-arm64-musl": "1.31.1",
6233
- "lightningcss-linux-x64-gnu": "1.31.1",
6234
- "lightningcss-linux-x64-musl": "1.31.1",
6235
- "lightningcss-win32-arm64-msvc": "1.31.1",
6236
- "lightningcss-win32-x64-msvc": "1.31.1"
6237
- }
6238
- },
6239
- "node_modules/lightningcss-android-arm64": {
6240
- "version": "1.31.1",
6241
- "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz",
6242
- "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==",
6243
- "cpu": [
6244
- "arm64"
6245
- ],
6246
- "license": "MPL-2.0",
6247
- "optional": true,
6248
- "os": [
6249
- "android"
6250
- ],
6251
- "engines": {
6252
- "node": ">= 12.0.0"
6253
- },
6254
- "funding": {
6255
- "type": "opencollective",
6256
- "url": "https://opencollective.com/parcel"
6257
- }
6258
- },
6259
- "node_modules/lightningcss-darwin-arm64": {
6260
- "version": "1.31.1",
6261
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz",
6262
- "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==",
6263
- "cpu": [
6264
- "arm64"
6265
- ],
6266
- "license": "MPL-2.0",
6267
- "optional": true,
6268
- "os": [
6269
- "darwin"
6270
- ],
6271
- "engines": {
6272
- "node": ">= 12.0.0"
6273
- },
6274
- "funding": {
6275
- "type": "opencollective",
6276
- "url": "https://opencollective.com/parcel"
6277
- }
6278
- },
6279
- "node_modules/lightningcss-darwin-x64": {
6280
- "version": "1.31.1",
6281
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz",
6282
- "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==",
6283
- "cpu": [
6284
- "x64"
6285
- ],
6286
- "license": "MPL-2.0",
6287
- "optional": true,
6288
- "os": [
6289
- "darwin"
6290
- ],
6291
- "engines": {
6292
- "node": ">= 12.0.0"
6293
- },
6294
- "funding": {
6295
- "type": "opencollective",
6296
- "url": "https://opencollective.com/parcel"
6297
- }
6298
- },
6299
- "node_modules/lightningcss-freebsd-x64": {
6300
- "version": "1.31.1",
6301
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz",
6302
- "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==",
6303
- "cpu": [
6304
- "x64"
6305
- ],
6306
- "license": "MPL-2.0",
6307
- "optional": true,
6308
- "os": [
6309
- "freebsd"
6310
- ],
6311
- "engines": {
6312
- "node": ">= 12.0.0"
6313
- },
6314
- "funding": {
6315
- "type": "opencollective",
6316
- "url": "https://opencollective.com/parcel"
6317
- }
6318
- },
6319
- "node_modules/lightningcss-linux-arm-gnueabihf": {
6320
- "version": "1.31.1",
6321
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz",
6322
- "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==",
6323
- "cpu": [
6324
- "arm"
6325
- ],
6326
- "license": "MPL-2.0",
6327
- "optional": true,
6328
- "os": [
6329
- "linux"
6330
- ],
6331
- "engines": {
6332
- "node": ">= 12.0.0"
6333
- },
6334
- "funding": {
6335
- "type": "opencollective",
6336
- "url": "https://opencollective.com/parcel"
6337
- }
6338
- },
6339
- "node_modules/lightningcss-linux-arm64-gnu": {
6340
- "version": "1.31.1",
6341
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz",
6342
- "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==",
6343
- "cpu": [
6344
- "arm64"
6345
- ],
6346
- "license": "MPL-2.0",
6347
- "optional": true,
6348
- "os": [
6349
- "linux"
6350
- ],
6351
- "engines": {
6352
- "node": ">= 12.0.0"
6353
- },
6354
- "funding": {
6355
- "type": "opencollective",
6356
- "url": "https://opencollective.com/parcel"
6357
- }
6358
- },
6359
- "node_modules/lightningcss-linux-arm64-musl": {
6360
- "version": "1.31.1",
6361
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz",
6362
- "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==",
6363
- "cpu": [
6364
- "arm64"
6365
- ],
6366
- "license": "MPL-2.0",
6367
- "optional": true,
6368
- "os": [
6369
- "linux"
6370
- ],
6371
- "engines": {
6372
- "node": ">= 12.0.0"
6373
- },
6374
- "funding": {
6375
- "type": "opencollective",
6376
- "url": "https://opencollective.com/parcel"
6377
- }
6378
- },
6379
- "node_modules/lightningcss-linux-x64-gnu": {
6380
- "version": "1.31.1",
6381
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz",
6382
- "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==",
6383
- "cpu": [
6384
- "x64"
6385
- ],
6386
- "license": "MPL-2.0",
6387
- "optional": true,
6388
- "os": [
6389
- "linux"
6390
- ],
6391
- "engines": {
6392
- "node": ">= 12.0.0"
6393
- },
6394
- "funding": {
6395
- "type": "opencollective",
6396
- "url": "https://opencollective.com/parcel"
6397
- }
6398
- },
6399
- "node_modules/lightningcss-linux-x64-musl": {
6400
- "version": "1.31.1",
6401
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz",
6402
- "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==",
6403
- "cpu": [
6404
- "x64"
6405
- ],
6406
- "license": "MPL-2.0",
6407
- "optional": true,
6408
- "os": [
6409
- "linux"
6410
- ],
6411
- "engines": {
6412
- "node": ">= 12.0.0"
6413
- },
6414
- "funding": {
6415
- "type": "opencollective",
6416
- "url": "https://opencollective.com/parcel"
6417
- }
6418
- },
6419
- "node_modules/lightningcss-win32-arm64-msvc": {
6420
- "version": "1.31.1",
6421
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz",
6422
- "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==",
6423
- "cpu": [
6424
- "arm64"
6425
- ],
6426
- "license": "MPL-2.0",
6427
- "optional": true,
6428
- "os": [
6429
- "win32"
6430
- ],
6431
- "engines": {
6432
- "node": ">= 12.0.0"
6433
- },
6434
- "funding": {
6435
- "type": "opencollective",
6436
- "url": "https://opencollective.com/parcel"
6437
- }
6438
- },
6439
- "node_modules/lightningcss-win32-x64-msvc": {
6440
- "version": "1.31.1",
6441
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz",
6442
- "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==",
6443
- "cpu": [
6444
- "x64"
6445
- ],
6446
- "license": "MPL-2.0",
6447
- "optional": true,
6448
- "os": [
6449
- "win32"
6450
- ],
6451
- "engines": {
6452
- "node": ">= 12.0.0"
6453
- },
6454
- "funding": {
6455
- "type": "opencollective",
6456
- "url": "https://opencollective.com/parcel"
6457
- }
6458
- },
6459
- "node_modules/lilconfig": {
6460
- "version": "3.1.3",
6461
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
6462
- "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
6463
- "dev": true,
6464
- "license": "MIT",
6465
- "engines": {
6466
- "node": ">=14"
6467
- },
6468
- "funding": {
6469
- "url": "https://github.com/sponsors/antonk52"
6470
- }
6471
- },
6472
- "node_modules/lines-and-columns": {
6473
- "version": "1.2.4",
6474
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
6475
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
6476
- "dev": true,
6477
- "license": "MIT"
6478
- },
6479
- "node_modules/locate-path": {
6480
- "version": "5.0.0",
6481
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
6482
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
6483
- "license": "MIT",
6484
- "dependencies": {
6485
- "p-locate": "^4.1.0"
6486
- },
6487
- "engines": {
6488
- "node": ">=8"
6489
- }
6490
- },
6491
- "node_modules/lodash.debounce": {
6492
- "version": "4.0.8",
6493
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
6494
- "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
6495
- "license": "MIT"
6496
- },
6497
- "node_modules/lodash.throttle": {
6498
- "version": "4.1.1",
6499
- "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
6500
- "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
6501
- "license": "MIT"
6502
- },
6503
- "node_modules/log-symbols": {
6504
- "version": "2.2.0",
6505
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
6506
- "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
6507
- "license": "MIT",
6508
- "dependencies": {
6509
- "chalk": "^2.0.1"
6510
- },
6511
- "engines": {
6512
- "node": ">=4"
6513
- }
6514
- },
6515
- "node_modules/log-symbols/node_modules/ansi-styles": {
6516
- "version": "3.2.1",
6517
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
6518
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
6519
- "license": "MIT",
6520
- "dependencies": {
6521
- "color-convert": "^1.9.0"
6522
- },
6523
- "engines": {
6524
- "node": ">=4"
6525
- }
6526
- },
6527
- "node_modules/log-symbols/node_modules/chalk": {
6528
- "version": "2.4.2",
6529
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
6530
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
6531
- "license": "MIT",
6532
- "dependencies": {
6533
- "ansi-styles": "^3.2.1",
6534
- "escape-string-regexp": "^1.0.5",
6535
- "supports-color": "^5.3.0"
6536
- },
6537
- "engines": {
6538
- "node": ">=4"
6539
- }
6540
- },
6541
- "node_modules/log-symbols/node_modules/color-convert": {
6542
- "version": "1.9.3",
6543
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
6544
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
6545
- "license": "MIT",
6546
- "dependencies": {
6547
- "color-name": "1.1.3"
6548
- }
6549
- },
6550
- "node_modules/log-symbols/node_modules/color-name": {
6551
- "version": "1.1.3",
6552
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
6553
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
6554
- "license": "MIT"
6555
- },
6556
- "node_modules/log-symbols/node_modules/escape-string-regexp": {
6557
- "version": "1.0.5",
6558
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
6559
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
6560
- "license": "MIT",
6561
- "engines": {
6562
- "node": ">=0.8.0"
6563
- }
6564
- },
6565
- "node_modules/log-symbols/node_modules/has-flag": {
6566
- "version": "3.0.0",
6567
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
6568
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
6569
- "license": "MIT",
6570
- "engines": {
6571
- "node": ">=4"
6572
- }
6573
- },
6574
- "node_modules/log-symbols/node_modules/supports-color": {
6575
- "version": "5.5.0",
6576
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
6577
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
6578
- "license": "MIT",
6579
- "dependencies": {
6580
- "has-flag": "^3.0.0"
6581
- },
6582
- "engines": {
6583
- "node": ">=4"
6584
- }
6585
- },
6586
- "node_modules/loose-envify": {
6587
- "version": "1.4.0",
6588
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
6589
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
6590
- "license": "MIT",
6591
- "dependencies": {
6592
- "js-tokens": "^3.0.0 || ^4.0.0"
6593
- },
6594
- "bin": {
6595
- "loose-envify": "cli.js"
6596
- }
6597
- },
6598
- "node_modules/lru-cache": {
6599
- "version": "5.1.1",
6600
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
6601
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
6602
- "license": "ISC",
6603
- "dependencies": {
6604
- "yallist": "^3.0.2"
6605
- }
6606
- },
6607
- "node_modules/makeerror": {
6608
- "version": "1.0.12",
6609
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
6610
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
6611
- "license": "BSD-3-Clause",
6612
- "dependencies": {
6613
- "tmpl": "1.0.5"
6614
- }
6615
- },
6616
- "node_modules/marky": {
6617
- "version": "1.3.0",
6618
- "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz",
6619
- "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==",
6620
- "license": "Apache-2.0"
6621
- },
6622
- "node_modules/mdn-data": {
6623
- "version": "2.0.14",
6624
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
6625
- "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
6626
- "license": "CC0-1.0"
6627
- },
6628
- "node_modules/memoize-one": {
6629
- "version": "5.2.1",
6630
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
6631
- "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
6632
- "license": "MIT"
6633
- },
6634
- "node_modules/merge-stream": {
6635
- "version": "2.0.0",
6636
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
6637
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
6638
- "license": "MIT"
6639
- },
6640
- "node_modules/merge2": {
6641
- "version": "1.4.1",
6642
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
6643
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
6644
- "dev": true,
6645
- "license": "MIT",
6646
- "engines": {
6647
- "node": ">= 8"
6648
- }
6649
- },
6650
- "node_modules/metro": {
6651
- "version": "0.83.3",
6652
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.3.tgz",
6653
- "integrity": "sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q==",
6654
- "license": "MIT",
6655
- "dependencies": {
6656
- "@babel/code-frame": "^7.24.7",
6657
- "@babel/core": "^7.25.2",
6658
- "@babel/generator": "^7.25.0",
6659
- "@babel/parser": "^7.25.3",
6660
- "@babel/template": "^7.25.0",
6661
- "@babel/traverse": "^7.25.3",
6662
- "@babel/types": "^7.25.2",
6663
- "accepts": "^1.3.7",
6664
- "chalk": "^4.0.0",
6665
- "ci-info": "^2.0.0",
6666
- "connect": "^3.6.5",
6667
- "debug": "^4.4.0",
6668
- "error-stack-parser": "^2.0.6",
6669
- "flow-enums-runtime": "^0.0.6",
6670
- "graceful-fs": "^4.2.4",
6671
- "hermes-parser": "0.32.0",
6672
- "image-size": "^1.0.2",
6673
- "invariant": "^2.2.4",
6674
- "jest-worker": "^29.7.0",
6675
- "jsc-safe-url": "^0.2.2",
6676
- "lodash.throttle": "^4.1.1",
6677
- "metro-babel-transformer": "0.83.3",
6678
- "metro-cache": "0.83.3",
6679
- "metro-cache-key": "0.83.3",
6680
- "metro-config": "0.83.3",
6681
- "metro-core": "0.83.3",
6682
- "metro-file-map": "0.83.3",
6683
- "metro-resolver": "0.83.3",
6684
- "metro-runtime": "0.83.3",
6685
- "metro-source-map": "0.83.3",
6686
- "metro-symbolicate": "0.83.3",
6687
- "metro-transform-plugins": "0.83.3",
6688
- "metro-transform-worker": "0.83.3",
6689
- "mime-types": "^2.1.27",
6690
- "nullthrows": "^1.1.1",
6691
- "serialize-error": "^2.1.0",
6692
- "source-map": "^0.5.6",
6693
- "throat": "^5.0.0",
6694
- "ws": "^7.5.10",
6695
- "yargs": "^17.6.2"
6696
- },
6697
- "bin": {
6698
- "metro": "src/cli.js"
6699
- },
6700
- "engines": {
6701
- "node": ">=20.19.4"
6702
- }
6703
- },
6704
- "node_modules/metro-babel-transformer": {
6705
- "version": "0.83.3",
6706
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.3.tgz",
6707
- "integrity": "sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g==",
6708
- "license": "MIT",
6709
- "dependencies": {
6710
- "@babel/core": "^7.25.2",
6711
- "flow-enums-runtime": "^0.0.6",
6712
- "hermes-parser": "0.32.0",
6713
- "nullthrows": "^1.1.1"
6714
- },
6715
- "engines": {
6716
- "node": ">=20.19.4"
6717
- }
6718
- },
6719
- "node_modules/metro-cache": {
6720
- "version": "0.83.3",
6721
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.3.tgz",
6722
- "integrity": "sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q==",
6723
- "license": "MIT",
6724
- "dependencies": {
6725
- "exponential-backoff": "^3.1.1",
6726
- "flow-enums-runtime": "^0.0.6",
6727
- "https-proxy-agent": "^7.0.5",
6728
- "metro-core": "0.83.3"
6729
- },
6730
- "engines": {
6731
- "node": ">=20.19.4"
6732
- }
6733
- },
6734
- "node_modules/metro-cache-key": {
6735
- "version": "0.83.3",
6736
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.3.tgz",
6737
- "integrity": "sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw==",
6738
- "license": "MIT",
6739
- "dependencies": {
6740
- "flow-enums-runtime": "^0.0.6"
6741
- },
6742
- "engines": {
6743
- "node": ">=20.19.4"
6744
- }
6745
- },
6746
- "node_modules/metro-config": {
6747
- "version": "0.83.3",
6748
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.3.tgz",
6749
- "integrity": "sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA==",
6750
- "license": "MIT",
6751
- "dependencies": {
6752
- "connect": "^3.6.5",
6753
- "flow-enums-runtime": "^0.0.6",
6754
- "jest-validate": "^29.7.0",
6755
- "metro": "0.83.3",
6756
- "metro-cache": "0.83.3",
6757
- "metro-core": "0.83.3",
6758
- "metro-runtime": "0.83.3",
6759
- "yaml": "^2.6.1"
6760
- },
6761
- "engines": {
6762
- "node": ">=20.19.4"
6763
- }
6764
- },
6765
- "node_modules/metro-core": {
6766
- "version": "0.83.3",
6767
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.3.tgz",
6768
- "integrity": "sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw==",
6769
- "license": "MIT",
6770
- "dependencies": {
6771
- "flow-enums-runtime": "^0.0.6",
6772
- "lodash.throttle": "^4.1.1",
6773
- "metro-resolver": "0.83.3"
6774
- },
6775
- "engines": {
6776
- "node": ">=20.19.4"
6777
- }
6778
- },
6779
- "node_modules/metro-file-map": {
6780
- "version": "0.83.3",
6781
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.3.tgz",
6782
- "integrity": "sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA==",
6783
- "license": "MIT",
6784
- "dependencies": {
6785
- "debug": "^4.4.0",
6786
- "fb-watchman": "^2.0.0",
6787
- "flow-enums-runtime": "^0.0.6",
6788
- "graceful-fs": "^4.2.4",
6789
- "invariant": "^2.2.4",
6790
- "jest-worker": "^29.7.0",
6791
- "micromatch": "^4.0.4",
6792
- "nullthrows": "^1.1.1",
6793
- "walker": "^1.0.7"
6794
- },
6795
- "engines": {
6796
- "node": ">=20.19.4"
6797
- }
6798
- },
6799
- "node_modules/metro-minify-terser": {
6800
- "version": "0.83.3",
6801
- "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.3.tgz",
6802
- "integrity": "sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ==",
6803
- "license": "MIT",
6804
- "dependencies": {
6805
- "flow-enums-runtime": "^0.0.6",
6806
- "terser": "^5.15.0"
6807
- },
6808
- "engines": {
6809
- "node": ">=20.19.4"
6810
- }
6811
- },
6812
- "node_modules/metro-resolver": {
6813
- "version": "0.83.3",
6814
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.3.tgz",
6815
- "integrity": "sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ==",
6816
- "license": "MIT",
6817
- "dependencies": {
6818
- "flow-enums-runtime": "^0.0.6"
6819
- },
6820
- "engines": {
6821
- "node": ">=20.19.4"
6822
- }
6823
- },
6824
- "node_modules/metro-runtime": {
6825
- "version": "0.83.3",
6826
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.3.tgz",
6827
- "integrity": "sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw==",
6828
- "license": "MIT",
6829
- "dependencies": {
6830
- "@babel/runtime": "^7.25.0",
6831
- "flow-enums-runtime": "^0.0.6"
6832
- },
6833
- "engines": {
6834
- "node": ">=20.19.4"
6835
- }
6836
- },
6837
- "node_modules/metro-source-map": {
6838
- "version": "0.83.3",
6839
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.3.tgz",
6840
- "integrity": "sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg==",
6841
- "license": "MIT",
6842
- "dependencies": {
6843
- "@babel/traverse": "^7.25.3",
6844
- "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3",
6845
- "@babel/types": "^7.25.2",
6846
- "flow-enums-runtime": "^0.0.6",
6847
- "invariant": "^2.2.4",
6848
- "metro-symbolicate": "0.83.3",
6849
- "nullthrows": "^1.1.1",
6850
- "ob1": "0.83.3",
6851
- "source-map": "^0.5.6",
6852
- "vlq": "^1.0.0"
6853
- },
6854
- "engines": {
6855
- "node": ">=20.19.4"
6856
- }
6857
- },
6858
- "node_modules/metro-symbolicate": {
6859
- "version": "0.83.3",
6860
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.3.tgz",
6861
- "integrity": "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw==",
6862
- "license": "MIT",
6863
- "dependencies": {
6864
- "flow-enums-runtime": "^0.0.6",
6865
- "invariant": "^2.2.4",
6866
- "metro-source-map": "0.83.3",
6867
- "nullthrows": "^1.1.1",
6868
- "source-map": "^0.5.6",
6869
- "vlq": "^1.0.0"
6870
- },
6871
- "bin": {
6872
- "metro-symbolicate": "src/index.js"
6873
- },
6874
- "engines": {
6875
- "node": ">=20.19.4"
6876
- }
6877
- },
6878
- "node_modules/metro-transform-plugins": {
6879
- "version": "0.83.3",
6880
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.3.tgz",
6881
- "integrity": "sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A==",
6882
- "license": "MIT",
6883
- "dependencies": {
6884
- "@babel/core": "^7.25.2",
6885
- "@babel/generator": "^7.25.0",
6886
- "@babel/template": "^7.25.0",
6887
- "@babel/traverse": "^7.25.3",
6888
- "flow-enums-runtime": "^0.0.6",
6889
- "nullthrows": "^1.1.1"
6890
- },
6891
- "engines": {
6892
- "node": ">=20.19.4"
6893
- }
6894
- },
6895
- "node_modules/metro-transform-worker": {
6896
- "version": "0.83.3",
6897
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.3.tgz",
6898
- "integrity": "sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA==",
6899
- "license": "MIT",
6900
- "dependencies": {
6901
- "@babel/core": "^7.25.2",
6902
- "@babel/generator": "^7.25.0",
6903
- "@babel/parser": "^7.25.3",
6904
- "@babel/types": "^7.25.2",
6905
- "flow-enums-runtime": "^0.0.6",
6906
- "metro": "0.83.3",
6907
- "metro-babel-transformer": "0.83.3",
6908
- "metro-cache": "0.83.3",
6909
- "metro-cache-key": "0.83.3",
6910
- "metro-minify-terser": "0.83.3",
6911
- "metro-source-map": "0.83.3",
6912
- "metro-transform-plugins": "0.83.3",
6913
- "nullthrows": "^1.1.1"
6914
- },
6915
- "engines": {
6916
- "node": ">=20.19.4"
6917
- }
6918
- },
6919
- "node_modules/micromatch": {
6920
- "version": "4.0.8",
6921
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
6922
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
6923
- "license": "MIT",
6924
- "dependencies": {
6925
- "braces": "^3.0.3",
6926
- "picomatch": "^2.3.1"
6927
- },
6928
- "engines": {
6929
- "node": ">=8.6"
6930
- }
6931
- },
6932
- "node_modules/mime": {
6933
- "version": "1.6.0",
6934
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
6935
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
6936
- "license": "MIT",
6937
- "bin": {
6938
- "mime": "cli.js"
6939
- },
6940
- "engines": {
6941
- "node": ">=4"
6942
- }
6943
- },
6944
- "node_modules/mime-db": {
6945
- "version": "1.52.0",
6946
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
6947
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
6948
- "license": "MIT",
6949
- "engines": {
6950
- "node": ">= 0.6"
6951
- }
6952
- },
6953
- "node_modules/mime-types": {
6954
- "version": "2.1.35",
6955
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
6956
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
6957
- "license": "MIT",
6958
- "dependencies": {
6959
- "mime-db": "1.52.0"
6960
- },
6961
- "engines": {
6962
- "node": ">= 0.6"
6963
- }
6964
- },
6965
- "node_modules/mimic-fn": {
6966
- "version": "1.2.0",
6967
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
6968
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
6969
- "license": "MIT",
6970
- "engines": {
6971
- "node": ">=4"
6972
- }
6973
- },
6974
- "node_modules/minimatch": {
6975
- "version": "10.2.4",
6976
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
6977
- "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
6978
- "license": "BlueOak-1.0.0",
6979
- "dependencies": {
6980
- "brace-expansion": "^5.0.2"
6981
- },
6982
- "engines": {
6983
- "node": "18 || 20 || >=22"
6984
- },
6985
- "funding": {
6986
- "url": "https://github.com/sponsors/isaacs"
6987
- }
6988
- },
6989
- "node_modules/minipass": {
6990
- "version": "7.1.3",
6991
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
6992
- "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
6993
- "license": "BlueOak-1.0.0",
6994
- "engines": {
6995
- "node": ">=16 || 14 >=14.17"
6996
- }
6997
- },
6998
- "node_modules/mkdirp": {
6999
- "version": "1.0.4",
7000
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
7001
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
7002
- "license": "MIT",
7003
- "bin": {
7004
- "mkdirp": "bin/cmd.js"
7005
- },
7006
- "engines": {
7007
- "node": ">=10"
7008
- }
7009
- },
7010
- "node_modules/ms": {
7011
- "version": "2.1.3",
7012
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
7013
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
7014
- "license": "MIT"
7015
- },
7016
- "node_modules/multitars": {
7017
- "version": "0.2.4",
7018
- "resolved": "https://registry.npmjs.org/multitars/-/multitars-0.2.4.tgz",
7019
- "integrity": "sha512-XgLbg1HHchFauMCQPRwMj6MSyDd5koPlTA1hM3rUFkeXzGpjU/I9fP3to7yrObE9jcN8ChIOQGrM0tV0kUZaKg==",
7020
- "license": "MIT"
7021
- },
7022
- "node_modules/mz": {
7023
- "version": "2.7.0",
7024
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
7025
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
7026
- "dev": true,
7027
- "license": "MIT",
7028
- "dependencies": {
7029
- "any-promise": "^1.0.0",
7030
- "object-assign": "^4.0.1",
7031
- "thenify-all": "^1.0.0"
7032
- }
7033
- },
7034
- "node_modules/nanoid": {
7035
- "version": "3.3.11",
7036
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
7037
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
7038
- "funding": [
7039
- {
7040
- "type": "github",
7041
- "url": "https://github.com/sponsors/ai"
7042
- }
7043
- ],
7044
- "license": "MIT",
7045
- "bin": {
7046
- "nanoid": "bin/nanoid.cjs"
7047
- },
7048
- "engines": {
7049
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
7050
- }
7051
- },
7052
- "node_modules/nativewind": {
7053
- "version": "4.2.2",
7054
- "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.2.tgz",
7055
- "integrity": "sha512-kUGbUamKUWdnAIjfBuhIrtDHFtMyL1pEE3AEbCuKeg656pHuB0KtJRk6Lrie/+8haj8hCSlwOleQFJLrE1sZgA==",
7056
- "license": "MIT",
7057
- "dependencies": {
7058
- "comment-json": "^4.2.5",
7059
- "debug": "^4.3.7",
7060
- "react-native-css-interop": "0.2.2"
7061
- },
7062
- "engines": {
7063
- "node": ">=16"
7064
- },
7065
- "peerDependencies": {
7066
- "tailwindcss": ">3.3.0"
7067
- }
7068
- },
7069
- "node_modules/negotiator": {
7070
- "version": "0.6.3",
7071
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
7072
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
7073
- "license": "MIT",
7074
- "engines": {
7075
- "node": ">= 0.6"
7076
- }
7077
- },
7078
- "node_modules/node-fetch": {
7079
- "version": "2.7.0",
7080
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
7081
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
7082
- "license": "MIT",
7083
- "dependencies": {
7084
- "whatwg-url": "^5.0.0"
7085
- },
7086
- "engines": {
7087
- "node": "4.x || >=6.0.0"
7088
- },
7089
- "peerDependencies": {
7090
- "encoding": "^0.1.0"
7091
- },
7092
- "peerDependenciesMeta": {
7093
- "encoding": {
7094
- "optional": true
7095
- }
7096
- }
7097
- },
7098
- "node_modules/node-forge": {
7099
- "version": "1.3.3",
7100
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz",
7101
- "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==",
7102
- "license": "(BSD-3-Clause OR GPL-2.0)",
7103
- "engines": {
7104
- "node": ">= 6.13.0"
7105
- }
7106
- },
7107
- "node_modules/node-int64": {
7108
- "version": "0.4.0",
7109
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
7110
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
7111
- "license": "MIT"
7112
- },
7113
- "node_modules/node-releases": {
7114
- "version": "2.0.27",
7115
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
7116
- "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
7117
- "license": "MIT"
7118
- },
7119
- "node_modules/normalize-path": {
7120
- "version": "3.0.0",
7121
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
7122
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
7123
- "license": "MIT",
7124
- "engines": {
7125
- "node": ">=0.10.0"
7126
- }
7127
- },
7128
- "node_modules/npm-package-arg": {
7129
- "version": "11.0.3",
7130
- "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz",
7131
- "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==",
7132
- "license": "ISC",
7133
- "dependencies": {
7134
- "hosted-git-info": "^7.0.0",
7135
- "proc-log": "^4.0.0",
7136
- "semver": "^7.3.5",
7137
- "validate-npm-package-name": "^5.0.0"
7138
- },
7139
- "engines": {
7140
- "node": "^16.14.0 || >=18.0.0"
7141
- }
7142
- },
7143
- "node_modules/nth-check": {
7144
- "version": "2.1.1",
7145
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
7146
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
7147
- "license": "BSD-2-Clause",
7148
- "dependencies": {
7149
- "boolbase": "^1.0.0"
7150
- },
7151
- "funding": {
7152
- "url": "https://github.com/fb55/nth-check?sponsor=1"
7153
- }
7154
- },
7155
- "node_modules/nullthrows": {
7156
- "version": "1.1.1",
7157
- "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
7158
- "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==",
7159
- "license": "MIT"
7160
- },
7161
- "node_modules/ob1": {
7162
- "version": "0.83.3",
7163
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.3.tgz",
7164
- "integrity": "sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA==",
7165
- "license": "MIT",
7166
- "dependencies": {
7167
- "flow-enums-runtime": "^0.0.6"
7168
- },
7169
- "engines": {
7170
- "node": ">=20.19.4"
7171
- }
7172
- },
7173
- "node_modules/object-assign": {
7174
- "version": "4.1.1",
7175
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
7176
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
7177
- "license": "MIT",
7178
- "engines": {
7179
- "node": ">=0.10.0"
7180
- }
7181
- },
7182
- "node_modules/object-hash": {
7183
- "version": "3.0.0",
7184
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
7185
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
7186
- "dev": true,
7187
- "license": "MIT",
7188
- "engines": {
7189
- "node": ">= 6"
7190
- }
7191
- },
7192
- "node_modules/on-finished": {
7193
- "version": "2.3.0",
7194
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
7195
- "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
7196
- "license": "MIT",
7197
- "dependencies": {
7198
- "ee-first": "1.1.1"
7199
- },
7200
- "engines": {
7201
- "node": ">= 0.8"
7202
- }
7203
- },
7204
- "node_modules/on-headers": {
7205
- "version": "1.1.0",
7206
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
7207
- "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
7208
- "license": "MIT",
7209
- "engines": {
7210
- "node": ">= 0.8"
7211
- }
7212
- },
7213
- "node_modules/once": {
7214
- "version": "1.4.0",
7215
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
7216
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
7217
- "license": "ISC",
7218
- "dependencies": {
7219
- "wrappy": "1"
7220
- }
7221
- },
7222
- "node_modules/onetime": {
7223
- "version": "2.0.1",
7224
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
7225
- "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
7226
- "license": "MIT",
7227
- "dependencies": {
7228
- "mimic-fn": "^1.0.0"
7229
- },
7230
- "engines": {
7231
- "node": ">=4"
7232
- }
7233
- },
7234
- "node_modules/open": {
7235
- "version": "7.4.2",
7236
- "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
7237
- "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
7238
- "license": "MIT",
7239
- "dependencies": {
7240
- "is-docker": "^2.0.0",
7241
- "is-wsl": "^2.1.1"
7242
- },
7243
- "engines": {
7244
- "node": ">=8"
7245
- },
7246
- "funding": {
7247
- "url": "https://github.com/sponsors/sindresorhus"
7248
- }
7249
- },
7250
- "node_modules/ora": {
7251
- "version": "3.4.0",
7252
- "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
7253
- "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
7254
- "license": "MIT",
7255
- "dependencies": {
7256
- "chalk": "^2.4.2",
7257
- "cli-cursor": "^2.1.0",
7258
- "cli-spinners": "^2.0.0",
7259
- "log-symbols": "^2.2.0",
7260
- "strip-ansi": "^5.2.0",
7261
- "wcwidth": "^1.0.1"
7262
- },
7263
- "engines": {
7264
- "node": ">=6"
7265
- }
7266
- },
7267
- "node_modules/ora/node_modules/ansi-regex": {
7268
- "version": "4.1.1",
7269
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
7270
- "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
7271
- "license": "MIT",
7272
- "engines": {
7273
- "node": ">=6"
7274
- }
7275
- },
7276
- "node_modules/ora/node_modules/ansi-styles": {
7277
- "version": "3.2.1",
7278
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
7279
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
7280
- "license": "MIT",
7281
- "dependencies": {
7282
- "color-convert": "^1.9.0"
7283
- },
7284
- "engines": {
7285
- "node": ">=4"
7286
- }
7287
- },
7288
- "node_modules/ora/node_modules/chalk": {
7289
- "version": "2.4.2",
7290
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
7291
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
7292
- "license": "MIT",
7293
- "dependencies": {
7294
- "ansi-styles": "^3.2.1",
7295
- "escape-string-regexp": "^1.0.5",
7296
- "supports-color": "^5.3.0"
7297
- },
7298
- "engines": {
7299
- "node": ">=4"
7300
- }
7301
- },
7302
- "node_modules/ora/node_modules/color-convert": {
7303
- "version": "1.9.3",
7304
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
7305
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
7306
- "license": "MIT",
7307
- "dependencies": {
7308
- "color-name": "1.1.3"
7309
- }
7310
- },
7311
- "node_modules/ora/node_modules/color-name": {
7312
- "version": "1.1.3",
7313
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
7314
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
7315
- "license": "MIT"
7316
- },
7317
- "node_modules/ora/node_modules/escape-string-regexp": {
7318
- "version": "1.0.5",
7319
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
7320
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
7321
- "license": "MIT",
7322
- "engines": {
7323
- "node": ">=0.8.0"
7324
- }
7325
- },
7326
- "node_modules/ora/node_modules/has-flag": {
7327
- "version": "3.0.0",
7328
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
7329
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
7330
- "license": "MIT",
7331
- "engines": {
7332
- "node": ">=4"
7333
- }
7334
- },
7335
- "node_modules/ora/node_modules/strip-ansi": {
7336
- "version": "5.2.0",
7337
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
7338
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
7339
- "license": "MIT",
7340
- "dependencies": {
7341
- "ansi-regex": "^4.1.0"
7342
- },
7343
- "engines": {
7344
- "node": ">=6"
7345
- }
7346
- },
7347
- "node_modules/ora/node_modules/supports-color": {
7348
- "version": "5.5.0",
7349
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
7350
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
7351
- "license": "MIT",
7352
- "dependencies": {
7353
- "has-flag": "^3.0.0"
7354
- },
7355
- "engines": {
7356
- "node": ">=4"
7357
- }
7358
- },
7359
- "node_modules/p-limit": {
7360
- "version": "2.3.0",
7361
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
7362
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
7363
- "license": "MIT",
7364
- "dependencies": {
7365
- "p-try": "^2.0.0"
7366
- },
7367
- "engines": {
7368
- "node": ">=6"
7369
- },
7370
- "funding": {
7371
- "url": "https://github.com/sponsors/sindresorhus"
7372
- }
7373
- },
7374
- "node_modules/p-locate": {
7375
- "version": "4.1.0",
7376
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
7377
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
7378
- "license": "MIT",
7379
- "dependencies": {
7380
- "p-limit": "^2.2.0"
7381
- },
7382
- "engines": {
7383
- "node": ">=8"
7384
- }
7385
- },
7386
- "node_modules/p-try": {
7387
- "version": "2.2.0",
7388
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
7389
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
7390
- "license": "MIT",
7391
- "engines": {
7392
- "node": ">=6"
7393
- }
7394
- },
7395
- "node_modules/parse-png": {
7396
- "version": "2.1.0",
7397
- "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz",
7398
- "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==",
7399
- "license": "MIT",
7400
- "dependencies": {
7401
- "pngjs": "^3.3.0"
7402
- },
7403
- "engines": {
7404
- "node": ">=10"
7405
- }
7406
- },
7407
- "node_modules/parseurl": {
7408
- "version": "1.3.3",
7409
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
7410
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
7411
- "license": "MIT",
7412
- "engines": {
7413
- "node": ">= 0.8"
7414
- }
7415
- },
7416
- "node_modules/path-exists": {
7417
- "version": "4.0.0",
7418
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
7419
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
7420
- "license": "MIT",
7421
- "engines": {
7422
- "node": ">=8"
7423
- }
7424
- },
7425
- "node_modules/path-is-absolute": {
7426
- "version": "1.0.1",
7427
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
7428
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
7429
- "license": "MIT",
7430
- "engines": {
7431
- "node": ">=0.10.0"
7432
- }
7433
- },
7434
- "node_modules/path-key": {
7435
- "version": "3.1.1",
7436
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
7437
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
7438
- "license": "MIT",
7439
- "engines": {
7440
- "node": ">=8"
7441
- }
7442
- },
7443
- "node_modules/path-parse": {
7444
- "version": "1.0.7",
7445
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
7446
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
7447
- "license": "MIT"
7448
- },
7449
- "node_modules/path-scurry": {
7450
- "version": "2.0.2",
7451
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
7452
- "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
7453
- "license": "BlueOak-1.0.0",
7454
- "dependencies": {
7455
- "lru-cache": "^11.0.0",
7456
- "minipass": "^7.1.2"
7457
- },
7458
- "engines": {
7459
- "node": "18 || 20 || >=22"
7460
- },
7461
- "funding": {
7462
- "url": "https://github.com/sponsors/isaacs"
7463
- }
7464
- },
7465
- "node_modules/path-scurry/node_modules/lru-cache": {
7466
- "version": "11.2.6",
7467
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
7468
- "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
7469
- "license": "BlueOak-1.0.0",
7470
- "engines": {
7471
- "node": "20 || >=22"
7472
- }
7473
- },
7474
- "node_modules/picocolors": {
7475
- "version": "1.1.1",
7476
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
7477
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
7478
- "license": "ISC"
7479
- },
7480
- "node_modules/picomatch": {
7481
- "version": "2.3.1",
7482
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
7483
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
7484
- "license": "MIT",
7485
- "engines": {
7486
- "node": ">=8.6"
7487
- },
7488
- "funding": {
7489
- "url": "https://github.com/sponsors/jonschlinkert"
7490
- }
7491
- },
7492
- "node_modules/pify": {
7493
- "version": "2.3.0",
7494
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
7495
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
7496
- "dev": true,
7497
- "license": "MIT",
7498
- "engines": {
7499
- "node": ">=0.10.0"
7500
- }
7501
- },
7502
- "node_modules/pirates": {
7503
- "version": "4.0.7",
7504
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
7505
- "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
7506
- "license": "MIT",
7507
- "engines": {
7508
- "node": ">= 6"
7509
- }
7510
- },
7511
- "node_modules/pkg-up": {
7512
- "version": "3.1.0",
7513
- "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
7514
- "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
7515
- "dev": true,
7516
- "license": "MIT",
7517
- "dependencies": {
7518
- "find-up": "^3.0.0"
7519
- },
7520
- "engines": {
7521
- "node": ">=8"
7522
- }
7523
- },
7524
- "node_modules/pkg-up/node_modules/find-up": {
7525
- "version": "3.0.0",
7526
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
7527
- "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
7528
- "dev": true,
7529
- "license": "MIT",
7530
- "dependencies": {
7531
- "locate-path": "^3.0.0"
7532
- },
7533
- "engines": {
7534
- "node": ">=6"
7535
- }
7536
- },
7537
- "node_modules/pkg-up/node_modules/locate-path": {
7538
- "version": "3.0.0",
7539
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
7540
- "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
7541
- "dev": true,
7542
- "license": "MIT",
7543
- "dependencies": {
7544
- "p-locate": "^3.0.0",
7545
- "path-exists": "^3.0.0"
7546
- },
7547
- "engines": {
7548
- "node": ">=6"
7549
- }
7550
- },
7551
- "node_modules/pkg-up/node_modules/p-locate": {
7552
- "version": "3.0.0",
7553
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
7554
- "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
7555
- "dev": true,
7556
- "license": "MIT",
7557
- "dependencies": {
7558
- "p-limit": "^2.0.0"
7559
- },
7560
- "engines": {
7561
- "node": ">=6"
7562
- }
7563
- },
7564
- "node_modules/pkg-up/node_modules/path-exists": {
7565
- "version": "3.0.0",
7566
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
7567
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
7568
- "dev": true,
7569
- "license": "MIT",
7570
- "engines": {
7571
- "node": ">=4"
7572
- }
7573
- },
7574
- "node_modules/plist": {
7575
- "version": "3.1.0",
7576
- "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
7577
- "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
7578
- "license": "MIT",
7579
- "dependencies": {
7580
- "@xmldom/xmldom": "^0.8.8",
7581
- "base64-js": "^1.5.1",
7582
- "xmlbuilder": "^15.1.1"
7583
- },
7584
- "engines": {
7585
- "node": ">=10.4.0"
7586
- }
7587
- },
7588
- "node_modules/pngjs": {
7589
- "version": "3.4.0",
7590
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
7591
- "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
7592
- "license": "MIT",
7593
- "engines": {
7594
- "node": ">=4.0.0"
7595
- }
7596
- },
7597
- "node_modules/postcss": {
7598
- "version": "8.4.49",
7599
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
7600
- "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
7601
- "funding": [
7602
- {
7603
- "type": "opencollective",
7604
- "url": "https://opencollective.com/postcss/"
7605
- },
7606
- {
7607
- "type": "tidelift",
7608
- "url": "https://tidelift.com/funding/github/npm/postcss"
7609
- },
7610
- {
7611
- "type": "github",
7612
- "url": "https://github.com/sponsors/ai"
7613
- }
7614
- ],
7615
- "license": "MIT",
7616
- "dependencies": {
7617
- "nanoid": "^3.3.7",
7618
- "picocolors": "^1.1.1",
7619
- "source-map-js": "^1.2.1"
7620
- },
7621
- "engines": {
7622
- "node": "^10 || ^12 || >=14"
7623
- }
7624
- },
7625
- "node_modules/postcss-import": {
7626
- "version": "15.1.0",
7627
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
7628
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
7629
- "dev": true,
7630
- "license": "MIT",
7631
- "dependencies": {
7632
- "postcss-value-parser": "^4.0.0",
7633
- "read-cache": "^1.0.0",
7634
- "resolve": "^1.1.7"
7635
- },
7636
- "engines": {
7637
- "node": ">=14.0.0"
7638
- },
7639
- "peerDependencies": {
7640
- "postcss": "^8.0.0"
7641
- }
7642
- },
7643
- "node_modules/postcss-js": {
7644
- "version": "4.1.0",
7645
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
7646
- "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
7647
- "dev": true,
7648
- "funding": [
7649
- {
7650
- "type": "opencollective",
7651
- "url": "https://opencollective.com/postcss/"
7652
- },
7653
- {
7654
- "type": "github",
7655
- "url": "https://github.com/sponsors/ai"
7656
- }
7657
- ],
7658
- "license": "MIT",
7659
- "dependencies": {
7660
- "camelcase-css": "^2.0.1"
7661
- },
7662
- "engines": {
7663
- "node": "^12 || ^14 || >= 16"
7664
- },
7665
- "peerDependencies": {
7666
- "postcss": "^8.4.21"
7667
- }
7668
- },
7669
- "node_modules/postcss-load-config": {
7670
- "version": "6.0.1",
7671
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
7672
- "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
7673
- "dev": true,
7674
- "funding": [
7675
- {
7676
- "type": "opencollective",
7677
- "url": "https://opencollective.com/postcss/"
7678
- },
7679
- {
7680
- "type": "github",
7681
- "url": "https://github.com/sponsors/ai"
7682
- }
7683
- ],
7684
- "license": "MIT",
7685
- "dependencies": {
7686
- "lilconfig": "^3.1.1"
7687
- },
7688
- "engines": {
7689
- "node": ">= 18"
7690
- },
7691
- "peerDependencies": {
7692
- "jiti": ">=1.21.0",
7693
- "postcss": ">=8.0.9",
7694
- "tsx": "^4.8.1",
7695
- "yaml": "^2.4.2"
7696
- },
7697
- "peerDependenciesMeta": {
7698
- "jiti": {
7699
- "optional": true
7700
- },
7701
- "postcss": {
7702
- "optional": true
7703
- },
7704
- "tsx": {
7705
- "optional": true
7706
- },
7707
- "yaml": {
7708
- "optional": true
7709
- }
7710
- }
7711
- },
7712
- "node_modules/postcss-nested": {
7713
- "version": "6.2.0",
7714
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
7715
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
7716
- "dev": true,
7717
- "funding": [
7718
- {
7719
- "type": "opencollective",
7720
- "url": "https://opencollective.com/postcss/"
7721
- },
7722
- {
7723
- "type": "github",
7724
- "url": "https://github.com/sponsors/ai"
7725
- }
7726
- ],
7727
- "license": "MIT",
7728
- "dependencies": {
7729
- "postcss-selector-parser": "^6.1.1"
7730
- },
7731
- "engines": {
7732
- "node": ">=12.0"
7733
- },
7734
- "peerDependencies": {
7735
- "postcss": "^8.2.14"
7736
- }
7737
- },
7738
- "node_modules/postcss-selector-parser": {
7739
- "version": "6.1.2",
7740
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
7741
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
7742
- "dev": true,
7743
- "license": "MIT",
7744
- "dependencies": {
7745
- "cssesc": "^3.0.0",
7746
- "util-deprecate": "^1.0.2"
7747
- },
7748
- "engines": {
7749
- "node": ">=4"
7750
- }
7751
- },
7752
- "node_modules/postcss-value-parser": {
7753
- "version": "4.2.0",
7754
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
7755
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
7756
- "license": "MIT"
7757
- },
7758
- "node_modules/pretty-format": {
7759
- "version": "29.7.0",
7760
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
7761
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
7762
- "license": "MIT",
7763
- "dependencies": {
7764
- "@jest/schemas": "^29.6.3",
7765
- "ansi-styles": "^5.0.0",
7766
- "react-is": "^18.0.0"
7767
- },
7768
- "engines": {
7769
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
7770
- }
7771
- },
7772
- "node_modules/pretty-format/node_modules/ansi-styles": {
7773
- "version": "5.2.0",
7774
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
7775
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
7776
- "license": "MIT",
7777
- "engines": {
7778
- "node": ">=10"
7779
- },
7780
- "funding": {
7781
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
7782
- }
7783
- },
7784
- "node_modules/proc-log": {
7785
- "version": "4.2.0",
7786
- "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
7787
- "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
7788
- "license": "ISC",
7789
- "engines": {
7790
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
7791
- }
7792
- },
7793
- "node_modules/progress": {
7794
- "version": "2.0.3",
7795
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
7796
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
7797
- "license": "MIT",
7798
- "engines": {
7799
- "node": ">=0.4.0"
7800
- }
7801
- },
7802
- "node_modules/promise": {
7803
- "version": "8.3.0",
7804
- "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz",
7805
- "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==",
7806
- "license": "MIT",
7807
- "dependencies": {
7808
- "asap": "~2.0.6"
7809
- }
7810
- },
7811
- "node_modules/prompts": {
7812
- "version": "2.4.2",
7813
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
7814
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
7815
- "license": "MIT",
7816
- "dependencies": {
7817
- "kleur": "^3.0.3",
7818
- "sisteransi": "^1.0.5"
7819
- },
7820
- "engines": {
7821
- "node": ">= 6"
7822
- }
7823
- },
7824
- "node_modules/query-string": {
7825
- "version": "7.1.3",
7826
- "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
7827
- "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
7828
- "license": "MIT",
7829
- "dependencies": {
7830
- "decode-uri-component": "^0.2.2",
7831
- "filter-obj": "^1.1.0",
7832
- "split-on-first": "^1.0.0",
7833
- "strict-uri-encode": "^2.0.0"
7834
- },
7835
- "engines": {
7836
- "node": ">=6"
7837
- },
7838
- "funding": {
7839
- "url": "https://github.com/sponsors/sindresorhus"
7840
- }
7841
- },
7842
- "node_modules/queue": {
7843
- "version": "6.0.2",
7844
- "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
7845
- "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
7846
- "license": "MIT",
7847
- "dependencies": {
7848
- "inherits": "~2.0.3"
7849
- }
7850
- },
7851
- "node_modules/queue-microtask": {
7852
- "version": "1.2.3",
7853
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
7854
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
7855
- "dev": true,
7856
- "funding": [
7857
- {
7858
- "type": "github",
7859
- "url": "https://github.com/sponsors/feross"
7860
- },
7861
- {
7862
- "type": "patreon",
7863
- "url": "https://www.patreon.com/feross"
7864
- },
7865
- {
7866
- "type": "consulting",
7867
- "url": "https://feross.org/support"
7868
- }
7869
- ],
7870
- "license": "MIT"
7871
- },
7872
- "node_modules/range-parser": {
7873
- "version": "1.2.1",
7874
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
7875
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
7876
- "license": "MIT",
7877
- "engines": {
7878
- "node": ">= 0.6"
7879
- }
7880
- },
7881
- "node_modules/react": {
7882
- "version": "19.2.0",
7883
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
7884
- "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
7885
- "license": "MIT",
7886
- "engines": {
7887
- "node": ">=0.10.0"
7888
- }
7889
- },
7890
- "node_modules/react-devtools-core": {
7891
- "version": "6.1.5",
7892
- "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz",
7893
- "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==",
7894
- "license": "MIT",
7895
- "dependencies": {
7896
- "shell-quote": "^1.6.1",
7897
- "ws": "^7"
7898
- }
7899
- },
7900
- "node_modules/react-dom": {
7901
- "version": "19.2.4",
7902
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
7903
- "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
7904
- "license": "MIT",
7905
- "dependencies": {
7906
- "scheduler": "^0.27.0"
7907
- },
7908
- "peerDependencies": {
7909
- "react": "^19.2.4"
7910
- }
7911
- },
7912
- "node_modules/react-fast-compare": {
7913
- "version": "3.2.2",
7914
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
7915
- "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
7916
- "license": "MIT"
7917
- },
7918
- "node_modules/react-freeze": {
7919
- "version": "1.0.4",
7920
- "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz",
7921
- "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==",
7922
- "license": "MIT",
7923
- "engines": {
7924
- "node": ">=10"
7925
- },
7926
- "peerDependencies": {
7927
- "react": ">=17.0.0"
7928
- }
7929
- },
7930
- "node_modules/react-is": {
7931
- "version": "18.3.1",
7932
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
7933
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
7934
- "license": "MIT"
7935
- },
7936
- "node_modules/react-native": {
7937
- "version": "0.83.2",
7938
- "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.83.2.tgz",
7939
- "integrity": "sha512-ZDma3SLkRN2U2dg0/EZqxNBAx4of/oTnPjXAQi299VLq2gdnbZowGy9hzqv+O7sTA62g+lM1v+2FM5DUnJ/6hg==",
7940
- "license": "MIT",
7941
- "dependencies": {
7942
- "@jest/create-cache-key-function": "^29.7.0",
7943
- "@react-native/assets-registry": "0.83.2",
7944
- "@react-native/codegen": "0.83.2",
7945
- "@react-native/community-cli-plugin": "0.83.2",
7946
- "@react-native/gradle-plugin": "0.83.2",
7947
- "@react-native/js-polyfills": "0.83.2",
7948
- "@react-native/normalize-colors": "0.83.2",
7949
- "@react-native/virtualized-lists": "0.83.2",
7950
- "abort-controller": "^3.0.0",
7951
- "anser": "^1.4.9",
7952
- "ansi-regex": "^5.0.0",
7953
- "babel-jest": "^29.7.0",
7954
- "babel-plugin-syntax-hermes-parser": "0.32.0",
7955
- "base64-js": "^1.5.1",
7956
- "commander": "^12.0.0",
7957
- "flow-enums-runtime": "^0.0.6",
7958
- "glob": "^7.1.1",
7959
- "hermes-compiler": "0.14.1",
7960
- "invariant": "^2.2.4",
7961
- "jest-environment-node": "^29.7.0",
7962
- "memoize-one": "^5.0.0",
7963
- "metro-runtime": "^0.83.3",
7964
- "metro-source-map": "^0.83.3",
7965
- "nullthrows": "^1.1.1",
7966
- "pretty-format": "^29.7.0",
7967
- "promise": "^8.3.0",
7968
- "react-devtools-core": "^6.1.5",
7969
- "react-refresh": "^0.14.0",
7970
- "regenerator-runtime": "^0.13.2",
7971
- "scheduler": "0.27.0",
7972
- "semver": "^7.1.3",
7973
- "stacktrace-parser": "^0.1.10",
7974
- "whatwg-fetch": "^3.0.0",
7975
- "ws": "^7.5.10",
7976
- "yargs": "^17.6.2"
7977
- },
7978
- "bin": {
7979
- "react-native": "cli.js"
7980
- },
7981
- "engines": {
7982
- "node": ">= 20.19.4"
7983
- },
7984
- "peerDependencies": {
7985
- "@types/react": "^19.1.1",
7986
- "react": "^19.2.0"
7987
- },
7988
- "peerDependenciesMeta": {
7989
- "@types/react": {
7990
- "optional": true
7991
- }
7992
- }
7993
- },
7994
- "node_modules/react-native-css-interop": {
7995
- "version": "0.2.2",
7996
- "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.2.tgz",
7997
- "integrity": "sha512-2eUyl7RH1RT6TYbe5nm+d4HZ2Pr6Nmve158B57tb5W4Bo52Xzp+PFeWAdFnAr2HNB+r9b6qa8o3xH1YREVQU0g==",
7998
- "license": "MIT",
7999
- "dependencies": {
8000
- "@babel/helper-module-imports": "^7.22.15",
8001
- "@babel/traverse": "^7.23.0",
8002
- "@babel/types": "^7.23.0",
8003
- "debug": "^4.3.7",
8004
- "lightningcss": "~1.27.0",
8005
- "semver": "^7.6.3"
8006
- },
8007
- "engines": {
8008
- "node": ">=18"
8009
- },
8010
- "peerDependencies": {
8011
- "react": ">=18",
8012
- "react-native": "*",
8013
- "react-native-reanimated": ">=3.6.2",
8014
- "tailwindcss": "~3"
8015
- },
8016
- "peerDependenciesMeta": {
8017
- "react-native-safe-area-context": {
8018
- "optional": true
8019
- },
8020
- "react-native-svg": {
8021
- "optional": true
8022
- }
8023
- }
8024
- },
8025
- "node_modules/react-native-css-interop/node_modules/detect-libc": {
8026
- "version": "1.0.3",
8027
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
8028
- "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
8029
- "license": "Apache-2.0",
8030
- "bin": {
8031
- "detect-libc": "bin/detect-libc.js"
8032
- },
8033
- "engines": {
8034
- "node": ">=0.10"
8035
- }
8036
- },
8037
- "node_modules/react-native-css-interop/node_modules/lightningcss": {
8038
- "version": "1.27.0",
8039
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz",
8040
- "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==",
8041
- "license": "MPL-2.0",
8042
- "dependencies": {
8043
- "detect-libc": "^1.0.3"
8044
- },
8045
- "engines": {
8046
- "node": ">= 12.0.0"
8047
- },
8048
- "funding": {
8049
- "type": "opencollective",
8050
- "url": "https://opencollective.com/parcel"
8051
- },
8052
- "optionalDependencies": {
8053
- "lightningcss-darwin-arm64": "1.27.0",
8054
- "lightningcss-darwin-x64": "1.27.0",
8055
- "lightningcss-freebsd-x64": "1.27.0",
8056
- "lightningcss-linux-arm-gnueabihf": "1.27.0",
8057
- "lightningcss-linux-arm64-gnu": "1.27.0",
8058
- "lightningcss-linux-arm64-musl": "1.27.0",
8059
- "lightningcss-linux-x64-gnu": "1.27.0",
8060
- "lightningcss-linux-x64-musl": "1.27.0",
8061
- "lightningcss-win32-arm64-msvc": "1.27.0",
8062
- "lightningcss-win32-x64-msvc": "1.27.0"
8063
- }
8064
- },
8065
- "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-arm64": {
8066
- "version": "1.27.0",
8067
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz",
8068
- "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==",
8069
- "cpu": [
8070
- "arm64"
8071
- ],
8072
- "license": "MPL-2.0",
8073
- "optional": true,
8074
- "os": [
8075
- "darwin"
8076
- ],
8077
- "engines": {
8078
- "node": ">= 12.0.0"
8079
- },
8080
- "funding": {
8081
- "type": "opencollective",
8082
- "url": "https://opencollective.com/parcel"
8083
- }
8084
- },
8085
- "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-x64": {
8086
- "version": "1.27.0",
8087
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz",
8088
- "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==",
8089
- "cpu": [
8090
- "x64"
8091
- ],
8092
- "license": "MPL-2.0",
8093
- "optional": true,
8094
- "os": [
8095
- "darwin"
8096
- ],
8097
- "engines": {
8098
- "node": ">= 12.0.0"
8099
- },
8100
- "funding": {
8101
- "type": "opencollective",
8102
- "url": "https://opencollective.com/parcel"
8103
- }
8104
- },
8105
- "node_modules/react-native-css-interop/node_modules/lightningcss-freebsd-x64": {
8106
- "version": "1.27.0",
8107
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz",
8108
- "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==",
8109
- "cpu": [
8110
- "x64"
8111
- ],
8112
- "license": "MPL-2.0",
8113
- "optional": true,
8114
- "os": [
8115
- "freebsd"
8116
- ],
8117
- "engines": {
8118
- "node": ">= 12.0.0"
8119
- },
8120
- "funding": {
8121
- "type": "opencollective",
8122
- "url": "https://opencollective.com/parcel"
8123
- }
8124
- },
8125
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm-gnueabihf": {
8126
- "version": "1.27.0",
8127
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz",
8128
- "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==",
8129
- "cpu": [
8130
- "arm"
8131
- ],
8132
- "license": "MPL-2.0",
8133
- "optional": true,
8134
- "os": [
8135
- "linux"
8136
- ],
8137
- "engines": {
8138
- "node": ">= 12.0.0"
8139
- },
8140
- "funding": {
8141
- "type": "opencollective",
8142
- "url": "https://opencollective.com/parcel"
8143
- }
8144
- },
8145
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-gnu": {
8146
- "version": "1.27.0",
8147
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz",
8148
- "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==",
8149
- "cpu": [
8150
- "arm64"
8151
- ],
8152
- "license": "MPL-2.0",
8153
- "optional": true,
8154
- "os": [
8155
- "linux"
8156
- ],
8157
- "engines": {
8158
- "node": ">= 12.0.0"
8159
- },
8160
- "funding": {
8161
- "type": "opencollective",
8162
- "url": "https://opencollective.com/parcel"
8163
- }
8164
- },
8165
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-musl": {
8166
- "version": "1.27.0",
8167
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz",
8168
- "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==",
8169
- "cpu": [
8170
- "arm64"
8171
- ],
8172
- "license": "MPL-2.0",
8173
- "optional": true,
8174
- "os": [
8175
- "linux"
8176
- ],
8177
- "engines": {
8178
- "node": ">= 12.0.0"
8179
- },
8180
- "funding": {
8181
- "type": "opencollective",
8182
- "url": "https://opencollective.com/parcel"
8183
- }
8184
- },
8185
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-gnu": {
8186
- "version": "1.27.0",
8187
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz",
8188
- "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==",
8189
- "cpu": [
8190
- "x64"
8191
- ],
8192
- "license": "MPL-2.0",
8193
- "optional": true,
8194
- "os": [
8195
- "linux"
8196
- ],
8197
- "engines": {
8198
- "node": ">= 12.0.0"
8199
- },
8200
- "funding": {
8201
- "type": "opencollective",
8202
- "url": "https://opencollective.com/parcel"
8203
- }
8204
- },
8205
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-musl": {
8206
- "version": "1.27.0",
8207
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz",
8208
- "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==",
8209
- "cpu": [
8210
- "x64"
8211
- ],
8212
- "license": "MPL-2.0",
8213
- "optional": true,
8214
- "os": [
8215
- "linux"
8216
- ],
8217
- "engines": {
8218
- "node": ">= 12.0.0"
8219
- },
8220
- "funding": {
8221
- "type": "opencollective",
8222
- "url": "https://opencollective.com/parcel"
8223
- }
8224
- },
8225
- "node_modules/react-native-css-interop/node_modules/lightningcss-win32-arm64-msvc": {
8226
- "version": "1.27.0",
8227
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz",
8228
- "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==",
8229
- "cpu": [
8230
- "arm64"
8231
- ],
8232
- "license": "MPL-2.0",
8233
- "optional": true,
8234
- "os": [
8235
- "win32"
8236
- ],
8237
- "engines": {
8238
- "node": ">= 12.0.0"
8239
- },
8240
- "funding": {
8241
- "type": "opencollective",
8242
- "url": "https://opencollective.com/parcel"
8243
- }
8244
- },
8245
- "node_modules/react-native-css-interop/node_modules/lightningcss-win32-x64-msvc": {
8246
- "version": "1.27.0",
8247
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz",
8248
- "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==",
8249
- "cpu": [
8250
- "x64"
8251
- ],
8252
- "license": "MPL-2.0",
8253
- "optional": true,
8254
- "os": [
8255
- "win32"
8256
- ],
8257
- "engines": {
8258
- "node": ">= 12.0.0"
8259
- },
8260
- "funding": {
8261
- "type": "opencollective",
8262
- "url": "https://opencollective.com/parcel"
8263
- }
8264
- },
8265
- "node_modules/react-native-draggable-flatlist": {
8266
- "version": "4.0.3",
8267
- "resolved": "https://registry.npmjs.org/react-native-draggable-flatlist/-/react-native-draggable-flatlist-4.0.3.tgz",
8268
- "integrity": "sha512-2F4x5BFieWdGq9SetD2nSAR7s7oQCSgNllYgERRXXtNfSOuAGAVbDb/3H3lP0y5f7rEyNwabKorZAD/SyyNbDw==",
8269
- "license": "MIT",
8270
- "dependencies": {
8271
- "@babel/preset-typescript": "^7.17.12"
8272
- },
8273
- "peerDependencies": {
8274
- "react-native": ">=0.64.0",
8275
- "react-native-gesture-handler": ">=2.0.0",
8276
- "react-native-reanimated": ">=2.8.0"
8277
- }
8278
- },
8279
- "node_modules/react-native-gesture-handler": {
8280
- "version": "2.30.0",
8281
- "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.30.0.tgz",
8282
- "integrity": "sha512-5YsnKHGa0X9C8lb5oCnKm0fLUPM6CRduvUUw2Bav4RIj/C3HcFh4RIUnF8wgG6JQWCL1//gRx4v+LVWgcIQdGA==",
8283
- "license": "MIT",
8284
- "dependencies": {
8285
- "@egjs/hammerjs": "^2.0.17",
8286
- "hoist-non-react-statics": "^3.3.0",
8287
- "invariant": "^2.2.4"
8288
- },
8289
- "peerDependencies": {
8290
- "react": "*",
8291
- "react-native": "*"
8292
- }
8293
- },
8294
- "node_modules/react-native-is-edge-to-edge": {
8295
- "version": "1.2.1",
8296
- "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz",
8297
- "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==",
8298
- "license": "MIT",
8299
- "peerDependencies": {
8300
- "react": "*",
8301
- "react-native": "*"
8302
- }
8303
- },
8304
- "node_modules/react-native-reanimated": {
8305
- "version": "4.2.1",
8306
- "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.1.tgz",
8307
- "integrity": "sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg==",
8308
- "license": "MIT",
8309
- "dependencies": {
8310
- "react-native-is-edge-to-edge": "1.2.1",
8311
- "semver": "7.7.3"
8312
- },
8313
- "peerDependencies": {
8314
- "react": "*",
8315
- "react-native": "*",
8316
- "react-native-worklets": ">=0.7.0"
8317
- }
8318
- },
8319
- "node_modules/react-native-reanimated/node_modules/semver": {
8320
- "version": "7.7.3",
8321
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
8322
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
8323
- "license": "ISC",
8324
- "bin": {
8325
- "semver": "bin/semver.js"
8326
- },
8327
- "engines": {
8328
- "node": ">=10"
8329
- }
8330
- },
8331
- "node_modules/react-native-safe-area-context": {
8332
- "version": "5.6.2",
8333
- "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz",
8334
- "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==",
8335
- "license": "MIT",
8336
- "peerDependencies": {
8337
- "react": "*",
8338
- "react-native": "*"
8339
- }
8340
- },
8341
- "node_modules/react-native-screens": {
8342
- "version": "4.23.0",
8343
- "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.23.0.tgz",
8344
- "integrity": "sha512-XhO3aK0UeLpBn4kLecd+J+EDeRRJlI/Ro9Fze06vo1q163VeYtzfU9QS09/VyDFMWR1qxDC1iazCArTPSFFiPw==",
8345
- "license": "MIT",
8346
- "dependencies": {
8347
- "react-freeze": "^1.0.0",
8348
- "warn-once": "^0.1.0"
8349
- },
8350
- "peerDependencies": {
8351
- "react": "*",
8352
- "react-native": "*"
8353
- }
8354
- },
8355
- "node_modules/react-native-svg": {
8356
- "version": "15.15.3",
8357
- "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.15.3.tgz",
8358
- "integrity": "sha512-/k4KYwPBLGcx2f5d4FjE+vCScK7QOX14cl2lIASJ28u4slHHtIhL0SZKU7u9qmRBHxTCKPoPBtN6haT1NENJNA==",
8359
- "license": "MIT",
8360
- "dependencies": {
8361
- "css-select": "^5.1.0",
8362
- "css-tree": "^1.1.3",
8363
- "warn-once": "0.1.1"
8364
- },
8365
- "peerDependencies": {
8366
- "react": "*",
8367
- "react-native": "*"
8368
- }
8369
- },
8370
- "node_modules/react-native-udp": {
8371
- "version": "4.1.7",
8372
- "resolved": "https://registry.npmjs.org/react-native-udp/-/react-native-udp-4.1.7.tgz",
8373
- "integrity": "sha512-NUE3zewu61NCdSsLlj+l0ad6qojcVEZPT4hVG/x6DU9U4iCzwtfZSASh9vm7teAcVzLkdD+cO3411LHshAi/wA==",
8374
- "license": "MIT",
8375
- "dependencies": {
8376
- "buffer": "^5.6.0",
8377
- "events": "^3.1.0"
8378
- }
8379
- },
8380
- "node_modules/react-native-web": {
8381
- "version": "0.21.2",
8382
- "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz",
8383
- "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==",
8384
- "license": "MIT",
8385
- "dependencies": {
8386
- "@babel/runtime": "^7.18.6",
8387
- "@react-native/normalize-colors": "^0.74.1",
8388
- "fbjs": "^3.0.4",
8389
- "inline-style-prefixer": "^7.0.1",
8390
- "memoize-one": "^6.0.0",
8391
- "nullthrows": "^1.1.1",
8392
- "postcss-value-parser": "^4.2.0",
8393
- "styleq": "^0.1.3"
8394
- },
8395
- "peerDependencies": {
8396
- "react": "^18.0.0 || ^19.0.0",
8397
- "react-dom": "^18.0.0 || ^19.0.0"
8398
- }
8399
- },
8400
- "node_modules/react-native-web/node_modules/@react-native/normalize-colors": {
8401
- "version": "0.74.89",
8402
- "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz",
8403
- "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==",
8404
- "license": "MIT"
8405
- },
8406
- "node_modules/react-native-web/node_modules/memoize-one": {
8407
- "version": "6.0.0",
8408
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
8409
- "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
8410
- "license": "MIT"
8411
- },
8412
- "node_modules/react-native-worklets": {
8413
- "version": "0.7.2",
8414
- "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.7.2.tgz",
8415
- "integrity": "sha512-DuLu1kMV/Uyl9pQHp3hehAlThoLw7Yk2FwRTpzASOmI+cd4845FWn3m2bk9MnjUw8FBRIyhwLqYm2AJaXDXsog==",
8416
- "license": "MIT",
8417
- "dependencies": {
8418
- "@babel/plugin-transform-arrow-functions": "7.27.1",
8419
- "@babel/plugin-transform-class-properties": "7.27.1",
8420
- "@babel/plugin-transform-classes": "7.28.4",
8421
- "@babel/plugin-transform-nullish-coalescing-operator": "7.27.1",
8422
- "@babel/plugin-transform-optional-chaining": "7.27.1",
8423
- "@babel/plugin-transform-shorthand-properties": "7.27.1",
8424
- "@babel/plugin-transform-template-literals": "7.27.1",
8425
- "@babel/plugin-transform-unicode-regex": "7.27.1",
8426
- "@babel/preset-typescript": "7.27.1",
8427
- "convert-source-map": "2.0.0",
8428
- "semver": "7.7.3"
8429
- },
8430
- "peerDependencies": {
8431
- "@babel/core": "*",
8432
- "react": "*",
8433
- "react-native": "*"
8434
- }
8435
- },
8436
- "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-class-properties": {
8437
- "version": "7.27.1",
8438
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz",
8439
- "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==",
8440
- "license": "MIT",
8441
- "dependencies": {
8442
- "@babel/helper-create-class-features-plugin": "^7.27.1",
8443
- "@babel/helper-plugin-utils": "^7.27.1"
8444
- },
8445
- "engines": {
8446
- "node": ">=6.9.0"
8447
- },
8448
- "peerDependencies": {
8449
- "@babel/core": "^7.0.0-0"
8450
- }
8451
- },
8452
- "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-classes": {
8453
- "version": "7.28.4",
8454
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
8455
- "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
8456
- "license": "MIT",
8457
- "dependencies": {
8458
- "@babel/helper-annotate-as-pure": "^7.27.3",
8459
- "@babel/helper-compilation-targets": "^7.27.2",
8460
- "@babel/helper-globals": "^7.28.0",
8461
- "@babel/helper-plugin-utils": "^7.27.1",
8462
- "@babel/helper-replace-supers": "^7.27.1",
8463
- "@babel/traverse": "^7.28.4"
8464
- },
8465
- "engines": {
8466
- "node": ">=6.9.0"
8467
- },
8468
- "peerDependencies": {
8469
- "@babel/core": "^7.0.0-0"
8470
- }
8471
- },
8472
- "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
8473
- "version": "7.27.1",
8474
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz",
8475
- "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==",
8476
- "license": "MIT",
8477
- "dependencies": {
8478
- "@babel/helper-plugin-utils": "^7.27.1"
8479
- },
8480
- "engines": {
8481
- "node": ">=6.9.0"
8482
- },
8483
- "peerDependencies": {
8484
- "@babel/core": "^7.0.0-0"
8485
- }
8486
- },
8487
- "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-optional-chaining": {
8488
- "version": "7.27.1",
8489
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
8490
- "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
8491
- "license": "MIT",
8492
- "dependencies": {
8493
- "@babel/helper-plugin-utils": "^7.27.1",
8494
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
8495
- },
8496
- "engines": {
8497
- "node": ">=6.9.0"
8498
- },
8499
- "peerDependencies": {
8500
- "@babel/core": "^7.0.0-0"
8501
- }
8502
- },
8503
- "node_modules/react-native-worklets/node_modules/@babel/preset-typescript": {
8504
- "version": "7.27.1",
8505
- "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz",
8506
- "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==",
8507
- "license": "MIT",
8508
- "dependencies": {
8509
- "@babel/helper-plugin-utils": "^7.27.1",
8510
- "@babel/helper-validator-option": "^7.27.1",
8511
- "@babel/plugin-syntax-jsx": "^7.27.1",
8512
- "@babel/plugin-transform-modules-commonjs": "^7.27.1",
8513
- "@babel/plugin-transform-typescript": "^7.27.1"
8514
- },
8515
- "engines": {
8516
- "node": ">=6.9.0"
8517
- },
8518
- "peerDependencies": {
8519
- "@babel/core": "^7.0.0-0"
8520
- }
8521
- },
8522
- "node_modules/react-native-worklets/node_modules/semver": {
8523
- "version": "7.7.3",
8524
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
8525
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
8526
- "license": "ISC",
8527
- "bin": {
8528
- "semver": "bin/semver.js"
8529
- },
8530
- "engines": {
8531
- "node": ">=10"
8532
- }
8533
- },
8534
- "node_modules/react-native/node_modules/@react-native/virtualized-lists": {
8535
- "version": "0.83.2",
8536
- "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.83.2.tgz",
8537
- "integrity": "sha512-N7mRjHLW/+KWxMp9IHRWyE3VIkeG1m3PnZJAGEFLCN8VFb7e4VfI567o7tE/HYcdcXCylw+Eqhlciz8gDeQ71g==",
8538
- "license": "MIT",
8539
- "dependencies": {
8540
- "invariant": "^2.2.4",
8541
- "nullthrows": "^1.1.1"
8542
- },
8543
- "engines": {
8544
- "node": ">= 20.19.4"
8545
- },
8546
- "peerDependencies": {
8547
- "@types/react": "^19.2.0",
8548
- "react": "*",
8549
- "react-native": "*"
8550
- },
8551
- "peerDependenciesMeta": {
8552
- "@types/react": {
8553
- "optional": true
8554
- }
8555
- }
8556
- },
8557
- "node_modules/react-native/node_modules/balanced-match": {
8558
- "version": "1.0.2",
8559
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
8560
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
8561
- "license": "MIT"
8562
- },
8563
- "node_modules/react-native/node_modules/brace-expansion": {
8564
- "version": "1.1.12",
8565
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
8566
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
8567
- "license": "MIT",
8568
- "dependencies": {
8569
- "balanced-match": "^1.0.0",
8570
- "concat-map": "0.0.1"
8571
- }
8572
- },
8573
- "node_modules/react-native/node_modules/commander": {
8574
- "version": "12.1.0",
8575
- "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
8576
- "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
8577
- "license": "MIT",
8578
- "engines": {
8579
- "node": ">=18"
8580
- }
8581
- },
8582
- "node_modules/react-native/node_modules/glob": {
8583
- "version": "7.2.3",
8584
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
8585
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
8586
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
8587
- "license": "ISC",
8588
- "dependencies": {
8589
- "fs.realpath": "^1.0.0",
8590
- "inflight": "^1.0.4",
8591
- "inherits": "2",
8592
- "minimatch": "^3.1.1",
8593
- "once": "^1.3.0",
8594
- "path-is-absolute": "^1.0.0"
8595
- },
8596
- "engines": {
8597
- "node": "*"
8598
- },
8599
- "funding": {
8600
- "url": "https://github.com/sponsors/isaacs"
8601
- }
8602
- },
8603
- "node_modules/react-native/node_modules/minimatch": {
8604
- "version": "3.1.5",
8605
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
8606
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
8607
- "license": "ISC",
8608
- "dependencies": {
8609
- "brace-expansion": "^1.1.7"
8610
- },
8611
- "engines": {
8612
- "node": "*"
8613
- }
8614
- },
8615
- "node_modules/react-refresh": {
8616
- "version": "0.14.2",
8617
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
8618
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
8619
- "license": "MIT",
8620
- "engines": {
8621
- "node": ">=0.10.0"
8622
- }
8623
- },
8624
- "node_modules/react-remove-scroll": {
8625
- "version": "2.7.2",
8626
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
8627
- "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
8628
- "license": "MIT",
8629
- "dependencies": {
8630
- "react-remove-scroll-bar": "^2.3.7",
8631
- "react-style-singleton": "^2.2.3",
8632
- "tslib": "^2.1.0",
8633
- "use-callback-ref": "^1.3.3",
8634
- "use-sidecar": "^1.1.3"
8635
- },
8636
- "engines": {
8637
- "node": ">=10"
8638
- },
8639
- "peerDependencies": {
8640
- "@types/react": "*",
8641
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
8642
- },
8643
- "peerDependenciesMeta": {
8644
- "@types/react": {
8645
- "optional": true
8646
- }
8647
- }
8648
- },
8649
- "node_modules/react-remove-scroll-bar": {
8650
- "version": "2.3.8",
8651
- "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
8652
- "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
8653
- "license": "MIT",
8654
- "dependencies": {
8655
- "react-style-singleton": "^2.2.2",
8656
- "tslib": "^2.0.0"
8657
- },
8658
- "engines": {
8659
- "node": ">=10"
8660
- },
8661
- "peerDependencies": {
8662
- "@types/react": "*",
8663
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
8664
- },
8665
- "peerDependenciesMeta": {
8666
- "@types/react": {
8667
- "optional": true
8668
- }
8669
- }
8670
- },
8671
- "node_modules/react-style-singleton": {
8672
- "version": "2.2.3",
8673
- "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
8674
- "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
8675
- "license": "MIT",
8676
- "dependencies": {
8677
- "get-nonce": "^1.0.0",
8678
- "tslib": "^2.0.0"
8679
- },
8680
- "engines": {
8681
- "node": ">=10"
8682
- },
8683
- "peerDependencies": {
8684
- "@types/react": "*",
8685
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
8686
- },
8687
- "peerDependenciesMeta": {
8688
- "@types/react": {
8689
- "optional": true
8690
- }
8691
- }
8692
- },
8693
- "node_modules/read-cache": {
8694
- "version": "1.0.0",
8695
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
8696
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
8697
- "dev": true,
8698
- "license": "MIT",
8699
- "dependencies": {
8700
- "pify": "^2.3.0"
8701
- }
8702
- },
8703
- "node_modules/readdirp": {
8704
- "version": "3.6.0",
8705
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
8706
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
8707
- "dev": true,
8708
- "license": "MIT",
8709
- "dependencies": {
8710
- "picomatch": "^2.2.1"
8711
- },
8712
- "engines": {
8713
- "node": ">=8.10.0"
8714
- }
8715
- },
8716
- "node_modules/regenerate": {
8717
- "version": "1.4.2",
8718
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
8719
- "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
8720
- "license": "MIT"
8721
- },
8722
- "node_modules/regenerate-unicode-properties": {
8723
- "version": "10.2.2",
8724
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz",
8725
- "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==",
8726
- "license": "MIT",
8727
- "dependencies": {
8728
- "regenerate": "^1.4.2"
8729
- },
8730
- "engines": {
8731
- "node": ">=4"
8732
- }
8733
- },
8734
- "node_modules/regenerator-runtime": {
8735
- "version": "0.13.11",
8736
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
8737
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
8738
- "license": "MIT"
8739
- },
8740
- "node_modules/regexpu-core": {
8741
- "version": "6.4.0",
8742
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz",
8743
- "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==",
8744
- "license": "MIT",
8745
- "dependencies": {
8746
- "regenerate": "^1.4.2",
8747
- "regenerate-unicode-properties": "^10.2.2",
8748
- "regjsgen": "^0.8.0",
8749
- "regjsparser": "^0.13.0",
8750
- "unicode-match-property-ecmascript": "^2.0.0",
8751
- "unicode-match-property-value-ecmascript": "^2.2.1"
8752
- },
8753
- "engines": {
8754
- "node": ">=4"
8755
- }
8756
- },
8757
- "node_modules/regjsgen": {
8758
- "version": "0.8.0",
8759
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
8760
- "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
8761
- "license": "MIT"
8762
- },
8763
- "node_modules/regjsparser": {
8764
- "version": "0.13.0",
8765
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz",
8766
- "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
8767
- "license": "BSD-2-Clause",
8768
- "dependencies": {
8769
- "jsesc": "~3.1.0"
8770
- },
8771
- "bin": {
8772
- "regjsparser": "bin/parser"
8773
- }
8774
- },
8775
- "node_modules/require-directory": {
8776
- "version": "2.1.1",
8777
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
8778
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
8779
- "license": "MIT",
8780
- "engines": {
8781
- "node": ">=0.10.0"
8782
- }
8783
- },
8784
- "node_modules/reselect": {
8785
- "version": "4.1.8",
8786
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
8787
- "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==",
8788
- "dev": true,
8789
- "license": "MIT"
8790
- },
8791
- "node_modules/resolve": {
8792
- "version": "1.22.11",
8793
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
8794
- "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
8795
- "license": "MIT",
8796
- "dependencies": {
8797
- "is-core-module": "^2.16.1",
8798
- "path-parse": "^1.0.7",
8799
- "supports-preserve-symlinks-flag": "^1.0.0"
8800
- },
8801
- "bin": {
8802
- "resolve": "bin/resolve"
8803
- },
8804
- "engines": {
8805
- "node": ">= 0.4"
8806
- },
8807
- "funding": {
8808
- "url": "https://github.com/sponsors/ljharb"
8809
- }
8810
- },
8811
- "node_modules/resolve-from": {
8812
- "version": "5.0.0",
8813
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
8814
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
8815
- "license": "MIT",
8816
- "engines": {
8817
- "node": ">=8"
8818
- }
8819
- },
8820
- "node_modules/resolve-workspace-root": {
8821
- "version": "2.0.1",
8822
- "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.1.tgz",
8823
- "integrity": "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==",
8824
- "license": "MIT"
8825
- },
8826
- "node_modules/restore-cursor": {
8827
- "version": "2.0.0",
8828
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
8829
- "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
8830
- "license": "MIT",
8831
- "dependencies": {
8832
- "onetime": "^2.0.0",
8833
- "signal-exit": "^3.0.2"
8834
- },
8835
- "engines": {
8836
- "node": ">=4"
8837
- }
8838
- },
8839
- "node_modules/reusify": {
8840
- "version": "1.1.0",
8841
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
8842
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
8843
- "dev": true,
8844
- "license": "MIT",
8845
- "engines": {
8846
- "iojs": ">=1.0.0",
8847
- "node": ">=0.10.0"
8848
- }
8849
- },
8850
- "node_modules/rimraf": {
8851
- "version": "3.0.2",
8852
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
8853
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
8854
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
8855
- "license": "ISC",
8856
- "dependencies": {
8857
- "glob": "^7.1.3"
8858
- },
8859
- "bin": {
8860
- "rimraf": "bin.js"
8861
- },
8862
- "funding": {
8863
- "url": "https://github.com/sponsors/isaacs"
8864
- }
8865
- },
8866
- "node_modules/rimraf/node_modules/balanced-match": {
8867
- "version": "1.0.2",
8868
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
8869
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
8870
- "license": "MIT"
8871
- },
8872
- "node_modules/rimraf/node_modules/brace-expansion": {
8873
- "version": "1.1.12",
8874
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
8875
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
8876
- "license": "MIT",
8877
- "dependencies": {
8878
- "balanced-match": "^1.0.0",
8879
- "concat-map": "0.0.1"
8880
- }
8881
- },
8882
- "node_modules/rimraf/node_modules/glob": {
8883
- "version": "7.2.3",
8884
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
8885
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
8886
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
8887
- "license": "ISC",
8888
- "dependencies": {
8889
- "fs.realpath": "^1.0.0",
8890
- "inflight": "^1.0.4",
8891
- "inherits": "2",
8892
- "minimatch": "^3.1.1",
8893
- "once": "^1.3.0",
8894
- "path-is-absolute": "^1.0.0"
8895
- },
8896
- "engines": {
8897
- "node": "*"
8898
- },
8899
- "funding": {
8900
- "url": "https://github.com/sponsors/isaacs"
8901
- }
8902
- },
8903
- "node_modules/rimraf/node_modules/minimatch": {
8904
- "version": "3.1.5",
8905
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
8906
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
8907
- "license": "ISC",
8908
- "dependencies": {
8909
- "brace-expansion": "^1.1.7"
8910
- },
8911
- "engines": {
8912
- "node": "*"
8913
- }
8914
- },
8915
- "node_modules/run-parallel": {
8916
- "version": "1.2.0",
8917
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
8918
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
8919
- "dev": true,
8920
- "funding": [
8921
- {
8922
- "type": "github",
8923
- "url": "https://github.com/sponsors/feross"
8924
- },
8925
- {
8926
- "type": "patreon",
8927
- "url": "https://www.patreon.com/feross"
8928
- },
8929
- {
8930
- "type": "consulting",
8931
- "url": "https://feross.org/support"
8932
- }
8933
- ],
8934
- "license": "MIT",
8935
- "dependencies": {
8936
- "queue-microtask": "^1.2.2"
8937
- }
8938
- },
8939
- "node_modules/safe-buffer": {
8940
- "version": "5.2.1",
8941
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
8942
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
8943
- "funding": [
8944
- {
8945
- "type": "github",
8946
- "url": "https://github.com/sponsors/feross"
8947
- },
8948
- {
8949
- "type": "patreon",
8950
- "url": "https://www.patreon.com/feross"
8951
- },
8952
- {
8953
- "type": "consulting",
8954
- "url": "https://feross.org/support"
8955
- }
8956
- ],
8957
- "license": "MIT"
8958
- },
8959
- "node_modules/sax": {
8960
- "version": "1.5.0",
8961
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
8962
- "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==",
8963
- "license": "BlueOak-1.0.0",
8964
- "engines": {
8965
- "node": ">=11.0.0"
8966
- }
8967
- },
8968
- "node_modules/scheduler": {
8969
- "version": "0.27.0",
8970
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
8971
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
8972
- "license": "MIT"
8973
- },
8974
- "node_modules/semver": {
8975
- "version": "7.7.4",
8976
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
8977
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
8978
- "license": "ISC",
8979
- "bin": {
8980
- "semver": "bin/semver.js"
8981
- },
8982
- "engines": {
8983
- "node": ">=10"
8984
- }
8985
- },
8986
- "node_modules/send": {
8987
- "version": "0.19.2",
8988
- "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz",
8989
- "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
8990
- "license": "MIT",
8991
- "dependencies": {
8992
- "debug": "2.6.9",
8993
- "depd": "2.0.0",
8994
- "destroy": "1.2.0",
8995
- "encodeurl": "~2.0.0",
8996
- "escape-html": "~1.0.3",
8997
- "etag": "~1.8.1",
8998
- "fresh": "~0.5.2",
8999
- "http-errors": "~2.0.1",
9000
- "mime": "1.6.0",
9001
- "ms": "2.1.3",
9002
- "on-finished": "~2.4.1",
9003
- "range-parser": "~1.2.1",
9004
- "statuses": "~2.0.2"
9005
- },
9006
- "engines": {
9007
- "node": ">= 0.8.0"
9008
- }
9009
- },
9010
- "node_modules/send/node_modules/debug": {
9011
- "version": "2.6.9",
9012
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
9013
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
9014
- "license": "MIT",
9015
- "dependencies": {
9016
- "ms": "2.0.0"
9017
- }
9018
- },
9019
- "node_modules/send/node_modules/debug/node_modules/ms": {
9020
- "version": "2.0.0",
9021
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
9022
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
9023
- "license": "MIT"
9024
- },
9025
- "node_modules/send/node_modules/encodeurl": {
9026
- "version": "2.0.0",
9027
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
9028
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
9029
- "license": "MIT",
9030
- "engines": {
9031
- "node": ">= 0.8"
9032
- }
9033
- },
9034
- "node_modules/send/node_modules/on-finished": {
9035
- "version": "2.4.1",
9036
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
9037
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
9038
- "license": "MIT",
9039
- "dependencies": {
9040
- "ee-first": "1.1.1"
9041
- },
9042
- "engines": {
9043
- "node": ">= 0.8"
9044
- }
9045
- },
9046
- "node_modules/send/node_modules/statuses": {
9047
- "version": "2.0.2",
9048
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
9049
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
9050
- "license": "MIT",
9051
- "engines": {
9052
- "node": ">= 0.8"
9053
- }
9054
- },
9055
- "node_modules/serialize-error": {
9056
- "version": "2.1.0",
9057
- "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
9058
- "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==",
9059
- "license": "MIT",
9060
- "engines": {
9061
- "node": ">=0.10.0"
9062
- }
9063
- },
9064
- "node_modules/serve-static": {
9065
- "version": "1.16.3",
9066
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
9067
- "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
9068
- "license": "MIT",
9069
- "dependencies": {
9070
- "encodeurl": "~2.0.0",
9071
- "escape-html": "~1.0.3",
9072
- "parseurl": "~1.3.3",
9073
- "send": "~0.19.1"
9074
- },
9075
- "engines": {
9076
- "node": ">= 0.8.0"
9077
- }
9078
- },
9079
- "node_modules/serve-static/node_modules/encodeurl": {
9080
- "version": "2.0.0",
9081
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
9082
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
9083
- "license": "MIT",
9084
- "engines": {
9085
- "node": ">= 0.8"
9086
- }
9087
- },
9088
- "node_modules/server-only": {
9089
- "version": "0.0.1",
9090
- "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
9091
- "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
9092
- "license": "MIT"
9093
- },
9094
- "node_modules/setimmediate": {
9095
- "version": "1.0.5",
9096
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
9097
- "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
9098
- "license": "MIT"
9099
- },
9100
- "node_modules/setprototypeof": {
9101
- "version": "1.2.0",
9102
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
9103
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
9104
- "license": "ISC"
9105
- },
9106
- "node_modules/sf-symbols-typescript": {
9107
- "version": "2.2.0",
9108
- "resolved": "https://registry.npmjs.org/sf-symbols-typescript/-/sf-symbols-typescript-2.2.0.tgz",
9109
- "integrity": "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw==",
9110
- "license": "MIT",
9111
- "engines": {
9112
- "node": ">=10"
9113
- }
9114
- },
9115
- "node_modules/shallowequal": {
9116
- "version": "1.1.0",
9117
- "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
9118
- "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
9119
- "license": "MIT"
9120
- },
9121
- "node_modules/shebang-command": {
9122
- "version": "2.0.0",
9123
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
9124
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
9125
- "license": "MIT",
9126
- "dependencies": {
9127
- "shebang-regex": "^3.0.0"
9128
- },
9129
- "engines": {
9130
- "node": ">=8"
9131
- }
9132
- },
9133
- "node_modules/shebang-regex": {
9134
- "version": "3.0.0",
9135
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
9136
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
9137
- "license": "MIT",
9138
- "engines": {
9139
- "node": ">=8"
9140
- }
9141
- },
9142
- "node_modules/shell-quote": {
9143
- "version": "1.8.3",
9144
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
9145
- "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
9146
- "license": "MIT",
9147
- "engines": {
9148
- "node": ">= 0.4"
9149
- },
9150
- "funding": {
9151
- "url": "https://github.com/sponsors/ljharb"
9152
- }
9153
- },
9154
- "node_modules/signal-exit": {
9155
- "version": "3.0.7",
9156
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
9157
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
9158
- "license": "ISC"
9159
- },
9160
- "node_modules/simple-plist": {
9161
- "version": "1.3.1",
9162
- "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz",
9163
- "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==",
9164
- "license": "MIT",
9165
- "dependencies": {
9166
- "bplist-creator": "0.1.0",
9167
- "bplist-parser": "0.3.1",
9168
- "plist": "^3.0.5"
9169
- }
9170
- },
9171
- "node_modules/simple-swizzle": {
9172
- "version": "0.2.4",
9173
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
9174
- "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
9175
- "license": "MIT",
9176
- "dependencies": {
9177
- "is-arrayish": "^0.3.1"
9178
- }
9179
- },
9180
- "node_modules/sisteransi": {
9181
- "version": "1.0.5",
9182
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
9183
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
9184
- "license": "MIT"
9185
- },
9186
- "node_modules/slash": {
9187
- "version": "3.0.0",
9188
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
9189
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
9190
- "license": "MIT",
9191
- "engines": {
9192
- "node": ">=8"
9193
- }
9194
- },
9195
- "node_modules/slugify": {
9196
- "version": "1.6.6",
9197
- "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
9198
- "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
9199
- "license": "MIT",
9200
- "engines": {
9201
- "node": ">=8.0.0"
9202
- }
9203
- },
9204
- "node_modules/source-map": {
9205
- "version": "0.5.7",
9206
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
9207
- "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
9208
- "license": "BSD-3-Clause",
9209
- "engines": {
9210
- "node": ">=0.10.0"
9211
- }
9212
- },
9213
- "node_modules/source-map-js": {
9214
- "version": "1.2.1",
9215
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
9216
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
9217
- "license": "BSD-3-Clause",
9218
- "engines": {
9219
- "node": ">=0.10.0"
9220
- }
9221
- },
9222
- "node_modules/source-map-support": {
9223
- "version": "0.5.21",
9224
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
9225
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
9226
- "license": "MIT",
9227
- "dependencies": {
9228
- "buffer-from": "^1.0.0",
9229
- "source-map": "^0.6.0"
9230
- }
9231
- },
9232
- "node_modules/source-map-support/node_modules/source-map": {
9233
- "version": "0.6.1",
9234
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
9235
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
9236
- "license": "BSD-3-Clause",
9237
- "engines": {
9238
- "node": ">=0.10.0"
9239
- }
9240
- },
9241
- "node_modules/split-on-first": {
9242
- "version": "1.1.0",
9243
- "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
9244
- "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
9245
- "license": "MIT",
9246
- "engines": {
9247
- "node": ">=6"
9248
- }
9249
- },
9250
- "node_modules/sprintf-js": {
9251
- "version": "1.0.3",
9252
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
9253
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
9254
- "license": "BSD-3-Clause"
9255
- },
9256
- "node_modules/stack-utils": {
9257
- "version": "2.0.6",
9258
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
9259
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
9260
- "license": "MIT",
9261
- "dependencies": {
9262
- "escape-string-regexp": "^2.0.0"
9263
- },
9264
- "engines": {
9265
- "node": ">=10"
9266
- }
9267
- },
9268
- "node_modules/stack-utils/node_modules/escape-string-regexp": {
9269
- "version": "2.0.0",
9270
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
9271
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
9272
- "license": "MIT",
9273
- "engines": {
9274
- "node": ">=8"
9275
- }
9276
- },
9277
- "node_modules/stackframe": {
9278
- "version": "1.3.4",
9279
- "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
9280
- "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
9281
- "license": "MIT"
9282
- },
9283
- "node_modules/stacktrace-parser": {
9284
- "version": "0.1.11",
9285
- "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz",
9286
- "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==",
9287
- "license": "MIT",
9288
- "dependencies": {
9289
- "type-fest": "^0.7.1"
9290
- },
9291
- "engines": {
9292
- "node": ">=6"
9293
- }
9294
- },
9295
- "node_modules/statuses": {
9296
- "version": "1.5.0",
9297
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
9298
- "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
9299
- "license": "MIT",
9300
- "engines": {
9301
- "node": ">= 0.6"
9302
- }
9303
- },
9304
- "node_modules/stream-buffers": {
9305
- "version": "2.2.0",
9306
- "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
9307
- "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==",
9308
- "license": "Unlicense",
9309
- "engines": {
9310
- "node": ">= 0.10.0"
9311
- }
9312
- },
9313
- "node_modules/strict-uri-encode": {
9314
- "version": "2.0.0",
9315
- "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
9316
- "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
9317
- "license": "MIT",
9318
- "engines": {
9319
- "node": ">=4"
9320
- }
9321
- },
9322
- "node_modules/string-width": {
9323
- "version": "4.2.3",
9324
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
9325
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
9326
- "license": "MIT",
9327
- "dependencies": {
9328
- "emoji-regex": "^8.0.0",
9329
- "is-fullwidth-code-point": "^3.0.0",
9330
- "strip-ansi": "^6.0.1"
9331
- },
9332
- "engines": {
9333
- "node": ">=8"
9334
- }
9335
- },
9336
- "node_modules/strip-ansi": {
9337
- "version": "6.0.1",
9338
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
9339
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
9340
- "license": "MIT",
9341
- "dependencies": {
9342
- "ansi-regex": "^5.0.1"
9343
- },
9344
- "engines": {
9345
- "node": ">=8"
9346
- }
9347
- },
9348
- "node_modules/structured-headers": {
9349
- "version": "0.4.1",
9350
- "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz",
9351
- "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==",
9352
- "license": "MIT"
9353
- },
9354
- "node_modules/styleq": {
9355
- "version": "0.1.3",
9356
- "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz",
9357
- "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==",
9358
- "license": "MIT"
9359
- },
9360
- "node_modules/sucrase": {
9361
- "version": "3.35.1",
9362
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
9363
- "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
9364
- "dev": true,
9365
- "license": "MIT",
9366
- "dependencies": {
9367
- "@jridgewell/gen-mapping": "^0.3.2",
9368
- "commander": "^4.0.0",
9369
- "lines-and-columns": "^1.1.6",
9370
- "mz": "^2.7.0",
9371
- "pirates": "^4.0.1",
9372
- "tinyglobby": "^0.2.11",
9373
- "ts-interface-checker": "^0.1.9"
9374
- },
9375
- "bin": {
9376
- "sucrase": "bin/sucrase",
9377
- "sucrase-node": "bin/sucrase-node"
9378
- },
9379
- "engines": {
9380
- "node": ">=16 || 14 >=14.17"
9381
- }
9382
- },
9383
- "node_modules/sucrase/node_modules/commander": {
9384
- "version": "4.1.1",
9385
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
9386
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
9387
- "dev": true,
9388
- "license": "MIT",
9389
- "engines": {
9390
- "node": ">= 6"
9391
- }
9392
- },
9393
- "node_modules/supports-color": {
9394
- "version": "7.2.0",
9395
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
9396
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
9397
- "license": "MIT",
9398
- "dependencies": {
9399
- "has-flag": "^4.0.0"
9400
- },
9401
- "engines": {
9402
- "node": ">=8"
9403
- }
9404
- },
9405
- "node_modules/supports-hyperlinks": {
9406
- "version": "2.3.0",
9407
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
9408
- "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
9409
- "license": "MIT",
9410
- "dependencies": {
9411
- "has-flag": "^4.0.0",
9412
- "supports-color": "^7.0.0"
9413
- },
9414
- "engines": {
9415
- "node": ">=8"
9416
- }
9417
- },
9418
- "node_modules/supports-preserve-symlinks-flag": {
9419
- "version": "1.0.0",
9420
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
9421
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
9422
- "license": "MIT",
9423
- "engines": {
9424
- "node": ">= 0.4"
9425
- },
9426
- "funding": {
9427
- "url": "https://github.com/sponsors/ljharb"
9428
- }
9429
- },
9430
- "node_modules/tailwindcss": {
9431
- "version": "3.4.19",
9432
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
9433
- "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
9434
- "dev": true,
9435
- "license": "MIT",
9436
- "dependencies": {
9437
- "@alloc/quick-lru": "^5.2.0",
9438
- "arg": "^5.0.2",
9439
- "chokidar": "^3.6.0",
9440
- "didyoumean": "^1.2.2",
9441
- "dlv": "^1.1.3",
9442
- "fast-glob": "^3.3.2",
9443
- "glob-parent": "^6.0.2",
9444
- "is-glob": "^4.0.3",
9445
- "jiti": "^1.21.7",
9446
- "lilconfig": "^3.1.3",
9447
- "micromatch": "^4.0.8",
9448
- "normalize-path": "^3.0.0",
9449
- "object-hash": "^3.0.0",
9450
- "picocolors": "^1.1.1",
9451
- "postcss": "^8.4.47",
9452
- "postcss-import": "^15.1.0",
9453
- "postcss-js": "^4.0.1",
9454
- "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
9455
- "postcss-nested": "^6.2.0",
9456
- "postcss-selector-parser": "^6.1.2",
9457
- "resolve": "^1.22.8",
9458
- "sucrase": "^3.35.0"
9459
- },
9460
- "bin": {
9461
- "tailwind": "lib/cli.js",
9462
- "tailwindcss": "lib/cli.js"
9463
- },
9464
- "engines": {
9465
- "node": ">=14.0.0"
9466
- }
9467
- },
9468
- "node_modules/terminal-link": {
9469
- "version": "2.1.1",
9470
- "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
9471
- "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
9472
- "license": "MIT",
9473
- "dependencies": {
9474
- "ansi-escapes": "^4.2.1",
9475
- "supports-hyperlinks": "^2.0.0"
9476
- },
9477
- "engines": {
9478
- "node": ">=8"
9479
- },
9480
- "funding": {
9481
- "url": "https://github.com/sponsors/sindresorhus"
9482
- }
9483
- },
9484
- "node_modules/terser": {
9485
- "version": "5.46.0",
9486
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
9487
- "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
9488
- "license": "BSD-2-Clause",
9489
- "dependencies": {
9490
- "@jridgewell/source-map": "^0.3.3",
9491
- "acorn": "^8.15.0",
9492
- "commander": "^2.20.0",
9493
- "source-map-support": "~0.5.20"
9494
- },
9495
- "bin": {
9496
- "terser": "bin/terser"
9497
- },
9498
- "engines": {
9499
- "node": ">=10"
9500
- }
9501
- },
9502
- "node_modules/terser/node_modules/commander": {
9503
- "version": "2.20.3",
9504
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
9505
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
9506
- "license": "MIT"
9507
- },
9508
- "node_modules/test-exclude": {
9509
- "version": "6.0.0",
9510
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
9511
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
9512
- "license": "ISC",
9513
- "dependencies": {
9514
- "@istanbuljs/schema": "^0.1.2",
9515
- "glob": "^7.1.4",
9516
- "minimatch": "^3.0.4"
9517
- },
9518
- "engines": {
9519
- "node": ">=8"
9520
- }
9521
- },
9522
- "node_modules/test-exclude/node_modules/balanced-match": {
9523
- "version": "1.0.2",
9524
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
9525
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
9526
- "license": "MIT"
9527
- },
9528
- "node_modules/test-exclude/node_modules/brace-expansion": {
9529
- "version": "1.1.12",
9530
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
9531
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
9532
- "license": "MIT",
9533
- "dependencies": {
9534
- "balanced-match": "^1.0.0",
9535
- "concat-map": "0.0.1"
9536
- }
9537
- },
9538
- "node_modules/test-exclude/node_modules/glob": {
9539
- "version": "7.2.3",
9540
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
9541
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
9542
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
9543
- "license": "ISC",
9544
- "dependencies": {
9545
- "fs.realpath": "^1.0.0",
9546
- "inflight": "^1.0.4",
9547
- "inherits": "2",
9548
- "minimatch": "^3.1.1",
9549
- "once": "^1.3.0",
9550
- "path-is-absolute": "^1.0.0"
9551
- },
9552
- "engines": {
9553
- "node": "*"
9554
- },
9555
- "funding": {
9556
- "url": "https://github.com/sponsors/isaacs"
9557
- }
9558
- },
9559
- "node_modules/test-exclude/node_modules/minimatch": {
9560
- "version": "3.1.5",
9561
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
9562
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
9563
- "license": "ISC",
9564
- "dependencies": {
9565
- "brace-expansion": "^1.1.7"
9566
- },
9567
- "engines": {
9568
- "node": "*"
9569
- }
9570
- },
9571
- "node_modules/thenify": {
9572
- "version": "3.3.1",
9573
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
9574
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
9575
- "dev": true,
9576
- "license": "MIT",
9577
- "dependencies": {
9578
- "any-promise": "^1.0.0"
9579
- }
9580
- },
9581
- "node_modules/thenify-all": {
9582
- "version": "1.6.0",
9583
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
9584
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
9585
- "dev": true,
9586
- "license": "MIT",
9587
- "dependencies": {
9588
- "thenify": ">= 3.1.0 < 4"
9589
- },
9590
- "engines": {
9591
- "node": ">=0.8"
9592
- }
9593
- },
9594
- "node_modules/throat": {
9595
- "version": "5.0.0",
9596
- "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
9597
- "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
9598
- "license": "MIT"
9599
- },
9600
- "node_modules/tinyglobby": {
9601
- "version": "0.2.15",
9602
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
9603
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
9604
- "dev": true,
9605
- "license": "MIT",
9606
- "dependencies": {
9607
- "fdir": "^6.5.0",
9608
- "picomatch": "^4.0.3"
9609
- },
9610
- "engines": {
9611
- "node": ">=12.0.0"
9612
- },
9613
- "funding": {
9614
- "url": "https://github.com/sponsors/SuperchupuDev"
9615
- }
9616
- },
9617
- "node_modules/tinyglobby/node_modules/fdir": {
9618
- "version": "6.5.0",
9619
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
9620
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
9621
- "dev": true,
9622
- "license": "MIT",
9623
- "engines": {
9624
- "node": ">=12.0.0"
9625
- },
9626
- "peerDependencies": {
9627
- "picomatch": "^3 || ^4"
9628
- },
9629
- "peerDependenciesMeta": {
9630
- "picomatch": {
9631
- "optional": true
9632
- }
9633
- }
9634
- },
9635
- "node_modules/tinyglobby/node_modules/picomatch": {
9636
- "version": "4.0.3",
9637
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
9638
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
9639
- "dev": true,
9640
- "license": "MIT",
9641
- "engines": {
9642
- "node": ">=12"
9643
- },
9644
- "funding": {
9645
- "url": "https://github.com/sponsors/jonschlinkert"
9646
- }
9647
- },
9648
- "node_modules/tmpl": {
9649
- "version": "1.0.5",
9650
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
9651
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
9652
- "license": "BSD-3-Clause"
9653
- },
9654
- "node_modules/to-regex-range": {
9655
- "version": "5.0.1",
9656
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
9657
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
9658
- "license": "MIT",
9659
- "dependencies": {
9660
- "is-number": "^7.0.0"
9661
- },
9662
- "engines": {
9663
- "node": ">=8.0"
9664
- }
9665
- },
9666
- "node_modules/toidentifier": {
9667
- "version": "1.0.1",
9668
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
9669
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
9670
- "license": "MIT",
9671
- "engines": {
9672
- "node": ">=0.6"
9673
- }
9674
- },
9675
- "node_modules/toqr": {
9676
- "version": "0.1.1",
9677
- "resolved": "https://registry.npmjs.org/toqr/-/toqr-0.1.1.tgz",
9678
- "integrity": "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA==",
9679
- "license": "MIT"
9680
- },
9681
- "node_modules/tr46": {
9682
- "version": "0.0.3",
9683
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
9684
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
9685
- "license": "MIT"
9686
- },
9687
- "node_modules/ts-interface-checker": {
9688
- "version": "0.1.13",
9689
- "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
9690
- "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
9691
- "dev": true,
9692
- "license": "Apache-2.0"
9693
- },
9694
- "node_modules/tslib": {
9695
- "version": "2.8.1",
9696
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
9697
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
9698
- "license": "0BSD"
9699
- },
9700
- "node_modules/type-detect": {
9701
- "version": "4.0.8",
9702
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
9703
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
9704
- "license": "MIT",
9705
- "engines": {
9706
- "node": ">=4"
9707
- }
9708
- },
9709
- "node_modules/type-fest": {
9710
- "version": "0.7.1",
9711
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
9712
- "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
9713
- "license": "(MIT OR CC0-1.0)",
9714
- "engines": {
9715
- "node": ">=8"
9716
- }
9717
- },
9718
- "node_modules/typescript": {
9719
- "version": "5.9.3",
9720
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
9721
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
9722
- "dev": true,
9723
- "license": "Apache-2.0",
9724
- "bin": {
9725
- "tsc": "bin/tsc",
9726
- "tsserver": "bin/tsserver"
9727
- },
9728
- "engines": {
9729
- "node": ">=14.17"
9730
- }
9731
- },
9732
- "node_modules/ua-parser-js": {
9733
- "version": "1.0.41",
9734
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz",
9735
- "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==",
9736
- "funding": [
9737
- {
9738
- "type": "opencollective",
9739
- "url": "https://opencollective.com/ua-parser-js"
9740
- },
9741
- {
9742
- "type": "paypal",
9743
- "url": "https://paypal.me/faisalman"
9744
- },
9745
- {
9746
- "type": "github",
9747
- "url": "https://github.com/sponsors/faisalman"
9748
- }
9749
- ],
9750
- "license": "MIT",
9751
- "bin": {
9752
- "ua-parser-js": "script/cli.js"
9753
- },
9754
- "engines": {
9755
- "node": "*"
9756
- }
9757
- },
9758
- "node_modules/undici-types": {
9759
- "version": "7.18.2",
9760
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
9761
- "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
9762
- "license": "MIT"
9763
- },
9764
- "node_modules/unicode-canonical-property-names-ecmascript": {
9765
- "version": "2.0.1",
9766
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
9767
- "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
9768
- "license": "MIT",
9769
- "engines": {
9770
- "node": ">=4"
9771
- }
9772
- },
9773
- "node_modules/unicode-match-property-ecmascript": {
9774
- "version": "2.0.0",
9775
- "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
9776
- "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
9777
- "license": "MIT",
9778
- "dependencies": {
9779
- "unicode-canonical-property-names-ecmascript": "^2.0.0",
9780
- "unicode-property-aliases-ecmascript": "^2.0.0"
9781
- },
9782
- "engines": {
9783
- "node": ">=4"
9784
- }
9785
- },
9786
- "node_modules/unicode-match-property-value-ecmascript": {
9787
- "version": "2.2.1",
9788
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
9789
- "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
9790
- "license": "MIT",
9791
- "engines": {
9792
- "node": ">=4"
9793
- }
9794
- },
9795
- "node_modules/unicode-property-aliases-ecmascript": {
9796
- "version": "2.2.0",
9797
- "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz",
9798
- "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==",
9799
- "license": "MIT",
9800
- "engines": {
9801
- "node": ">=4"
9802
- }
9803
- },
9804
- "node_modules/unpipe": {
9805
- "version": "1.0.0",
9806
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
9807
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
9808
- "license": "MIT",
9809
- "engines": {
9810
- "node": ">= 0.8"
9811
- }
9812
- },
9813
- "node_modules/update-browserslist-db": {
9814
- "version": "1.2.3",
9815
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
9816
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
9817
- "funding": [
9818
- {
9819
- "type": "opencollective",
9820
- "url": "https://opencollective.com/browserslist"
9821
- },
9822
- {
9823
- "type": "tidelift",
9824
- "url": "https://tidelift.com/funding/github/npm/browserslist"
9825
- },
9826
- {
9827
- "type": "github",
9828
- "url": "https://github.com/sponsors/ai"
9829
- }
9830
- ],
9831
- "license": "MIT",
9832
- "dependencies": {
9833
- "escalade": "^3.2.0",
9834
- "picocolors": "^1.1.1"
9835
- },
9836
- "bin": {
9837
- "update-browserslist-db": "cli.js"
9838
- },
9839
- "peerDependencies": {
9840
- "browserslist": ">= 4.21.0"
9841
- }
9842
- },
9843
- "node_modules/use-callback-ref": {
9844
- "version": "1.3.3",
9845
- "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
9846
- "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
9847
- "license": "MIT",
9848
- "dependencies": {
9849
- "tslib": "^2.0.0"
9850
- },
9851
- "engines": {
9852
- "node": ">=10"
9853
- },
9854
- "peerDependencies": {
9855
- "@types/react": "*",
9856
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
9857
- },
9858
- "peerDependenciesMeta": {
9859
- "@types/react": {
9860
- "optional": true
9861
- }
9862
- }
9863
- },
9864
- "node_modules/use-latest-callback": {
9865
- "version": "0.2.6",
9866
- "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.6.tgz",
9867
- "integrity": "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==",
9868
- "license": "MIT",
9869
- "peerDependencies": {
9870
- "react": ">=16.8"
9871
- }
9872
- },
9873
- "node_modules/use-sidecar": {
9874
- "version": "1.1.3",
9875
- "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
9876
- "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
9877
- "license": "MIT",
9878
- "dependencies": {
9879
- "detect-node-es": "^1.1.0",
9880
- "tslib": "^2.0.0"
9881
- },
9882
- "engines": {
9883
- "node": ">=10"
9884
- },
9885
- "peerDependencies": {
9886
- "@types/react": "*",
9887
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
9888
- },
9889
- "peerDependenciesMeta": {
9890
- "@types/react": {
9891
- "optional": true
9892
- }
9893
- }
9894
- },
9895
- "node_modules/use-sync-external-store": {
9896
- "version": "1.6.0",
9897
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
9898
- "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
9899
- "license": "MIT",
9900
- "peerDependencies": {
9901
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
9902
- }
9903
- },
9904
- "node_modules/util-deprecate": {
9905
- "version": "1.0.2",
9906
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
9907
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
9908
- "dev": true,
9909
- "license": "MIT"
9910
- },
9911
- "node_modules/utils-merge": {
9912
- "version": "1.0.1",
9913
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
9914
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
9915
- "license": "MIT",
9916
- "engines": {
9917
- "node": ">= 0.4.0"
9918
- }
9919
- },
9920
- "node_modules/uuid": {
9921
- "version": "7.0.3",
9922
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
9923
- "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
9924
- "license": "MIT",
9925
- "bin": {
9926
- "uuid": "dist/bin/uuid"
9927
- }
9928
- },
9929
- "node_modules/validate-npm-package-name": {
9930
- "version": "5.0.1",
9931
- "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz",
9932
- "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==",
9933
- "license": "ISC",
9934
- "engines": {
9935
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
9936
- }
9937
- },
9938
- "node_modules/vary": {
9939
- "version": "1.1.2",
9940
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
9941
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
9942
- "license": "MIT",
9943
- "engines": {
9944
- "node": ">= 0.8"
9945
- }
9946
- },
9947
- "node_modules/vaul": {
9948
- "version": "1.1.2",
9949
- "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz",
9950
- "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==",
9951
- "license": "MIT",
9952
- "dependencies": {
9953
- "@radix-ui/react-dialog": "^1.1.1"
9954
- },
9955
- "peerDependencies": {
9956
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
9957
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
9958
- }
9959
- },
9960
- "node_modules/vlq": {
9961
- "version": "1.0.1",
9962
- "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
9963
- "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
9964
- "license": "MIT"
9965
- },
9966
- "node_modules/walker": {
9967
- "version": "1.0.8",
9968
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
9969
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
9970
- "license": "Apache-2.0",
9971
- "dependencies": {
9972
- "makeerror": "1.0.12"
9973
- }
9974
- },
9975
- "node_modules/warn-once": {
9976
- "version": "0.1.1",
9977
- "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz",
9978
- "integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==",
9979
- "license": "MIT"
9980
- },
9981
- "node_modules/wcwidth": {
9982
- "version": "1.0.1",
9983
- "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
9984
- "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
9985
- "license": "MIT",
9986
- "dependencies": {
9987
- "defaults": "^1.0.3"
9988
- }
9989
- },
9990
- "node_modules/webidl-conversions": {
9991
- "version": "3.0.1",
9992
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
9993
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
9994
- "license": "BSD-2-Clause"
9995
- },
9996
- "node_modules/whatwg-fetch": {
9997
- "version": "3.6.20",
9998
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
9999
- "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==",
10000
- "license": "MIT"
10001
- },
10002
- "node_modules/whatwg-url": {
10003
- "version": "5.0.0",
10004
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
10005
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
10006
- "license": "MIT",
10007
- "dependencies": {
10008
- "tr46": "~0.0.3",
10009
- "webidl-conversions": "^3.0.0"
10010
- }
10011
- },
10012
- "node_modules/whatwg-url-minimum": {
10013
- "version": "0.1.1",
10014
- "resolved": "https://registry.npmjs.org/whatwg-url-minimum/-/whatwg-url-minimum-0.1.1.tgz",
10015
- "integrity": "sha512-u2FNVjFVFZhdjb502KzXy1gKn1mEisQRJssmSJT8CPhZdZa0AP6VCbWlXERKyGu0l09t0k50FiDiralpGhBxgA==",
10016
- "license": "MIT"
10017
- },
10018
- "node_modules/which": {
10019
- "version": "2.0.2",
10020
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
10021
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
10022
- "license": "ISC",
10023
- "dependencies": {
10024
- "isexe": "^2.0.0"
10025
- },
10026
- "bin": {
10027
- "node-which": "bin/node-which"
10028
- },
10029
- "engines": {
10030
- "node": ">= 8"
10031
- }
10032
- },
10033
- "node_modules/wrap-ansi": {
10034
- "version": "7.0.0",
10035
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
10036
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
10037
- "license": "MIT",
10038
- "dependencies": {
10039
- "ansi-styles": "^4.0.0",
10040
- "string-width": "^4.1.0",
10041
- "strip-ansi": "^6.0.0"
10042
- },
10043
- "engines": {
10044
- "node": ">=10"
10045
- },
10046
- "funding": {
10047
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
10048
- }
10049
- },
10050
- "node_modules/wrappy": {
10051
- "version": "1.0.2",
10052
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
10053
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
10054
- "license": "ISC"
10055
- },
10056
- "node_modules/write-file-atomic": {
10057
- "version": "4.0.2",
10058
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
10059
- "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
10060
- "license": "ISC",
10061
- "dependencies": {
10062
- "imurmurhash": "^0.1.4",
10063
- "signal-exit": "^3.0.7"
10064
- },
10065
- "engines": {
10066
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
10067
- }
10068
- },
10069
- "node_modules/ws": {
10070
- "version": "7.5.10",
10071
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
10072
- "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
10073
- "license": "MIT",
10074
- "engines": {
10075
- "node": ">=8.3.0"
10076
- },
10077
- "peerDependencies": {
10078
- "bufferutil": "^4.0.1",
10079
- "utf-8-validate": "^5.0.2"
10080
- },
10081
- "peerDependenciesMeta": {
10082
- "bufferutil": {
10083
- "optional": true
10084
- },
10085
- "utf-8-validate": {
10086
- "optional": true
10087
- }
10088
- }
10089
- },
10090
- "node_modules/xcode": {
10091
- "version": "3.0.1",
10092
- "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
10093
- "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
10094
- "license": "Apache-2.0",
10095
- "dependencies": {
10096
- "simple-plist": "^1.1.0",
10097
- "uuid": "^7.0.3"
10098
- },
10099
- "engines": {
10100
- "node": ">=10.0.0"
10101
- }
10102
- },
10103
- "node_modules/xml2js": {
10104
- "version": "0.6.0",
10105
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz",
10106
- "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==",
10107
- "license": "MIT",
10108
- "dependencies": {
10109
- "sax": ">=0.6.0",
10110
- "xmlbuilder": "~11.0.0"
10111
- },
10112
- "engines": {
10113
- "node": ">=4.0.0"
10114
- }
10115
- },
10116
- "node_modules/xml2js/node_modules/xmlbuilder": {
10117
- "version": "11.0.1",
10118
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
10119
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
10120
- "license": "MIT",
10121
- "engines": {
10122
- "node": ">=4.0"
10123
- }
10124
- },
10125
- "node_modules/xmlbuilder": {
10126
- "version": "15.1.1",
10127
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
10128
- "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
10129
- "license": "MIT",
10130
- "engines": {
10131
- "node": ">=8.0"
10132
- }
10133
- },
10134
- "node_modules/y18n": {
10135
- "version": "5.0.8",
10136
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
10137
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
10138
- "license": "ISC",
10139
- "engines": {
10140
- "node": ">=10"
10141
- }
10142
- },
10143
- "node_modules/yallist": {
10144
- "version": "3.1.1",
10145
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
10146
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
10147
- "license": "ISC"
10148
- },
10149
- "node_modules/yaml": {
10150
- "version": "2.8.2",
10151
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
10152
- "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
10153
- "license": "ISC",
10154
- "bin": {
10155
- "yaml": "bin.mjs"
10156
- },
10157
- "engines": {
10158
- "node": ">= 14.6"
10159
- },
10160
- "funding": {
10161
- "url": "https://github.com/sponsors/eemeli"
10162
- }
10163
- },
10164
- "node_modules/yargs": {
10165
- "version": "17.7.2",
10166
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
10167
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
10168
- "license": "MIT",
10169
- "dependencies": {
10170
- "cliui": "^8.0.1",
10171
- "escalade": "^3.1.1",
10172
- "get-caller-file": "^2.0.5",
10173
- "require-directory": "^2.1.1",
10174
- "string-width": "^4.2.3",
10175
- "y18n": "^5.0.5",
10176
- "yargs-parser": "^21.1.1"
10177
- },
10178
- "engines": {
10179
- "node": ">=12"
10180
- }
10181
- },
10182
- "node_modules/yargs-parser": {
10183
- "version": "21.1.1",
10184
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
10185
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
10186
- "license": "ISC",
10187
- "engines": {
10188
- "node": ">=12"
10189
- }
10190
- },
10191
- "node_modules/zod": {
10192
- "version": "3.25.76",
10193
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
10194
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
10195
- "license": "MIT",
10196
- "funding": {
10197
- "url": "https://github.com/sponsors/colinhacks"
10198
- }
10199
- }
10200
- }
10201
-}
package.json
deleted file mode 100644
....@@ -1,51 +0,0 @@
1
-{
2
- "name": "pailot",
3
- "version": "1.0.0",
4
- "main": "expo-router/entry",
5
- "scripts": {
6
- "start": "expo start",
7
- "android": "expo run:android",
8
- "ios": "expo run:ios",
9
- "web": "expo start --web"
10
- },
11
- "dependencies": {
12
- "@react-navigation/bottom-tabs": "^7.15.3",
13
- "@react-navigation/native": "^7.1.31",
14
- "expo": "~55.0.4",
15
- "expo-audio": "^55.0.8",
16
- "expo-clipboard": "~55.0.8",
17
- "expo-constants": "~55.0.7",
18
- "expo-file-system": "~55.0.10",
19
- "expo-haptics": "~55.0.8",
20
- "expo-image-picker": "~55.0.11",
21
- "expo-linking": "~55.0.7",
22
- "expo-router": "~55.0.3",
23
- "expo-secure-store": "~55.0.8",
24
- "expo-sharing": "~55.0.11",
25
- "expo-splash-screen": "~55.0.10",
26
- "expo-status-bar": "~55.0.4",
27
- "expo-system-ui": "~55.0.9",
28
- "expo-web-browser": "~55.0.9",
29
- "nativewind": "^4",
30
- "react": "19.2.0",
31
- "react-dom": "^19.2.4",
32
- "react-native": "0.83.2",
33
- "react-native-draggable-flatlist": "^4.0.3",
34
- "react-native-gesture-handler": "~2.30.0",
35
- "react-native-reanimated": "4.2.1",
36
- "react-native-safe-area-context": "~5.6.2",
37
- "react-native-screens": "~4.23.0",
38
- "react-native-svg": "15.15.3",
39
- "react-native-udp": "^4.1.7",
40
- "react-native-web": "^0.21.0",
41
- "react-native-worklets": "0.7.2"
42
- },
43
- "devDependencies": {
44
- "@types/react": "~19.2.2",
45
- "babel-plugin-module-resolver": "^5.0.2",
46
- "babel-preset-expo": "^55.0.10",
47
- "tailwindcss": "^3.4.19",
48
- "typescript": "~5.9.2"
49
- },
50
- "private": true
51
-}
pubspec.lock
....@@ -0,0 +1,1218 @@
1
+# Generated by pub
2
+# See https://dart.dev/tools/pub/glossary#lockfile
3
+packages:
4
+ args:
5
+ dependency: transitive
6
+ description:
7
+ name: args
8
+ sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
9
+ url: "https://pub.dev"
10
+ source: hosted
11
+ version: "2.7.0"
12
+ async:
13
+ dependency: transitive
14
+ description:
15
+ name: async
16
+ sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
17
+ url: "https://pub.dev"
18
+ source: hosted
19
+ version: "2.13.0"
20
+ audioplayers:
21
+ dependency: "direct main"
22
+ description:
23
+ name: audioplayers
24
+ sha256: a72dd459d1a48f61a6fb9c0134dba26597c9236af40639ff0eb70eb4e0baab70
25
+ url: "https://pub.dev"
26
+ source: hosted
27
+ version: "6.6.0"
28
+ audioplayers_android:
29
+ dependency: transitive
30
+ description:
31
+ name: audioplayers_android
32
+ sha256: "60a6728277228413a85755bd3ffd6fab98f6555608923813ce383b190a360605"
33
+ url: "https://pub.dev"
34
+ source: hosted
35
+ version: "5.2.1"
36
+ audioplayers_darwin:
37
+ dependency: transitive
38
+ description:
39
+ name: audioplayers_darwin
40
+ sha256: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91
41
+ url: "https://pub.dev"
42
+ source: hosted
43
+ version: "6.4.0"
44
+ audioplayers_linux:
45
+ dependency: transitive
46
+ description:
47
+ name: audioplayers_linux
48
+ sha256: f75bce1ce864170ef5e6a2c6a61cd3339e1a17ce11e99a25bae4474ea491d001
49
+ url: "https://pub.dev"
50
+ source: hosted
51
+ version: "4.2.1"
52
+ audioplayers_platform_interface:
53
+ dependency: transitive
54
+ description:
55
+ name: audioplayers_platform_interface
56
+ sha256: "0e2f6a919ab56d0fec272e801abc07b26ae7f31980f912f24af4748763e5a656"
57
+ url: "https://pub.dev"
58
+ source: hosted
59
+ version: "7.1.1"
60
+ audioplayers_web:
61
+ dependency: transitive
62
+ description:
63
+ name: audioplayers_web
64
+ sha256: faa8fa6587f996a6f604433b53af44c57a1407d4fe8dff5766cf63d6875e8de9
65
+ url: "https://pub.dev"
66
+ source: hosted
67
+ version: "5.2.0"
68
+ audioplayers_windows:
69
+ dependency: transitive
70
+ description:
71
+ name: audioplayers_windows
72
+ sha256: bafff2b38b6f6d331887558ba6e0a01c9c208d9dbb3ad0005234db065122a734
73
+ url: "https://pub.dev"
74
+ source: hosted
75
+ version: "4.3.0"
76
+ bonsoir:
77
+ dependency: "direct main"
78
+ description:
79
+ name: bonsoir
80
+ sha256: "42f2c1eb55e833bcb541dfcb759851da0a703106646a0cf15a16c6de21f4a5a4"
81
+ url: "https://pub.dev"
82
+ source: hosted
83
+ version: "6.0.2"
84
+ bonsoir_android:
85
+ dependency: transitive
86
+ description:
87
+ name: bonsoir_android
88
+ sha256: e19728f94a0d9813abf9e2edf644fede008e58ef539865a1be86ac5d8994154e
89
+ url: "https://pub.dev"
90
+ source: hosted
91
+ version: "6.0.1"
92
+ bonsoir_darwin:
93
+ dependency: transitive
94
+ description:
95
+ name: bonsoir_darwin
96
+ sha256: e242a03a019fd474be657715826cfc13e43d02c88e46ec5611a20b9d4f72854d
97
+ url: "https://pub.dev"
98
+ source: hosted
99
+ version: "6.0.1"
100
+ bonsoir_linux:
101
+ dependency: transitive
102
+ description:
103
+ name: bonsoir_linux
104
+ sha256: "9c326c572c241c6a38ab7a8a5dba27c82917ec12504f84308ce3b5706619e8d3"
105
+ url: "https://pub.dev"
106
+ source: hosted
107
+ version: "6.0.2"
108
+ bonsoir_platform_interface:
109
+ dependency: transitive
110
+ description:
111
+ name: bonsoir_platform_interface
112
+ sha256: "3fa0c46b30eb2a2f48be6fa53591a5c0425bf00520be761b61763e58b51814ff"
113
+ url: "https://pub.dev"
114
+ source: hosted
115
+ version: "6.0.1"
116
+ bonsoir_windows:
117
+ dependency: transitive
118
+ description:
119
+ name: bonsoir_windows
120
+ sha256: "34c54802baaa2f00e3c4ab7ea46888f2a829876753778e2f40e3f273c3382d34"
121
+ url: "https://pub.dev"
122
+ source: hosted
123
+ version: "6.0.1"
124
+ boolean_selector:
125
+ dependency: transitive
126
+ description:
127
+ name: boolean_selector
128
+ sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
129
+ url: "https://pub.dev"
130
+ source: hosted
131
+ version: "2.1.2"
132
+ characters:
133
+ dependency: transitive
134
+ description:
135
+ name: characters
136
+ sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
137
+ url: "https://pub.dev"
138
+ source: hosted
139
+ version: "1.4.1"
140
+ clock:
141
+ dependency: transitive
142
+ description:
143
+ name: clock
144
+ sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
145
+ url: "https://pub.dev"
146
+ source: hosted
147
+ version: "1.1.2"
148
+ code_assets:
149
+ dependency: transitive
150
+ description:
151
+ name: code_assets
152
+ sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
153
+ url: "https://pub.dev"
154
+ source: hosted
155
+ version: "1.0.0"
156
+ collection:
157
+ dependency: "direct main"
158
+ description:
159
+ name: collection
160
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
161
+ url: "https://pub.dev"
162
+ source: hosted
163
+ version: "1.19.1"
164
+ connectivity_plus:
165
+ dependency: "direct main"
166
+ description:
167
+ name: connectivity_plus
168
+ sha256: b8fe52979ff12432ecf8f0abf6ff70410b1bb734be1c9e4f2f86807ad7166c79
169
+ url: "https://pub.dev"
170
+ source: hosted
171
+ version: "7.1.0"
172
+ connectivity_plus_platform_interface:
173
+ dependency: transitive
174
+ description:
175
+ name: connectivity_plus_platform_interface
176
+ sha256: "3c09627c536d22fd24691a905cdd8b14520de69da52c7a97499c8be5284a32ed"
177
+ url: "https://pub.dev"
178
+ source: hosted
179
+ version: "2.1.0"
180
+ cross_file:
181
+ dependency: transitive
182
+ description:
183
+ name: cross_file
184
+ sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937"
185
+ url: "https://pub.dev"
186
+ source: hosted
187
+ version: "0.3.5+2"
188
+ crypto:
189
+ dependency: "direct main"
190
+ description:
191
+ name: crypto
192
+ sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
193
+ url: "https://pub.dev"
194
+ source: hosted
195
+ version: "3.0.7"
196
+ cupertino_icons:
197
+ dependency: "direct main"
198
+ description:
199
+ name: cupertino_icons
200
+ sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
201
+ url: "https://pub.dev"
202
+ source: hosted
203
+ version: "1.0.8"
204
+ dbus:
205
+ dependency: transitive
206
+ description:
207
+ name: dbus
208
+ sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270
209
+ url: "https://pub.dev"
210
+ source: hosted
211
+ version: "0.7.12"
212
+ device_info_plus:
213
+ dependency: transitive
214
+ description:
215
+ name: device_info_plus
216
+ sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
217
+ url: "https://pub.dev"
218
+ source: hosted
219
+ version: "11.5.0"
220
+ device_info_plus_platform_interface:
221
+ dependency: transitive
222
+ description:
223
+ name: device_info_plus_platform_interface
224
+ sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
225
+ url: "https://pub.dev"
226
+ source: hosted
227
+ version: "7.0.3"
228
+ event_bus:
229
+ dependency: transitive
230
+ description:
231
+ name: event_bus
232
+ sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304"
233
+ url: "https://pub.dev"
234
+ source: hosted
235
+ version: "2.0.1"
236
+ fake_async:
237
+ dependency: transitive
238
+ description:
239
+ name: fake_async
240
+ sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
241
+ url: "https://pub.dev"
242
+ source: hosted
243
+ version: "1.3.3"
244
+ ffi:
245
+ dependency: transitive
246
+ description:
247
+ name: ffi
248
+ sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
249
+ url: "https://pub.dev"
250
+ source: hosted
251
+ version: "2.2.0"
252
+ file:
253
+ dependency: transitive
254
+ description:
255
+ name: file
256
+ sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
257
+ url: "https://pub.dev"
258
+ source: hosted
259
+ version: "7.0.1"
260
+ file_picker:
261
+ dependency: "direct main"
262
+ description:
263
+ name: file_picker
264
+ sha256: "57d9a1dd5063f85fa3107fb42d1faffda52fdc948cefd5fe5ea85267a5fc7343"
265
+ url: "https://pub.dev"
266
+ source: hosted
267
+ version: "10.3.10"
268
+ file_selector_linux:
269
+ dependency: transitive
270
+ description:
271
+ name: file_selector_linux
272
+ sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0"
273
+ url: "https://pub.dev"
274
+ source: hosted
275
+ version: "0.9.4"
276
+ file_selector_macos:
277
+ dependency: transitive
278
+ description:
279
+ name: file_selector_macos
280
+ sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a"
281
+ url: "https://pub.dev"
282
+ source: hosted
283
+ version: "0.9.5"
284
+ file_selector_platform_interface:
285
+ dependency: transitive
286
+ description:
287
+ name: file_selector_platform_interface
288
+ sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85"
289
+ url: "https://pub.dev"
290
+ source: hosted
291
+ version: "2.7.0"
292
+ file_selector_windows:
293
+ dependency: transitive
294
+ description:
295
+ name: file_selector_windows
296
+ sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd"
297
+ url: "https://pub.dev"
298
+ source: hosted
299
+ version: "0.9.3+5"
300
+ fixnum:
301
+ dependency: transitive
302
+ description:
303
+ name: fixnum
304
+ sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
305
+ url: "https://pub.dev"
306
+ source: hosted
307
+ version: "1.1.1"
308
+ flutter:
309
+ dependency: "direct main"
310
+ description: flutter
311
+ source: sdk
312
+ version: "0.0.0"
313
+ flutter_app_badger:
314
+ dependency: "direct main"
315
+ description:
316
+ name: flutter_app_badger
317
+ sha256: "64d4a279bab862ed28850431b9b446b9820aaae0bf363322d51077419f930fa8"
318
+ url: "https://pub.dev"
319
+ source: hosted
320
+ version: "1.5.0"
321
+ flutter_lints:
322
+ dependency: "direct dev"
323
+ description:
324
+ name: flutter_lints
325
+ sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
326
+ url: "https://pub.dev"
327
+ source: hosted
328
+ version: "6.0.0"
329
+ flutter_markdown:
330
+ dependency: "direct main"
331
+ description:
332
+ name: flutter_markdown
333
+ sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
334
+ url: "https://pub.dev"
335
+ source: hosted
336
+ version: "0.7.7+1"
337
+ flutter_plugin_android_lifecycle:
338
+ dependency: transitive
339
+ description:
340
+ name: flutter_plugin_android_lifecycle
341
+ sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1
342
+ url: "https://pub.dev"
343
+ source: hosted
344
+ version: "2.0.33"
345
+ flutter_riverpod:
346
+ dependency: "direct main"
347
+ description:
348
+ name: flutter_riverpod
349
+ sha256: "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1"
350
+ url: "https://pub.dev"
351
+ source: hosted
352
+ version: "2.6.1"
353
+ flutter_secure_storage:
354
+ dependency: "direct main"
355
+ description:
356
+ name: flutter_secure_storage
357
+ sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
358
+ url: "https://pub.dev"
359
+ source: hosted
360
+ version: "9.2.4"
361
+ flutter_secure_storage_linux:
362
+ dependency: transitive
363
+ description:
364
+ name: flutter_secure_storage_linux
365
+ sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
366
+ url: "https://pub.dev"
367
+ source: hosted
368
+ version: "1.2.3"
369
+ flutter_secure_storage_macos:
370
+ dependency: transitive
371
+ description:
372
+ name: flutter_secure_storage_macos
373
+ sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
374
+ url: "https://pub.dev"
375
+ source: hosted
376
+ version: "3.1.3"
377
+ flutter_secure_storage_platform_interface:
378
+ dependency: transitive
379
+ description:
380
+ name: flutter_secure_storage_platform_interface
381
+ sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
382
+ url: "https://pub.dev"
383
+ source: hosted
384
+ version: "1.1.2"
385
+ flutter_secure_storage_web:
386
+ dependency: transitive
387
+ description:
388
+ name: flutter_secure_storage_web
389
+ sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
390
+ url: "https://pub.dev"
391
+ source: hosted
392
+ version: "1.2.1"
393
+ flutter_secure_storage_windows:
394
+ dependency: transitive
395
+ description:
396
+ name: flutter_secure_storage_windows
397
+ sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
398
+ url: "https://pub.dev"
399
+ source: hosted
400
+ version: "3.1.2"
401
+ flutter_test:
402
+ dependency: "direct dev"
403
+ description: flutter
404
+ source: sdk
405
+ version: "0.0.0"
406
+ flutter_web_plugins:
407
+ dependency: transitive
408
+ description: flutter
409
+ source: sdk
410
+ version: "0.0.0"
411
+ glob:
412
+ dependency: transitive
413
+ description:
414
+ name: glob
415
+ sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
416
+ url: "https://pub.dev"
417
+ source: hosted
418
+ version: "2.1.3"
419
+ go_router:
420
+ dependency: "direct main"
421
+ description:
422
+ name: go_router
423
+ sha256: f02fd7d2a4dc512fec615529824fdd217fecb3a3d3de68360293a551f21634b3
424
+ url: "https://pub.dev"
425
+ source: hosted
426
+ version: "14.8.1"
427
+ hooks:
428
+ dependency: transitive
429
+ description:
430
+ name: hooks
431
+ sha256: e79ed1e8e1929bc6ecb6ec85f0cb519c887aa5b423705ded0d0f2d9226def388
432
+ url: "https://pub.dev"
433
+ source: hosted
434
+ version: "1.0.2"
435
+ http:
436
+ dependency: transitive
437
+ description:
438
+ name: http
439
+ sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
440
+ url: "https://pub.dev"
441
+ source: hosted
442
+ version: "1.6.0"
443
+ http_parser:
444
+ dependency: transitive
445
+ description:
446
+ name: http_parser
447
+ sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
448
+ url: "https://pub.dev"
449
+ source: hosted
450
+ version: "4.1.2"
451
+ image_picker:
452
+ dependency: "direct main"
453
+ description:
454
+ name: image_picker
455
+ sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320"
456
+ url: "https://pub.dev"
457
+ source: hosted
458
+ version: "1.2.1"
459
+ image_picker_android:
460
+ dependency: transitive
461
+ description:
462
+ name: image_picker_android
463
+ sha256: eda9b91b7e266d9041084a42d605a74937d996b87083395c5e47835916a86156
464
+ url: "https://pub.dev"
465
+ source: hosted
466
+ version: "0.8.13+14"
467
+ image_picker_for_web:
468
+ dependency: transitive
469
+ description:
470
+ name: image_picker_for_web
471
+ sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214"
472
+ url: "https://pub.dev"
473
+ source: hosted
474
+ version: "3.1.1"
475
+ image_picker_ios:
476
+ dependency: transitive
477
+ description:
478
+ name: image_picker_ios
479
+ sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588
480
+ url: "https://pub.dev"
481
+ source: hosted
482
+ version: "0.8.13+6"
483
+ image_picker_linux:
484
+ dependency: transitive
485
+ description:
486
+ name: image_picker_linux
487
+ sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4"
488
+ url: "https://pub.dev"
489
+ source: hosted
490
+ version: "0.2.2"
491
+ image_picker_macos:
492
+ dependency: transitive
493
+ description:
494
+ name: image_picker_macos
495
+ sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91"
496
+ url: "https://pub.dev"
497
+ source: hosted
498
+ version: "0.2.2+1"
499
+ image_picker_platform_interface:
500
+ dependency: transitive
501
+ description:
502
+ name: image_picker_platform_interface
503
+ sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c"
504
+ url: "https://pub.dev"
505
+ source: hosted
506
+ version: "2.11.1"
507
+ image_picker_windows:
508
+ dependency: transitive
509
+ description:
510
+ name: image_picker_windows
511
+ sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae
512
+ url: "https://pub.dev"
513
+ source: hosted
514
+ version: "0.2.2"
515
+ in_app_purchase:
516
+ dependency: "direct main"
517
+ description:
518
+ name: in_app_purchase
519
+ sha256: "5cddd7f463f3bddb1d37a72b95066e840d5822d66291331d7f8f05ce32c24b6c"
520
+ url: "https://pub.dev"
521
+ source: hosted
522
+ version: "3.2.3"
523
+ in_app_purchase_android:
524
+ dependency: transitive
525
+ description:
526
+ name: in_app_purchase_android
527
+ sha256: "634bee4734b17fe55f370f0ac07a22431a9666e0f3a870c6d20350856e8bbf71"
528
+ url: "https://pub.dev"
529
+ source: hosted
530
+ version: "0.4.0+10"
531
+ in_app_purchase_platform_interface:
532
+ dependency: transitive
533
+ description:
534
+ name: in_app_purchase_platform_interface
535
+ sha256: "1d353d38251da5b9fea6635c0ebfc6bb17a2d28d0e86ea5e083bf64244f1fb4c"
536
+ url: "https://pub.dev"
537
+ source: hosted
538
+ version: "1.4.0"
539
+ in_app_purchase_storekit:
540
+ dependency: transitive
541
+ description:
542
+ name: in_app_purchase_storekit
543
+ sha256: "1d512809edd9f12ff88fce4596a13a18134e2499013f4d6a8894b04699363c93"
544
+ url: "https://pub.dev"
545
+ source: hosted
546
+ version: "0.4.8+1"
547
+ intl:
548
+ dependency: "direct main"
549
+ description:
550
+ name: intl
551
+ sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
552
+ url: "https://pub.dev"
553
+ source: hosted
554
+ version: "0.20.2"
555
+ js:
556
+ dependency: transitive
557
+ description:
558
+ name: js
559
+ sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
560
+ url: "https://pub.dev"
561
+ source: hosted
562
+ version: "0.6.7"
563
+ json_annotation:
564
+ dependency: transitive
565
+ description:
566
+ name: json_annotation
567
+ sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8
568
+ url: "https://pub.dev"
569
+ source: hosted
570
+ version: "4.11.0"
571
+ leak_tracker:
572
+ dependency: transitive
573
+ description:
574
+ name: leak_tracker
575
+ sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
576
+ url: "https://pub.dev"
577
+ source: hosted
578
+ version: "11.0.2"
579
+ leak_tracker_flutter_testing:
580
+ dependency: transitive
581
+ description:
582
+ name: leak_tracker_flutter_testing
583
+ sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
584
+ url: "https://pub.dev"
585
+ source: hosted
586
+ version: "3.0.10"
587
+ leak_tracker_testing:
588
+ dependency: transitive
589
+ description:
590
+ name: leak_tracker_testing
591
+ sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
592
+ url: "https://pub.dev"
593
+ source: hosted
594
+ version: "3.0.2"
595
+ lints:
596
+ dependency: transitive
597
+ description:
598
+ name: lints
599
+ sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df"
600
+ url: "https://pub.dev"
601
+ source: hosted
602
+ version: "6.1.0"
603
+ logging:
604
+ dependency: transitive
605
+ description:
606
+ name: logging
607
+ sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
608
+ url: "https://pub.dev"
609
+ source: hosted
610
+ version: "1.3.0"
611
+ markdown:
612
+ dependency: transitive
613
+ description:
614
+ name: markdown
615
+ sha256: ee85086ad7698b42522c6ad42fe195f1b9898e4d974a1af4576c1a3a176cada9
616
+ url: "https://pub.dev"
617
+ source: hosted
618
+ version: "7.3.1"
619
+ matcher:
620
+ dependency: transitive
621
+ description:
622
+ name: matcher
623
+ sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
624
+ url: "https://pub.dev"
625
+ source: hosted
626
+ version: "0.12.19"
627
+ material_color_utilities:
628
+ dependency: transitive
629
+ description:
630
+ name: material_color_utilities
631
+ sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
632
+ url: "https://pub.dev"
633
+ source: hosted
634
+ version: "0.13.0"
635
+ meta:
636
+ dependency: transitive
637
+ description:
638
+ name: meta
639
+ sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
640
+ url: "https://pub.dev"
641
+ source: hosted
642
+ version: "1.17.0"
643
+ mime:
644
+ dependency: transitive
645
+ description:
646
+ name: mime
647
+ sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
648
+ url: "https://pub.dev"
649
+ source: hosted
650
+ version: "2.0.0"
651
+ mqtt_client:
652
+ dependency: "direct main"
653
+ description:
654
+ name: mqtt_client
655
+ sha256: fd22ea00a4c7b5623e01000a91a256d62a8bacba38e9812170458070c52affed
656
+ url: "https://pub.dev"
657
+ source: hosted
658
+ version: "10.11.9"
659
+ native_toolchain_c:
660
+ dependency: transitive
661
+ description:
662
+ name: native_toolchain_c
663
+ sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572"
664
+ url: "https://pub.dev"
665
+ source: hosted
666
+ version: "0.17.6"
667
+ nm:
668
+ dependency: transitive
669
+ description:
670
+ name: nm
671
+ sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
672
+ url: "https://pub.dev"
673
+ source: hosted
674
+ version: "0.5.0"
675
+ objective_c:
676
+ dependency: transitive
677
+ description:
678
+ name: objective_c
679
+ sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52"
680
+ url: "https://pub.dev"
681
+ source: hosted
682
+ version: "9.3.0"
683
+ path:
684
+ dependency: transitive
685
+ description:
686
+ name: path
687
+ sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
688
+ url: "https://pub.dev"
689
+ source: hosted
690
+ version: "1.9.1"
691
+ path_provider:
692
+ dependency: "direct main"
693
+ description:
694
+ name: path_provider
695
+ sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
696
+ url: "https://pub.dev"
697
+ source: hosted
698
+ version: "2.1.5"
699
+ path_provider_android:
700
+ dependency: transitive
701
+ description:
702
+ name: path_provider_android
703
+ sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
704
+ url: "https://pub.dev"
705
+ source: hosted
706
+ version: "2.2.22"
707
+ path_provider_foundation:
708
+ dependency: transitive
709
+ description:
710
+ name: path_provider_foundation
711
+ sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
712
+ url: "https://pub.dev"
713
+ source: hosted
714
+ version: "2.6.0"
715
+ path_provider_linux:
716
+ dependency: transitive
717
+ description:
718
+ name: path_provider_linux
719
+ sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
720
+ url: "https://pub.dev"
721
+ source: hosted
722
+ version: "2.2.1"
723
+ path_provider_platform_interface:
724
+ dependency: transitive
725
+ description:
726
+ name: path_provider_platform_interface
727
+ sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
728
+ url: "https://pub.dev"
729
+ source: hosted
730
+ version: "2.1.2"
731
+ path_provider_windows:
732
+ dependency: transitive
733
+ description:
734
+ name: path_provider_windows
735
+ sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
736
+ url: "https://pub.dev"
737
+ source: hosted
738
+ version: "2.3.0"
739
+ permission_handler:
740
+ dependency: "direct main"
741
+ description:
742
+ name: permission_handler
743
+ sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
744
+ url: "https://pub.dev"
745
+ source: hosted
746
+ version: "11.4.0"
747
+ permission_handler_android:
748
+ dependency: transitive
749
+ description:
750
+ name: permission_handler_android
751
+ sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
752
+ url: "https://pub.dev"
753
+ source: hosted
754
+ version: "12.1.0"
755
+ permission_handler_apple:
756
+ dependency: transitive
757
+ description:
758
+ name: permission_handler_apple
759
+ sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
760
+ url: "https://pub.dev"
761
+ source: hosted
762
+ version: "9.4.7"
763
+ permission_handler_html:
764
+ dependency: transitive
765
+ description:
766
+ name: permission_handler_html
767
+ sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
768
+ url: "https://pub.dev"
769
+ source: hosted
770
+ version: "0.1.3+5"
771
+ permission_handler_platform_interface:
772
+ dependency: transitive
773
+ description:
774
+ name: permission_handler_platform_interface
775
+ sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
776
+ url: "https://pub.dev"
777
+ source: hosted
778
+ version: "4.3.0"
779
+ permission_handler_windows:
780
+ dependency: transitive
781
+ description:
782
+ name: permission_handler_windows
783
+ sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
784
+ url: "https://pub.dev"
785
+ source: hosted
786
+ version: "0.2.1"
787
+ petitparser:
788
+ dependency: transitive
789
+ description:
790
+ name: petitparser
791
+ sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
792
+ url: "https://pub.dev"
793
+ source: hosted
794
+ version: "7.0.2"
795
+ platform:
796
+ dependency: transitive
797
+ description:
798
+ name: platform
799
+ sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
800
+ url: "https://pub.dev"
801
+ source: hosted
802
+ version: "3.1.6"
803
+ plugin_platform_interface:
804
+ dependency: transitive
805
+ description:
806
+ name: plugin_platform_interface
807
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
808
+ url: "https://pub.dev"
809
+ source: hosted
810
+ version: "2.1.8"
811
+ pub_semver:
812
+ dependency: transitive
813
+ description:
814
+ name: pub_semver
815
+ sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
816
+ url: "https://pub.dev"
817
+ source: hosted
818
+ version: "2.2.0"
819
+ push:
820
+ dependency: "direct main"
821
+ description:
822
+ name: push
823
+ sha256: "0ab12f0c194d22e000d5b1e911d66fd5a090b7786cc19228cb77946c922513b3"
824
+ url: "https://pub.dev"
825
+ source: hosted
826
+ version: "3.3.3"
827
+ record:
828
+ dependency: "direct main"
829
+ description:
830
+ name: record
831
+ sha256: d5b6b334f3ab02460db6544e08583c942dbf23e3504bf1e14fd4cbe3d9409277
832
+ url: "https://pub.dev"
833
+ source: hosted
834
+ version: "6.2.0"
835
+ record_android:
836
+ dependency: transitive
837
+ description:
838
+ name: record_android
839
+ sha256: "94783f08403aed33ffb68797bf0715b0812eb852f3c7985644c945faea462ba1"
840
+ url: "https://pub.dev"
841
+ source: hosted
842
+ version: "1.5.1"
843
+ record_ios:
844
+ dependency: transitive
845
+ description:
846
+ name: record_ios
847
+ sha256: "8df7c136131bd05efc19256af29b2ba6ccc000ccc2c80d4b6b6d7a8d21a3b5a9"
848
+ url: "https://pub.dev"
849
+ source: hosted
850
+ version: "1.2.0"
851
+ record_linux:
852
+ dependency: transitive
853
+ description:
854
+ name: record_linux
855
+ sha256: c31a35cc158cd666fc6395f7f56fc054f31685571684be6b97670a27649ce5c7
856
+ url: "https://pub.dev"
857
+ source: hosted
858
+ version: "1.3.0"
859
+ record_macos:
860
+ dependency: transitive
861
+ description:
862
+ name: record_macos
863
+ sha256: "084902e63fc9c0c224c29203d6c75f0bdf9b6a40536c9d916393c8f4c4256488"
864
+ url: "https://pub.dev"
865
+ source: hosted
866
+ version: "1.2.1"
867
+ record_platform_interface:
868
+ dependency: transitive
869
+ description:
870
+ name: record_platform_interface
871
+ sha256: "8a81dbc4e14e1272a285bbfef6c9136d070a47d9b0d1f40aa6193516253ee2f6"
872
+ url: "https://pub.dev"
873
+ source: hosted
874
+ version: "1.5.0"
875
+ record_web:
876
+ dependency: transitive
877
+ description:
878
+ name: record_web
879
+ sha256: "7e9846981c1f2d111d86f0ae3309071f5bba8b624d1c977316706f08fc31d16d"
880
+ url: "https://pub.dev"
881
+ source: hosted
882
+ version: "1.3.0"
883
+ record_windows:
884
+ dependency: transitive
885
+ description:
886
+ name: record_windows
887
+ sha256: "223258060a1d25c62bae18282c16783f28581ec19401d17e56b5205b9f039d78"
888
+ url: "https://pub.dev"
889
+ source: hosted
890
+ version: "1.0.7"
891
+ riverpod:
892
+ dependency: transitive
893
+ description:
894
+ name: riverpod
895
+ sha256: "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959"
896
+ url: "https://pub.dev"
897
+ source: hosted
898
+ version: "2.6.1"
899
+ riverpod_annotation:
900
+ dependency: "direct main"
901
+ description:
902
+ name: riverpod_annotation
903
+ sha256: e14b0bf45b71326654e2705d462f21b958f987087be850afd60578fcd502d1b8
904
+ url: "https://pub.dev"
905
+ source: hosted
906
+ version: "2.6.1"
907
+ share_plus:
908
+ dependency: "direct main"
909
+ description:
910
+ name: share_plus
911
+ sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840"
912
+ url: "https://pub.dev"
913
+ source: hosted
914
+ version: "12.0.1"
915
+ share_plus_platform_interface:
916
+ dependency: transitive
917
+ description:
918
+ name: share_plus_platform_interface
919
+ sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a"
920
+ url: "https://pub.dev"
921
+ source: hosted
922
+ version: "6.1.0"
923
+ shared_preferences:
924
+ dependency: "direct main"
925
+ description:
926
+ name: shared_preferences
927
+ sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64"
928
+ url: "https://pub.dev"
929
+ source: hosted
930
+ version: "2.5.4"
931
+ shared_preferences_android:
932
+ dependency: transitive
933
+ description:
934
+ name: shared_preferences_android
935
+ sha256: "8374d6200ab33ac99031a852eba4c8eb2170c4bf20778b3e2c9eccb45384fb41"
936
+ url: "https://pub.dev"
937
+ source: hosted
938
+ version: "2.4.21"
939
+ shared_preferences_foundation:
940
+ dependency: transitive
941
+ description:
942
+ name: shared_preferences_foundation
943
+ sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
944
+ url: "https://pub.dev"
945
+ source: hosted
946
+ version: "2.5.6"
947
+ shared_preferences_linux:
948
+ dependency: transitive
949
+ description:
950
+ name: shared_preferences_linux
951
+ sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
952
+ url: "https://pub.dev"
953
+ source: hosted
954
+ version: "2.4.1"
955
+ shared_preferences_platform_interface:
956
+ dependency: transitive
957
+ description:
958
+ name: shared_preferences_platform_interface
959
+ sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
960
+ url: "https://pub.dev"
961
+ source: hosted
962
+ version: "2.4.1"
963
+ shared_preferences_web:
964
+ dependency: transitive
965
+ description:
966
+ name: shared_preferences_web
967
+ sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
968
+ url: "https://pub.dev"
969
+ source: hosted
970
+ version: "2.4.3"
971
+ shared_preferences_windows:
972
+ dependency: transitive
973
+ description:
974
+ name: shared_preferences_windows
975
+ sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
976
+ url: "https://pub.dev"
977
+ source: hosted
978
+ version: "2.4.1"
979
+ sky_engine:
980
+ dependency: transitive
981
+ description: flutter
982
+ source: sdk
983
+ version: "0.0.0"
984
+ source_span:
985
+ dependency: transitive
986
+ description:
987
+ name: source_span
988
+ sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
989
+ url: "https://pub.dev"
990
+ source: hosted
991
+ version: "1.10.2"
992
+ stack_trace:
993
+ dependency: transitive
994
+ description:
995
+ name: stack_trace
996
+ sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
997
+ url: "https://pub.dev"
998
+ source: hosted
999
+ version: "1.12.1"
1000
+ state_notifier:
1001
+ dependency: transitive
1002
+ description:
1003
+ name: state_notifier
1004
+ sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb
1005
+ url: "https://pub.dev"
1006
+ source: hosted
1007
+ version: "1.0.0"
1008
+ stream_channel:
1009
+ dependency: transitive
1010
+ description:
1011
+ name: stream_channel
1012
+ sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
1013
+ url: "https://pub.dev"
1014
+ source: hosted
1015
+ version: "2.1.4"
1016
+ string_scanner:
1017
+ dependency: transitive
1018
+ description:
1019
+ name: string_scanner
1020
+ sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
1021
+ url: "https://pub.dev"
1022
+ source: hosted
1023
+ version: "1.4.1"
1024
+ synchronized:
1025
+ dependency: transitive
1026
+ description:
1027
+ name: synchronized
1028
+ sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
1029
+ url: "https://pub.dev"
1030
+ source: hosted
1031
+ version: "3.4.0"
1032
+ term_glyph:
1033
+ dependency: transitive
1034
+ description:
1035
+ name: term_glyph
1036
+ sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
1037
+ url: "https://pub.dev"
1038
+ source: hosted
1039
+ version: "1.2.2"
1040
+ test_api:
1041
+ dependency: transitive
1042
+ description:
1043
+ name: test_api
1044
+ sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
1045
+ url: "https://pub.dev"
1046
+ source: hosted
1047
+ version: "0.7.10"
1048
+ typed_data:
1049
+ dependency: transitive
1050
+ description:
1051
+ name: typed_data
1052
+ sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
1053
+ url: "https://pub.dev"
1054
+ source: hosted
1055
+ version: "1.4.0"
1056
+ udp:
1057
+ dependency: "direct main"
1058
+ description:
1059
+ name: udp
1060
+ sha256: "50ea45d7ee80ad4c62de4ec0e8ed3ae65c36e9fe8cd0655a2bcd1503d2708e5a"
1061
+ url: "https://pub.dev"
1062
+ source: hosted
1063
+ version: "5.0.3"
1064
+ url_launcher:
1065
+ dependency: "direct main"
1066
+ description:
1067
+ name: url_launcher
1068
+ sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
1069
+ url: "https://pub.dev"
1070
+ source: hosted
1071
+ version: "6.3.2"
1072
+ url_launcher_android:
1073
+ dependency: transitive
1074
+ description:
1075
+ name: url_launcher_android
1076
+ sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572"
1077
+ url: "https://pub.dev"
1078
+ source: hosted
1079
+ version: "6.3.29"
1080
+ url_launcher_ios:
1081
+ dependency: transitive
1082
+ description:
1083
+ name: url_launcher_ios
1084
+ sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
1085
+ url: "https://pub.dev"
1086
+ source: hosted
1087
+ version: "6.4.1"
1088
+ url_launcher_linux:
1089
+ dependency: transitive
1090
+ description:
1091
+ name: url_launcher_linux
1092
+ sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
1093
+ url: "https://pub.dev"
1094
+ source: hosted
1095
+ version: "3.2.2"
1096
+ url_launcher_macos:
1097
+ dependency: transitive
1098
+ description:
1099
+ name: url_launcher_macos
1100
+ sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
1101
+ url: "https://pub.dev"
1102
+ source: hosted
1103
+ version: "3.2.5"
1104
+ url_launcher_platform_interface:
1105
+ dependency: transitive
1106
+ description:
1107
+ name: url_launcher_platform_interface
1108
+ sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
1109
+ url: "https://pub.dev"
1110
+ source: hosted
1111
+ version: "2.3.2"
1112
+ url_launcher_web:
1113
+ dependency: transitive
1114
+ description:
1115
+ name: url_launcher_web
1116
+ sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
1117
+ url: "https://pub.dev"
1118
+ source: hosted
1119
+ version: "2.4.2"
1120
+ url_launcher_windows:
1121
+ dependency: transitive
1122
+ description:
1123
+ name: url_launcher_windows
1124
+ sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
1125
+ url: "https://pub.dev"
1126
+ source: hosted
1127
+ version: "3.1.5"
1128
+ uuid:
1129
+ dependency: "direct main"
1130
+ description:
1131
+ name: uuid
1132
+ sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"
1133
+ url: "https://pub.dev"
1134
+ source: hosted
1135
+ version: "4.5.3"
1136
+ vector_math:
1137
+ dependency: transitive
1138
+ description:
1139
+ name: vector_math
1140
+ sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
1141
+ url: "https://pub.dev"
1142
+ source: hosted
1143
+ version: "2.2.0"
1144
+ vibration:
1145
+ dependency: "direct main"
1146
+ description:
1147
+ name: vibration
1148
+ sha256: "3b08a0579c2f9c18d5d78cb5c74f1005f731e02eeca6d72561a2e8059bf98ec3"
1149
+ url: "https://pub.dev"
1150
+ source: hosted
1151
+ version: "2.1.0"
1152
+ vibration_platform_interface:
1153
+ dependency: transitive
1154
+ description:
1155
+ name: vibration_platform_interface
1156
+ sha256: "6ffeee63547562a6fef53c05a41d4fdcae2c0595b83ef59a4813b0612cd2bc36"
1157
+ url: "https://pub.dev"
1158
+ source: hosted
1159
+ version: "0.0.3"
1160
+ vm_service:
1161
+ dependency: transitive
1162
+ description:
1163
+ name: vm_service
1164
+ sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
1165
+ url: "https://pub.dev"
1166
+ source: hosted
1167
+ version: "15.0.2"
1168
+ web:
1169
+ dependency: transitive
1170
+ description:
1171
+ name: web
1172
+ sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
1173
+ url: "https://pub.dev"
1174
+ source: hosted
1175
+ version: "1.1.1"
1176
+ win32:
1177
+ dependency: transitive
1178
+ description:
1179
+ name: win32
1180
+ sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
1181
+ url: "https://pub.dev"
1182
+ source: hosted
1183
+ version: "5.15.0"
1184
+ win32_registry:
1185
+ dependency: transitive
1186
+ description:
1187
+ name: win32_registry
1188
+ sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
1189
+ url: "https://pub.dev"
1190
+ source: hosted
1191
+ version: "2.1.0"
1192
+ xdg_directories:
1193
+ dependency: transitive
1194
+ description:
1195
+ name: xdg_directories
1196
+ sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
1197
+ url: "https://pub.dev"
1198
+ source: hosted
1199
+ version: "1.1.0"
1200
+ xml:
1201
+ dependency: transitive
1202
+ description:
1203
+ name: xml
1204
+ sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
1205
+ url: "https://pub.dev"
1206
+ source: hosted
1207
+ version: "6.6.1"
1208
+ yaml:
1209
+ dependency: transitive
1210
+ description:
1211
+ name: yaml
1212
+ sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
1213
+ url: "https://pub.dev"
1214
+ source: hosted
1215
+ version: "3.1.3"
1216
+sdks:
1217
+ dart: ">=3.11.1 <4.0.0"
1218
+ flutter: ">=3.38.4"
pubspec.yaml
....@@ -0,0 +1,46 @@
1
+name: pailot
2
+description: "Voice-first AI communicator"
3
+publish_to: 'none'
4
+version: 1.0.0+1
5
+
6
+environment:
7
+ sdk: ^3.11.1
8
+
9
+dependencies:
10
+ flutter:
11
+ sdk: flutter
12
+ cupertino_icons: ^1.0.8
13
+ flutter_riverpod: ^2.6.1
14
+ riverpod_annotation: ^2.6.1
15
+ go_router: ^14.8.1
16
+ path_provider: ^2.1.0
17
+ shared_preferences: ^2.5.3
18
+ record: ^6.2.0
19
+ audioplayers: ^6.1.0
20
+ permission_handler: ^11.4.0
21
+ image_picker: ^1.1.2
22
+ flutter_secure_storage: ^9.2.4
23
+ vibration: ^2.0.1
24
+ share_plus: ^12.0.1
25
+ udp: ^5.0.3
26
+ intl: ^0.20.2
27
+ mqtt_client: ^10.6.0
28
+ uuid: ^4.5.1
29
+ collection: ^1.19.1
30
+ file_picker: ^10.3.10
31
+ flutter_markdown: ^0.7.7+1
32
+ bonsoir: ^6.0.2
33
+ crypto: ^3.0.7
34
+ push: ^3.3.3
35
+ flutter_app_badger: ^1.5.0
36
+ connectivity_plus: ^7.1.0
37
+ in_app_purchase: ^3.2.3
38
+ url_launcher: ^6.3.2
39
+
40
+dev_dependencies:
41
+ flutter_test:
42
+ sdk: flutter
43
+ flutter_lints: ^6.0.0
44
+
45
+flutter:
46
+ uses-material-design: true
services/audio.ts
deleted file mode 100644
....@@ -1,228 +0,0 @@
1
-import {
2
- createAudioPlayer,
3
- requestRecordingPermissionsAsync,
4
- setAudioModeAsync,
5
-} from "expo-audio";
6
-import * as LegacyFileSystem from "expo-file-system/legacy";
7
-import { AppState } from "react-native";
8
-
9
-export interface RecordingResult {
10
- uri: string;
11
- durationMs: number;
12
-}
13
-
14
-// --- Audio mode (set once at import time) ---
15
-// Setting this on every playback causes iOS to renegotiate the audio route,
16
-// which disconnects Bluetooth/CarPlay. Set it once and leave it alone.
17
-let _audioModeReady = false;
18
-async function ensureAudioMode(): Promise<void> {
19
- if (_audioModeReady) return;
20
- _audioModeReady = true;
21
- try {
22
- await setAudioModeAsync({ playsInSilentMode: true });
23
- } catch {
24
- _audioModeReady = false; // retry next time
25
- }
26
-}
27
-// Eagerly initialize on module load
28
-ensureAudioMode();
29
-
30
-// --- Autoplay suppression ---
31
-// Don't autoplay voice messages when the app is in the background
32
-// or when the user is on a phone call (detected via audio interruption).
33
-let _autoplayEnabled = true;
34
-let _audioInterrupted = false;
35
-
36
-// Track app state — suppress autoplay when backgrounded
37
-AppState.addEventListener("change", (state) => {
38
- _autoplayEnabled = state === "active";
39
-});
40
-
41
-/** Check if autoplay is safe right now (app in foreground, no interruption). */
42
-export function canAutoplay(): boolean {
43
- return _autoplayEnabled && !_audioInterrupted;
44
-}
45
-
46
-/** Called externally to signal audio interruption (e.g., phone call started/ended). */
47
-export function setAudioInterrupted(interrupted: boolean): void {
48
- _audioInterrupted = interrupted;
49
-}
50
-
51
-// --- Singleton audio player ---
52
-// Only ONE audio can play at a time. Any new play request stops the current one.
53
-
54
-let currentPlayer: ReturnType<typeof createAudioPlayer> | null = null;
55
-let currentUri: string | null = null;
56
-let cancelCurrent: (() => void) | null = null;
57
-
58
-// Listeners get the URI of what's playing (or null when stopped)
59
-const playingListeners = new Set<(uri: string | null) => void>();
60
-
61
-function notifyListeners(uri: string | null): void {
62
- currentUri = uri;
63
- for (const cb of playingListeners) cb(uri);
64
-}
65
-
66
-/** Subscribe to playing state changes. Returns unsubscribe function. */
67
-export function onPlayingChange(cb: (uri: string | null) => void): () => void {
68
- playingListeners.add(cb);
69
- return () => { playingListeners.delete(cb); };
70
-}
71
-
72
-/** Get the URI currently playing, or null. */
73
-export function playingUri(): string | null {
74
- return currentUri;
75
-}
76
-
77
-export function isPlaying(): boolean {
78
- return currentPlayer !== null;
79
-}
80
-
81
-export async function requestPermissions(): Promise<boolean> {
82
- const { status } = await requestRecordingPermissionsAsync();
83
- return status === "granted";
84
-}
85
-
86
-let audioCounter = 0;
87
-
88
-/**
89
- * Convert a base64 audio string to a file URI.
90
- */
91
-export async function saveBase64Audio(base64: string, ext = "m4a"): Promise<string> {
92
- const tmpPath = `${LegacyFileSystem.cacheDirectory}pailot-voice-${++audioCounter}.${ext}`;
93
- await LegacyFileSystem.writeAsStringAsync(tmpPath, base64, {
94
- encoding: LegacyFileSystem.EncodingType.Base64,
95
- });
96
- return tmpPath;
97
-}
98
-
99
-// --- Audio queue for chaining sequential voice notes (autoplay) ---
100
-const audioQueue: Array<{ uri: string; onFinish?: () => void }> = [];
101
-let processingQueue = false;
102
-
103
-/**
104
- * Play audio. Stops any current playback first (singleton).
105
- * Multiple calls chain sequentially via queue (for chunked voice notes).
106
- */
107
-export async function playAudio(
108
- uri: string,
109
- onFinish?: () => void
110
-): Promise<void> {
111
- audioQueue.push({ uri, onFinish });
112
- if (!processingQueue) {
113
- processAudioQueue();
114
- }
115
-}
116
-
117
-/**
118
- * Play a single audio file, stopping any current playback first.
119
- * Does NOT queue — immediately replaces whatever is playing.
120
- */
121
-export async function playSingle(
122
- uri: string,
123
- onFinish?: () => void
124
-): Promise<void> {
125
- await stopPlayback();
126
- await playOneAudio(uri, onFinish);
127
-}
128
-
129
-async function processAudioQueue(): Promise<void> {
130
- if (processingQueue) return;
131
- processingQueue = true;
132
-
133
- while (audioQueue.length > 0) {
134
- const item = audioQueue.shift()!;
135
- await playOneAudio(item.uri, item.onFinish, false);
136
- }
137
-
138
- processingQueue = false;
139
-}
140
-
141
-function playOneAudio(uri: string, onFinish?: () => void, cancelPrevious = true): Promise<void> {
142
- return new Promise<void>(async (resolve) => {
143
- let settled = false;
144
- const finish = () => {
145
- if (settled) return;
146
- settled = true;
147
- cancelCurrent = null;
148
- clearTimeout(timer);
149
- onFinish?.();
150
- try { player?.pause(); } catch { /* ignore */ }
151
- try { player?.remove(); } catch { /* ignore */ }
152
- if (currentPlayer === player) {
153
- currentPlayer = null;
154
- notifyListeners(null);
155
- }
156
- resolve();
157
- };
158
-
159
- // Stop any currently playing audio first (only for non-queued calls)
160
- if (cancelPrevious && cancelCurrent) {
161
- cancelCurrent();
162
- }
163
-
164
- // Register cancel callback so stopPlayback can abort us
165
- cancelCurrent = finish;
166
-
167
- // Safety timeout
168
- const timer = setTimeout(finish, 5 * 60 * 1000);
169
- let player: ReturnType<typeof createAudioPlayer> | null = null;
170
-
171
- try {
172
- await ensureAudioMode();
173
-
174
- player = createAudioPlayer(uri);
175
- currentPlayer = player;
176
- notifyListeners(uri);
177
-
178
- player.addListener("playbackStatusUpdate", (status) => {
179
- if (!status.playing && status.currentTime > 0) {
180
- if (status.duration <= 0 || status.currentTime >= status.duration) {
181
- // Playback finished naturally
182
- finish();
183
- } else {
184
- // Paused mid-playback — likely audio interruption (phone call)
185
- setAudioInterrupted(true);
186
- }
187
- } else if (status.playing && _audioInterrupted) {
188
- // Resumed after interruption
189
- setAudioInterrupted(false);
190
- }
191
- });
192
-
193
- player.play();
194
- } catch (error) {
195
- console.error("Failed to play audio:", error);
196
- settled = true;
197
- cancelCurrent = null;
198
- clearTimeout(timer);
199
- resolve();
200
- }
201
- });
202
-}
203
-
204
-/**
205
- * Stop current playback and clear the queue.
206
- */
207
-export async function stopPlayback(): Promise<void> {
208
- audioQueue.length = 0;
209
- if (cancelCurrent) {
210
- cancelCurrent();
211
- } else if (currentPlayer) {
212
- try {
213
- currentPlayer.pause();
214
- currentPlayer.remove();
215
- } catch {
216
- // Ignore cleanup errors
217
- }
218
- currentPlayer = null;
219
- notifyListeners(null);
220
- }
221
-}
222
-
223
-export async function encodeAudioToBase64(uri: string): Promise<string> {
224
- const result = await LegacyFileSystem.readAsStringAsync(uri, {
225
- encoding: LegacyFileSystem.EncodingType.Base64,
226
- });
227
- return result;
228
-}
services/notifications.ts
deleted file mode 100644
....@@ -1,40 +0,0 @@
1
-/**
2
- * Local push notifications for background message delivery.
3
- *
4
- * Uses a minimal Objective-C native module (ios/LocalNotifications/) that wraps
5
- * UNUserNotificationCenter directly. No aps-environment entitlement needed.
6
- */
7
-import { AppState, NativeModules } from "react-native";
8
-
9
-const { LocalNotifications } = NativeModules;
10
-
11
-let permissionGranted = false;
12
-
13
-/** Request notification permissions. Call once at app startup. */
14
-export async function requestNotificationPermissions(): Promise<boolean> {
15
- try {
16
- if (!LocalNotifications) return false;
17
- permissionGranted = await LocalNotifications.requestPermissions();
18
- } catch {
19
- permissionGranted = false;
20
- }
21
- return permissionGranted;
22
-}
23
-
24
-/** Returns true if the app is currently in the background or inactive. */
25
-export function isAppBackgrounded(): boolean {
26
- return AppState.currentState !== "active";
27
-}
28
-
29
-/** Fire a local notification for an incoming message. */
30
-export async function notifyIncomingMessage(
31
- title: string,
32
- body: string,
33
-): Promise<void> {
34
- if (!permissionGranted || !isAppBackgrounded() || !LocalNotifications) return;
35
- try {
36
- await LocalNotifications.notify(title, body);
37
- } catch {
38
- // Best-effort
39
- }
40
-}
services/websocket.ts
deleted file mode 100644
....@@ -1,246 +0,0 @@
1
-import { AppState, AppStateStatus } from "react-native";
2
-import { WsOutgoing } from "../types";
3
-
4
-type WebSocketMessage = Record<string, unknown>;
5
-type MessageCallback = (data: WebSocketMessage) => void;
6
-type StatusCallback = () => void;
7
-type ReconnectCallback = (attempt: number) => void;
8
-type ErrorCallback = (error: Event) => void;
9
-
10
-interface WebSocketClientOptions {
11
- onMessage?: MessageCallback;
12
- onOpen?: StatusCallback;
13
- onClose?: StatusCallback;
14
- onReconnecting?: ReconnectCallback;
15
- onError?: ErrorCallback;
16
-}
17
-
18
-const INITIAL_RECONNECT_DELAY = 1000;
19
-const MAX_RECONNECT_DELAY = 30000;
20
-const RECONNECT_MULTIPLIER = 2;
21
-const LOCAL_TIMEOUT = 2500;
22
-const CONNECT_TIMEOUT = 5000; // max time for any single connection attempt
23
-const HEARTBEAT_INTERVAL = 30000; // 30s ping to detect zombie sockets
24
-
25
-export class WebSocketClient {
26
- private ws: WebSocket | null = null;
27
- private urls: string[] = [];
28
- private urlIndex: number = 0;
29
- private reconnectDelay: number = INITIAL_RECONNECT_DELAY;
30
- private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
31
- private connectTimer: ReturnType<typeof setTimeout> | null = null;
32
- private localTimer: ReturnType<typeof setTimeout> | null = null;
33
- private heartbeatTimer: ReturnType<typeof setInterval> | null = null;
34
- private lastMessageAt: number = 0; // timestamp of last received message (any type)
35
- private shouldReconnect: boolean = false;
36
- private connected: boolean = false;
37
- private wasConnected: boolean = false; // true if we ever connected (for reconnect logic)
38
- private reconnectAttempt: number = 0;
39
- private callbacks: WebSocketClientOptions = {};
40
-
41
- constructor() {
42
- // When app comes back to foreground, verify the connection
43
- AppState.addEventListener("change", (state: AppStateStatus) => {
44
- if (state === "active" && this.shouldReconnect) {
45
- if (!this.ws || this.ws.readyState === WebSocket.CLOSED || this.ws.readyState === WebSocket.CLOSING) {
46
- // Socket is definitively dead — force immediate reconnect
47
- this.reconnectDelay = INITIAL_RECONNECT_DELAY;
48
- this.urlIndex = 0;
49
- this.tryUrl();
50
- } else if (this.connected) {
51
- // Socket might be alive — send a ping and restart heartbeat
52
- // to give it a fresh 2-interval window to prove liveness
53
- this.startHeartbeat();
54
- this.sendPing();
55
- }
56
- }
57
- });
58
- }
59
-
60
- setCallbacks(callbacks: WebSocketClientOptions) {
61
- this.callbacks = callbacks;
62
- }
63
-
64
- connect(urls: string[]) {
65
- this.urls = urls.filter(Boolean);
66
- if (this.urls.length === 0) return;
67
- this.shouldReconnect = true;
68
- this.reconnectDelay = INITIAL_RECONNECT_DELAY;
69
- this.urlIndex = 0;
70
- this.connected = false;
71
- this.tryUrl();
72
- }
73
-
74
- private cleanup() {
75
- if (this.localTimer) { clearTimeout(this.localTimer); this.localTimer = null; }
76
- if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; }
77
- if (this.connectTimer) { clearTimeout(this.connectTimer); this.connectTimer = null; }
78
- this.stopHeartbeat();
79
- if (this.ws) {
80
- const old = this.ws;
81
- this.ws = null;
82
- old.onopen = null;
83
- old.onclose = null;
84
- old.onerror = null;
85
- old.onmessage = null;
86
- try { old.close(); } catch { /* ignore */ }
87
- }
88
- }
89
-
90
- private startHeartbeat() {
91
- this.stopHeartbeat();
92
- this.lastMessageAt = Date.now();
93
- this.heartbeatTimer = setInterval(() => {
94
- const silentMs = Date.now() - this.lastMessageAt;
95
- if (silentMs > HEARTBEAT_INTERVAL * 2) {
96
- // No message (including pong) for 2 full intervals — zombie socket
97
- this.connected = false;
98
- this.callbacks.onClose?.();
99
- this.reconnectDelay = INITIAL_RECONNECT_DELAY;
100
- this.urlIndex = 0;
101
- this.tryUrl();
102
- return;
103
- }
104
- // Send a ping so the server has something to respond to
105
- this.sendPing();
106
- }, HEARTBEAT_INTERVAL);
107
- }
108
-
109
- private stopHeartbeat() {
110
- if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; }
111
- }
112
-
113
- private sendPing() {
114
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
115
- try {
116
- this.ws.send(JSON.stringify({ type: "ping" }));
117
- } catch {
118
- // Send failed — socket is dead
119
- this.connected = false;
120
- this.callbacks.onClose?.();
121
- this.reconnectDelay = INITIAL_RECONNECT_DELAY;
122
- this.urlIndex = 0;
123
- this.tryUrl();
124
- }
125
- }
126
- }
127
-
128
- private tryUrl() {
129
- this.cleanup();
130
-
131
- const url = this.urls[this.urlIndex];
132
- if (!url) return;
133
-
134
- const ws = new WebSocket(url);
135
- this.ws = ws;
136
-
137
- // If trying local (index 0) and we have a remote fallback,
138
- // give local 2.5s before switching to remote
139
- if (this.urlIndex === 0 && this.urls.length > 1) {
140
- this.localTimer = setTimeout(() => {
141
- this.localTimer = null;
142
- if (this.connected) return; // already connected, ignore
143
- // Local didn't connect in time — try remote
144
- this.urlIndex = 1;
145
- this.tryUrl();
146
- }, LOCAL_TIMEOUT);
147
- }
148
-
149
- // Timeout: if this connection attempt doesn't succeed within CONNECT_TIMEOUT,
150
- // treat it as failed. Prevents hanging on unreachable remote URLs.
151
- this.connectTimer = setTimeout(() => {
152
- this.connectTimer = null;
153
- if (ws === this.ws && !this.connected) {
154
- // Force close and let onclose trigger reconnect
155
- try { ws.close(); } catch { /* ignore */ }
156
- }
157
- }, CONNECT_TIMEOUT);
158
-
159
- ws.onopen = () => {
160
- if (ws !== this.ws) return; // stale
161
- if (this.connectTimer) { clearTimeout(this.connectTimer); this.connectTimer = null; }
162
- this.connected = true;
163
- this.wasConnected = true;
164
- this.reconnectAttempt = 0;
165
- if (this.localTimer) { clearTimeout(this.localTimer); this.localTimer = null; }
166
- this.reconnectDelay = INITIAL_RECONNECT_DELAY;
167
- this.startHeartbeat();
168
- this.callbacks.onOpen?.();
169
- };
170
-
171
- ws.onmessage = (event) => {
172
- if (ws !== this.ws) return; // stale
173
- this.lastMessageAt = Date.now(); // any message proves the connection is alive
174
- try {
175
- const data = JSON.parse(event.data) as WebSocketMessage;
176
- if (data.type === "pong") return; // heartbeat response, don't forward
177
- this.callbacks.onMessage?.(data);
178
- } catch {
179
- this.callbacks.onMessage?.({ type: "text", content: String(event.data) });
180
- }
181
- };
182
-
183
- ws.onclose = () => {
184
- if (ws !== this.ws) return; // stale
185
- this.connected = false;
186
- this.callbacks.onClose?.();
187
- if (this.shouldReconnect) {
188
- this.scheduleReconnect();
189
- }
190
- };
191
-
192
- ws.onerror = () => {
193
- if (ws !== this.ws) return; // stale
194
- // Don't do anything here — onclose always fires after onerror
195
- // and handles reconnect. Just swallow the error event.
196
- };
197
- }
198
-
199
- private scheduleReconnect() {
200
- if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
201
- this.reconnectAttempt++;
202
- // Signal reconnecting state to UI so it shows yellow/orange, not red
203
- this.callbacks.onReconnecting?.(this.reconnectAttempt);
204
- this.reconnectTimer = setTimeout(() => {
205
- this.reconnectTimer = null;
206
- this.reconnectDelay = Math.min(
207
- this.reconnectDelay * RECONNECT_MULTIPLIER,
208
- MAX_RECONNECT_DELAY
209
- );
210
- // Always try local first (daemon restarts are local), then remote on retry
211
- if (this.urls.length > 1) {
212
- // First attempt: local. Second: remote. Then alternate.
213
- this.urlIndex = this.reconnectAttempt % 2 === 1 ? 0 : 1;
214
- }
215
- this.tryUrl();
216
- }, this.reconnectDelay);
217
- }
218
-
219
- disconnect() {
220
- this.shouldReconnect = false;
221
- this.connected = false;
222
- this.cleanup();
223
- }
224
-
225
- send(message: WsOutgoing) {
226
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
227
- this.ws.send(JSON.stringify(message));
228
- return true;
229
- }
230
- return false;
231
- }
232
-
233
- get readyState(): number {
234
- return this.ws?.readyState ?? WebSocket.CLOSED;
235
- }
236
-
237
- get isConnected(): boolean {
238
- return this.connected;
239
- }
240
-
241
- get currentUrl(): string {
242
- return this.urls[this.urlIndex] ?? "";
243
- }
244
-}
245
-
246
-export const wsClient = new WebSocketClient();
services/wol.ts
deleted file mode 100644
....@@ -1,122 +0,0 @@
1
-/**
2
- * Wake-on-LAN service — sends a magic packet to wake a sleeping Mac.
3
- *
4
- * The magic packet is 6 bytes of 0xFF followed by the target MAC address
5
- * repeated 16 times, sent as a UDP broadcast on port 9.
6
- */
7
-import dgram from "react-native-udp";
8
-
9
-function parseMac(mac: string): number[] {
10
- const parts = mac
11
- .replace(/[:-]/g, "")
12
- .match(/.{2}/g);
13
- if (!parts || parts.length !== 6) {
14
- throw new Error(`Invalid MAC address: ${mac}`);
15
- }
16
- return parts.map((h) => parseInt(h, 16));
17
-}
18
-
19
-function buildMagicPacket(mac: string): Uint8Array {
20
- const macBytes = parseMac(mac);
21
- const packet = new Uint8Array(102);
22
-
23
- // 6 bytes of 0xFF
24
- for (let i = 0; i < 6; i++) {
25
- packet[i] = 0xff;
26
- }
27
-
28
- // MAC address repeated 16 times
29
- for (let i = 0; i < 16; i++) {
30
- const offset = 6 + i * 6;
31
- for (let j = 0; j < 6; j++) {
32
- packet[offset + j] = macBytes[j];
33
- }
34
- }
35
-
36
- return packet;
37
-}
38
-
39
-/**
40
- * Send a Wake-on-LAN magic packet to the given MAC address.
41
- * Sends to both the subnet broadcast (derived from host) and 255.255.255.255.
42
- */
43
-export async function sendWol(mac: string, host?: string): Promise<void> {
44
- const packet = buildMagicPacket(mac);
45
-
46
- // Derive broadcast address from host IP (replace last octet with 255)
47
- const broadcastAddresses = ["255.255.255.255"];
48
- if (host) {
49
- const parts = host.split(".");
50
- if (parts.length === 4) {
51
- parts[3] = "255";
52
- const subnetBroadcast = parts.join(".");
53
- if (!broadcastAddresses.includes(subnetBroadcast)) {
54
- broadcastAddresses.push(subnetBroadcast);
55
- }
56
- }
57
- }
58
-
59
- const TIMEOUT_MS = 5000;
60
-
61
- return new Promise<void>((resolve, reject) => {
62
- let settled = false;
63
- const settle = (fn: () => void) => {
64
- if (settled) return;
65
- settled = true;
66
- clearTimeout(timer);
67
- fn();
68
- };
69
-
70
- const timer = setTimeout(() => {
71
- settle(() => {
72
- try { socket.close(); } catch { /* ignore */ }
73
- reject(new Error("WoL timed out — magic packet may not have been sent"));
74
- });
75
- }, TIMEOUT_MS);
76
-
77
- const socket = dgram.createSocket({ type: "udp4" });
78
-
79
- socket.once("error", (err: Error) => {
80
- settle(() => {
81
- try { socket.close(); } catch { /* ignore */ }
82
- reject(err);
83
- });
84
- });
85
-
86
- socket.bind(0, () => {
87
- try {
88
- socket.setBroadcast(true);
89
- } catch {
90
- // Some platforms don't support setBroadcast — continue anyway
91
- }
92
-
93
- let pending = broadcastAddresses.length;
94
-
95
- for (const addr of broadcastAddresses) {
96
- socket.send(packet, 0, packet.length, 9, addr, (err?: Error) => {
97
- if (err) {
98
- settle(() => {
99
- try { socket.close(); } catch { /* ignore */ }
100
- reject(err);
101
- });
102
- return;
103
- }
104
- pending--;
105
- if (pending === 0) {
106
- settle(() => {
107
- try { socket.close(); } catch { /* ignore */ }
108
- resolve();
109
- });
110
- }
111
- });
112
- }
113
- });
114
- });
115
-}
116
-
117
-/**
118
- * Validate a MAC address string.
119
- */
120
-export function isValidMac(mac: string): boolean {
121
- return /^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$/.test(mac.trim());
122
-}
tailwind.config.js
deleted file mode 100644
....@@ -1,45 +0,0 @@
1
-/** @type {import('tailwindcss').Config} */
2
-module.exports = {
3
- content: [
4
- "./App.{js,jsx,ts,tsx}",
5
- "./app/**/*.{js,jsx,ts,tsx}",
6
- "./components/**/*.{js,jsx,ts,tsx}",
7
- ],
8
- presets: [require("nativewind/preset")],
9
- theme: {
10
- extend: {
11
- colors: {
12
- // PAILot dark theme — deep navy/charcoal
13
- "pai-bg": "#0A0A0F",
14
- "pai-bg-secondary": "#14141F",
15
- "pai-bg-tertiary": "#1E1E2E",
16
- "pai-surface": "#252538",
17
- "pai-border": "#2E2E45",
18
- "pai-text": "#E8E8F0",
19
- "pai-text-secondary": "#9898B0",
20
- "pai-text-muted": "#5A5A78",
21
- // Accent — electric blue
22
- "pai-accent": "#4A9EFF",
23
- "pai-accent-light": "#7AB8FF",
24
- "pai-accent-dark": "#2A7EDF",
25
- // Voice — warm amber for recording states
26
- "pai-voice": "#FF9F43",
27
- "pai-voice-light": "#FFB976",
28
- "pai-voice-dark": "#E88A2A",
29
- // Status
30
- "pai-success": "#2ED573",
31
- "pai-warning": "#FFA502",
32
- "pai-error": "#FF4757",
33
- },
34
- fontSize: {
35
- "2xs": ["0.625rem", { lineHeight: "0.875rem" }],
36
- "car": ["1.25rem", { lineHeight: "1.75rem" }],
37
- },
38
- spacing: {
39
- "18": "4.5rem",
40
- "22": "5.5rem",
41
- },
42
- },
43
- },
44
- plugins: [],
45
-};
test/widget_test.dart
....@@ -0,0 +1,8 @@
1
+import 'package:flutter_test/flutter_test.dart';
2
+
3
+void main() {
4
+ testWidgets('App smoke test', (WidgetTester tester) async {
5
+ // Placeholder - PAILot requires platform services for full testing
6
+ expect(true, isTrue);
7
+ });
8
+}
tools/build-android.sh
....@@ -0,0 +1,17 @@
1
+#!/bin/bash
2
+# PAILot Android Build Script
3
+set -euo pipefail
4
+
5
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+
8
+cd "$APP_DIR"
9
+
10
+echo "=== Building APK ==="
11
+JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.18/libexec/openjdk.jdk/Contents/Home \
12
+ flutter build apk --release --no-tree-shake-icons
13
+
14
+echo ""
15
+echo "=== Done ==="
16
+echo "APK: build/app/outputs/flutter-apk/app-release.apk"
17
+echo "Run ./tools/deploy-android.sh to install on device"
tools/build.sh
....@@ -0,0 +1,25 @@
1
+#!/bin/bash
2
+# PAILot iOS Build Script
3
+set -euo pipefail
4
+
5
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+
8
+cd "$APP_DIR"
9
+
10
+echo "=== Building IPA ==="
11
+flutter build ipa --release --no-pub --export-method development --no-tree-shake-icons
12
+
13
+echo ""
14
+echo "=== Fixing archive name ==="
15
+ARCHIVE="build/ios/archive/Runner.xcarchive/Info.plist"
16
+if [ -f "$ARCHIVE" ]; then
17
+ plutil -replace Name -string "PAILot" "$ARCHIVE"
18
+ plutil -replace SchemeName -string "PAILot" "$ARCHIVE"
19
+ echo " Archive name set to 'PAILot'"
20
+fi
21
+
22
+echo ""
23
+echo "=== Done ==="
24
+echo "Build complete: build/ios/ipa/pailot.ipa"
25
+echo "Run ./tools/deploy.sh to install on device"
tools/deploy-android.sh
....@@ -0,0 +1,31 @@
1
+#!/bin/bash
2
+# PAILot Android Deploy Script
3
+set -euo pipefail
4
+
5
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+APK="$APP_DIR/build/app/outputs/flutter-apk/app-release.apk"
8
+
9
+cd "$APP_DIR"
10
+
11
+# Check adb connection
12
+if ! adb devices 2>/dev/null | grep -q "device$"; then
13
+ echo "ERROR: No Android device connected. Connect via USB or wireless adb."
14
+ exit 1
15
+fi
16
+
17
+DEVICE_NAME=$(adb shell getprop ro.product.model 2>/dev/null | tr -d '\r')
18
+echo "=== Deploying to: ${DEVICE_NAME:-unknown device} ==="
19
+
20
+if [[ ! -f "$APK" ]]; then
21
+ echo "=== No APK found, building first ==="
22
+ bash tools/build-android.sh
23
+fi
24
+
25
+echo ""
26
+echo "=== Installing APK ==="
27
+adb install -r "$APK"
28
+
29
+echo ""
30
+echo "=== Done ==="
31
+echo "Force-quit and reopen PAILot on your ${DEVICE_NAME:-device}."
tools/deploy.sh
....@@ -0,0 +1,32 @@
1
+#!/bin/bash
2
+# PAILot iOS Deploy Script
3
+set -euo pipefail
4
+
5
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+
8
+cd "$APP_DIR"
9
+
10
+# Device UDIDs
11
+MATTHIAS="8708CADC-3330-50B6-AA0A-1655526A573A"
12
+DEVICE="$MATTHIAS"
13
+
14
+while [[ $# -gt 0 ]]; do
15
+ case "$1" in
16
+ -a) DEVICE="$AMELIE"; shift ;;
17
+ *) shift ;;
18
+ esac
19
+done
20
+
21
+# Build first if no IPA exists
22
+if [[ ! -f build/ios/ipa/pailot.ipa ]]; then
23
+ echo "=== No IPA found, building first ==="
24
+ bash tools/build.sh
25
+fi
26
+
27
+echo "=== Installing on device $DEVICE ==="
28
+xcrun devicectl device install app --device "$DEVICE" build/ios/ipa/pailot.ipa
29
+
30
+echo ""
31
+echo "=== Done ==="
32
+echo "Force-quit and reopen PAILot on your phone."
tsconfig.json
deleted file mode 100644
....@@ -1,19 +0,0 @@
1
-{
2
- "extends": "expo/tsconfig.base",
3
- "compilerOptions": {
4
- "strict": true,
5
- "baseUrl": ".",
6
- "paths": {
7
- "@components": ["./components"],
8
- "@components/*": ["./components/*"],
9
- "@contexts": ["./contexts"],
10
- "@contexts/*": ["./contexts/*"],
11
- "@services": ["./services"],
12
- "@services/*": ["./services/*"],
13
- "@core": ["./core"],
14
- "@core/*": ["./core/*"],
15
- "@types": ["./types"],
16
- "@types/*": ["./types/*"]
17
- }
18
- }
19
-}
types/index.ts
deleted file mode 100644
....@@ -1,164 +0,0 @@
1
-export type MessageRole = "user" | "assistant" | "system";
2
-export type MessageType = "text" | "voice" | "image";
3
-
4
-export interface Message {
5
- id: string;
6
- role: MessageRole;
7
- type: MessageType;
8
- content: string;
9
- audioUri?: string;
10
- imageBase64?: string;
11
- timestamp: number;
12
- status?: "sending" | "sent" | "error";
13
- duration?: number;
14
-}
15
-
16
-export interface ServerConfig {
17
- host: string;
18
- port: number;
19
- localHost?: string;
20
- macAddress?: string;
21
-}
22
-
23
-export type ConnectionStatus = "disconnected" | "connecting" | "reconnecting" | "connected" | "compacting";
24
-
25
-// --- WebSocket protocol ---
26
-
27
-/** Outgoing from app to watcher */
28
-export interface WsTextMessage {
29
- type: "text";
30
- content: string;
31
- sessionId?: string;
32
-}
33
-
34
-export interface WsVoiceMessage {
35
- type: "voice";
36
- audioBase64: string;
37
- content: string;
38
- messageId?: string;
39
- sessionId?: string;
40
-}
41
-
42
-export interface WsImageMessage {
43
- type: "image";
44
- imageBase64: string;
45
- caption: string;
46
- mimeType: string;
47
- sessionId?: string;
48
-}
49
-
50
-export interface WsCommandMessage {
51
- type: "command";
52
- command: string;
53
- args?: Record<string, unknown>;
54
- sessionId?: string;
55
-}
56
-
57
-export type WsOutgoing = WsTextMessage | WsVoiceMessage | WsImageMessage | WsCommandMessage;
58
-
59
-/** Incoming from watcher to app */
60
-export interface WsIncomingText {
61
- type: "text";
62
- content: string;
63
- sessionId?: string;
64
-}
65
-
66
-export interface WsIncomingVoice {
67
- type: "voice";
68
- content: string;
69
- audioBase64?: string;
70
- sessionId?: string;
71
-}
72
-
73
-export interface WsIncomingImage {
74
- type: "image";
75
- imageBase64: string;
76
- caption?: string;
77
- sessionId?: string;
78
-}
79
-
80
-export interface WsSession {
81
- index: number;
82
- name: string;
83
- type: "claude" | "terminal";
84
- kind?: "api" | "visual";
85
- isActive: boolean;
86
- id: string;
87
-}
88
-
89
-export interface WsIncomingSessions {
90
- type: "sessions";
91
- sessions: WsSession[];
92
-}
93
-
94
-export interface WsIncomingSessionSwitched {
95
- type: "session_switched";
96
- name: string;
97
- sessionId: string;
98
-}
99
-
100
-export interface WsIncomingSessionRenamed {
101
- type: "session_renamed";
102
- sessionId: string;
103
- name: string;
104
-}
105
-
106
-export interface WsIncomingTranscript {
107
- type: "transcript";
108
- messageId: string;
109
- content: string;
110
-}
111
-
112
-export interface WsIncomingTyping {
113
- type: "typing";
114
- typing: boolean;
115
- sessionId?: string;
116
-}
117
-
118
-export interface WsIncomingError {
119
- type: "error";
120
- message: string;
121
-}
122
-
123
-export interface WsIncomingStatus {
124
- type: "status";
125
- status: string;
126
-}
127
-
128
-export interface PaiProject {
129
- name: string;
130
- slug: string;
131
- path: string;
132
- sessions: number;
133
-}
134
-
135
-export interface WsIncomingProjects {
136
- type: "projects";
137
- projects: PaiProject[];
138
-}
139
-
140
-export interface WsIncomingUnread {
141
- type: "unread";
142
- sessionId: string;
143
-}
144
-
145
-export interface WsIncomingCatchUp {
146
- type: "catch_up";
147
- messages: Record<string, unknown>[];
148
- serverSeq: number;
149
-}
150
-
151
-export type WsIncoming =
152
- | WsIncomingText
153
- | WsIncomingVoice
154
- | WsIncomingImage
155
- | WsIncomingSessions
156
- | WsIncomingSessionSwitched
157
- | WsIncomingSessionRenamed
158
- | WsIncomingTranscript
159
- | WsIncomingTyping
160
- | WsIncomingError
161
- | WsIncomingStatus
162
- | WsIncomingProjects
163
- | WsIncomingUnread
164
- | WsIncomingCatchUp;
web/favicon.png
Binary files differ
web/icons/Icon-192.png
Binary files differ
web/icons/Icon-512.png
Binary files differ
web/icons/Icon-maskable-192.png
Binary files differ
web/icons/Icon-maskable-512.png
Binary files differ
web/index.html
....@@ -0,0 +1,46 @@
1
+<!DOCTYPE html>
2
+<html>
3
+<head>
4
+ <!--
5
+ If you are serving your web app in a path other than the root, change the
6
+ href value below to reflect the base path you are serving from.
7
+
8
+ The path provided below has to start and end with a slash "/" in order for
9
+ it to work correctly.
10
+
11
+ For more details:
12
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
13
+
14
+ This is a placeholder for base href that will be replaced by the value of
15
+ the `--base-href` argument provided to `flutter build`.
16
+ -->
17
+ <base href="$FLUTTER_BASE_HREF">
18
+
19
+ <meta charset="UTF-8">
20
+ <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21
+ <meta name="description" content="A new Flutter project.">
22
+
23
+ <!-- iOS meta tags & icons -->
24
+ <meta name="mobile-web-app-capable" content="yes">
25
+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
26
+ <meta name="apple-mobile-web-app-title" content="pailot">
27
+ <link rel="apple-touch-icon" href="icons/Icon-192.png">
28
+
29
+ <!-- Favicon -->
30
+ <link rel="icon" type="image/png" href="favicon.png"/>
31
+
32
+ <title>pailot</title>
33
+ <link rel="manifest" href="manifest.json">
34
+</head>
35
+<body>
36
+ <!--
37
+ You can customize the "flutter_bootstrap.js" script.
38
+ This is useful to provide a custom configuration to the Flutter loader
39
+ or to give the user feedback during the initialization process.
40
+
41
+ For more details:
42
+ * https://docs.flutter.dev/platform-integration/web/initialization
43
+ -->
44
+ <script src="flutter_bootstrap.js" async></script>
45
+</body>
46
+</html>
web/manifest.json
....@@ -0,0 +1,35 @@
1
+{
2
+ "name": "pailot",
3
+ "short_name": "pailot",
4
+ "start_url": ".",
5
+ "display": "standalone",
6
+ "background_color": "#0175C2",
7
+ "theme_color": "#0175C2",
8
+ "description": "A new Flutter project.",
9
+ "orientation": "portrait-primary",
10
+ "prefer_related_applications": false,
11
+ "icons": [
12
+ {
13
+ "src": "icons/Icon-192.png",
14
+ "sizes": "192x192",
15
+ "type": "image/png"
16
+ },
17
+ {
18
+ "src": "icons/Icon-512.png",
19
+ "sizes": "512x512",
20
+ "type": "image/png"
21
+ },
22
+ {
23
+ "src": "icons/Icon-maskable-192.png",
24
+ "sizes": "192x192",
25
+ "type": "image/png",
26
+ "purpose": "maskable"
27
+ },
28
+ {
29
+ "src": "icons/Icon-maskable-512.png",
30
+ "sizes": "512x512",
31
+ "type": "image/png",
32
+ "purpose": "maskable"
33
+ }
34
+ ]
35
+}
windows/.gitignore
....@@ -0,0 +1,17 @@
1
+flutter/ephemeral/
2
+
3
+# Visual Studio user-specific files.
4
+*.suo
5
+*.user
6
+*.userosscache
7
+*.sln.docstates
8
+
9
+# Visual Studio build-related files.
10
+x64/
11
+x86/
12
+
13
+# Visual Studio cache files
14
+# files ending in .cache can be ignored
15
+*.[Cc]ache
16
+# but keep track of directories ending in .cache
17
+!*.[Cc]ache/
windows/CMakeLists.txt
....@@ -0,0 +1,108 @@
1
+# Project-level configuration.
2
+cmake_minimum_required(VERSION 3.14)
3
+project(pailot LANGUAGES CXX)
4
+
5
+# The name of the executable created for the application. Change this to change
6
+# the on-disk name of your application.
7
+set(BINARY_NAME "pailot")
8
+
9
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
10
+# versions of CMake.
11
+cmake_policy(VERSION 3.14...3.25)
12
+
13
+# Define build configuration option.
14
+get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
15
+if(IS_MULTICONFIG)
16
+ set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
17
+ CACHE STRING "" FORCE)
18
+else()
19
+ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
20
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
21
+ STRING "Flutter build mode" FORCE)
22
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
23
+ "Debug" "Profile" "Release")
24
+ endif()
25
+endif()
26
+# Define settings for the Profile build mode.
27
+set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
28
+set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
29
+set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
30
+set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
31
+
32
+# Use Unicode for all projects.
33
+add_definitions(-DUNICODE -D_UNICODE)
34
+
35
+# Compilation settings that should be applied to most targets.
36
+#
37
+# Be cautious about adding new options here, as plugins use this function by
38
+# default. In most cases, you should add new options to specific targets instead
39
+# of modifying this function.
40
+function(APPLY_STANDARD_SETTINGS TARGET)
41
+ target_compile_features(${TARGET} PUBLIC cxx_std_17)
42
+ target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
43
+ target_compile_options(${TARGET} PRIVATE /EHsc)
44
+ target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
45
+ target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
46
+endfunction()
47
+
48
+# Flutter library and tool build rules.
49
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
50
+add_subdirectory(${FLUTTER_MANAGED_DIR})
51
+
52
+# Application build; see runner/CMakeLists.txt.
53
+add_subdirectory("runner")
54
+
55
+
56
+# Generated plugin build rules, which manage building the plugins and adding
57
+# them to the application.
58
+include(flutter/generated_plugins.cmake)
59
+
60
+
61
+# === Installation ===
62
+# Support files are copied into place next to the executable, so that it can
63
+# run in place. This is done instead of making a separate bundle (as on Linux)
64
+# so that building and running from within Visual Studio will work.
65
+set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")
66
+# Make the "install" step default, as it's required to run.
67
+set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
68
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
69
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
70
+endif()
71
+
72
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
73
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
74
+
75
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
76
+ COMPONENT Runtime)
77
+
78
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
79
+ COMPONENT Runtime)
80
+
81
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
82
+ COMPONENT Runtime)
83
+
84
+if(PLUGIN_BUNDLED_LIBRARIES)
85
+ install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
86
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
87
+ COMPONENT Runtime)
88
+endif()
89
+
90
+# Copy the native assets provided by the build.dart from all packages.
91
+set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/")
92
+install(DIRECTORY "${NATIVE_ASSETS_DIR}"
93
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
94
+ COMPONENT Runtime)
95
+
96
+# Fully re-copy the assets directory on each build to avoid having stale files
97
+# from a previous install.
98
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
99
+install(CODE "
100
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
101
+ " COMPONENT Runtime)
102
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
103
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
104
+
105
+# Install the AOT library on non-Debug builds only.
106
+install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
107
+ CONFIGURATIONS Profile;Release
108
+ COMPONENT Runtime)
windows/flutter/CMakeLists.txt
....@@ -0,0 +1,109 @@
1
+# This file controls Flutter-level build steps. It should not be edited.
2
+cmake_minimum_required(VERSION 3.14)
3
+
4
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
5
+
6
+# Configuration provided via flutter tool.
7
+include(${EPHEMERAL_DIR}/generated_config.cmake)
8
+
9
+# TODO: Move the rest of this into files in ephemeral. See
10
+# https://github.com/flutter/flutter/issues/57146.
11
+set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
12
+
13
+# Set fallback configurations for older versions of the flutter tool.
14
+if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
15
+ set(FLUTTER_TARGET_PLATFORM "windows-x64")
16
+endif()
17
+
18
+# === Flutter Library ===
19
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
20
+
21
+# Published to parent scope for install step.
22
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
23
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
24
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
25
+set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
26
+
27
+list(APPEND FLUTTER_LIBRARY_HEADERS
28
+ "flutter_export.h"
29
+ "flutter_windows.h"
30
+ "flutter_messenger.h"
31
+ "flutter_plugin_registrar.h"
32
+ "flutter_texture_registrar.h"
33
+)
34
+list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
35
+add_library(flutter INTERFACE)
36
+target_include_directories(flutter INTERFACE
37
+ "${EPHEMERAL_DIR}"
38
+)
39
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
40
+add_dependencies(flutter flutter_assemble)
41
+
42
+# === Wrapper ===
43
+list(APPEND CPP_WRAPPER_SOURCES_CORE
44
+ "core_implementations.cc"
45
+ "standard_codec.cc"
46
+)
47
+list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
48
+list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
49
+ "plugin_registrar.cc"
50
+)
51
+list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
52
+list(APPEND CPP_WRAPPER_SOURCES_APP
53
+ "flutter_engine.cc"
54
+ "flutter_view_controller.cc"
55
+)
56
+list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
57
+
58
+# Wrapper sources needed for a plugin.
59
+add_library(flutter_wrapper_plugin STATIC
60
+ ${CPP_WRAPPER_SOURCES_CORE}
61
+ ${CPP_WRAPPER_SOURCES_PLUGIN}
62
+)
63
+apply_standard_settings(flutter_wrapper_plugin)
64
+set_target_properties(flutter_wrapper_plugin PROPERTIES
65
+ POSITION_INDEPENDENT_CODE ON)
66
+set_target_properties(flutter_wrapper_plugin PROPERTIES
67
+ CXX_VISIBILITY_PRESET hidden)
68
+target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
69
+target_include_directories(flutter_wrapper_plugin PUBLIC
70
+ "${WRAPPER_ROOT}/include"
71
+)
72
+add_dependencies(flutter_wrapper_plugin flutter_assemble)
73
+
74
+# Wrapper sources needed for the runner.
75
+add_library(flutter_wrapper_app STATIC
76
+ ${CPP_WRAPPER_SOURCES_CORE}
77
+ ${CPP_WRAPPER_SOURCES_APP}
78
+)
79
+apply_standard_settings(flutter_wrapper_app)
80
+target_link_libraries(flutter_wrapper_app PUBLIC flutter)
81
+target_include_directories(flutter_wrapper_app PUBLIC
82
+ "${WRAPPER_ROOT}/include"
83
+)
84
+add_dependencies(flutter_wrapper_app flutter_assemble)
85
+
86
+# === Flutter tool backend ===
87
+# _phony_ is a non-existent file to force this command to run every time,
88
+# since currently there's no way to get a full input/output list from the
89
+# flutter tool.
90
+set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
91
+set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
92
+add_custom_command(
93
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
94
+ ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
95
+ ${CPP_WRAPPER_SOURCES_APP}
96
+ ${PHONY_OUTPUT}
97
+ COMMAND ${CMAKE_COMMAND} -E env
98
+ ${FLUTTER_TOOL_ENVIRONMENT}
99
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
100
+ ${FLUTTER_TARGET_PLATFORM} $<CONFIG>
101
+ VERBATIM
102
+)
103
+add_custom_target(flutter_assemble DEPENDS
104
+ "${FLUTTER_LIBRARY}"
105
+ ${FLUTTER_LIBRARY_HEADERS}
106
+ ${CPP_WRAPPER_SOURCES_CORE}
107
+ ${CPP_WRAPPER_SOURCES_PLUGIN}
108
+ ${CPP_WRAPPER_SOURCES_APP}
109
+)
windows/flutter/generated_plugin_registrant.cc
....@@ -0,0 +1,38 @@
1
+//
2
+// Generated file. Do not edit.
3
+//
4
+
5
+// clang-format off
6
+
7
+#include "generated_plugin_registrant.h"
8
+
9
+#include <audioplayers_windows/audioplayers_windows_plugin.h>
10
+#include <bonsoir_windows/bonsoir_windows_plugin_c_api.h>
11
+#include <connectivity_plus/connectivity_plus_windows_plugin.h>
12
+#include <file_selector_windows/file_selector_windows.h>
13
+#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
14
+#include <permission_handler_windows/permission_handler_windows_plugin.h>
15
+#include <record_windows/record_windows_plugin_c_api.h>
16
+#include <share_plus/share_plus_windows_plugin_c_api.h>
17
+#include <url_launcher_windows/url_launcher_windows.h>
18
+
19
+void RegisterPlugins(flutter::PluginRegistry* registry) {
20
+ AudioplayersWindowsPluginRegisterWithRegistrar(
21
+ registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
22
+ BonsoirWindowsPluginCApiRegisterWithRegistrar(
23
+ registry->GetRegistrarForPlugin("BonsoirWindowsPluginCApi"));
24
+ ConnectivityPlusWindowsPluginRegisterWithRegistrar(
25
+ registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
26
+ FileSelectorWindowsRegisterWithRegistrar(
27
+ registry->GetRegistrarForPlugin("FileSelectorWindows"));
28
+ FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
29
+ registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
30
+ PermissionHandlerWindowsPluginRegisterWithRegistrar(
31
+ registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
32
+ RecordWindowsPluginCApiRegisterWithRegistrar(
33
+ registry->GetRegistrarForPlugin("RecordWindowsPluginCApi"));
34
+ SharePlusWindowsPluginCApiRegisterWithRegistrar(
35
+ registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
36
+ UrlLauncherWindowsRegisterWithRegistrar(
37
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
38
+}
windows/flutter/generated_plugin_registrant.h
....@@ -0,0 +1,15 @@
1
+//
2
+// Generated file. Do not edit.
3
+//
4
+
5
+// clang-format off
6
+
7
+#ifndef GENERATED_PLUGIN_REGISTRANT_
8
+#define GENERATED_PLUGIN_REGISTRANT_
9
+
10
+#include <flutter/plugin_registry.h>
11
+
12
+// Registers Flutter plugins.
13
+void RegisterPlugins(flutter::PluginRegistry* registry);
14
+
15
+#endif // GENERATED_PLUGIN_REGISTRANT_
windows/flutter/generated_plugins.cmake
....@@ -0,0 +1,32 @@
1
+#
2
+# Generated file, do not edit.
3
+#
4
+
5
+list(APPEND FLUTTER_PLUGIN_LIST
6
+ audioplayers_windows
7
+ bonsoir_windows
8
+ connectivity_plus
9
+ file_selector_windows
10
+ flutter_secure_storage_windows
11
+ permission_handler_windows
12
+ record_windows
13
+ share_plus
14
+ url_launcher_windows
15
+)
16
+
17
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
18
+)
19
+
20
+set(PLUGIN_BUNDLED_LIBRARIES)
21
+
22
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
23
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
24
+ target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
25
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
26
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
27
+endforeach(plugin)
28
+
29
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
30
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
31
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
32
+endforeach(ffi_plugin)
windows/runner/CMakeLists.txt
....@@ -0,0 +1,40 @@
1
+cmake_minimum_required(VERSION 3.14)
2
+project(runner LANGUAGES CXX)
3
+
4
+# Define the application target. To change its name, change BINARY_NAME in the
5
+# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
6
+# work.
7
+#
8
+# Any new source files that you add to the application should be added here.
9
+add_executable(${BINARY_NAME} WIN32
10
+ "flutter_window.cpp"
11
+ "main.cpp"
12
+ "utils.cpp"
13
+ "win32_window.cpp"
14
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
15
+ "Runner.rc"
16
+ "runner.exe.manifest"
17
+)
18
+
19
+# Apply the standard set of build settings. This can be removed for applications
20
+# that need different build settings.
21
+apply_standard_settings(${BINARY_NAME})
22
+
23
+# Add preprocessor definitions for the build version.
24
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
25
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
26
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
27
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
28
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
29
+
30
+# Disable Windows macros that collide with C++ standard library functions.
31
+target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
32
+
33
+# Add dependency libraries and include directories. Add any application-specific
34
+# dependencies here.
35
+target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
36
+target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
37
+target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
38
+
39
+# Run the Flutter tool portions of the build. This must not be removed.
40
+add_dependencies(${BINARY_NAME} flutter_assemble)
windows/runner/Runner.rc
....@@ -0,0 +1,121 @@
1
+// Microsoft Visual C++ generated resource script.
2
+//
3
+#pragma code_page(65001)
4
+#include "resource.h"
5
+
6
+#define APSTUDIO_READONLY_SYMBOLS
7
+/////////////////////////////////////////////////////////////////////////////
8
+//
9
+// Generated from the TEXTINCLUDE 2 resource.
10
+//
11
+#include "winres.h"
12
+
13
+/////////////////////////////////////////////////////////////////////////////
14
+#undef APSTUDIO_READONLY_SYMBOLS
15
+
16
+/////////////////////////////////////////////////////////////////////////////
17
+// English (United States) resources
18
+
19
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
20
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21
+
22
+#ifdef APSTUDIO_INVOKED
23
+/////////////////////////////////////////////////////////////////////////////
24
+//
25
+// TEXTINCLUDE
26
+//
27
+
28
+1 TEXTINCLUDE
29
+BEGIN
30
+ "resource.h\0"
31
+END
32
+
33
+2 TEXTINCLUDE
34
+BEGIN
35
+ "#include ""winres.h""\r\n"
36
+ "\0"
37
+END
38
+
39
+3 TEXTINCLUDE
40
+BEGIN
41
+ "\r\n"
42
+ "\0"
43
+END
44
+
45
+#endif // APSTUDIO_INVOKED
46
+
47
+
48
+/////////////////////////////////////////////////////////////////////////////
49
+//
50
+// Icon
51
+//
52
+
53
+// Icon with lowest ID value placed first to ensure application icon
54
+// remains consistent on all systems.
55
+IDI_APP_ICON ICON "resources\\app_icon.ico"
56
+
57
+
58
+/////////////////////////////////////////////////////////////////////////////
59
+//
60
+// Version
61
+//
62
+
63
+#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
64
+#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
65
+#else
66
+#define VERSION_AS_NUMBER 1,0,0,0
67
+#endif
68
+
69
+#if defined(FLUTTER_VERSION)
70
+#define VERSION_AS_STRING FLUTTER_VERSION
71
+#else
72
+#define VERSION_AS_STRING "1.0.0"
73
+#endif
74
+
75
+VS_VERSION_INFO VERSIONINFO
76
+ FILEVERSION VERSION_AS_NUMBER
77
+ PRODUCTVERSION VERSION_AS_NUMBER
78
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
79
+#ifdef _DEBUG
80
+ FILEFLAGS VS_FF_DEBUG
81
+#else
82
+ FILEFLAGS 0x0L
83
+#endif
84
+ FILEOS VOS__WINDOWS32
85
+ FILETYPE VFT_APP
86
+ FILESUBTYPE 0x0L
87
+BEGIN
88
+ BLOCK "StringFileInfo"
89
+ BEGIN
90
+ BLOCK "040904e4"
91
+ BEGIN
92
+ VALUE "CompanyName", "com.tekmidian" "\0"
93
+ VALUE "FileDescription", "pailot" "\0"
94
+ VALUE "FileVersion", VERSION_AS_STRING "\0"
95
+ VALUE "InternalName", "pailot" "\0"
96
+ VALUE "LegalCopyright", "Copyright (C) 2026 com.tekmidian. All rights reserved." "\0"
97
+ VALUE "OriginalFilename", "pailot.exe" "\0"
98
+ VALUE "ProductName", "pailot" "\0"
99
+ VALUE "ProductVersion", VERSION_AS_STRING "\0"
100
+ END
101
+ END
102
+ BLOCK "VarFileInfo"
103
+ BEGIN
104
+ VALUE "Translation", 0x409, 1252
105
+ END
106
+END
107
+
108
+#endif // English (United States) resources
109
+/////////////////////////////////////////////////////////////////////////////
110
+
111
+
112
+
113
+#ifndef APSTUDIO_INVOKED
114
+/////////////////////////////////////////////////////////////////////////////
115
+//
116
+// Generated from the TEXTINCLUDE 3 resource.
117
+//
118
+
119
+
120
+/////////////////////////////////////////////////////////////////////////////
121
+#endif // not APSTUDIO_INVOKED
windows/runner/flutter_window.cpp
....@@ -0,0 +1,71 @@
1
+#include "flutter_window.h"
2
+
3
+#include <optional>
4
+
5
+#include "flutter/generated_plugin_registrant.h"
6
+
7
+FlutterWindow::FlutterWindow(const flutter::DartProject& project)
8
+ : project_(project) {}
9
+
10
+FlutterWindow::~FlutterWindow() {}
11
+
12
+bool FlutterWindow::OnCreate() {
13
+ if (!Win32Window::OnCreate()) {
14
+ return false;
15
+ }
16
+
17
+ RECT frame = GetClientArea();
18
+
19
+ // The size here must match the window dimensions to avoid unnecessary surface
20
+ // creation / destruction in the startup path.
21
+ flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
22
+ frame.right - frame.left, frame.bottom - frame.top, project_);
23
+ // Ensure that basic setup of the controller was successful.
24
+ if (!flutter_controller_->engine() || !flutter_controller_->view()) {
25
+ return false;
26
+ }
27
+ RegisterPlugins(flutter_controller_->engine());
28
+ SetChildContent(flutter_controller_->view()->GetNativeWindow());
29
+
30
+ flutter_controller_->engine()->SetNextFrameCallback([&]() {
31
+ this->Show();
32
+ });
33
+
34
+ // Flutter can complete the first frame before the "show window" callback is
35
+ // registered. The following call ensures a frame is pending to ensure the
36
+ // window is shown. It is a no-op if the first frame hasn't completed yet.
37
+ flutter_controller_->ForceRedraw();
38
+
39
+ return true;
40
+}
41
+
42
+void FlutterWindow::OnDestroy() {
43
+ if (flutter_controller_) {
44
+ flutter_controller_ = nullptr;
45
+ }
46
+
47
+ Win32Window::OnDestroy();
48
+}
49
+
50
+LRESULT
51
+FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
52
+ WPARAM const wparam,
53
+ LPARAM const lparam) noexcept {
54
+ // Give Flutter, including plugins, an opportunity to handle window messages.
55
+ if (flutter_controller_) {
56
+ std::optional<LRESULT> result =
57
+ flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
58
+ lparam);
59
+ if (result) {
60
+ return *result;
61
+ }
62
+ }
63
+
64
+ switch (message) {
65
+ case WM_FONTCHANGE:
66
+ flutter_controller_->engine()->ReloadSystemFonts();
67
+ break;
68
+ }
69
+
70
+ return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
71
+}
windows/runner/flutter_window.h
....@@ -0,0 +1,33 @@
1
+#ifndef RUNNER_FLUTTER_WINDOW_H_
2
+#define RUNNER_FLUTTER_WINDOW_H_
3
+
4
+#include <flutter/dart_project.h>
5
+#include <flutter/flutter_view_controller.h>
6
+
7
+#include <memory>
8
+
9
+#include "win32_window.h"
10
+
11
+// A window that does nothing but host a Flutter view.
12
+class FlutterWindow : public Win32Window {
13
+ public:
14
+ // Creates a new FlutterWindow hosting a Flutter view running |project|.
15
+ explicit FlutterWindow(const flutter::DartProject& project);
16
+ virtual ~FlutterWindow();
17
+
18
+ protected:
19
+ // Win32Window:
20
+ bool OnCreate() override;
21
+ void OnDestroy() override;
22
+ LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
23
+ LPARAM const lparam) noexcept override;
24
+
25
+ private:
26
+ // The project to run.
27
+ flutter::DartProject project_;
28
+
29
+ // The Flutter instance hosted by this window.
30
+ std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
31
+};
32
+
33
+#endif // RUNNER_FLUTTER_WINDOW_H_
windows/runner/main.cpp
....@@ -0,0 +1,43 @@
1
+#include <flutter/dart_project.h>
2
+#include <flutter/flutter_view_controller.h>
3
+#include <windows.h>
4
+
5
+#include "flutter_window.h"
6
+#include "utils.h"
7
+
8
+int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
9
+ _In_ wchar_t *command_line, _In_ int show_command) {
10
+ // Attach to console when present (e.g., 'flutter run') or create a
11
+ // new console when running with a debugger.
12
+ if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
13
+ CreateAndAttachConsole();
14
+ }
15
+
16
+ // Initialize COM, so that it is available for use in the library and/or
17
+ // plugins.
18
+ ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
19
+
20
+ flutter::DartProject project(L"data");
21
+
22
+ std::vector<std::string> command_line_arguments =
23
+ GetCommandLineArguments();
24
+
25
+ project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
26
+
27
+ FlutterWindow window(project);
28
+ Win32Window::Point origin(10, 10);
29
+ Win32Window::Size size(1280, 720);
30
+ if (!window.Create(L"pailot", origin, size)) {
31
+ return EXIT_FAILURE;
32
+ }
33
+ window.SetQuitOnClose(true);
34
+
35
+ ::MSG msg;
36
+ while (::GetMessage(&msg, nullptr, 0, 0)) {
37
+ ::TranslateMessage(&msg);
38
+ ::DispatchMessage(&msg);
39
+ }
40
+
41
+ ::CoUninitialize();
42
+ return EXIT_SUCCESS;
43
+}
windows/runner/resource.h
....@@ -0,0 +1,16 @@
1
+//{{NO_DEPENDENCIES}}
2
+// Microsoft Visual C++ generated include file.
3
+// Used by Runner.rc
4
+//
5
+#define IDI_APP_ICON 101
6
+
7
+// Next default values for new objects
8
+//
9
+#ifdef APSTUDIO_INVOKED
10
+#ifndef APSTUDIO_READONLY_SYMBOLS
11
+#define _APS_NEXT_RESOURCE_VALUE 102
12
+#define _APS_NEXT_COMMAND_VALUE 40001
13
+#define _APS_NEXT_CONTROL_VALUE 1001
14
+#define _APS_NEXT_SYMED_VALUE 101
15
+#endif
16
+#endif
windows/runner/resources/app_icon.ico
Binary files differ
windows/runner/runner.exe.manifest
....@@ -0,0 +1,14 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3
+ <application xmlns="urn:schemas-microsoft-com:asm.v3">
4
+ <windowsSettings>
5
+ <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
6
+ </windowsSettings>
7
+ </application>
8
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
9
+ <application>
10
+ <!-- Windows 10 and Windows 11 -->
11
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
12
+ </application>
13
+ </compatibility>
14
+</assembly>
windows/runner/utils.cpp
....@@ -0,0 +1,65 @@
1
+#include "utils.h"
2
+
3
+#include <flutter_windows.h>
4
+#include <io.h>
5
+#include <stdio.h>
6
+#include <windows.h>
7
+
8
+#include <iostream>
9
+
10
+void CreateAndAttachConsole() {
11
+ if (::AllocConsole()) {
12
+ FILE *unused;
13
+ if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
14
+ _dup2(_fileno(stdout), 1);
15
+ }
16
+ if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
17
+ _dup2(_fileno(stdout), 2);
18
+ }
19
+ std::ios::sync_with_stdio();
20
+ FlutterDesktopResyncOutputStreams();
21
+ }
22
+}
23
+
24
+std::vector<std::string> GetCommandLineArguments() {
25
+ // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
26
+ int argc;
27
+ wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
28
+ if (argv == nullptr) {
29
+ return std::vector<std::string>();
30
+ }
31
+
32
+ std::vector<std::string> command_line_arguments;
33
+
34
+ // Skip the first argument as it's the binary name.
35
+ for (int i = 1; i < argc; i++) {
36
+ command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
37
+ }
38
+
39
+ ::LocalFree(argv);
40
+
41
+ return command_line_arguments;
42
+}
43
+
44
+std::string Utf8FromUtf16(const wchar_t* utf16_string) {
45
+ if (utf16_string == nullptr) {
46
+ return std::string();
47
+ }
48
+ unsigned int target_length = ::WideCharToMultiByte(
49
+ CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50
+ -1, nullptr, 0, nullptr, nullptr)
51
+ -1; // remove the trailing null character
52
+ int input_length = (int)wcslen(utf16_string);
53
+ std::string utf8_string;
54
+ if (target_length == 0 || target_length > utf8_string.max_size()) {
55
+ return utf8_string;
56
+ }
57
+ utf8_string.resize(target_length);
58
+ int converted_length = ::WideCharToMultiByte(
59
+ CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
60
+ input_length, utf8_string.data(), target_length, nullptr, nullptr);
61
+ if (converted_length == 0) {
62
+ return std::string();
63
+ }
64
+ return utf8_string;
65
+}
windows/runner/utils.h
....@@ -0,0 +1,19 @@
1
+#ifndef RUNNER_UTILS_H_
2
+#define RUNNER_UTILS_H_
3
+
4
+#include <string>
5
+#include <vector>
6
+
7
+// Creates a console for the process, and redirects stdout and stderr to
8
+// it for both the runner and the Flutter library.
9
+void CreateAndAttachConsole();
10
+
11
+// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12
+// encoded in UTF-8. Returns an empty std::string on failure.
13
+std::string Utf8FromUtf16(const wchar_t* utf16_string);
14
+
15
+// Gets the command line arguments passed in as a std::vector<std::string>,
16
+// encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
17
+std::vector<std::string> GetCommandLineArguments();
18
+
19
+#endif // RUNNER_UTILS_H_
windows/runner/win32_window.cpp
....@@ -0,0 +1,288 @@
1
+#include "win32_window.h"
2
+
3
+#include <dwmapi.h>
4
+#include <flutter_windows.h>
5
+
6
+#include "resource.h"
7
+
8
+namespace {
9
+
10
+/// Window attribute that enables dark mode window decorations.
11
+///
12
+/// Redefined in case the developer's machine has a Windows SDK older than
13
+/// version 10.0.22000.0.
14
+/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
15
+#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
16
+#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
17
+#endif
18
+
19
+constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
20
+
21
+/// Registry key for app theme preference.
22
+///
23
+/// A value of 0 indicates apps should use dark mode. A non-zero or missing
24
+/// value indicates apps should use light mode.
25
+constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
26
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
27
+constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
28
+
29
+// The number of Win32Window objects that currently exist.
30
+static int g_active_window_count = 0;
31
+
32
+using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
33
+
34
+// Scale helper to convert logical scaler values to physical using passed in
35
+// scale factor
36
+int Scale(int source, double scale_factor) {
37
+ return static_cast<int>(source * scale_factor);
38
+}
39
+
40
+// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
41
+// This API is only needed for PerMonitor V1 awareness mode.
42
+void EnableFullDpiSupportIfAvailable(HWND hwnd) {
43
+ HMODULE user32_module = LoadLibraryA("User32.dll");
44
+ if (!user32_module) {
45
+ return;
46
+ }
47
+ auto enable_non_client_dpi_scaling =
48
+ reinterpret_cast<EnableNonClientDpiScaling*>(
49
+ GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
50
+ if (enable_non_client_dpi_scaling != nullptr) {
51
+ enable_non_client_dpi_scaling(hwnd);
52
+ }
53
+ FreeLibrary(user32_module);
54
+}
55
+
56
+} // namespace
57
+
58
+// Manages the Win32Window's window class registration.
59
+class WindowClassRegistrar {
60
+ public:
61
+ ~WindowClassRegistrar() = default;
62
+
63
+ // Returns the singleton registrar instance.
64
+ static WindowClassRegistrar* GetInstance() {
65
+ if (!instance_) {
66
+ instance_ = new WindowClassRegistrar();
67
+ }
68
+ return instance_;
69
+ }
70
+
71
+ // Returns the name of the window class, registering the class if it hasn't
72
+ // previously been registered.
73
+ const wchar_t* GetWindowClass();
74
+
75
+ // Unregisters the window class. Should only be called if there are no
76
+ // instances of the window.
77
+ void UnregisterWindowClass();
78
+
79
+ private:
80
+ WindowClassRegistrar() = default;
81
+
82
+ static WindowClassRegistrar* instance_;
83
+
84
+ bool class_registered_ = false;
85
+};
86
+
87
+WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
88
+
89
+const wchar_t* WindowClassRegistrar::GetWindowClass() {
90
+ if (!class_registered_) {
91
+ WNDCLASS window_class{};
92
+ window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
93
+ window_class.lpszClassName = kWindowClassName;
94
+ window_class.style = CS_HREDRAW | CS_VREDRAW;
95
+ window_class.cbClsExtra = 0;
96
+ window_class.cbWndExtra = 0;
97
+ window_class.hInstance = GetModuleHandle(nullptr);
98
+ window_class.hIcon =
99
+ LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
100
+ window_class.hbrBackground = 0;
101
+ window_class.lpszMenuName = nullptr;
102
+ window_class.lpfnWndProc = Win32Window::WndProc;
103
+ RegisterClass(&window_class);
104
+ class_registered_ = true;
105
+ }
106
+ return kWindowClassName;
107
+}
108
+
109
+void WindowClassRegistrar::UnregisterWindowClass() {
110
+ UnregisterClass(kWindowClassName, nullptr);
111
+ class_registered_ = false;
112
+}
113
+
114
+Win32Window::Win32Window() {
115
+ ++g_active_window_count;
116
+}
117
+
118
+Win32Window::~Win32Window() {
119
+ --g_active_window_count;
120
+ Destroy();
121
+}
122
+
123
+bool Win32Window::Create(const std::wstring& title,
124
+ const Point& origin,
125
+ const Size& size) {
126
+ Destroy();
127
+
128
+ const wchar_t* window_class =
129
+ WindowClassRegistrar::GetInstance()->GetWindowClass();
130
+
131
+ const POINT target_point = {static_cast<LONG>(origin.x),
132
+ static_cast<LONG>(origin.y)};
133
+ HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
134
+ UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
135
+ double scale_factor = dpi / 96.0;
136
+
137
+ HWND window = CreateWindow(
138
+ window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
139
+ Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
140
+ Scale(size.width, scale_factor), Scale(size.height, scale_factor),
141
+ nullptr, nullptr, GetModuleHandle(nullptr), this);
142
+
143
+ if (!window) {
144
+ return false;
145
+ }
146
+
147
+ UpdateTheme(window);
148
+
149
+ return OnCreate();
150
+}
151
+
152
+bool Win32Window::Show() {
153
+ return ShowWindow(window_handle_, SW_SHOWNORMAL);
154
+}
155
+
156
+// static
157
+LRESULT CALLBACK Win32Window::WndProc(HWND const window,
158
+ UINT const message,
159
+ WPARAM const wparam,
160
+ LPARAM const lparam) noexcept {
161
+ if (message == WM_NCCREATE) {
162
+ auto window_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
163
+ SetWindowLongPtr(window, GWLP_USERDATA,
164
+ reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));
165
+
166
+ auto that = static_cast<Win32Window*>(window_struct->lpCreateParams);
167
+ EnableFullDpiSupportIfAvailable(window);
168
+ that->window_handle_ = window;
169
+ } else if (Win32Window* that = GetThisFromHandle(window)) {
170
+ return that->MessageHandler(window, message, wparam, lparam);
171
+ }
172
+
173
+ return DefWindowProc(window, message, wparam, lparam);
174
+}
175
+
176
+LRESULT
177
+Win32Window::MessageHandler(HWND hwnd,
178
+ UINT const message,
179
+ WPARAM const wparam,
180
+ LPARAM const lparam) noexcept {
181
+ switch (message) {
182
+ case WM_DESTROY:
183
+ window_handle_ = nullptr;
184
+ Destroy();
185
+ if (quit_on_close_) {
186
+ PostQuitMessage(0);
187
+ }
188
+ return 0;
189
+
190
+ case WM_DPICHANGED: {
191
+ auto newRectSize = reinterpret_cast<RECT*>(lparam);
192
+ LONG newWidth = newRectSize->right - newRectSize->left;
193
+ LONG newHeight = newRectSize->bottom - newRectSize->top;
194
+
195
+ SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
196
+ newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
197
+
198
+ return 0;
199
+ }
200
+ case WM_SIZE: {
201
+ RECT rect = GetClientArea();
202
+ if (child_content_ != nullptr) {
203
+ // Size and position the child window.
204
+ MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
205
+ rect.bottom - rect.top, TRUE);
206
+ }
207
+ return 0;
208
+ }
209
+
210
+ case WM_ACTIVATE:
211
+ if (child_content_ != nullptr) {
212
+ SetFocus(child_content_);
213
+ }
214
+ return 0;
215
+
216
+ case WM_DWMCOLORIZATIONCOLORCHANGED:
217
+ UpdateTheme(hwnd);
218
+ return 0;
219
+ }
220
+
221
+ return DefWindowProc(window_handle_, message, wparam, lparam);
222
+}
223
+
224
+void Win32Window::Destroy() {
225
+ OnDestroy();
226
+
227
+ if (window_handle_) {
228
+ DestroyWindow(window_handle_);
229
+ window_handle_ = nullptr;
230
+ }
231
+ if (g_active_window_count == 0) {
232
+ WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
233
+ }
234
+}
235
+
236
+Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
237
+ return reinterpret_cast<Win32Window*>(
238
+ GetWindowLongPtr(window, GWLP_USERDATA));
239
+}
240
+
241
+void Win32Window::SetChildContent(HWND content) {
242
+ child_content_ = content;
243
+ SetParent(content, window_handle_);
244
+ RECT frame = GetClientArea();
245
+
246
+ MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
247
+ frame.bottom - frame.top, true);
248
+
249
+ SetFocus(child_content_);
250
+}
251
+
252
+RECT Win32Window::GetClientArea() {
253
+ RECT frame;
254
+ GetClientRect(window_handle_, &frame);
255
+ return frame;
256
+}
257
+
258
+HWND Win32Window::GetHandle() {
259
+ return window_handle_;
260
+}
261
+
262
+void Win32Window::SetQuitOnClose(bool quit_on_close) {
263
+ quit_on_close_ = quit_on_close;
264
+}
265
+
266
+bool Win32Window::OnCreate() {
267
+ // No-op; provided for subclasses.
268
+ return true;
269
+}
270
+
271
+void Win32Window::OnDestroy() {
272
+ // No-op; provided for subclasses.
273
+}
274
+
275
+void Win32Window::UpdateTheme(HWND const window) {
276
+ DWORD light_mode;
277
+ DWORD light_mode_size = sizeof(light_mode);
278
+ LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
279
+ kGetPreferredBrightnessRegValue,
280
+ RRF_RT_REG_DWORD, nullptr, &light_mode,
281
+ &light_mode_size);
282
+
283
+ if (result == ERROR_SUCCESS) {
284
+ BOOL enable_dark_mode = light_mode == 0;
285
+ DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
286
+ &enable_dark_mode, sizeof(enable_dark_mode));
287
+ }
288
+}
windows/runner/win32_window.h
....@@ -0,0 +1,102 @@
1
+#ifndef RUNNER_WIN32_WINDOW_H_
2
+#define RUNNER_WIN32_WINDOW_H_
3
+
4
+#include <windows.h>
5
+
6
+#include <functional>
7
+#include <memory>
8
+#include <string>
9
+
10
+// A class abstraction for a high DPI-aware Win32 Window. Intended to be
11
+// inherited from by classes that wish to specialize with custom
12
+// rendering and input handling
13
+class Win32Window {
14
+ public:
15
+ struct Point {
16
+ unsigned int x;
17
+ unsigned int y;
18
+ Point(unsigned int x, unsigned int y) : x(x), y(y) {}
19
+ };
20
+
21
+ struct Size {
22
+ unsigned int width;
23
+ unsigned int height;
24
+ Size(unsigned int width, unsigned int height)
25
+ : width(width), height(height) {}
26
+ };
27
+
28
+ Win32Window();
29
+ virtual ~Win32Window();
30
+
31
+ // Creates a win32 window with |title| that is positioned and sized using
32
+ // |origin| and |size|. New windows are created on the default monitor. Window
33
+ // sizes are specified to the OS in physical pixels, hence to ensure a
34
+ // consistent size this function will scale the inputted width and height as
35
+ // as appropriate for the default monitor. The window is invisible until
36
+ // |Show| is called. Returns true if the window was created successfully.
37
+ bool Create(const std::wstring& title, const Point& origin, const Size& size);
38
+
39
+ // Show the current window. Returns true if the window was successfully shown.
40
+ bool Show();
41
+
42
+ // Release OS resources associated with window.
43
+ void Destroy();
44
+
45
+ // Inserts |content| into the window tree.
46
+ void SetChildContent(HWND content);
47
+
48
+ // Returns the backing Window handle to enable clients to set icon and other
49
+ // window properties. Returns nullptr if the window has been destroyed.
50
+ HWND GetHandle();
51
+
52
+ // If true, closing this window will quit the application.
53
+ void SetQuitOnClose(bool quit_on_close);
54
+
55
+ // Return a RECT representing the bounds of the current client area.
56
+ RECT GetClientArea();
57
+
58
+ protected:
59
+ // Processes and route salient window messages for mouse handling,
60
+ // size change and DPI. Delegates handling of these to member overloads that
61
+ // inheriting classes can handle.
62
+ virtual LRESULT MessageHandler(HWND window,
63
+ UINT const message,
64
+ WPARAM const wparam,
65
+ LPARAM const lparam) noexcept;
66
+
67
+ // Called when CreateAndShow is called, allowing subclass window-related
68
+ // setup. Subclasses should return false if setup fails.
69
+ virtual bool OnCreate();
70
+
71
+ // Called when Destroy is called.
72
+ virtual void OnDestroy();
73
+
74
+ private:
75
+ friend class WindowClassRegistrar;
76
+
77
+ // OS callback called by message pump. Handles the WM_NCCREATE message which
78
+ // is passed when the non-client area is being created and enables automatic
79
+ // non-client DPI scaling so that the non-client area automatically
80
+ // responds to changes in DPI. All other messages are handled by
81
+ // MessageHandler.
82
+ static LRESULT CALLBACK WndProc(HWND const window,
83
+ UINT const message,
84
+ WPARAM const wparam,
85
+ LPARAM const lparam) noexcept;
86
+
87
+ // Retrieves a class instance pointer for |window|
88
+ static Win32Window* GetThisFromHandle(HWND const window) noexcept;
89
+
90
+ // Update the window frame's theme to match the system theme.
91
+ static void UpdateTheme(HWND const window);
92
+
93
+ bool quit_on_close_ = false;
94
+
95
+ // window handle for top level window.
96
+ HWND window_handle_ = nullptr;
97
+
98
+ // window handle for hosted content.
99
+ HWND child_content_ = nullptr;
100
+};
101
+
102
+#endif // RUNNER_WIN32_WINDOW_H_