From 96ace06e9239e74a56667d50c8d120cf018ccbe8 Mon Sep 17 00:00:00 2001 From: Eliel Date: Sun, 19 Apr 2026 17:58:20 -0300 Subject: [PATCH 01/10] Fix radar aircraft selection and orientation --- .../Views/Components/NativeRadarMapView.swift | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/MeuLabApp/Views/Components/NativeRadarMapView.swift b/MeuLabApp/Views/Components/NativeRadarMapView.swift index 38e0e59..2de8484 100644 --- a/MeuLabApp/Views/Components/NativeRadarMapView.swift +++ b/MeuLabApp/Views/Components/NativeRadarMapView.swift @@ -150,12 +150,14 @@ struct NativeRadarMapView: View { .onChange(of: selectedAircraftID) { _, newID in // If the user just dismissed this aircraft, reject Map re-selection if let newID, newID == dismissedAircraftID { + selectedAircraft = nil + isFollowing = false selectedAircraftID = nil return } - dismissedAircraftID = nil withAnimation(.easeInOut(duration: 0.2)) { if let id = newID { + dismissedAircraftID = nil selectedAircraft = aircraftWithPosition.first { $0.id == id } } else { selectedAircraft = nil @@ -242,6 +244,7 @@ struct NativeRadarMapView: View { ) { RadarAircraftPin( aircraft: ac, + rotationDegrees: aircraftRotationDegrees(for: ac), isSelected: selectedAircraftID == ac.id, isFavorite: favoritesManager.isFavorite(aircraft: ac) ) @@ -532,22 +535,17 @@ struct NativeRadarMapView: View { } Button { - let dismissed = selectedAircraftID - withAnimation(.easeInOut(duration: 0.2)) { - dismissedAircraftID = dismissed - selectedAircraftID = nil - selectedAircraft = nil - isFollowing = false - } - // Allow re-selection of the same aircraft after a short delay - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - dismissedAircraftID = nil - } + dismissSelectedAircraft() } label: { Image(systemName: "xmark.circle.fill") .font(.system(size: 18)) .foregroundStyle(.secondary) + .frame(width: 34, height: 34) + .background(Color(.systemGray5).opacity(0.85)) + .clipShape(Circle()) + .contentShape(Circle()) } + .buttonStyle(.plain) } } @@ -830,8 +828,54 @@ struct NativeRadarMapView: View { return altitudeColor(ac.altitudeFt).opacity(0.6) } + private func aircraftRotationDegrees(for aircraft: Aircraft) -> Double { + // SF Symbol "airplane" is drawn with the nose already tilted ~45 degrees. + let symbolBaseCourse = 45.0 + let course = recentCourse(for: aircraft) ?? aircraft.track ?? 0 + return normalizedDegrees(course - symbolBaseCourse) + } + + private func recentCourse(for aircraft: Aircraft) -> Double? { + guard let history = trailHistory[aircraft.id], history.count >= 2 else { return nil } + return bearing(from: history[history.count - 2], to: history[history.count - 1]) + } + + private func bearing(from start: CLLocationCoordinate2D, to end: CLLocationCoordinate2D) -> Double { + let startLat = start.latitude * .pi / 180 + let endLat = end.latitude * .pi / 180 + let deltaLon = (end.longitude - start.longitude) * .pi / 180 + + let y = sin(deltaLon) * cos(endLat) + let x = + cos(startLat) * sin(endLat) + - sin(startLat) * cos(endLat) * cos(deltaLon) + + return normalizedDegrees(atan2(y, x) * 180 / .pi) + } + + private func normalizedDegrees(_ value: Double) -> Double { + let normalized = value.truncatingRemainder(dividingBy: 360) + return normalized >= 0 ? normalized : normalized + 360 + } + + private func dismissSelectedAircraft() { + let dismissed = selectedAircraftID ?? selectedAircraft?.id + withAnimation(.easeInOut(duration: 0.2)) { + dismissedAircraftID = dismissed + selectedAircraftID = nil + selectedAircraft = nil + isFollowing = false + } + + // Keep the dismissed id briefly so MapKit cannot immediately restore the selection. + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + if selectedAircraftID == nil { + dismissedAircraftID = nil + } + } + } + private func updateTrails() { - guard showTrails else { return } for ac in aircraftWithPosition { guard let lat = ac.lat, let lon = ac.lon else { continue } let coord = CLLocationCoordinate2D(latitude: lat, longitude: lon) @@ -905,6 +949,7 @@ private struct AirportPin: View { struct RadarAircraftPin: View { let aircraft: Aircraft + let rotationDegrees: Double let isSelected: Bool var isFavorite: Bool = false @State private var emergencyPulse = false @@ -944,7 +989,7 @@ struct RadarAircraftPin: View { Image(systemName: aircraft.isMilitary ? "shield.fill" : "airplane") .font(.system(size: isSelected ? 24 : 18, weight: .semibold)) .foregroundStyle(markerColor) - .rotationEffect(.degrees(aircraft.isMilitary ? 0 : (aircraft.track ?? 0))) + .rotationEffect(.degrees(aircraft.isMilitary ? 0 : rotationDegrees)) .shadow(color: markerColor.opacity(0.5), radius: isSelected ? 6 : 3) // Favorite star From 4f92487f20e027089904766e5134a31764503a09 Mon Sep 17 00:00:00 2001 From: Eliel Date: Sun, 19 Apr 2026 18:00:23 -0300 Subject: [PATCH 02/10] Add remaining local project changes --- BIBLE_READER_INTEGRATION_PATTERNS.swift | 328 +++++ MeuLabApp.xcodeproj/project.pbxproj | 136 +- MeuLabApp.xcodeproj/project.pbxproj.backup3 | 1229 ++++++++++++++++++ MeuLabApp.xcodeproj/project.pbxproj.backup4 | 1230 +++++++++++++++++++ MeuLabApp/Core/NetworkEnvironment.swift | 98 +- MeuLabApp/Core/Networking/APIService.swift | 61 +- MeuLabApp/Info.plist | 83 +- MeuLabApp/Models/ADSBModels.swift | 47 +- MeuLabApp/Models/SatelliteModels.swift | 403 ++++-- MeuLabApp/Models/SystemExtrasModels.swift | 14 +- MeuLabApp/Services/APIService.swift | 82 +- QUICKSTART_SECRETS.md | 318 ----- QUICK_START.sh | 181 +++ README.md | 154 --- SECRETS_SETUP.md | 342 ------ TESTING_INSTRUCTIONS.md | 171 --- WATCHSECRETS_SETUP.md | 74 -- XCCONFIG_ALTERNATIVE.md | 275 ----- add_bible_reader_files.py | 99 ++ add_bible_reader_to_project.py | 45 + add_reader_pbxproj.py | 93 ++ add_secrets_swift.py | 73 ++ build_fresh.sh | 5 + final_setup.py | 68 + fix_secrets.py | 91 ++ run_fix.sh | 3 + setup_bible_reader.py | 93 ++ ssh_all.exp | 11 + ssh_analytics.exp | 19 + ssh_cmd.exp | 7 + ssh_create_apis.exp | 113 ++ ssh_ctx.exp | 8 + ssh_inspect.exp | 50 + ssh_inspect2.exp | 36 + ssh_p1.exp | 10 + test_api_ssh.exp | 20 + test_api_ssh2.exp | 44 + verify_build_phases.py | 89 ++ verify_setup.py | 101 ++ xcode_build_phases.py | 85 ++ xcode_integrate.py | 208 ++++ 41 files changed, 4865 insertions(+), 1732 deletions(-) create mode 100644 BIBLE_READER_INTEGRATION_PATTERNS.swift create mode 100644 MeuLabApp.xcodeproj/project.pbxproj.backup3 create mode 100644 MeuLabApp.xcodeproj/project.pbxproj.backup4 delete mode 100644 QUICKSTART_SECRETS.md create mode 100644 QUICK_START.sh delete mode 100644 README.md delete mode 100644 SECRETS_SETUP.md delete mode 100644 TESTING_INSTRUCTIONS.md delete mode 100644 WATCHSECRETS_SETUP.md delete mode 100644 XCCONFIG_ALTERNATIVE.md create mode 100644 add_bible_reader_files.py create mode 100644 add_bible_reader_to_project.py create mode 100644 add_reader_pbxproj.py create mode 100644 add_secrets_swift.py create mode 100644 build_fresh.sh create mode 100644 final_setup.py create mode 100644 fix_secrets.py create mode 100644 run_fix.sh create mode 100644 setup_bible_reader.py create mode 100644 ssh_all.exp create mode 100644 ssh_analytics.exp create mode 100644 ssh_cmd.exp create mode 100644 ssh_create_apis.exp create mode 100644 ssh_ctx.exp create mode 100644 ssh_inspect.exp create mode 100644 ssh_inspect2.exp create mode 100644 ssh_p1.exp create mode 100644 test_api_ssh.exp create mode 100644 test_api_ssh2.exp create mode 100644 verify_build_phases.py create mode 100644 verify_setup.py create mode 100644 xcode_build_phases.py create mode 100644 xcode_integrate.py diff --git a/BIBLE_READER_INTEGRATION_PATTERNS.swift b/BIBLE_READER_INTEGRATION_PATTERNS.swift new file mode 100644 index 0000000..f883e9f --- /dev/null +++ b/BIBLE_READER_INTEGRATION_PATTERNS.swift @@ -0,0 +1,328 @@ +// MARK: - Integration with Existing BibleView + +/* + This file shows how to integrate the new Bible Reader with Siri support + into the existing BibleView/BibleNavigateView structure without duplication. + + Current Structure (Existing): + ├── BibleView (main tab) + ├── BibleNavigateView (books → chapters → verses) + ├── BibleSearchView (full-text search) + └── BibleRandomView (random verse picker) + + New Structure (With Reading Enhancement): + ├── BibleView (main tab) ✓ unchanged + ├── BibleNavigateView (books → chapters) + ├── BibleChapterReaderView ← NEW: reader with Siri integration + ├── BibleSearchView ✓ unchanged + └── BibleRandomView ✓ unchanged +*/ + +import SwiftUI + +// MARK: - Extension: Add Reader Button to BibleNavigateView + +/* + Modify existing /Views/Tabs/BibleNavigateView.swift to add a "Read" button + when a chapter is displayed. + + Current code (hypothetical): + + struct BibleChapterView: View { + let chapter: BibleChapter + + var body: some View { + List(chapter.verses, id: \.number) { verse in + VerseRow(verseNumber: verse.number, text: verse.text) + } + } + } + + → Change to: +*/ + +struct BibleChapterViewWithReader: View { + let bookName: String + let bookSlug: String + let chapterNumber: Int + let verses: [String] + + @State private var showReader = false + @State private var readerViewModel: BibleReaderViewModel? + + var body: some View { + VStack { + // Standard verse list + List(Array(verses.enumerated()), id: \.offset) { index, verse in + VStack(alignment: .leading, spacing: 4) { + Text("\(index + 1)") + .font(.caption) + .fontWeight(.semibold) + .foregroundStyle(.secondary) + + Text(verse) + .font(.body) + } + } + .navigationTitle("Capítulo \(chapterNumber)") + + // Read Button at bottom + Button(action: { showReader = true }) { + HStack { + Image(systemName: "play.circle.fill") + Text("Ler Capítulo") + } + .frame(maxWidth: .infinity) + .padding() + .background(Color.blue) + .foregroundStyle(.white) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .padding() + } + } + .sheet(isPresented: $showReader) { + BibleChapterReaderView() + .onAppear { + let vm = BibleReaderViewModel() + vm.setChapter(book: bookName, chapter: chapterNumber, verses: verses) + self.readerViewModel = vm + } + } + } +} + +// MARK: - Extension: BibleRandomView Integration + +/* + Update BibleRandomView to include a "Read Verse" button that can start reading. + + Current structure (hypothetical): + + struct BibleRandomView: View { + @State private var randomVerse: BibleVerse? + + var body: some View { + // Display random verse + // Button to get another random verse + } + } + + → Extend with reader integration: +*/ + +// Extension on existing view model to support single-verse reading +extension BibleReaderViewModel { + func playSingleVerse(_ verse: String, from book: String, chapter: Int) { + setChapter(book: book, chapter: chapter, verses: [verse]) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + play() + } + } +} + +// MARK: - Extension: BibleSearchView Integration + +/* + Add "Read Results" option to search results. + + Current structure (hypothetical): + + struct BibleSearchView: View { + @State private var searchResults: [SearchResult] + + var body: some View { + List(searchResults) { result in + Text(result.verse) + } + } + } + + → Extend with: +*/ + +struct BibleSearchViewWithReader: View { + @State private var searchQuery = "" + @State private var searchResults: [String] = [] + @State private var showReader = false + @State private var selectedResultIndex = 0 + + var body: some View { + VStack { + SearchBar(text: $searchQuery) + .onChange(of: searchQuery) { oldValue, newValue in + performSearch(newValue) + } + + List(Array(searchResults.enumerated()), id: \.offset) { index, result in + VStack(alignment: .leading, spacing: 4) { + Text(result) + .font(.body) + + Button(action: { + selectedResultIndex = index + showReader = true + }) { + HStack { + Image(systemName: "play.circle") + Text("Ler") + } + .font(.caption) + .foregroundStyle(.blue) + } + } + } + } + .sheet(isPresented: $showReader) { + BibleChapterReaderView() + .onAppear { + let vm = BibleReaderViewModel() + let verse = searchResults[selectedResultIndex] + vm.playSingleVerse(verse, from: "Resultados", chapter: selectedResultIndex + 1) + } + } + } + + private func performSearch(_ query: String) { + // Existing BibleLoader search implementation + // searchResults = BibleLoader.shared.search(query: query) + } +} + +// MARK: - ContentView Integration + +/* + Ensure BibleReaderIntegrationView is used instead of BibleView + when Siri intends to open a reader. + + In ContentView.swift: +*/ + +// Example integration point +struct BibleTabVariant1: View { + @State private var shouldShowReader = false + + var body: some View { + Group { + if shouldShowReader { + BibleReaderIntegrationView() + } else { + BibleView() // Existing view + } + } + .onAppear { + checkForSiriIntent() + } + } + + private func checkForSiriIntent() { + let defaults = UserDefaults.standard + shouldShowReader = defaults.bool(forKey: "bibleReaderShouldPlay") + } +} + +// Alternative: Add reader as sub-tab +struct BibleTabWithReader: View { + @State private var selectedTab = "navigate" + + var body: some View { + TabView(selection: $selectedTab) { + BibleView() + .tabItem { + Label("Navegar", systemImage: "book") + } + .tag("navigate") + + BibleReaderIntegrationView() + .tabItem { + Label("Ler", systemImage: "play.circle") + } + .tag("reader") + } + } +} + +// MARK: - UserDefaults Keys (Centralized) + +struct BibleReaderUserDefaultsKeys { + static let bookName = "bibleReaderBook" + static let chapterNumber = "bibleReaderChapter" + static let shouldAutoPlay = "bibleReaderShouldPlay" + static let action = "bibleReaderAction" + static let lastReadBook = "bibleLastReadBook" + static let lastReadChapter = "bibleLastReadChapter" + static let bookmarkVerses = "bibleBookmarkedVerses" // Future: bookmarking +} + +// MARK: - Persistence Extension + +extension BibleReaderViewModel { + func saveLastChapter() { + let defaults = UserDefaults.standard + defaults.set(currentBook, forKey: BibleReaderUserDefaultsKeys.lastReadBook) + defaults.set(currentChapterNumber, forKey: BibleReaderUserDefaultsKeys.lastReadChapter) + } + + func loadLastChapter() -> Bool { + let defaults = UserDefaults.standard + guard let book = defaults.string(forKey: BibleReaderUserDefaultsKeys.lastReadBook), + let chapter = defaults.integer(forKey: BibleReaderUserDefaultsKeys.lastReadChapter) + as? Int + else { + return false + } + + // Load verses from BibleLoader or your data source + // let verses = BibleLoader.shared.chapter(bookSlug: book.lowercased(), chapterNumber: chapter)?.verses ?? [] + // setChapter(book: book, chapter: chapter, verses: verses) + + return true + } +} + +// MARK: - Shortcut Extension + +/* + If user bookmarks verses, extend to support: + "Ler meus versículos marcados no MeuLabApp" + + Implementation: +*/ + +struct BibleBookmarkedVersesIntent: AppIntent { + static var title: LocalizedStringResource = "Ler Versículos Marcados" + static var description = IntentDescription("Lê todos os versículos que você marcou") + static var openAppWhenRun = true + + func perform() async throws -> some IntentResult & ProvidesDialog { + UserDefaults.standard.set("loadBookmarked", forKey: "bibleReaderAction") + return .result(dialog: IntentDialog(stringLiteral: "Abrindo seus versículos marcados")) + } +} + +// MARK: - Testing Helper + +#if DEBUG + struct BibleReaderTestHelper { + static func testChapter() -> (book: String, chapter: Int, verses: [String]) { + return ( + book: "João", + chapter: 3, + verses: SampleBibleData.johnChapter3Verses + ) + } + + static func setTestData() { + let defaults = UserDefaults.standard + defaults.set("João", forKey: BibleReaderUserDefaultsKeys.bookName) + defaults.set(3, forKey: BibleReaderUserDefaultsKeys.chapterNumber) + defaults.set(true, forKey: BibleReaderUserDefaultsKeys.shouldAutoPlay) + } + + static func clearTestData() { + let defaults = UserDefaults.standard + defaults.removeObject(forKey: BibleReaderUserDefaultsKeys.bookName) + defaults.removeObject(forKey: BibleReaderUserDefaultsKeys.chapterNumber) + defaults.removeObject(forKey: BibleReaderUserDefaultsKeys.shouldAutoPlay) + } + } +#endif diff --git a/MeuLabApp.xcodeproj/project.pbxproj b/MeuLabApp.xcodeproj/project.pbxproj index 7653d7e..432aa83 100644 --- a/MeuLabApp.xcodeproj/project.pbxproj +++ b/MeuLabApp.xcodeproj/project.pbxproj @@ -7,18 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - BIBI02 /* BibleReadingIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBI01 /* BibleReadingIntents.swift */; }; - BIBSP02 /* BibleSpeechService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBSP01 /* BibleSpeechService.swift */; }; - BIBVM02 /* BibleReaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBVM01 /* BibleReaderViewModel.swift */; }; - BIBM02 /* BibleModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBM01 /* BibleModels.swift */; }; - BIBL02 /* BibleLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBL01 /* BibleLoader.swift */; }; - BIBV02 /* BibleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBV01 /* BibleView.swift */; }; - BIBN02 /* BibleNavigateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBN01 /* BibleNavigateView.swift */; }; - BIBS02 /* BibleSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBS01 /* BibleSearchView.swift */; }; - BIBR02 /* BibleRandomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBR01 /* BibleRandomView.swift */; }; - LGM02 /* LiquidGlass+Modifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = LGM01 /* LiquidGlass+Modifiers.swift */; }; - FMDS02 /* FoundationModelService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FMDS01 /* FoundationModelService.swift */; }; - INTV02 /* IntelligenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = INTV01 /* IntelligenceView.swift */; }; 001 /* MeuLabApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101 /* MeuLabApp.swift */; }; 002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 102 /* ContentView.swift */; }; 003 /* ADSBModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 103 /* ADSBModels.swift */; }; @@ -34,7 +22,6 @@ 013 /* RadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113 /* RadioView.swift */; }; 014 /* WeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114 /* WeatherView.swift */; }; 015 /* SatelliteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115 /* SatelliteView.swift */; }; - 016 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; 017 /* AircraftMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118 /* AircraftMapView.swift */; }; 018 /* ACARSModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 119 /* ACARSModels.swift */; }; 019 /* ACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120 /* ACARSView.swift */; }; @@ -69,14 +56,23 @@ 052 /* FirestickModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153 /* FirestickModels.swift */; }; 053 /* NativeRadarMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 154 /* NativeRadarMapView.swift */; }; 3909786604B94EE5BE1AD25A /* MeuLabWatch/Services/WatchSecrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */; }; + 7F0B7866E4944B48AAFB4F3A /* bible.json in Resources */ = {isa = PBXBuildFile; fileRef = EB2CCDD5B45142E9817882CE /* bible.json */; }; A1B2C3D4E5F6A7B8C9D0E1F2 /* MeuLabApp/Core/Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0C1B2D3E4F5A6B7C8D9E0 /* MeuLabApp/Core/Secrets.swift */; }; AC100 /* MeuLabApp/Core/Utils/AircraftClassification.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */; }; B1C2D3E4F5A6B7C8D9E0F1A2 /* MeuLabApp/Core/NetworkEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */; }; + BIBI02 /* BibleReadingIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBI01 /* BibleReadingIntents.swift */; }; + BIBL02 /* BibleLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBL01 /* BibleLoader.swift */; }; + BIBM02 /* BibleModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBM01 /* BibleModels.swift */; }; + BIBN02 /* BibleNavigateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBN01 /* BibleNavigateView.swift */; }; + BIBR02 /* BibleRandomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBR01 /* BibleRandomView.swift */; }; + BIBS02 /* BibleSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBS01 /* BibleSearchView.swift */; }; + BIBSP02 /* BibleSpeechService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBSP01 /* BibleSpeechService.swift */; }; + BIBV02 /* BibleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBV01 /* BibleView.swift */; }; + BIBVM02 /* BibleReaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBVM01 /* BibleReaderViewModel.swift */; }; F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71A10232F2FB5780048CED8 /* WatchRadioView.swift */; }; F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F762D6282F44164400D6BA3B /* OpenSkyService.swift */; }; F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */; }; - 7F0B7866E4944B48AAFB4F3A /* bible.json in Resources */ = {isa = PBXBuildFile; fileRef = EB2CCDD5B45142E9817882CE /* bible.json */; }; F7803D5F2F4A9A7B001C8722 /* Secrets.plist in Resources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; F7803D602F4A9A7B001C8722 /* Secrets.plist in Resources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; F7803D612F4A9A7B001C8722 /* Secrets.plist in Resources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; @@ -88,6 +84,9 @@ F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */; }; FM100 /* MeuLabApp/Core/Services/FavoritesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */; }; + FMDS02 /* FoundationModelService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FMDS01 /* FoundationModelService.swift */; }; + INTV02 /* IntelligenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = INTV01 /* IntelligenceView.swift */; }; + LGM02 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */; }; RR200 /* RemoteRadioModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR100 /* RemoteRadioModels.swift */; }; RR201 /* RemoteRadioAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR101 /* RemoteRadioAPIClient.swift */; }; RR202 /* RemoteRadioWebRTCClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR102 /* RemoteRadioWebRTCClient.swift */; }; @@ -114,8 +113,7 @@ WN10 /* WatchTuyaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN09 /* WatchTuyaView.swift */; }; WN12 /* MeuLabComplications.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN11 /* MeuLabComplications.swift */; }; WN14 /* MeuLabSmartStackWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN15 /* MeuLabSmartStackWidgets.swift */; }; - - EAFD3BB6506D4F608EF69453 /* Secrets.plist in Sources */ = {isa = PBXBuildFile; fileRef = 51ADBBAD15B948D0924D9825 /* Secrets.plist */; };/* End PBXBuildFile section */ +/* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */ = { @@ -167,40 +165,7 @@ }; /* End PBXCopyFilesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - WW901 /* Normalize Embedded Watch Info */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Normalize Embedded Watch Info"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "WATCH_PLIST=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Watch/MeuLabWatch.app/Info.plist\"\nif [ -f \"$WATCH_PLIST\" ]; then\n /usr/libexec/PlistBuddy -c \"Delete :UIDeviceFamily\" \"$WATCH_PLIST\" >/dev/null 2>&1 || true\n /usr/libexec/PlistBuddy -c \"Add :UIDeviceFamily array\" \"$WATCH_PLIST\"\n /usr/libexec/PlistBuddy -c \"Add :UIDeviceFamily:0 integer 4\" \"$WATCH_PLIST\"\nfi\n"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXFileReference section */ - BIBI01 /* BibleReadingIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleReadingIntents.swift; sourceTree = ""; }; - BIBSP01 /* BibleSpeechService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleSpeechService.swift; sourceTree = ""; }; - BIBVM01 /* BibleReaderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleReaderViewModel.swift; sourceTree = ""; }; - FMDS01 /* FoundationModelService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationModelService.swift; sourceTree = ""; }; - BIBM01 /* BibleModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleModels.swift; sourceTree = ""; }; - BIBL01 /* BibleLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleLoader.swift; sourceTree = ""; }; - BIBV01 /* BibleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleView.swift; sourceTree = ""; }; - BIBN01 /* BibleNavigateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleNavigateView.swift; sourceTree = ""; }; - BIBS01 /* BibleSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleSearchView.swift; sourceTree = ""; }; - BIBR01 /* BibleRandomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleRandomView.swift; sourceTree = ""; }; - INTV01 /* IntelligenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntelligenceView.swift; sourceTree = ""; }; 100 /* MeuLabApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 101 /* MeuLabApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp.swift; sourceTree = ""; }; 102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -253,10 +218,19 @@ 153 /* FirestickModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirestickModels.swift; sourceTree = ""; }; 154 /* NativeRadarMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeRadarMapView.swift; sourceTree = ""; }; AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/Utils/AircraftClassification.swift; sourceTree = SOURCE_ROOT; }; + BIBI01 /* BibleReadingIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleReadingIntents.swift; sourceTree = ""; }; + BIBL01 /* BibleLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleLoader.swift; sourceTree = ""; }; + BIBM01 /* BibleModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleModels.swift; sourceTree = ""; }; + BIBN01 /* BibleNavigateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleNavigateView.swift; sourceTree = ""; }; + BIBR01 /* BibleRandomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleRandomView.swift; sourceTree = ""; }; + BIBS01 /* BibleSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleSearchView.swift; sourceTree = ""; }; + BIBSP01 /* BibleSpeechService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleSpeechService.swift; sourceTree = ""; }; + BIBV01 /* BibleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleView.swift; sourceTree = ""; }; + BIBVM01 /* BibleReaderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleReaderViewModel.swift; sourceTree = ""; }; C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/NetworkEnvironment.swift; sourceTree = SOURCE_ROOT; }; - EB2CCDD5B45142E9817882CE /* bible.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = bible.json; sourceTree = ""; }; D916AD0964D84EF1A89E02C6 /* Secrets.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Secrets.plist; sourceTree = ""; }; E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatch/Services/WatchSecrets.swift; sourceTree = ""; }; + EB2CCDD5B45142E9817882CE /* bible.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = bible.json; sourceTree = ""; }; F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; F71A10232F2FB5780048CED8 /* WatchRadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRadioView.swift; sourceTree = ""; }; F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MeuLabApp.entitlements; sourceTree = ""; }; @@ -270,7 +244,9 @@ F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatellitePassPredictor.swift; sourceTree = ""; }; F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNowPlayingFetcher.swift; sourceTree = ""; }; FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/Services/FavoritesManager.swift; sourceTree = SOURCE_ROOT; }; - LGM01 /* LiquidGlass+Modifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/Extensions/LiquidGlass+Modifiers.swift"; sourceTree = SOURCE_ROOT; }; + FMDS01 /* FoundationModelService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationModelService.swift; sourceTree = ""; }; + INTV01 /* IntelligenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntelligenceView.swift; sourceTree = ""; }; + LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/Extensions/LiquidGlass+Modifiers.swift"; sourceTree = SOURCE_ROOT; }; RR100 /* RemoteRadioModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioModels.swift; sourceTree = ""; }; RR101 /* RemoteRadioAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioAPIClient.swift; sourceTree = ""; }; RR102 /* RemoteRadioWebRTCClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioWebRTCClient.swift; sourceTree = ""; }; @@ -539,7 +515,7 @@ C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */, AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */, FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */, - LGM01 /* LiquidGlass+Modifiers.swift */, + LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */, E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */, ); name = "Recovered References"; @@ -571,15 +547,6 @@ path = MeuLabWatch; sourceTree = ""; }; - WN13 /* Complications */ = { - isa = PBXGroup; - children = ( - WN11 /* MeuLabComplications.swift */, - WN15 /* MeuLabSmartStackWidgets.swift */, - ); - path = Complications; - sourceTree = ""; - }; W302 /* Views */ = { isa = PBXGroup; children = ( @@ -616,6 +583,15 @@ path = Models; sourceTree = ""; }; + WN13 /* Complications */ = { + isa = PBXGroup; + children = ( + WN11 /* MeuLabComplications.swift */, + WN15 /* MeuLabSmartStackWidgets.swift */, + ); + path = Complications; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -787,6 +763,28 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + WW901 /* Normalize Embedded Watch Info */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Normalize Embedded Watch Info"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "WATCH_PLIST=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Watch/MeuLabWatch.app/Info.plist\"\nif [ -f \"$WATCH_PLIST\" ]; then\n /usr/libexec/PlistBuddy -c \"Delete :UIDeviceFamily\" \"$WATCH_PLIST\" >/dev/null 2>&1 || true\n /usr/libexec/PlistBuddy -c \"Add :UIDeviceFamily array\" \"$WATCH_PLIST\"\n /usr/libexec/PlistBuddy -c \"Add :UIDeviceFamily:0 integer 4\" \"$WATCH_PLIST\"\nfi\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 401 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -863,7 +861,7 @@ RR202 /* RemoteRadioWebRTCClient.swift in Sources */, RR203 /* RemoteRadioViewModel.swift in Sources */, RR204 /* RemoteRadioView.swift in Sources */, - LGM02 /* LiquidGlass+Modifiers.swift in Sources */, + LGM02 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1083,9 +1081,14 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MeuLabApp/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = MeuLab; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você."; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "MeuLab precisa de acesso para salvar imagens de satélite na sua galeria."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIRequiredDeviceCapabilities = armv7; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1131,9 +1134,14 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MeuLabApp/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = MeuLab; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você."; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "MeuLab precisa de acesso para salvar imagens de satélite na sua galeria."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIRequiredDeviceCapabilities = armv7; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/MeuLabApp.xcodeproj/project.pbxproj.backup3 b/MeuLabApp.xcodeproj/project.pbxproj.backup3 new file mode 100644 index 0000000..922bfd5 --- /dev/null +++ b/MeuLabApp.xcodeproj/project.pbxproj.backup3 @@ -0,0 +1,1229 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 70; + objects = { + +/* Begin PBXBuildFile section */ + 001 /* MeuLabApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101 /* MeuLabApp.swift */; }; + 002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 102 /* ContentView.swift */; }; + 003 /* ADSBModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 103 /* ADSBModels.swift */; }; + 004 /* SystemModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 104 /* SystemModels.swift */; }; + 005 /* RadioModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105 /* RadioModels.swift */; }; + 006 /* WeatherModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106 /* WeatherModels.swift */; }; + 007 /* SatelliteModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107 /* SatelliteModels.swift */; }; + 008 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 108 /* APIService.swift */; }; + 009 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 109 /* AudioPlayer.swift */; }; + 010 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110 /* AppState.swift */; }; + 011 /* ADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111 /* ADSBView.swift */; }; + 012 /* SystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 112 /* SystemView.swift */; }; + 013 /* RadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113 /* RadioView.swift */; }; + 014 /* WeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114 /* WeatherView.swift */; }; + 015 /* SatelliteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115 /* SatelliteView.swift */; }; + 016 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + 017 /* AircraftMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118 /* AircraftMapView.swift */; }; + 018 /* ACARSModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 119 /* ACARSModels.swift */; }; + 019 /* ACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120 /* ACARSView.swift */; }; + 020 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 121 /* MapView.swift */; }; + 021 /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 122 /* PushNotificationManager.swift */; }; + 022 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123 /* LocationManager.swift */; }; + 023 /* RadarWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124 /* RadarWebView.swift */; }; + 024 /* RadarHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125 /* RadarHTML.swift */; }; + 025 /* SystemExtrasModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 126 /* SystemExtrasModels.swift */; }; + 026 /* InfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127 /* InfraView.swift */; }; + 027 /* RadarSplashOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 128 /* RadarSplashOverlay.swift */; }; + 028 /* RadarSplashSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129 /* RadarSplashSwiftUI.swift */; }; + 029 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 130 /* LaunchScreen.storyboard */; }; + 030 /* NotificationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131 /* NotificationModels.swift */; }; + 031 /* NotificationFeedManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132 /* NotificationFeedManager.swift */; }; + 032 /* Formatters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133 /* Formatters.swift */; }; + 033 /* OpenMeteoModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134 /* OpenMeteoModels.swift */; }; + 034 /* LabIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135 /* LabIntents.swift */; }; + 035 /* LabShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136 /* LabShortcuts.swift */; }; + 036 /* AviationStackModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137 /* AviationStackModels.swift */; }; + 037 /* WidgetDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138 /* WidgetDataManager.swift */; }; + 038 /* AnalyticsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139 /* AnalyticsModels.swift */; }; + 039 /* iPadSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140 /* iPadSplitView.swift */; }; + 040 /* EnhancedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 141 /* EnhancedContentView.swift */; }; + 041 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142 /* ThemeManagerView.swift */; }; + 043 /* AnalyticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144 /* AnalyticsView.swift */; }; + 044 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145 /* AlertsView.swift */; }; + 045 /* FlightSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 146 /* FlightSearchView.swift */; }; + 047 /* DataExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148 /* DataExportView.swift */; }; + 048 /* RemoteControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149 /* RemoteControlView.swift */; }; + 049 /* ContainerLogsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 150 /* ContainerLogsView.swift */; }; + 050 /* HealthCheckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151 /* HealthCheckView.swift */; }; + 051 /* StatCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152 /* StatCard.swift */; }; + 052 /* FirestickModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153 /* FirestickModels.swift */; }; + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71A10232F2FB5780048CED8 /* WatchRadioView.swift */; }; + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F762D6282F44164400D6BA3B /* OpenSkyService.swift */; }; + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */; }; + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F795720F2F1347AB0058B81B /* WidgetKit.framework */; }; + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F79572112F1347AB0058B81B /* SwiftUI.framework */; }; + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */; }; + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */; }; + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + F7E628E92F1430BA00763B43 /* LegacyRadarWebViewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */; }; + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */; }; + W001 /* MeuLabWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = W101 /* MeuLabWatchApp.swift */; }; + W002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W102 /* ContentView.swift */; }; + W003 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W103 /* HomeView.swift */; }; + W004 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W104 /* AlertsView.swift */; }; + W005 /* WatchADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W105 /* WatchADSBView.swift */; }; + W006 /* WatchACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W106 /* WatchACARSView.swift */; }; + W007 /* WatchSystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W107 /* WatchSystemView.swift */; }; + W008 /* WatchInfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W108 /* WatchInfraView.swift */; }; + W009 /* WatchWeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W109 /* WatchWeatherView.swift */; }; + W010 /* WatchSatDumpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W110 /* WatchSatDumpView.swift */; }; + W011 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = W111 /* Assets.xcassets */; }; + W012 /* MeuLabWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = W100 /* MeuLabWatch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + W013 /* WatchAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = W113 /* WatchAPIService.swift */; }; + W014 /* WatchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = W114 /* WatchModels.swift */; }; + + 8E67D5B72FC44490AD989D19 /* Secrets.plist in Sources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; + 3909786604B94EE5BE1AD25A /* WatchSecrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E181A3D935D7491286930152 /* WatchSecrets.swift */; };/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F703A8B92F40352B007B6FD3; + remoteInfo = MeuLabNotificationService; + }; + F79572212F1347AC0058B81B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F795720C2F1347AB0058B81B; + remoteInfo = MeuLabWidgetsExtension; + }; + W200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = W400; + remoteInfo = MeuLabWatch; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F79572282F1347AC0058B81B /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */, + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + W300 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + W012 /* MeuLabWatch.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 100 /* MeuLabApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 101 /* MeuLabApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp.swift; sourceTree = ""; }; + 102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 103 /* ADSBModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBModels.swift; sourceTree = ""; }; + 104 /* SystemModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemModels.swift; sourceTree = ""; }; + 105 /* RadioModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioModels.swift; sourceTree = ""; }; + 106 /* WeatherModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherModels.swift; sourceTree = ""; }; + 107 /* SatelliteModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteModels.swift; sourceTree = ""; }; + 108 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; + 109 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; + 110 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 111 /* ADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBView.swift; sourceTree = ""; }; + 112 /* SystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemView.swift; sourceTree = ""; }; + 113 /* RadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioView.swift; sourceTree = ""; }; + 114 /* WeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherView.swift; sourceTree = ""; }; + 115 /* SatelliteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteView.swift; sourceTree = ""; }; + 116 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 117 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 118 /* AircraftMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AircraftMapView.swift; sourceTree = ""; }; + 119 /* ACARSModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSModels.swift; sourceTree = ""; }; + 120 /* ACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSView.swift; sourceTree = ""; }; + 121 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 122 /* PushNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationManager.swift; sourceTree = ""; }; + 123 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; + 124 /* RadarWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarWebView.swift; sourceTree = ""; }; + 125 /* RadarHTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarHTML.swift; sourceTree = ""; }; + 126 /* SystemExtrasModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtrasModels.swift; sourceTree = ""; }; + 127 /* InfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfraView.swift; sourceTree = ""; }; + 128 /* RadarSplashOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashOverlay.swift; sourceTree = ""; }; + 129 /* RadarSplashSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashSwiftUI.swift; sourceTree = ""; }; + 130 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 131 /* NotificationModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationModels.swift; sourceTree = ""; }; + 132 /* NotificationFeedManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFeedManager.swift; sourceTree = ""; }; + 133 /* Formatters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Formatters.swift; sourceTree = ""; }; + 134 /* OpenMeteoModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMeteoModels.swift; sourceTree = ""; }; + 135 /* LabIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabIntents.swift; sourceTree = ""; }; + 136 /* LabShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabShortcuts.swift; sourceTree = ""; }; + 137 /* AviationStackModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AviationStackModels.swift; sourceTree = ""; }; + 138 /* WidgetDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataManager.swift; sourceTree = ""; }; + 139 /* AnalyticsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsModels.swift; sourceTree = ""; }; + 140 /* iPadSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iPadSplitView.swift; sourceTree = ""; }; + 141 /* EnhancedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedContentView.swift; sourceTree = ""; }; + 142 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = ""; }; + 144 /* AnalyticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsView.swift; sourceTree = ""; }; + 145 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + 146 /* FlightSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightSearchView.swift; sourceTree = ""; }; + 148 /* DataExportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExportView.swift; sourceTree = ""; }; + 149 /* RemoteControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteControlView.swift; sourceTree = ""; }; + 150 /* ContainerLogsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerLogsView.swift; sourceTree = ""; }; + 151 /* HealthCheckView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthCheckView.swift; sourceTree = ""; }; + 152 /* StatCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatCard.swift; sourceTree = ""; }; + 153 /* FirestickModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirestickModels.swift; sourceTree = ""; }; + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRadioView.swift; sourceTree = ""; }; + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MeuLabApp.entitlements; sourceTree = ""; }; + F762D6282F44164400D6BA3B /* OpenSkyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSkyService.swift; sourceTree = ""; }; + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryCache.swift; sourceTree = ""; }; + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F795720F2F1347AB0058B81B /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + F79572112F1347AB0058B81B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedWatchContentView.swift; sourceTree = ""; }; + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatellitePassPredictor.swift; sourceTree = ""; }; + F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyRadarWebViewStore.swift; sourceTree = ""; }; + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNowPlayingFetcher.swift; sourceTree = ""; }; + W100 /* MeuLabWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + W101 /* MeuLabWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatchApp.swift; sourceTree = ""; }; + W102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + W103 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + W104 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + W105 /* WatchADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchADSBView.swift; sourceTree = ""; }; + W106 /* WatchACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchACARSView.swift; sourceTree = ""; }; + W107 /* WatchSystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSystemView.swift; sourceTree = ""; }; + W108 /* WatchInfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchInfraView.swift; sourceTree = ""; }; + W109 /* WatchWeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchWeatherView.swift; sourceTree = ""; }; + W110 /* WatchSatDumpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSatDumpView.swift; sourceTree = ""; }; + W111 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + W112 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + W113 /* WatchAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAPIService.swift; sourceTree = ""; }; + W114 /* WatchModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchModels.swift; sourceTree = ""; }; + + D916AD0964D84EF1A89E02C6 /* Secrets.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Secrets.plist; sourceTree = ""; }; + E181A3D935D7491286930152 /* WatchSecrets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatch/Services/WatchSecrets.swift; sourceTree = ""; };/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + }; + F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabNotificationService; sourceTree = ""; }; + F79572132F1347AB0058B81B /* MeuLabWidgets */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabWidgets; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 200 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B72F40352B007B6FD3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720A2F1347AB0058B81B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */, + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W201 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 300 = { + isa = PBXGroup; + children = ( + 301 /* MeuLabApp */, + W301 /* MeuLabWatch */, + F79572132F1347AB0058B81B /* MeuLabWidgets */, + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + F795720E2F1347AB0058B81B /* Frameworks */, + 302 /* Products */, + ); + sourceTree = ""; + }; + 301 /* MeuLabApp */ = { + isa = PBXGroup; + children = ( + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */, + 101 /* MeuLabApp.swift */, + 102 /* ContentView.swift */, + 140 /* iPadSplitView.swift */, + 141 /* EnhancedContentView.swift */, + 117 /* Info.plist */, + 303 /* Models */, + 304 /* Services */, + 305 /* ViewModels */, + 306 /* Views */, + 310 /* Intents */, + 307 /* Resources */, + ); + path = MeuLabApp; + sourceTree = ""; + }; + 302 /* Products */ = { + isa = PBXGroup; + children = ( + 100 /* MeuLabApp.app */, + W100 /* MeuLabWatch.app */, + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */, + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */, + ); + name = Products; + sourceTree = ""; + }; + 303 /* Models */ = { + isa = PBXGroup; + children = ( + 103 /* ADSBModels.swift */, + 119 /* ACARSModels.swift */, + 104 /* SystemModels.swift */, + 126 /* SystemExtrasModels.swift */, + 153 /* FirestickModels.swift */, + 131 /* NotificationModels.swift */, + 105 /* RadioModels.swift */, + 106 /* WeatherModels.swift */, + 107 /* SatelliteModels.swift */, + 134 /* OpenMeteoModels.swift */, + 137 /* AviationStackModels.swift */, + 139 /* AnalyticsModels.swift */, + ); + path = Models; + sourceTree = ""; + }; + 304 /* Services */ = { + isa = PBXGroup; + children = ( + 108 /* APIService.swift */, + 109 /* AudioPlayer.swift */, + 122 /* PushNotificationManager.swift */, + 123 /* LocationManager.swift */, + 132 /* NotificationFeedManager.swift */, + 133 /* Formatters.swift */, + 138 /* WidgetDataManager.swift */, + ); + path = Services; + sourceTree = ""; + }; + 305 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 110 /* AppState.swift */, + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */, + F762D6282F44164400D6BA3B /* OpenSkyService.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 306 /* Views */ = { + isa = PBXGroup; + children = ( + 308 /* Tabs */, + 309 /* Components */, + 311 /* Settings */, + ); + path = Views; + sourceTree = ""; + }; + 307 /* Resources */ = { + isa = PBXGroup; + children = ( + 116 /* Assets.xcassets */, + 130 /* LaunchScreen.storyboard */, + ); + path = Resources; + sourceTree = ""; + }; + 308 /* Tabs */ = { + isa = PBXGroup; + children = ( + 111 /* ADSBView.swift */, + 120 /* ACARSView.swift */, + 112 /* SystemView.swift */, + 127 /* InfraView.swift */, + 113 /* RadioView.swift */, + 114 /* WeatherView.swift */, + 115 /* SatelliteView.swift */, + 144 /* AnalyticsView.swift */, + 145 /* AlertsView.swift */, + 146 /* FlightSearchView.swift */, + 148 /* DataExportView.swift */, + 149 /* RemoteControlView.swift */, + 150 /* ContainerLogsView.swift */, + 151 /* HealthCheckView.swift */, + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */, + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */, + ); + path = Tabs; + sourceTree = ""; + }; + 309 /* Components */ = { + isa = PBXGroup; + children = ( + 118 /* AircraftMapView.swift */, + 121 /* MapView.swift */, + 124 /* RadarWebView.swift */, + 125 /* RadarHTML.swift */, + 128 /* RadarSplashOverlay.swift */, + 129 /* RadarSplashSwiftUI.swift */, + F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */, + 152 /* StatCard.swift */, + ); + path = Components; + sourceTree = ""; + }; + 310 /* Intents */ = { + isa = PBXGroup; + children = ( + 135 /* LabIntents.swift */, + 136 /* LabShortcuts.swift */, + ); + path = Intents; + sourceTree = ""; + }; + 311 /* Settings */ = { + isa = PBXGroup; + children = ( + 142 /* ThemeManagerView.swift */, + ); + path = Settings; + sourceTree = ""; + }; + F795720E2F1347AB0058B81B /* Frameworks */ = { + isa = PBXGroup; + children = ( + F795720F2F1347AB0058B81B /* WidgetKit.framework */, + F79572112F1347AB0058B81B /* SwiftUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + W301 /* MeuLabWatch */ = { + isa = PBXGroup; + children = ( + W101 /* MeuLabWatchApp.swift */, + W102 /* ContentView.swift */, + W112 /* Info.plist */, + W111 /* Assets.xcassets */, + W302 /* Views */, + W303 /* Services */, + W304 /* Models */, + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */, + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */, + ); + path = MeuLabWatch; + sourceTree = ""; + }; + W302 /* Views */ = { + isa = PBXGroup; + children = ( + W103 /* HomeView.swift */, + W104 /* AlertsView.swift */, + W105 /* WatchADSBView.swift */, + W106 /* WatchACARSView.swift */, + W107 /* WatchSystemView.swift */, + W108 /* WatchInfraView.swift */, + W109 /* WatchWeatherView.swift */, + W110 /* WatchSatDumpView.swift */, + ); + path = Views; + sourceTree = ""; + }; + W303 /* Services */ = { + isa = PBXGroup; + children = ( + W113 /* WatchAPIService.swift */, + ); + path = Services; + sourceTree = ""; + }; + W304 /* Models */ = { + isa = PBXGroup; + children = ( + W114 /* WatchModels.swift */, + ); + path = Models; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 400 /* MeuLabApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */; + buildPhases = ( + 401 /* Sources */, + 200 /* Frameworks */, + 402 /* Resources */, + W300 /* Embed Watch Content */, + F79572282F1347AC0058B81B /* Embed Foundation Extensions */, + ); + buildRules = ( + ); + dependencies = ( + W401 /* PBXTargetDependency */, + F79572222F1347AC0058B81B /* PBXTargetDependency */, + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */, + ); + name = MeuLabApp; + productName = MeuLabApp; + productReference = 100 /* MeuLabApp.app */; + productType = "com.apple.product-type.application"; + }; + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */ = { + isa = PBXNativeTarget; + buildConfigurationList = F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */; + buildPhases = ( + F703A8B62F40352B007B6FD3 /* Sources */, + F703A8B72F40352B007B6FD3 /* Frameworks */, + F703A8B82F40352B007B6FD3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + ); + name = MeuLabNotificationService; + packageProductDependencies = ( + ); + productName = MeuLabNotificationService; + productReference = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; + productType = "com.apple.product-type.app-extension"; + }; + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */; + buildPhases = ( + F79572092F1347AB0058B81B /* Sources */, + F795720A2F1347AB0058B81B /* Frameworks */, + F795720B2F1347AB0058B81B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F79572132F1347AB0058B81B /* MeuLabWidgets */, + ); + name = MeuLabWidgetsExtension; + packageProductDependencies = ( + ); + productName = MeuLabWidgetsExtension; + productReference = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; + W400 /* MeuLabWatch */ = { + isa = PBXNativeTarget; + buildConfigurationList = W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */; + buildPhases = ( + W402 /* Sources */, + W201 /* Frameworks */, + W403 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MeuLabWatch; + productName = MeuLabWatch; + productReference = W100 /* MeuLabWatch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 600 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2620; + LastUpgradeCheck = 2620; + TargetAttributes = { + 400 = { + CreatedOnToolsVersion = 15.0; + }; + F703A8B92F40352B007B6FD3 = { + CreatedOnToolsVersion = 26.2; + }; + F795720C2F1347AB0058B81B = { + CreatedOnToolsVersion = 26.2; + }; + W400 = { + CreatedOnToolsVersion = 15.0; + }; + }; + }; + buildConfigurationList = 601 /* Build configuration list for PBXProject "MeuLabApp" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = "pt-BR"; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + "pt-BR", + ); + mainGroup = 300; + productRefGroup = 302 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 400 /* MeuLabApp */, + W400 /* MeuLabWatch */, + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */, + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 402 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */, + 029 /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B82F40352B007B6FD3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720B2F1347AB0058B81B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 016 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W403 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + W011 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 401 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 001 /* MeuLabApp.swift in Sources */, + 002 /* ContentView.swift in Sources */, + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */, + 003 /* ADSBModels.swift in Sources */, + 004 /* SystemModels.swift in Sources */, + 052 /* FirestickModels.swift in Sources */, + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */, + 005 /* RadioModels.swift in Sources */, + 006 /* WeatherModels.swift in Sources */, + 007 /* SatelliteModels.swift in Sources */, + 008 /* APIService.swift in Sources */, + 009 /* AudioPlayer.swift in Sources */, + 010 /* AppState.swift in Sources */, + 011 /* ADSBView.swift in Sources */, + 012 /* SystemView.swift in Sources */, + 013 /* RadioView.swift in Sources */, + 014 /* WeatherView.swift in Sources */, + 015 /* SatelliteView.swift in Sources */, + 017 /* AircraftMapView.swift in Sources */, + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */, + 018 /* ACARSModels.swift in Sources */, + 019 /* ACARSView.swift in Sources */, + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */, + 020 /* MapView.swift in Sources */, + 021 /* PushNotificationManager.swift in Sources */, + 022 /* LocationManager.swift in Sources */, + 023 /* RadarWebView.swift in Sources */, + 024 /* RadarHTML.swift in Sources */, + 025 /* SystemExtrasModels.swift in Sources */, + 026 /* InfraView.swift in Sources */, + 027 /* RadarSplashOverlay.swift in Sources */, + F7E628E92F1430BA00763B43 /* LegacyRadarWebViewStore.swift in Sources */, + 028 /* RadarSplashSwiftUI.swift in Sources */, + 030 /* NotificationModels.swift in Sources */, + 031 /* NotificationFeedManager.swift in Sources */, + 032 /* Formatters.swift in Sources */, + 033 /* OpenMeteoModels.swift in Sources */, + 034 /* LabIntents.swift in Sources */, + 035 /* LabShortcuts.swift in Sources */, + 036 /* AviationStackModels.swift in Sources */, + 037 /* WidgetDataManager.swift in Sources */, + 038 /* AnalyticsModels.swift in Sources */, + 039 /* iPadSplitView.swift in Sources */, + 040 /* EnhancedContentView.swift in Sources */, + 041 /* ThemeManagerView.swift in Sources */, + 043 /* AnalyticsView.swift in Sources */, + 044 /* AlertsView.swift in Sources */, + 045 /* FlightSearchView.swift in Sources */, + 047 /* DataExportView.swift in Sources */, + 048 /* RemoteControlView.swift in Sources */, + 049 /* ContainerLogsView.swift in Sources */, + 050 /* HealthCheckView.swift in Sources */, + 051 /* StatCard.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B62F40352B007B6FD3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F79572092F1347AB0058B81B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W402 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */, + W001 /* MeuLabWatchApp.swift in Sources */, + W002 /* ContentView.swift in Sources */, + W003 /* HomeView.swift in Sources */, + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */, + W004 /* AlertsView.swift in Sources */, + W005 /* WatchADSBView.swift in Sources */, + W006 /* WatchACARSView.swift in Sources */, + W007 /* WatchSystemView.swift in Sources */, + W008 /* WatchInfraView.swift in Sources */, + W009 /* WatchWeatherView.swift in Sources */, + W010 /* WatchSatDumpView.swift in Sources */, + W013 /* WatchAPIService.swift in Sources */, + W014 /* WatchModels.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + targetProxy = F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */; + }; + F79572222F1347AC0058B81B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + targetProxy = F79572212F1347AC0058B81B /* PBXContainerItemProxy */; + }; + W401 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = W400 /* MeuLabWatch */; + targetProxy = W200 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 700 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + 701 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; + 702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F703A8C22F40352B007B6FD3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F703A8C32F40352B007B6FD3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F79572262F1347AC0058B81B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F79572272F1347AC0058B81B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + W702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + W703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 702 /* Debug */, + 703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 601 /* Build configuration list for PBXProject "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 700 /* Debug */, + 701 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F703A8C22F40352B007B6FD3 /* Debug */, + F703A8C32F40352B007B6FD3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F79572262F1347AC0058B81B /* Debug */, + F79572272F1347AC0058B81B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + W702 /* Debug */, + W703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 600 /* Project object */; +} diff --git a/MeuLabApp.xcodeproj/project.pbxproj.backup4 b/MeuLabApp.xcodeproj/project.pbxproj.backup4 new file mode 100644 index 0000000..fb993a4 --- /dev/null +++ b/MeuLabApp.xcodeproj/project.pbxproj.backup4 @@ -0,0 +1,1230 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 70; + objects = { + +/* Begin PBXBuildFile section */ + 001 /* MeuLabApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101 /* MeuLabApp.swift */; }; + 002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 102 /* ContentView.swift */; }; + 003 /* ADSBModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 103 /* ADSBModels.swift */; }; + 004 /* SystemModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 104 /* SystemModels.swift */; }; + 005 /* RadioModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105 /* RadioModels.swift */; }; + 006 /* WeatherModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106 /* WeatherModels.swift */; }; + 007 /* SatelliteModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107 /* SatelliteModels.swift */; }; + 008 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 108 /* APIService.swift */; }; + 009 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 109 /* AudioPlayer.swift */; }; + 010 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110 /* AppState.swift */; }; + 011 /* ADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111 /* ADSBView.swift */; }; + 012 /* SystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 112 /* SystemView.swift */; }; + 013 /* RadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113 /* RadioView.swift */; }; + 014 /* WeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114 /* WeatherView.swift */; }; + 015 /* SatelliteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115 /* SatelliteView.swift */; }; + 016 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + 017 /* AircraftMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118 /* AircraftMapView.swift */; }; + 018 /* ACARSModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 119 /* ACARSModels.swift */; }; + 019 /* ACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120 /* ACARSView.swift */; }; + 020 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 121 /* MapView.swift */; }; + 021 /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 122 /* PushNotificationManager.swift */; }; + 022 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123 /* LocationManager.swift */; }; + 023 /* RadarWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124 /* RadarWebView.swift */; }; + 024 /* RadarHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125 /* RadarHTML.swift */; }; + 025 /* SystemExtrasModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 126 /* SystemExtrasModels.swift */; }; + 026 /* InfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127 /* InfraView.swift */; }; + 027 /* RadarSplashOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 128 /* RadarSplashOverlay.swift */; }; + 028 /* RadarSplashSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129 /* RadarSplashSwiftUI.swift */; }; + 029 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 130 /* LaunchScreen.storyboard */; }; + 030 /* NotificationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131 /* NotificationModels.swift */; }; + 031 /* NotificationFeedManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132 /* NotificationFeedManager.swift */; }; + 032 /* Formatters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133 /* Formatters.swift */; }; + 033 /* OpenMeteoModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134 /* OpenMeteoModels.swift */; }; + 034 /* LabIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135 /* LabIntents.swift */; }; + 035 /* LabShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136 /* LabShortcuts.swift */; }; + 036 /* AviationStackModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137 /* AviationStackModels.swift */; }; + 037 /* WidgetDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138 /* WidgetDataManager.swift */; }; + 038 /* AnalyticsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139 /* AnalyticsModels.swift */; }; + 039 /* iPadSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140 /* iPadSplitView.swift */; }; + 040 /* EnhancedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 141 /* EnhancedContentView.swift */; }; + 041 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142 /* ThemeManagerView.swift */; }; + 043 /* AnalyticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144 /* AnalyticsView.swift */; }; + 044 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145 /* AlertsView.swift */; }; + 045 /* FlightSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 146 /* FlightSearchView.swift */; }; + 047 /* DataExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148 /* DataExportView.swift */; }; + 048 /* RemoteControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149 /* RemoteControlView.swift */; }; + 049 /* ContainerLogsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 150 /* ContainerLogsView.swift */; }; + 050 /* HealthCheckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151 /* HealthCheckView.swift */; }; + 051 /* StatCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152 /* StatCard.swift */; }; + 052 /* FirestickModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153 /* FirestickModels.swift */; }; + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71A10232F2FB5780048CED8 /* WatchRadioView.swift */; }; + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F762D6282F44164400D6BA3B /* OpenSkyService.swift */; }; + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */; }; + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F795720F2F1347AB0058B81B /* WidgetKit.framework */; }; + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F79572112F1347AB0058B81B /* SwiftUI.framework */; }; + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */; }; + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */; }; + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + F7E628E92F1430BA00763B43 /* LegacyRadarWebViewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */; }; + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */; }; + W001 /* MeuLabWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = W101 /* MeuLabWatchApp.swift */; }; + W002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W102 /* ContentView.swift */; }; + W003 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W103 /* HomeView.swift */; }; + W004 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W104 /* AlertsView.swift */; }; + W005 /* WatchADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W105 /* WatchADSBView.swift */; }; + W006 /* WatchACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W106 /* WatchACARSView.swift */; }; + W007 /* WatchSystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W107 /* WatchSystemView.swift */; }; + W008 /* WatchInfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W108 /* WatchInfraView.swift */; }; + W009 /* WatchWeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W109 /* WatchWeatherView.swift */; }; + W010 /* WatchSatDumpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W110 /* WatchSatDumpView.swift */; }; + W011 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = W111 /* Assets.xcassets */; }; + W012 /* MeuLabWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = W100 /* MeuLabWatch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + W013 /* WatchAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = W113 /* WatchAPIService.swift */; }; + W014 /* WatchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = W114 /* WatchModels.swift */; }; + + 8E67D5B72FC44490AD989D19 /* Secrets.plist in Sources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; + 3909786604B94EE5BE1AD25A /* WatchSecrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E181A3D935D7491286930152 /* WatchSecrets.swift */; };/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F703A8B92F40352B007B6FD3; + remoteInfo = MeuLabNotificationService; + }; + F79572212F1347AC0058B81B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F795720C2F1347AB0058B81B; + remoteInfo = MeuLabWidgetsExtension; + }; + W200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = W400; + remoteInfo = MeuLabWatch; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F79572282F1347AC0058B81B /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */, + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + W300 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + W012 /* MeuLabWatch.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 100 /* MeuLabApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 101 /* MeuLabApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp.swift; sourceTree = ""; }; + 102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 103 /* ADSBModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBModels.swift; sourceTree = ""; }; + 104 /* SystemModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemModels.swift; sourceTree = ""; }; + 105 /* RadioModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioModels.swift; sourceTree = ""; }; + 106 /* WeatherModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherModels.swift; sourceTree = ""; }; + 107 /* SatelliteModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteModels.swift; sourceTree = ""; }; + 108 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; + 109 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; + 110 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 111 /* ADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBView.swift; sourceTree = ""; }; + 112 /* SystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemView.swift; sourceTree = ""; }; + 113 /* RadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioView.swift; sourceTree = ""; }; + 114 /* WeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherView.swift; sourceTree = ""; }; + 115 /* SatelliteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteView.swift; sourceTree = ""; }; + 116 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 117 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 118 /* AircraftMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AircraftMapView.swift; sourceTree = ""; }; + 119 /* ACARSModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSModels.swift; sourceTree = ""; }; + 120 /* ACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSView.swift; sourceTree = ""; }; + 121 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 122 /* PushNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationManager.swift; sourceTree = ""; }; + 123 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; + 124 /* RadarWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarWebView.swift; sourceTree = ""; }; + 125 /* RadarHTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarHTML.swift; sourceTree = ""; }; + 126 /* SystemExtrasModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtrasModels.swift; sourceTree = ""; }; + 127 /* InfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfraView.swift; sourceTree = ""; }; + 128 /* RadarSplashOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashOverlay.swift; sourceTree = ""; }; + 129 /* RadarSplashSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashSwiftUI.swift; sourceTree = ""; }; + 130 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 131 /* NotificationModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationModels.swift; sourceTree = ""; }; + 132 /* NotificationFeedManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFeedManager.swift; sourceTree = ""; }; + 133 /* Formatters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Formatters.swift; sourceTree = ""; }; + 134 /* OpenMeteoModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMeteoModels.swift; sourceTree = ""; }; + 135 /* LabIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabIntents.swift; sourceTree = ""; }; + 136 /* LabShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabShortcuts.swift; sourceTree = ""; }; + 137 /* AviationStackModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AviationStackModels.swift; sourceTree = ""; }; + 138 /* WidgetDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataManager.swift; sourceTree = ""; }; + 139 /* AnalyticsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsModels.swift; sourceTree = ""; }; + 140 /* iPadSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iPadSplitView.swift; sourceTree = ""; }; + 141 /* EnhancedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedContentView.swift; sourceTree = ""; }; + 142 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = ""; }; + 144 /* AnalyticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsView.swift; sourceTree = ""; }; + 145 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + 146 /* FlightSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightSearchView.swift; sourceTree = ""; }; + 148 /* DataExportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExportView.swift; sourceTree = ""; }; + 149 /* RemoteControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteControlView.swift; sourceTree = ""; }; + 150 /* ContainerLogsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerLogsView.swift; sourceTree = ""; }; + 151 /* HealthCheckView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthCheckView.swift; sourceTree = ""; }; + 152 /* StatCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatCard.swift; sourceTree = ""; }; + 153 /* FirestickModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirestickModels.swift; sourceTree = ""; }; + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRadioView.swift; sourceTree = ""; }; + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MeuLabApp.entitlements; sourceTree = ""; }; + F762D6282F44164400D6BA3B /* OpenSkyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSkyService.swift; sourceTree = ""; }; + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryCache.swift; sourceTree = ""; }; + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F795720F2F1347AB0058B81B /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + F79572112F1347AB0058B81B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedWatchContentView.swift; sourceTree = ""; }; + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatellitePassPredictor.swift; sourceTree = ""; }; + F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyRadarWebViewStore.swift; sourceTree = ""; }; + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNowPlayingFetcher.swift; sourceTree = ""; }; + W100 /* MeuLabWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + W101 /* MeuLabWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatchApp.swift; sourceTree = ""; }; + W102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + W103 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + W104 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + W105 /* WatchADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchADSBView.swift; sourceTree = ""; }; + W106 /* WatchACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchACARSView.swift; sourceTree = ""; }; + W107 /* WatchSystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSystemView.swift; sourceTree = ""; }; + W108 /* WatchInfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchInfraView.swift; sourceTree = ""; }; + W109 /* WatchWeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchWeatherView.swift; sourceTree = ""; }; + W110 /* WatchSatDumpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSatDumpView.swift; sourceTree = ""; }; + W111 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + W112 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + W113 /* WatchAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAPIService.swift; sourceTree = ""; }; + W114 /* WatchModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchModels.swift; sourceTree = ""; }; + + D916AD0964D84EF1A89E02C6 /* Secrets.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Secrets.plist; sourceTree = ""; }; + E181A3D935D7491286930152 /* WatchSecrets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatch/Services/WatchSecrets.swift; sourceTree = ""; };/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + }; + F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabNotificationService; sourceTree = ""; }; + F79572132F1347AB0058B81B /* MeuLabWidgets */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabWidgets; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 200 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B72F40352B007B6FD3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720A2F1347AB0058B81B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */, + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W201 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 300 = { + isa = PBXGroup; + children = ( + 301 /* MeuLabApp */, + W301 /* MeuLabWatch */, + F79572132F1347AB0058B81B /* MeuLabWidgets */, + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + F795720E2F1347AB0058B81B /* Frameworks */, + 302 /* Products */, + ); + sourceTree = ""; + }; + 301 /* MeuLabApp */ = { + isa = PBXGroup; + children = ( + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */, + 101 /* MeuLabApp.swift */, + 102 /* ContentView.swift */, + 140 /* iPadSplitView.swift */, + 141 /* EnhancedContentView.swift */, + 117 /* Info.plist */, + 303 /* Models */, + 304 /* Services */, + 305 /* ViewModels */, + 306 /* Views */, + 310 /* Intents */, + 307 /* Resources */, + ); + path = MeuLabApp; + sourceTree = ""; + }; + 302 /* Products */ = { + isa = PBXGroup; + children = ( + 100 /* MeuLabApp.app */, + W100 /* MeuLabWatch.app */, + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */, + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */, + ); + name = Products; + sourceTree = ""; + }; + 303 /* Models */ = { + isa = PBXGroup; + children = ( + 103 /* ADSBModels.swift */, + 119 /* ACARSModels.swift */, + 104 /* SystemModels.swift */, + 126 /* SystemExtrasModels.swift */, + 153 /* FirestickModels.swift */, + 131 /* NotificationModels.swift */, + 105 /* RadioModels.swift */, + 106 /* WeatherModels.swift */, + 107 /* SatelliteModels.swift */, + 134 /* OpenMeteoModels.swift */, + 137 /* AviationStackModels.swift */, + 139 /* AnalyticsModels.swift */, + ); + path = Models; + sourceTree = ""; + }; + 304 /* Services */ = { + isa = PBXGroup; + children = ( + 108 /* APIService.swift */, + 109 /* AudioPlayer.swift */, + 122 /* PushNotificationManager.swift */, + 123 /* LocationManager.swift */, + 132 /* NotificationFeedManager.swift */, + 133 /* Formatters.swift */, + 138 /* WidgetDataManager.swift */, + ); + path = Services; + sourceTree = ""; + }; + 305 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 110 /* AppState.swift */, + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */, + F762D6282F44164400D6BA3B /* OpenSkyService.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 306 /* Views */ = { + isa = PBXGroup; + children = ( + 308 /* Tabs */, + 309 /* Components */, + 311 /* Settings */, + ); + path = Views; + sourceTree = ""; + }; + 307 /* Resources */ = { + isa = PBXGroup; + children = ( + 116 /* Assets.xcassets */, + 130 /* LaunchScreen.storyboard */, + ); + path = Resources; + sourceTree = ""; + }; + 308 /* Tabs */ = { + isa = PBXGroup; + children = ( + 111 /* ADSBView.swift */, + 120 /* ACARSView.swift */, + 112 /* SystemView.swift */, + 127 /* InfraView.swift */, + 113 /* RadioView.swift */, + 114 /* WeatherView.swift */, + 115 /* SatelliteView.swift */, + 144 /* AnalyticsView.swift */, + 145 /* AlertsView.swift */, + 146 /* FlightSearchView.swift */, + 148 /* DataExportView.swift */, + 149 /* RemoteControlView.swift */, + 150 /* ContainerLogsView.swift */, + 151 /* HealthCheckView.swift */, + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */, + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */, + ); + path = Tabs; + sourceTree = ""; + }; + 309 /* Components */ = { + isa = PBXGroup; + children = ( + 118 /* AircraftMapView.swift */, + 121 /* MapView.swift */, + 124 /* RadarWebView.swift */, + 125 /* RadarHTML.swift */, + 128 /* RadarSplashOverlay.swift */, + 129 /* RadarSplashSwiftUI.swift */, + F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */, + 152 /* StatCard.swift */, + ); + path = Components; + sourceTree = ""; + }; + 310 /* Intents */ = { + isa = PBXGroup; + children = ( + 135 /* LabIntents.swift */, + 136 /* LabShortcuts.swift */, + ); + path = Intents; + sourceTree = ""; + }; + 311 /* Settings */ = { + isa = PBXGroup; + children = ( + 142 /* ThemeManagerView.swift */, + ); + path = Settings; + sourceTree = ""; + }; + F795720E2F1347AB0058B81B /* Frameworks */ = { + isa = PBXGroup; + children = ( + F795720F2F1347AB0058B81B /* WidgetKit.framework */, + F79572112F1347AB0058B81B /* SwiftUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + W301 /* MeuLabWatch */ = { + isa = PBXGroup; + children = ( + W101 /* MeuLabWatchApp.swift */, + W102 /* ContentView.swift */, + W112 /* Info.plist */, + W111 /* Assets.xcassets */, + W302 /* Views */, + W303 /* Services */, + W304 /* Models */, + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */, + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */, + ); + path = MeuLabWatch; + sourceTree = ""; + }; + W302 /* Views */ = { + isa = PBXGroup; + children = ( + W103 /* HomeView.swift */, + W104 /* AlertsView.swift */, + W105 /* WatchADSBView.swift */, + W106 /* WatchACARSView.swift */, + W107 /* WatchSystemView.swift */, + W108 /* WatchInfraView.swift */, + W109 /* WatchWeatherView.swift */, + W110 /* WatchSatDumpView.swift */, + ); + path = Views; + sourceTree = ""; + }; + W303 /* Services */ = { + isa = PBXGroup; + children = ( + W113 /* WatchAPIService.swift */, + ); + path = Services; + sourceTree = ""; + }; + W304 /* Models */ = { + isa = PBXGroup; + children = ( + W114 /* WatchModels.swift */, + ); + path = Models; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 400 /* MeuLabApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */; + buildPhases = ( + 401 /* Sources */, + 200 /* Frameworks */, + 402 /* Resources */, + W300 /* Embed Watch Content */, + F79572282F1347AC0058B81B /* Embed Foundation Extensions */, + ); + buildRules = ( + ); + dependencies = ( + W401 /* PBXTargetDependency */, + F79572222F1347AC0058B81B /* PBXTargetDependency */, + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */, + ); + name = MeuLabApp; + productName = MeuLabApp; + productReference = 100 /* MeuLabApp.app */; + productType = "com.apple.product-type.application"; + }; + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */ = { + isa = PBXNativeTarget; + buildConfigurationList = F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */; + buildPhases = ( + F703A8B62F40352B007B6FD3 /* Sources */, + F703A8B72F40352B007B6FD3 /* Frameworks */, + F703A8B82F40352B007B6FD3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + ); + name = MeuLabNotificationService; + packageProductDependencies = ( + ); + productName = MeuLabNotificationService; + productReference = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; + productType = "com.apple.product-type.app-extension"; + }; + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */; + buildPhases = ( + F79572092F1347AB0058B81B /* Sources */, + F795720A2F1347AB0058B81B /* Frameworks */, + F795720B2F1347AB0058B81B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F79572132F1347AB0058B81B /* MeuLabWidgets */, + ); + name = MeuLabWidgetsExtension; + packageProductDependencies = ( + ); + productName = MeuLabWidgetsExtension; + productReference = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; + W400 /* MeuLabWatch */ = { + isa = PBXNativeTarget; + buildConfigurationList = W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */; + buildPhases = ( + W402 /* Sources */, + W201 /* Frameworks */, + W403 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MeuLabWatch; + productName = MeuLabWatch; + productReference = W100 /* MeuLabWatch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 600 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2620; + LastUpgradeCheck = 2620; + TargetAttributes = { + 400 = { + CreatedOnToolsVersion = 15.0; + }; + F703A8B92F40352B007B6FD3 = { + CreatedOnToolsVersion = 26.2; + }; + F795720C2F1347AB0058B81B = { + CreatedOnToolsVersion = 26.2; + }; + W400 = { + CreatedOnToolsVersion = 15.0; + }; + }; + }; + buildConfigurationList = 601 /* Build configuration list for PBXProject "MeuLabApp" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = "pt-BR"; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + "pt-BR", + ); + mainGroup = 300; + productRefGroup = 302 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 400 /* MeuLabApp */, + W400 /* MeuLabWatch */, + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */, + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 402 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */, + 029 /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B82F40352B007B6FD3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720B2F1347AB0058B81B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 016 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W403 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + W011 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 401 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 001 /* MeuLabApp.swift in Sources */, + 002 /* ContentView.swift in Sources */, + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */, + 003 /* ADSBModels.swift in Sources */, + 004 /* SystemModels.swift in Sources */, + 052 /* FirestickModels.swift in Sources */, + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */, + 005 /* RadioModels.swift in Sources */, + 006 /* WeatherModels.swift in Sources */, + 007 /* SatelliteModels.swift in Sources */, + 008 /* APIService.swift in Sources */, + 009 /* AudioPlayer.swift in Sources */, + 010 /* AppState.swift in Sources */, + 011 /* ADSBView.swift in Sources */, + 012 /* SystemView.swift in Sources */, + 013 /* RadioView.swift in Sources */, + 014 /* WeatherView.swift in Sources */, + 015 /* SatelliteView.swift in Sources */, + 017 /* AircraftMapView.swift in Sources */, + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */, + 018 /* ACARSModels.swift in Sources */, + 019 /* ACARSView.swift in Sources */, + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */, + 020 /* MapView.swift in Sources */, + 021 /* PushNotificationManager.swift in Sources */, + 022 /* LocationManager.swift in Sources */, + 023 /* RadarWebView.swift in Sources */, + 024 /* RadarHTML.swift in Sources */, + 025 /* SystemExtrasModels.swift in Sources */, + 026 /* InfraView.swift in Sources */, + 027 /* RadarSplashOverlay.swift in Sources */, + F7E628E92F1430BA00763B43 /* LegacyRadarWebViewStore.swift in Sources */, + 028 /* RadarSplashSwiftUI.swift in Sources */, + 030 /* NotificationModels.swift in Sources */, + 031 /* NotificationFeedManager.swift in Sources */, + 032 /* Formatters.swift in Sources */, + 033 /* OpenMeteoModels.swift in Sources */, + 034 /* LabIntents.swift in Sources */, + 035 /* LabShortcuts.swift in Sources */, + 036 /* AviationStackModels.swift in Sources */, + 037 /* WidgetDataManager.swift in Sources */, + 038 /* AnalyticsModels.swift in Sources */, + 039 /* iPadSplitView.swift in Sources */, + 040 /* EnhancedContentView.swift in Sources */, + 041 /* ThemeManagerView.swift in Sources */, + 043 /* AnalyticsView.swift in Sources */, + 044 /* AlertsView.swift in Sources */, + 045 /* FlightSearchView.swift in Sources */, + 047 /* DataExportView.swift in Sources */, + 048 /* RemoteControlView.swift in Sources */, + 049 /* ContainerLogsView.swift in Sources */, + 050 /* HealthCheckView.swift in Sources */, + 051 /* StatCard.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B62F40352B007B6FD3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F79572092F1347AB0058B81B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W402 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */, + W001 /* MeuLabWatchApp.swift in Sources */, + W002 /* ContentView.swift in Sources */, + W003 /* HomeView.swift in Sources */, + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */, + W004 /* AlertsView.swift in Sources */, + W005 /* WatchADSBView.swift in Sources */, + W006 /* WatchACARSView.swift in Sources */, + W007 /* WatchSystemView.swift in Sources */, + W008 /* WatchInfraView.swift in Sources */, + W009 /* WatchWeatherView.swift in Sources */, + W010 /* WatchSatDumpView.swift in Sources */, + W013 /* WatchAPIService.swift in Sources */, + W014 /* WatchModels.swift in Sources */, + + 3909786604B94EE5BE1AD25A /* WatchSecrets.swift in Sources */,); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + targetProxy = F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */; + }; + F79572222F1347AC0058B81B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + targetProxy = F79572212F1347AC0058B81B /* PBXContainerItemProxy */; + }; + W401 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = W400 /* MeuLabWatch */; + targetProxy = W200 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 700 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + 701 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; + 702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F703A8C22F40352B007B6FD3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F703A8C32F40352B007B6FD3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F79572262F1347AC0058B81B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F79572272F1347AC0058B81B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + W702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + W703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 702 /* Debug */, + 703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 601 /* Build configuration list for PBXProject "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 700 /* Debug */, + 701 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F703A8C22F40352B007B6FD3 /* Debug */, + F703A8C32F40352B007B6FD3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F79572262F1347AC0058B81B /* Debug */, + F79572272F1347AC0058B81B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + W702 /* Debug */, + W703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 600 /* Project object */; +} diff --git a/MeuLabApp/Core/NetworkEnvironment.swift b/MeuLabApp/Core/NetworkEnvironment.swift index 985eaab..5fe389a 100644 --- a/MeuLabApp/Core/NetworkEnvironment.swift +++ b/MeuLabApp/Core/NetworkEnvironment.swift @@ -1,9 +1,6 @@ import Foundation -import Network -import Combine -/// Detects whether the device is on the local network and provides -/// the fastest base URLs (local IP vs Cloudflare tunnel). +/// Provides the base API URL. Always uses the production remote endpoint. @MainActor final class NetworkEnvironment: ObservableObject { static let shared = NetworkEnvironment() @@ -12,97 +9,8 @@ final class NetworkEnvironment: ObservableObject { @Published private(set) var apiBaseURL: String = "https://app.meulab.fun" - /// True when using direct local IP (fast path) + /// Always false — local network probing has been removed. @Published private(set) var isLocal: Bool = false - // MARK: - Constants - - private let localAPIBase = "http://10.0.1.50:8090" - private let remoteAPIBase = "https://app.meulab.fun" - - // MARK: - Private - - private let monitor = NWPathMonitor() - private let probeSession: URLSession - private var monitorStarted = false - - private init() { - let config = URLSessionConfiguration.ephemeral - config.timeoutIntervalForRequest = 1.5 - config.timeoutIntervalForResource = 2 - config.waitsForConnectivity = false - config.requestCachePolicy = .reloadIgnoringLocalCacheData - self.probeSession = URLSession(configuration: config) - - startMonitoring() - } - - // MARK: - Network Monitoring - - private func startMonitoring() { - guard !monitorStarted else { return } - monitorStarted = true - - monitor.pathUpdateHandler = { [weak self] _ in - Task { @MainActor in - await self?.probeLocal() - } - } - monitor.start(queue: .global(qos: .utility)) - - // Also probe immediately on launch - Task { - await probeLocal() - } - } - - /// Quickly probe whether the local API is reachable. - private func probeLocal() async { - let probeURL = URL(string: "\(localAPIBase)/api/adsb/summary")! - var request = URLRequest(url: probeURL) - request.httpMethod = "GET" - request.timeoutInterval = 1.5 - // Add auth token - let token = Secrets.apiToken.isEmpty ? Secrets.apiTokenAlternative : Secrets.apiToken - if !token.isEmpty { - request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") - } - - do { - let (_, response) = try await probeSession.data(for: request) - if let http = response as? HTTPURLResponse, (200...299).contains(http.statusCode) { - switchToLocal() - return - } - } catch { - // probe failed – not on local network - } - switchToRemote() - } - - private func switchToLocal() { - guard !isLocal else { return } - isLocal = true - apiBaseURL = localAPIBase - pushChanges() - } - - private func switchToRemote() { - guard isLocal || apiBaseURL == remoteAPIBase else { - // Already remote on first launch - isLocal = false - return - } - isLocal = false - apiBaseURL = remoteAPIBase - pushChanges() - } - - /// Push current URL to APIService. - private func pushChanges() { - let url = apiBaseURL - Task { - await APIService.shared.updateBaseURL(url) - } - } + private init() {} } diff --git a/MeuLabApp/Core/Networking/APIService.swift b/MeuLabApp/Core/Networking/APIService.swift index 618d7bf..d86842d 100644 --- a/MeuLabApp/Core/Networking/APIService.swift +++ b/MeuLabApp/Core/Networking/APIService.swift @@ -5,14 +5,9 @@ actor APIService: APIServiceProtocol { static let shared = APIService() private var baseURL = "https://app.meulab.fun" - private let adsbLolURL = "https://voa.meulab.fun" + private let radarBaseURL = "https://radar.meulab.fun" private let apiToken: String - // Localização do receptor para buscar aeronaves próximas - private let receiverLat = -20.512504 - private let receiverLon = -47.400830 - private let searchRadiusNm = 250 // Raio de busca em milhas náuticas - private let session: URLSession private init() { @@ -27,19 +22,21 @@ actor APIService: APIServiceProtocol { private static func loadAPIToken() -> String { if let token = Bundle.main.infoDictionary?["API_TOKEN"] as? String, - !token.isEmpty { + !token.isEmpty + { return token } guard let url = Bundle.main.url(forResource: "Secrets", withExtension: "plist"), - let data = try? Data(contentsOf: url), - let plist = try? PropertyListSerialization.propertyList( + let data = try? Data(contentsOf: url), + let plist = try? PropertyListSerialization.propertyList( from: data, options: [], format: nil - ) as? [String: Any], - let token = plist["API_TOKEN"] as? String, - !token.isEmpty else { + ) as? [String: Any], + let token = plist["API_TOKEN"] as? String, + !token.isEmpty + else { Logger.warning("API_TOKEN não encontrado em Info.plist ou Secrets.plist") return "" } @@ -116,11 +113,11 @@ actor APIService: APIServiceProtocol { try await fetch("/api/adsb/aircraft?limit=\(limit)") } - // MARK: - ADSB.lol Network API + // MARK: - Radar direto (radar.meulab.fun) - /// Busca aeronaves da rede ADSB.lol num raio ao redor do receptor + /// Busca aeronaves ao vivo diretamente do receptor ADS-B local (sem autenticação) func fetchADSBLolAircraft() async throws -> [Aircraft] { - let urlString = "\(adsbLolURL)/v2/lat/\(receiverLat)/lon/\(receiverLon)/dist/\(searchRadiusNm)" + let urlString = "\(radarBaseURL)/data/aircraft.json" guard let url = URL(string: urlString) else { throw APIError.invalidURL @@ -128,6 +125,7 @@ actor APIService: APIServiceProtocol { var request = URLRequest(url: url) request.setValue("MeuLabApp/1.0", forHTTPHeaderField: "User-Agent") + request.cachePolicy = .reloadIgnoringLocalCacheData Logger.logRequest(method: "GET", url: urlString) @@ -136,27 +134,30 @@ actor APIService: APIServiceProtocol { (data, response) = try await session.data(for: request) } catch { let apiError = APIError.from(error) - Logger.logError(apiError, context: "ADSB.lol Aircraft") + Logger.logError(apiError, context: "Radar Aircraft") throw apiError } guard let httpResponse = response as? HTTPURLResponse, - httpResponse.statusCode == 200 else { + httpResponse.statusCode == 200 + else { let statusCode = (response as? HTTPURLResponse)?.statusCode ?? 0 throw APIError.serverError(statusCode) } do { let decoder = JSONDecoder() - let adsbLolResponse = try decoder.decode(ADSBLolResponse.self, from: data) + let radarResponse = try decoder.decode(RadarAircraftResponse.self, from: data) - // Converter para Aircraft com source = .network - let aircraft = adsbLolResponse.ac?.compactMap { $0.toAircraft() } ?? [] - Logger.info("ADSB.lol retornou \(aircraft.count) aeronaves") + // Converte para Aircraft, filtrando apenas os com posição + let aircraft = radarResponse.aircraft.compactMap { $0.toAircraft() } + Logger.info( + "Radar retornou \(aircraft.count) aeronaves (total: \(radarResponse.aircraft.count))" + ) return aircraft } catch { let decodingError = APIError.decodingError(error.localizedDescription) - Logger.logError(decodingError, context: "ADSB.lol Decoding") + Logger.logError(decodingError, context: "Radar Decoding") throw decodingError } } @@ -192,7 +193,8 @@ actor APIService: APIServiceProtocol { func imageURL(passName: String, folderName: String, imageName: String) -> URL? { let path = "/api/satdump/image?pass=\(passName)&folder=\(folderName)&image=\(imageName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), - var components = URLComponents(string: "\(baseURL)\(encodedPath)") else { + var components = URLComponents(string: "\(baseURL)\(encodedPath)") + else { return nil } return components.url @@ -213,7 +215,8 @@ actor APIService: APIServiceProtocol { } func searchACARSMessages(query: String) async throws -> ACARSSearchResult { - guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { + guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) + else { throw APIError.invalidURL } return try await fetch("/api/acars/search?q=\(encoded)") @@ -221,14 +224,18 @@ actor APIService: APIServiceProtocol { // MARK: - Image Loading with Auth - func fetchImageData(passName: String, folderName: String, imageName: String) async throws -> Data { - let path = "/api/satdump/image?pass=\(passName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? passName)&folder=\(folderName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? folderName)&image=\(imageName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? imageName)" + func fetchImageData(passName: String, folderName: String, imageName: String) async throws + -> Data + { + let path = + "/api/satdump/image?pass=\(passName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? passName)&folder=\(folderName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? folderName)&image=\(imageName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? imageName)" let request = try makeRequest(path: path) let (data, response) = try await session.data(for: request) guard let httpResponse = response as? HTTPURLResponse, - httpResponse.statusCode == 200 else { + httpResponse.statusCode == 200 + else { throw APIError.serverError((response as? HTTPURLResponse)?.statusCode ?? 0) } diff --git a/MeuLabApp/Info.plist b/MeuLabApp/Info.plist index 2e7b98d..d3c9fe2 100644 --- a/MeuLabApp/Info.plist +++ b/MeuLabApp/Info.plist @@ -2,94 +2,38 @@ - CFBundleDevelopmentRegion - pt_BR - CFBundleDisplayName - MeuLab - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - - UIBackgroundModes - - audio - fetch - remote-notification - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSPhotoLibraryAddUsageDescription - MeuLab precisa de acesso para salvar imagens de satélite na sua galeria. - NSLocationWhenInUseUsageDescription - MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição. - NSLocationAlwaysAndWhenInUseUsageDescription - MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você. NSAppTransportSecurity NSAllowsArbitraryLoads - NSAllowsLocalNetworking - NSAllowsArbitraryLoadsInWebContent + NSAllowsLocalNetworking + NSExceptionDomains - apple-mapkit.com + 10.0.1.50 NSExceptionAllowsInsecureHTTPLoads - + NSIncludesSubdomains - meulab.fun + apple-mapkit.com NSExceptionAllowsInsecureHTTPLoads NSIncludesSubdomains - webnow.com.br + meulab.fun NSExceptionAllowsInsecureHTTPLoads - + NSIncludesSubdomains - 10.0.1.50 + webnow.com.br NSExceptionAllowsInsecureHTTPLoads @@ -98,5 +42,16 @@ + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UIBackgroundModes + + audio + fetch + remote-notification + diff --git a/MeuLabApp/Models/ADSBModels.swift b/MeuLabApp/Models/ADSBModels.swift index 5c53019..79c8dda 100644 --- a/MeuLabApp/Models/ADSBModels.swift +++ b/MeuLabApp/Models/ADSBModels.swift @@ -498,45 +498,63 @@ struct Aircraft: Codable, Identifiable, Equatable { } } -// MARK: - ADSB.lol API Response +// MARK: - radar.meulab.fun Direct API Response +struct RadarAircraftResponse: Codable { + let now: Double + let messages: Int + let aircraft: [ADSBLolAircraft] +} + +// MARK: - ADSB.lol / Backend Proxy Response struct ADSBLolResponse: Codable { - let ac: [ADSBLolAircraft]? + let ac: [ADSBLolAircraft]? // adsb.lol format + let aircraft: [ADSBLolAircraft]? // radar.meulab.fun / backend format let now: Double? let total: Int? let ctime: Double? let ptime: Int? + + var allAircraft: [ADSBLolAircraft] { + aircraft ?? ac ?? [] + } } struct ADSBLolAircraft: Codable { let hex: String? + let type: String? // Fonte: adsb_icao, mlat, adsr_icao let flight: String? - let t: String? // Tipo de aeronave - let r: String? // Registro + let t: String? // Tipo ICAO de aeronave (ex: "A320") + let r: String? // Matrícula (ex: "PR-MYK") + let desc: String? // Descrição longa (ex: "AIRBUS A-320") let lat: Double? let lon: Double? let alt_baro: IntOrString? let alt_geom: Int? - let gs: Double? // Ground speed + let gs: Double? // Ground speed em nós let track: Double? - let baro_rate: Int? + let geom_rate: Int? // Taxa de subida/descida geométrica (GPS) + let baro_rate: Int? // Taxa de subida/descida barométrica let squawk: String? + let emergency: String? let category: String? + let seen: Double? + let seen_pos: Double? + let rssi: Double? + let r_dst: Double? // Distância do receptor em km + let r_dir: Double? // Direção do receptor em graus + let messages: Int? + let mlat: [String]? let nav_altitude_mcp: Int? let nav_heading: Double? let nic: Int? let rc: Int? - let seen_pos: Double? let version: Int? let nic_baro: Int? let nac_p: Int? let nac_v: Int? let sil: Int? let sil_type: String? - let mlat: [String]? let tisb: [String]? - let messages: Int? - let seen: Double? - let rssi: Double? // Converter para Aircraft func toAircraft() -> Aircraft? { @@ -549,6 +567,9 @@ struct ADSBLolAircraft: Codable { altFt = alt_geom ?? 0 } + // r_dst vem em km do receptor; converter para nm + let distNm: Double? = r_dst.map { $0 / 1.852 } + return Aircraft( id: hex, hex: hex, @@ -562,8 +583,8 @@ struct ADSBLolAircraft: Codable { altitudeFt: altFt, speedKt: Int(gs ?? 0), speedKmh: Int((gs ?? 0) * 1.852), - distanceNm: nil, - verticalRateFpm: baro_rate ?? 0, + distanceNm: distNm, + verticalRateFpm: baro_rate ?? geom_rate ?? 0, squawk: squawk, source: .network ) diff --git a/MeuLabApp/Models/SatelliteModels.swift b/MeuLabApp/Models/SatelliteModels.swift index 3d13b88..b4debc3 100644 --- a/MeuLabApp/Models/SatelliteModels.swift +++ b/MeuLabApp/Models/SatelliteModels.swift @@ -100,17 +100,20 @@ struct SatelliteImage: Codable, Identifiable, Equatable { // MARK: - Last Images Response +/// Response from /api/satdump/last/images (new schema: pass object + root images array). struct LastImages: Codable, Equatable { let timestamp: String - let passName: String + let pass: SatDumpRecordedPass? + let count: Int? let images: [SatelliteImage] enum CodingKeys: String, CodingKey { - case timestamp - case passName = "pass_name" - case images + case timestamp, pass, count, images } + /// Derived pass name for display / AI summary (backwards-compat with old `pass_name` field). + var passName: String { pass?.name ?? pass?.id ?? "" } + var iconName: String { let n = passName.lowercased() if n.contains("meteor") { return "satellite.fill" } @@ -143,6 +146,17 @@ struct PassesListPaginated: Codable { case totalCount = "total_count" case totalPages = "total_pages" } + + init(from decoder: Decoder) throws { + let c = try decoder.container(keyedBy: CodingKeys.self) + timestamp = try c.decode(String.self, forKey: .timestamp) + count = try c.decode(Int.self, forKey: .count) + totalCount = try c.decodeIfPresent(Int.self, forKey: .totalCount) ?? count + page = try c.decodeIfPresent(Int.self, forKey: .page) ?? 1 + limit = try c.decodeIfPresent(Int.self, forKey: .limit) ?? 50 + totalPages = try c.decodeIfPresent(Int.self, forKey: .totalPages) ?? 1 + passes = try c.decodeIfPresent([SatellitePassExtended].self, forKey: .passes) ?? [] + } } struct SatellitePassExtended: Codable, Identifiable, Equatable { @@ -151,6 +165,9 @@ struct SatellitePassExtended: Codable, Identifiable, Equatable { let imageCount: Int let sizeMb: Double let qualityStars: Int + let satellite: String? + let passTimestamp: String? + let products: [String]? var id: String { name } @@ -159,11 +176,24 @@ struct SatellitePassExtended: Codable, Identifiable, Equatable { } enum CodingKeys: String, CodingKey { - case name + case name, satellite, products case imageFolder = "image_folder" case imageCount = "image_count" case sizeMb = "size_mb" case qualityStars = "quality_stars" + case passTimestamp = "timestamp" + } + + init(from decoder: Decoder) throws { + let c = try decoder.container(keyedBy: CodingKeys.self) + name = try c.decode(String.self, forKey: .name) + imageFolder = try c.decodeIfPresent(String.self, forKey: .imageFolder) ?? "" + imageCount = try c.decodeIfPresent(Int.self, forKey: .imageCount) ?? 0 + sizeMb = try c.decodeIfPresent(Double.self, forKey: .sizeMb) ?? 0.0 + qualityStars = try c.decodeIfPresent(Int.self, forKey: .qualityStars) ?? 0 + satellite = try c.decodeIfPresent(String.self, forKey: .satellite) + passTimestamp = try c.decodeIfPresent(String.self, forKey: .passTimestamp) + products = try c.decodeIfPresent([String].self, forKey: .products) } var iconName: String { @@ -248,36 +278,81 @@ struct CleanupPassInfo: Codable, Identifiable { } } +// MARK: - SatDump Recorded Pass (new API format) + +/// A recorded SatDump pass as returned by /api/satdump/status (last_pass), +/// /api/satdump/passes and /api/satdump/last/images. +struct SatDumpRecordedPass: Codable, Equatable, Identifiable { + let id: String + let name: String? + let satellite: String? + let timestamp: String? + let products: [String]? + let imageCount: Int? + let images: [AnyCodable]? + + enum CodingKeys: String, CodingKey { + case id, name, satellite, timestamp, products, images + case imageCount = "image_count" + } +} + // MARK: - SatDump Status +/// Response from /api/satdump/status (new schema, 2026-04). +/// Bridges into legacy `SatDumpStatus` for view compatibility. struct SatDumpStatusResponse: Codable, Equatable { let timestamp: String - let status: SatDumpStatus + let ok: Bool? + let meteorBaseExists: Bool? + let orbcommBaseExists: Bool? + let meteorPassCount: Int? + let orbcommRunCount: Int? + let lastPass: SatDumpRecordedPass? + let stale: Bool? - // Custom decoder to handle status that can be object or error - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - timestamp = try container.decode(String.self, forKey: .timestamp) - - // Try to decode status as SatDumpStatus - if let statusObj = try? container.decode(SatDumpStatus.self, forKey: .status) { - status = statusObj + enum CodingKeys: String, CodingKey { + case timestamp, ok, stale + case meteorBaseExists = "meteor_base_exists" + case orbcommBaseExists = "orbcomm_base_exists" + case meteorPassCount = "meteor_pass_count" + case orbcommRunCount = "orbcomm_run_count" + case lastPass = "last_pass" + } + + /// Bridge into the legacy `SatDumpStatus` type consumed by views. + var status: SatDumpStatus { + let passName = lastPass?.name ?? lastPass?.id ?? "Desconhecido" + let imageCount = lastPass?.imageCount ?? 0 + let lastModified = lastPass?.timestamp ?? timestamp + + // Calculate age from lastPass.timestamp (ISO 8601) to now + let ageMinutes: Double + if let ts = lastPass?.timestamp, + let date = ISO8601DateFormatter().date(from: ts) + ?? { + let f = DateFormatter() + f.locale = Locale(identifier: "en_US_POSIX") + f.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" + return f.date(from: ts) + }() + { + ageMinutes = Date().timeIntervalSince(date) / 60.0 } else { - // If it fails, create a placeholder status (could be error response) - status = SatDumpStatus( - passName: "Unknown", - sizeBytes: 0, - sizeMb: 0, - imageCount: 0, - lastModified: "", - ageMinutes: 0, - isRecent: false - ) + ageMinutes = 0 } - } - enum CodingKeys: String, CodingKey { - case timestamp, status + let isRecent = !(stale ?? true) || ageMinutes < 30 + + return SatDumpStatus( + passName: passName, + sizeBytes: 0, + sizeMb: 0.0, + imageCount: imageCount, + lastModified: lastModified, + ageMinutes: ageMinutes, + isRecent: isRecent + ) } } @@ -400,6 +475,8 @@ struct OrbcommRun: Codable, Identifiable, Equatable { // MARK: - Orbcomm Decoded +/// Response from /api/satdump/orbcomm/decoded (new schema: data nested object). +/// View-bridge properties keep the same interface as the old flat format. struct OrbcommDecodedResponse: Codable { let timestamp: String let run: String @@ -409,6 +486,52 @@ struct OrbcommDecodedResponse: Codable { let events: [AnyCodable] let groupedBySat: [String: AnyCodable]? + // MARK: Custom decoder — new API wraps data under "data" key + + private enum RootKeys: String, CodingKey { case timestamp, data } + private enum DataKeys: String, CodingKey { + case run, limit, files, winner + } + private enum FilesKeys: String, CodingKey { case jsonl, log } + private enum WinnerKeys: String, CodingKey { + case totalEvents = "total_events" + case validSatEvents = "valid_sat_events" + } + + init(from decoder: Decoder) throws { + let root = try decoder.container(keyedBy: RootKeys.self) + timestamp = try root.decode(String.self, forKey: .timestamp) + + if let dataContainer = try? root.nestedContainer(keyedBy: DataKeys.self, forKey: .data) { + run = (try? dataContainer.decodeIfPresent(String.self, forKey: .run)) ?? "" + if let filesContainer = try? dataContainer.nestedContainer( + keyedBy: FilesKeys.self, forKey: .files) + { + log = try? filesContainer.decodeIfPresent(String.self, forKey: .log) ?? nil + jsonl = try? filesContainer.decodeIfPresent(String.self, forKey: .jsonl) ?? nil + } else { + log = nil + jsonl = nil + } + if let winnerContainer = try? dataContainer.nestedContainer( + keyedBy: WinnerKeys.self, forKey: .winner) + { + count = (try? winnerContainer.decodeIfPresent(Int.self, forKey: .totalEvents)) ?? 0 + } else { + count = 0 + } + } else { + // Fallback: try flat old format + let flat = try decoder.container(keyedBy: CodingKeys.self) + run = (try? flat.decodeIfPresent(String.self, forKey: .run)) ?? "" + log = try? flat.decodeIfPresent(String.self, forKey: .log) ?? nil + jsonl = try? flat.decodeIfPresent(String.self, forKey: .jsonl) ?? nil + count = (try? flat.decodeIfPresent(Int.self, forKey: .count)) ?? 0 + } + events = [] + groupedBySat = nil + } + enum CodingKeys: String, CodingKey { case timestamp, run, log, jsonl, count, events case groupedBySat = "grouped_by_sat" @@ -441,6 +564,13 @@ struct SatellitePositionsResponse: Codable { let timestamp: String let station: StationLocation let satellites: [SatellitePosition] + let degraded: Bool? + let degradedReason: String? + + enum CodingKeys: String, CodingKey { + case timestamp, station, satellites, degraded + case degradedReason = "degraded_reason" + } } struct StationLocation: Codable, Equatable { @@ -514,161 +644,176 @@ struct SatelliteStatusResponse: Codable, Equatable { } // MARK: - GPS Globe +// Decodes the new gps.meulab.fun/api/state payload (satellite tracking API). +// Bridge computed properties expose the legacy interface used by views. struct GPSGlobeState: Codable, Equatable { let generatedAt: String - let tzOffsetMinutes: Int? - let tzName: String? - let receiver: GPSGlobeReceiver - let gpsd: GPSGlobeGPSD - let sky: GPSGlobeSky - let tle: GPSGlobeTLE? - let satellitesVisible: [GPSGlobeSatellite] + let observer: GPSGlobeObserver + let satellites: [GPSGlobeSatellite] enum CodingKeys: String, CodingKey { case generatedAt = "generated_at" - case tzOffsetMinutes = "tz_offset_minutes" - case tzName = "tz_name" - case receiver, gpsd, sky, tle - case satellitesVisible = "satellites_visible" + case observer + case satellites } var generatedDate: Date? { Formatters.isoDate.date(from: generatedAt) ?? Formatters.isoDateNoFrac.date(from: generatedAt) } -} -struct GPSGlobeReceiver: Codable, Equatable { - let lat: Double - let lon: Double - let altitudeM: Double? - let mode: Int? - let speedMS: Double? - let trackDeg: Double? - let horizontalErrorM: Double? - let verticalErrorM: Double? - let timestamp: String? - let ageSeconds: Double? - let lastMessageAgeSeconds: Double? + // MARK: View bridge properties - enum CodingKeys: String, CodingKey { - case lat, lon, mode, timestamp - case altitudeM = "altitude_m" - case speedMS = "speed_ms" - case trackDeg = "track_deg" - case horizontalErrorM = "horizontal_error_m" - case verticalErrorM = "vertical_error_m" - case ageSeconds = "age_seconds" - case lastMessageAgeSeconds = "last_message_age_seconds" + var satellitesVisible: [GPSGlobeSatellite] { satellites } + + var receiver: GPSGlobeReceiver { + GPSGlobeReceiver(lat: observer.lat, lon: observer.lon, altitudeM: observer.altM) + } + + var gpsd: GPSGlobeGPSD { GPSGlobeGPSD() } + + var sky: GPSGlobeSky { + let capturable = satellites.filter { $0.capturableNow == true }.count + return GPSGlobeSky( + gpsVisible: satellites.isEmpty ? nil : satellites.count, + gpsUsed: capturable > 0 ? capturable : nil + ) } } -struct GPSGlobeGPSD: Codable, Equatable { - let device: GPSGlobeDevice? - let lastMessageAt: Double? - let error: String? +struct GPSGlobeObserver: Codable, Equatable { + let lat: Double + let lon: Double + let altM: Double? + let qth: String? enum CodingKeys: String, CodingKey { - case device, error - case lastMessageAt = "last_message_at" + case lat, lon, qth + case altM = "alt_m" } } -struct GPSGlobeDevice: Codable, Equatable { - let path: String? - let driver: String? - let subtype: String? - let subtype1: String? - let cycle: Double? +/// Bridge struct — constructed from GPSGlobeObserver; not Codable. +struct GPSGlobeReceiver: Equatable { + let lat: Double + let lon: Double + let altitudeM: Double? + var mode: Int? = nil + var horizontalErrorM: Double? = nil } -struct GPSGlobeSky: Codable, Equatable { - let hdop: Double? - let pdop: Double? - let vdop: Double? - let nSatellites: Int? - let usedSatellites: Int? - let gpsVisible: Int? - let gpsUsed: Int? +/// Bridge struct — not present in new API; provides nil error to views. +struct GPSGlobeGPSD: Equatable { + var error: String? = nil +} - enum CodingKeys: String, CodingKey { - case hdop, pdop, vdop - case nSatellites = "n_satellites" - case usedSatellites = "used_satellites" - case gpsVisible = "gps_visible" - case gpsUsed = "gps_used" - } +/// Bridge struct — derived from satellite array counts; not Codable. +struct GPSGlobeSky: Equatable { + var hdop: Double? = nil + var pdop: Double? = nil + var vdop: Double? = nil + var nSatellites: Int? = nil + var usedSatellites: Int? = nil + var gpsVisible: Int? = nil + var gpsUsed: Int? = nil } -struct GPSGlobeTLE: Codable, Equatable { - let count: Int? - let lastFetchAt: Double? - let lastFetchISO: String? - let lastError: String? +/// Represents the next pass info object in gps.meulab.fun/api/state satellites[].next_pass +struct GPSGlobeNextPass: Codable, Equatable { + let satellite: String? + let aosUtc: String? + let losUtc: String? + let durationSec: Double? + let maxElevationDeg: Double? + let centerFrequencyHz: Int? + let recommendedGain: Int? + let recommendedDurationSec: Int? enum CodingKeys: String, CodingKey { - case count - case lastFetchAt = "last_fetch_at" - case lastFetchISO = "last_fetch_iso" - case lastError = "last_error" + case satellite + case aosUtc = "aos_utc" + case losUtc = "los_utc" + case durationSec = "duration_sec" + case maxElevationDeg = "max_elevation_deg" + case centerFrequencyHz = "center_frequency_hz" + case recommendedGain = "recommended_gain" + case recommendedDurationSec = "recommended_duration_sec" } } +/// Satellite entry from the new API payload. struct GPSGlobeSatellite: Codable, Equatable, Identifiable { - let prn: Int - let azimuthDeg: Double? + // Stored (decoded) properties — id is now a String (e.g. "orbcomm-fm112") + let id: String + let satellite: String? + let family: String? + let latitudeDeg: Double? + let longitudeDeg: Double? + let altitudeKm: Double? + let speedKmS: Double? + let speedKmH: Double? let elevationDeg: Double? - let signalDBHz: Double? - let used: Bool - let health: Int? - let name: String? - let noradID: Int? - let intlDesignator: String? let imageURL: String? - let block: String? - let launch: GPSGlobeLaunch? - let orbit: GPSGlobeOrbit? - let subpoint: GPSGlobeSubpoint? + let capturableNow: Bool? + let nextPass: GPSGlobeNextPass? + let nextAosInSec: Double? + let observerQth: String? enum CodingKeys: String, CodingKey { - case prn, used, health, name, block, launch, orbit, subpoint - case azimuthDeg = "azimuth_deg" + case id, satellite, family + case latitudeDeg = "latitude_deg" + case longitudeDeg = "longitude_deg" + case altitudeKm = "altitude_km" + case speedKmS = "speed_km_s" + case speedKmH = "speed_km_h" case elevationDeg = "elevation_deg" - case signalDBHz = "signal_dbhz" - case noradID = "norad_id" - case intlDesignator = "intl_designator" case imageURL = "image_url" + case capturableNow = "capturable_now" + case nextPass = "next_pass" + case nextAosInSec = "next_aos_in_sec" + case observerQth = "observer_qth" } - var id: Int { prn } + // MARK: View bridge computed properties + + /// Stable Int derived from the String id for SceneKit node keying (session-local only) + var prn: Int { abs(id.hashValue) } + var used: Bool { capturableNow ?? false } + var name: String? { satellite } + var displayName: String { satellite ?? "SAT \(id)" } + var azimuthDeg: Double? { nil } + var signalDBHz: Double? { nil } + var noradID: Int? { nil } + var intlDesignator: String? { nil } + var block: String? { nil } + var health: Int? { nil } + var launch: GPSGlobeLaunch? { nil } - var displayName: String { - name ?? "PRN \(prn)" + var orbit: GPSGlobeOrbit? { + guard let speed = speedKmH else { return nil } + return GPSGlobeOrbit(speedKMH: speed, periodMinutes: nil) + } + + var subpoint: GPSGlobeSubpoint? { + guard let lat = latitudeDeg, let lon = longitudeDeg else { return nil } + return GPSGlobeSubpoint( + lat: lat, lon: lon, altitudeKM: altitudeKm, displayAltitude: altitudeKm) } } -struct GPSGlobeLaunch: Codable, Equatable { +/// Bridge struct — represents known launch metadata; always nil for new API. +struct GPSGlobeLaunch: Equatable { let dateLocalized: String? let timeUTC: String? let site: String? let vehicle: String? - - enum CodingKeys: String, CodingKey { - case site, vehicle - case dateLocalized = "date_localized" - case timeUTC = "time_utc" - } } -struct GPSGlobeOrbit: Codable, Equatable { +/// Bridge struct — orbital parameters; speedKMH sourced from new API. +struct GPSGlobeOrbit: Equatable { let speedKMH: Double? let periodMinutes: Double? - - enum CodingKeys: String, CodingKey { - case speedKMH = "speed_kmh" - case periodMinutes = "period_minutes" - } } struct GPSGlobeSubpoint: Codable, Equatable { diff --git a/MeuLabApp/Models/SystemExtrasModels.swift b/MeuLabApp/Models/SystemExtrasModels.swift index 36f39fc..fadf2fd 100644 --- a/MeuLabApp/Models/SystemExtrasModels.swift +++ b/MeuLabApp/Models/SystemExtrasModels.swift @@ -103,11 +103,19 @@ struct NetworkInterface: Codable, Equatable, Identifiable { } } +// MARK: - Remote Source + +struct APIRemoteSource: Codable, Equatable { + let type: String? + let host: String? +} + // MARK: - Docker struct DockerVersionResponse: Codable, Equatable { let timestamp: String let version: DockerVersionPayload + let source: APIRemoteSource? } struct DockerVersionPayload: Codable, Equatable { @@ -199,6 +207,7 @@ struct DockerComponent: Codable, Equatable, Identifiable { struct DockerStatusResponse: Codable, Equatable { let timestamp: String let containers: [DockerContainer] + let source: APIRemoteSource? } struct DockerContainer: Codable, Equatable, Identifiable { @@ -282,6 +291,7 @@ struct DockerLogsResponse: Codable { struct SystemdStatusResponse: Codable, Equatable { let timestamp: String let services: [SystemdService] + let source: APIRemoteSource? } struct SystemdService: Codable, Equatable, Identifiable { @@ -452,8 +462,8 @@ enum FlexibleTimestamp: Codable, Equatable { } } -private extension DateFormatter { - static let timeFormatter: DateFormatter = { +extension DateFormatter { + fileprivate static let timeFormatter: DateFormatter = { let f = DateFormatter() f.dateFormat = "HH:mm" return f diff --git a/MeuLabApp/Services/APIService.swift b/MeuLabApp/Services/APIService.swift index 9e06b26..d42d48b 100644 --- a/MeuLabApp/Services/APIService.swift +++ b/MeuLabApp/Services/APIService.swift @@ -7,6 +7,7 @@ enum APIError: Error, LocalizedError { case decodingError(Error) case unauthorized case serverError(Int) + case notAvailable case unknown var errorDescription: String? { @@ -21,6 +22,8 @@ enum APIError: Error, LocalizedError { return "Não autorizado" case .serverError(let code): return "Erro do servidor: \(code)" + case .notAvailable: + return "Recurso indisponível no momento" case .unknown: return "Erro desconhecido" } @@ -31,6 +34,7 @@ actor APIService { static let shared = APIService() private var baseURL = Secrets.apiBaseURL + private let radarBaseURL = "https://radar.meulab.fun" private let gpsGlobeBaseURL = "https://gps.meulab.fun" private let apiToken = Secrets.apiToken.isEmpty ? Secrets.apiTokenAlternative : Secrets.apiToken @@ -169,6 +173,24 @@ actor APIService { } } + // MARK: - Radar Request Helpers (radar.meulab.fun — public, no auth) + + private func fetchFromRadar(_ path: String) async throws -> T { + guard let url = URL(string: "\(radarBaseURL)\(path)") else { + throw APIError.invalidURL + } + var request = URLRequest(url: url) + request.setValue("MeuLabApp/1.0", forHTTPHeaderField: "User-Agent") + request.setValue("application/json", forHTTPHeaderField: "Accept") + request.cachePolicy = .reloadIgnoringLocalCacheData + let (data, _) = try await performRequest(request) + do { + return try JSONDecoder().decode(T.self, from: data) + } catch { + throw APIError.decodingError(error) + } + } + // MARK: - API2 Request Helpers private func makeAPI2Request(path: String) throws -> URLRequest { @@ -249,6 +271,50 @@ actor APIService { try await fetch("/api/adsb/alerts") } + // MARK: - radar.meulab.fun Direct Endpoints (sem autenticação) + + /// Aeronaves ao vivo do receptor local (~0.3 s de latência) + func fetchRawAircraftList() async throws -> RadarAircraftResponse { + try await fetchFromRadar("/data/aircraft.json") + } + + /// Informações do receptor (posição, versão, capacidades) + func fetchReceiverInfo() async throws -> Data { + try await fetchFromRadar("/data/receiver.json") + } + + /// Estatísticas de desempenho por janela de tempo + func fetchRadarStats() async throws -> Data { + try await fetchFromRadar("/data/stats.json") + } + + /// Status do sistema e feeders ativos + func fetchRadarStatus() async throws -> Data { + try await fetchFromRadar("/data/status.json") + } + + /// Trajetória recente de uma aeronave (últimas horas, gravada a cada 15 s) + func fetchAircraftTrace(hex: String) async throws -> Data { + let prefix = String(hex.suffix(2)) + guard + let url = URL(string: "\(radarBaseURL)/data/traces/\(prefix)/trace_recent_\(hex).json") + else { + throw APIError.invalidURL + } + var request = URLRequest(url: url) + request.setValue("MeuLabApp/1.0", forHTTPHeaderField: "User-Agent") + let (data, response) = try await session.data(for: request) + guard let http = response as? HTTPURLResponse, http.statusCode == 200 else { + throw APIError.serverError((response as? HTTPURLResponse)?.statusCode ?? 0) + } + return data + } + + /// URL da silhueta de um tipo de aeronave + func aircraftSilhouetteURL(type: String) -> URL? { + URL(string: "\(radarBaseURL)/aircraft_sil/\(type).png") + } + func fetchTuyaTemperatureHumidity(historyLimit: Int = 12) async throws -> TuyaTemperatureHumidityResponse { @@ -529,13 +595,21 @@ actor APIService { func fetchSatDumpFFT() async throws -> Data { if let cached = BinaryCache.shared.cachedData(forPath: "/api/satdump/fft") { return cached } - let data = try await fetchData("/api/satdump/fft") - BinaryCache.shared.store(data, forPath: "/api/satdump/fft") - return data + do { + let data = try await fetchData("/api/satdump/fft") + BinaryCache.shared.store(data, forPath: "/api/satdump/fft") + return data + } catch APIError.serverError(501) { + throw APIError.notAvailable + } } func fetchSatDumpLive() async throws -> SatDumpLiveResponse { - try await fetch("/api/satdump/live") + do { + return try await fetch("/api/satdump/live") + } catch APIError.serverError(501) { + throw APIError.notAvailable + } } func fetchGPSGlobeState() async throws -> GPSGlobeState { diff --git a/QUICKSTART_SECRETS.md b/QUICKSTART_SECRETS.md deleted file mode 100644 index 30c3cea..0000000 --- a/QUICKSTART_SECRETS.md +++ /dev/null @@ -1,318 +0,0 @@ -# 🚀 Setup Rápido: Secrets + API Tokens (5 minutos) - -Implementação de segurança para tokens de API sem commitá-los no GitHub. - -## ✅ O que foi implementado - -1. **Enum `Secrets`** - centraliza leitura de tokens (iOS) -2. **Enum `WatchSecrets`** - versão para watchOS -3. **Arquivo `Secrets.plist.example`** - template com placeholders -4. **.gitignore atualizado** - ignora `Secrets.plist` e `*.xcconfig` -5. **APIService.swift** - updated para usar `Secrets` -6. **WatchAPIService.swift** - updated para usar `WatchSecrets` - ---- - -## 🔧 Setup em 5 Passos - -### ✅ Passo 1: Criar Secrets.plist local (1 min) - -```bash -cd /Users/eliel/Library/Mobile\ Documents/com~apple~CloudDocs/apps\ criados/botapp/MeuLabApp - -# Copiar template -cp Secrets.plist.example Secrets.plist - -# Editar com valores reais (em seu editor favorito) -cat > Secrets.plist << 'EOF' - - - - - API_BASE_URL - https://app.meulab.fun - MEULAB_API_TOKEN - p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs - API_TOKEN - p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs - - -EOF -``` - -**Resultado:** Arquivo `Secrets.plist` local criado ✅ - ---- - -### ✅ Passo 2: Adicionar ao Xcode (2 min) - -#### Para **MeuLabApp** (iOS): - -1. **Abra Xcode:** - ```bash - open MeuLabApp.xcodeproj - ``` - -2. **Adicionar Secrets.plist:** - - **Menu:** File → Add Files to "MeuLabApp" - - **Selecione:** `Secrets.plist` (na raiz) - - **Copiar se necessário:** ❌ NÃO (arquivo já está lá) - - **Targets:** - - ✅ **MeuLabApp** - - ✅ **MeuLabWatch** - - ✅ **MeuLabWidgets** - - **Clique:** Add - -3. **Verificar Target Membership:** - - Selecione `Secrets.plist` no Navigator - - Abra **File Inspector** (Cmd ⌘ + Option ⌥ + 1) - - **Target Membership:** - - ✅ MeuLabApp - - ✅ MeuLabWatch - - ✅ MeuLabWidgets - -#### Para **MeuLabWatch** (watchOS): - -1. **Adicionar WatchSecrets.swift:** - - **Menu:** File → Add Files to "MeuLabApp" - - **Selecione:** `MeuLabWatch/Services/WatchSecrets.swift` - - **Targets:** ✅ **MeuLabWatch** apenas - - **Clique:** Add - -2. **Verificar Target Membership:** - - Selecione `WatchSecrets.swift` no Navigator - - **File Inspector** → **Target Membership:** - - ✅ MeuLabWatch - - ❌ MeuLabApp - - ❌ MeuLabWidgets - -**Resultado:** Arquivos adicionados aos targets corretos ✅ - ---- - -### ✅ Passo 3: Compilar e testar (1 min) - -```bash -# Clean build -xcodebuild clean -scheme MeuLabApp - -# Build -xcodebuild build -scheme MeuLabApp - -# Build watchOS -xcodebuild build -scheme MeuLabWatch -``` - -**Esperado no console:** -``` -🔐 Secrets Configuration Status: - API Base URL: https://app.meulab.fun - API Token configured: true - Token (first 10 chars): p19Yl1wAR... - -🔐 watchOS Secrets: Token configured = true -``` - ---- - -### ✅ Passo 4: Executar no Simulator (1 min) - -```bash -# Abrir Xcode -open MeuLabApp.xcodeproj - -# Ou compilar e executar -xcodebuild -scheme MeuLabApp -destination 'platform=iOS Simulator,name=iPhone 15' -``` - -**Resultado:** App inicia com tokens carregados ✅ - ---- - -### ✅ Passo 5: Verificar Segurança Git (1 min) - -```bash -# 1. Confirmar que Secrets.plist NÃO aparece em status -git status | grep Secrets -# (não deve mostrar nada) - -# 2. Confirmar que arquivo está em .gitignore -cat .gitignore | grep -A2 "Local secret files" -# Deve mostrar: Secrets.plist e xcconfig - -# 3. Listar arquivos que SERIAM commitados -git ls-files -# Não deve ter Secrets.plist - -# 4. Status final -git status -# Deve estar clean (sem Secrets.plist) -``` - -**Resultado:** Segredos protegidos do GitHub ✅ - ---- - -## 📋 Checklist de Conclusão - -- [ ] `Secrets.plist` criado com valores reais -- [ ] `Secrets.plist` adicionado ao Xcode com targets: iOS, watchOS, widgets -- [ ] `WatchSecrets.swift` adicionado ao Xcode com target: watchOS -- [ ] `Secrets.swift` adicionado ao Xcode com target: iOS -- [ ] Projeto compila sem erros -- [ ] Console mostra mensagens de Secrets carregados -- [ ] `git status` não mostra Secrets.plist -- [ ] `.gitignore` contém Secrets.plist - ---- - -## 🔍 Onde os Secrets são Lidos? - -### No iOS (MeuLabApp): - -```swift -// MeuLabApp/Services/APIService.swift -private let baseURL = Secrets.apiBaseURL -private let apiToken = Secrets.apiToken - -// Internamente, Secrets.swift tenta: -// 1. Environment variable: MEULAB_API_TOKEN -// 2. Info.plist: MEULAB_API_TOKEN -// 3. Secrets.plist: MEULAB_API_TOKEN -// 4. Fallback: "" (string vazia com aviso DEBUG) -``` - -### No watchOS (MeuLabWatch): - -```swift -// MeuLabWatch/Services/WatchAPIService.swift -private let apiToken = WatchSecrets.apiToken.isEmpty ? WatchSecrets.apiTokenAlternative : WatchSecrets.apiToken - -// Mesma ordem de prioridade -``` - ---- - -## 🆘 Troubleshooting - -### ❌ "Cannot find 'Secrets' in scope" - -**Causa:** Arquivo não foi adicionado ao target iOS - -**Solução:** -```bash -# 1. Verificar se está em pbxproj: -grep "Secrets.swift" MeuLabApp.xcodeproj/project.pbxproj | head -3 - -# 2. Verificar Target Membership no Xcode: -# File → Secrets.swift → File Inspector → targets - -# 3. Se faltar, adicionar manualmente: -# File → Add Files → Secrets.swift → targets MeuLabApp ✅ -``` - ---- - -### ❌ "Cannot find 'WatchSecrets' in scope" - -**Causa:** WatchSecrets.swift não foi adicionado ao target watchOS - -**Solução:** -```bash -# 1. Verificar: -grep "WatchSecrets.swift" MeuLabApp.xcodeproj/project.pbxproj - -# 2. Se não existir, adicionar: -# File → Add Files → MeuLabWatch/Services/WatchSecrets.swift -# Target: ✅ MeuLabWatch apenas - -# 3. Script auxiliar (opcional): -python3 add_watchsecrets.py -``` - ---- - -### ❌ "Token de API não configurado" - -**Causa:** Secrets.plist não no bundle ou valores vazios - -**Solução:** -```bash -# 1. Verificar se arquivo existe: -ls Secrets.plist - -# 2. Verificar Target Membership: -# Secrets.plist → File Inspector → ✅ MeuLabApp, ✅ MeuLabWatch, ✅ MeuLabWidgets - -# 3. Limpar build e recompilar: -xcodebuild clean -scheme MeuLabApp -xcodebuild build -scheme MeuLabApp - -# 4. Verificar conteúdo: -cat Secrets.plist | grep -A1 MEULAB_API_TOKEN -``` - ---- - -### ❌ "fatal: pathspec 'Secrets.plist' did not match any files" - -**Causa:** Git tentando adicionar Secrets.plist (não deveria) - -**Solução:** -```bash -# Confirmar que está em .gitignore -git check-ignore Secrets.plist -# Deve retornar: Secrets.plist - -# Se não está: -echo "Secrets.plist" >> .gitignore -git add .gitignore -git commit -m "Update .gitignore - ensure Secrets.plist ignored" -``` - ---- - -## 📚 Documentação Completa - -- **[SECRETS_SETUP.md](SECRETS_SETUP.md)** - Setup detalhado (todos os métodos) -- **[XCCONFIG_ALTERNATIVE.md](XCCONFIG_ALTERNATIVE.md)** - Alternativa com xcconfig -- **[WATCHSECRETS_SETUP.md](WATCHSECRETS_SETUP.md)** - Setup do watchOS - ---- - -## 🎯 Próximos Passos - -Depois do setup: - -1. **Teste a API:** - ```bash - curl -H "Authorization: Bearer p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs" \ - https://app.meulab.fun/health - ``` - -2. **Commit da configuração:** - ```bash - git add .gitignore Secrets.plist.example Config.default.xcconfig . - git commit -m "security: add Secrets infrastructure (no real tokens)" - git push - ``` - -3. **Comunicar ao time:** - - "Configuração segura de tokens implementada" - - "Cada dev precisa criar Secrets.plist localmente" - - "Link para SECRETS_SETUP.md" - ---- - -## ✨ Segurança Garantida - -✅ **Tokens NUNCA no GitHub** -✅ **Fallback seguro** (aviso DEBUG se não configurado) -✅ **Suporta CI/CD** (env vars ou xcconfig) -✅ **Multi-target** (iOS, watchOS, widgets) -✅ **Fácil setup** (5 minutos) - ---- - -**Última atualização:** 21 de fevereiro de 2026 -**Status:** 🟢 Pronto para uso diff --git a/QUICK_START.sh b/QUICK_START.sh new file mode 100644 index 0000000..affd4b7 --- /dev/null +++ b/QUICK_START.sh @@ -0,0 +1,181 @@ +#!/bin/bash +# QUICK START - Bible Reader with Siri Integration +# +# This file explains how to complete the Bible Reader setup +# +# Status: 95% Complete - Just need to add files to Xcode! +# +######################################################################### + +echo " +╔════════════════════════════════════════════════════════════════╗ +║ BIBLE READER WITH SIRI - QUICK START ║ +║ ║ +║ ✅ All code created and placed on disk ║ +║ ⏳ Just need to add files to Xcode project ║ +║ 📍 Estimated time: 5 minutes ║ +╚════════════════════════════════════════════════════════════════╝ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +STEP 1: OPEN XCODE +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + 1. Launch Xcode + 2. Open this project: + MeuLabApp.xcodeproj + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +STEP 2: ADD 6 NEW FILES TO PROJECT +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + In Xcode menu: + File → Add Files to \"MeuLabApp\" + + Then select these 6 files (use Cmd+Click to select multiple): + + ✓ MeuLabApp/Services/BibleSpeechService.swift + ✓ MeuLabApp/ViewModels/BibleReaderViewModel.swift + ✓ MeuLabApp/Views/BibleChapterReaderView.swift + ✓ MeuLabApp/Intents/BibleReadingIntents.swift + ✓ MeuLabApp/Models/BibleReaderModels.swift + ✓ MeuLabApp/Views/BibleReaderIntegrationView.swift + + IMPORTANT: Check these options: + ✓ Copy items if needed + ✓ Create groups + ✓ Add to targets: MeuLabApp (THIS IS CRITICAL!) + + Then click: Add + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +STEP 3: BUILD +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + In Xcode: + Cmd + B (Build) + + Result should be: + ✅ BUILD SUCCEEDED + + If you get errors, re-check Step 2! + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +STEP 4: TEST +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + 1. Run app: Cmd+R + 2. Go to: Bíblia tab + 3. Tap a book: João + 4. Tap a chapter: 3 + 5. Tap Play ▶️ button + 6. Watch: Verses highlight in real-time + 7. Enjoy: Ouvir a Bíblia sendo lida! + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +STEP 5 (OPTIONAL): TEST SIRI +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + On Simulator: + Cmd+Shift+K (opens Siri) + Type: \"Ler João capítulo 3 no MeuLabApp\" + Press Enter + + Expected: App opens → Chapter loads → Audio plays! + + On Real Device: + Say: \"Hey Siri\" + Say: \"Ler João capítulo 3 no MeuLabApp\" + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +FILES THAT WERE CREATED +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Services: + • BibleSpeechService.swift - Text-to-speech with per-verse queuing + +ViewModels: + • BibleReaderViewModel.swift - State management (@Observable) + +Views: + • BibleChapterReaderView.swift - Standalone reader UI + • BibleReaderIntegrationView.swift - Siri intent handler + + MODIFIED: + • BibleNavigateView.swift - Added playback controls + +Intents: + • BibleReadingIntents.swift - Siri voice commands + +Models: + • BibleReaderModels.swift - Data structures + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +DOCUMENTATION FILES +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Read these for more details: + + 1. XCODE_INTEGRATION_GUIDE.md + → Detailed Xcode setup with screenshots + + 2. BIBLE_READER_INTEGRATION_COMPLETE.md + → What was done, what's ready, testing checklist + + 3. BIBLE_READER_ARCHITECTURE.md + → Technical architecture and data flow + + 4. SIRI_VOICE_COMMANDS.md + → All Siri phrases in Portuguese + + 5. BUILD_AND_TEST_GUIDE.md + → Complete test cases and verification + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +WHAT YOU GET +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✅ Play/Pause/Stop buttons +✅ Real-time verse highlighting (gold background) +✅ Auto-scrolling to current verse +✅ Tap verse to skip to it +✅ Siri voice commands: + • \"Ler [Livro] capítulo [Número]\" + • \"Pausar leitura\" + • \"Retomar leitura\" + • \"Parar leitura\" +✅ Text-to-speech in Portuguese +✅ Production-ready code +✅ Extensive documentation + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +TROUBLESHOOTING +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Problem: \"cannot find 'BibleReaderViewModel' in scope\" +Solution: You missed Step 2. Make sure \"Add to targets: MeuLabApp\" + is checked when adding files. + +Problem: Build fails, but no obvious errors +Solution: Clean build: Cmd+Shift+K, then Cmd+B + +Problem: No audio playing +Solution: Check simulator: Hardware → Audio Output → unmute + +Problem: Verses not highlighting +Solution: Make sure all 6 files were added in Step 2 + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +YOU'RE ALMOST DONE! +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +95% complete. Just 5 minutes to go! + +1. Open Xcode +2. Add 6 files +3. Build +4. Enjoy! + +Questions? Check XCODE_INTEGRATION_GUIDE.md + +Good luck! 📚✨ +" diff --git a/README.md b/README.md deleted file mode 100644 index 2936418..0000000 --- a/README.md +++ /dev/null @@ -1,154 +0,0 @@ -# MeuLab App - -App SwiftUI para iOS/iPadOS que monitora dados do servidor Raspberry Pi em tempo real. - -## Funcionalidades - -- **ADS-B**: Rastreamento de aeronaves em tempo real -- **Satélite**: Imagens do Meteor M2-x via SatDump -- **Sistema**: Status do Raspberry Pi (CPU, RAM, disco, Wi-Fi) -- **Rádio**: Player da Diário FM com Now Playing no Control Center -- **Clima**: Previsão do tempo para Franca, SP - -## Requisitos - -- Xcode 15.0+ -- iOS 17.0+ / iPadOS 17.0+ -- Swift 5.9+ - -## Build Apple Silicon - -### iPhone real (arm64) - -```bash -xcodebuild -project MeuLabApp.xcodeproj \ - -scheme MeuLabApp \ - -configuration Release \ - -destination 'generic/platform=iOS' \ - -derivedDataPath build/DerivedData \ - CODE_SIGNING_ALLOWED=NO build -``` - -### Simulador Apple Silicon (arm64) - -```bash -xcodebuild -project MeuLabApp.xcodeproj \ - -scheme MeuLabApp \ - -configuration Debug \ - -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \ - -derivedDataPath build/DerivedDataSimNoSign \ - CODE_SIGNING_ALLOWED=NO build -``` - -## Screenshots - -Para gerar screenshots de varias telas no simulador Apple Silicon: - -```bash -./scripts/capture_apple_silicon_screenshots.sh -``` - -Arquivos gerados em: - -```text -Screenshots/apple-silicon/ -``` - -## Instalação - -1. Copie a pasta `MeuLabApp` para seu Mac -2. Abra `MeuLabApp.xcodeproj` no Xcode -3. Configure o Team de desenvolvimento em Signing & Capabilities -4. Conecte seu iPhone/iPad ou selecione um simulador -5. Build e Run (⌘R) - -## Configuração - -O app já está configurado para conectar à API em `https://app.meulab.fun` - -### Segredos (não commitar) - -Defina os segredos no Scheme do Xcode (Run > Arguments > Environment Variables) ou no `Info.plist` local: - -```text -MEULAB_API_TOKEN -MEULAB_OPENSKY_CLIENT_SECRET -MEULAB_MAPKIT_JWT -``` - -Sem essas variáveis, endpoints protegidos podem retornar não autorizado. - -## Estrutura do Projeto - -``` -MeuLabApp/ -├── MeuLabApp.swift # Entry point -├── ContentView.swift # TabView principal -├── Info.plist # Configurações do app -├── Models/ # Modelos de dados -│ ├── ADSBModels.swift -│ ├── SystemModels.swift -│ ├── RadioModels.swift -│ ├── WeatherModels.swift -│ └── SatelliteModels.swift -├── Services/ # Serviços -│ ├── APIService.swift # Cliente da API -│ └── AudioPlayer.swift # Player de streaming -├── ViewModels/ # Estado do app -│ └── AppState.swift -├── Views/ # Interfaces -│ └── Tabs/ -│ ├── ADSBView.swift -│ ├── SystemView.swift -│ ├── RadioView.swift -│ ├── WeatherView.swift -│ └── SatelliteView.swift -└── Resources/ - └── Assets.xcassets/ -``` - -## API Endpoints - -O app consome os seguintes endpoints: - -| Endpoint | Descrição | -|----------|-----------| -| `/api/adsb/summary` | Resumo do tráfego aéreo | -| `/api/adsb/aircraft` | Lista de aeronaves | -| `/api/system/status` | Status do sistema | -| `/api/radio/now-playing` | Música tocando agora | -| `/api/weather/current` | Clima atual e previsão | -| `/api/satdump/last/images` | Últimas imagens de satélite | -| `/api/satdump/passes` | Lista de passes | -| `/api/satdump/image` | Serve imagem PNG | - -## Características Técnicas - -- **Refresh automático**: Dados atualizados a cada 250ms -- **Interface estável**: Updates condicionais para evitar "jitter" -- **Background audio**: Rádio continua tocando em background -- **Now Playing**: Metadados exibidos no Control Center -- **iTunes integration**: Artwork e informações das músicas - -## Notificações Push - -Para ativar notificações push: - -1. Configure um certificado APNs no Apple Developer Portal -2. Adicione o capability "Push Notifications" no Xcode -3. Configure o servidor para enviar notificações via APNs - -## Licença - -Uso pessoal - MeuLab.fun - -## Publicar no GitHub - -```bash -git init -git add . -git commit -m "Prepare Apple Silicon build and screenshots" -git branch -M main -git remote add origin -git push -u origin main -``` diff --git a/SECRETS_SETUP.md b/SECRETS_SETUP.md deleted file mode 100644 index f095ad5..0000000 --- a/SECRETS_SETUP.md +++ /dev/null @@ -1,342 +0,0 @@ -# 🔐 Setup Local de Secrets - Configuração Segura de Tokens - -Este guia explica como configurar tokens de API localmente **SEM commitar segredos no GitHub**. - -## 📋 Arquitetura de Segurança - -O app agora segue esta prioridade para carregar secrets: - -``` -1. Variáveis de Ambiente (CI/CD, terminal) - ↓ -2. Info.plist (build variables, xcconfig) - ↓ -3. Secrets.plist (local only, in .gitignore) - ↓ -4. Fallback vazio com aviso DEBUG -``` - ---- - -## ⚙️ Método 1: Usando Secrets.plist (Recomendado para Desenvolvimento Local) - -### Passo 1: Criar o arquivo Secrets.plist - -1. **Copiar o arquivo exemplo:** - ```bash - cd /Users/eliel/Library/Mobile\ Documents/com~apple~CloudDocs/apps\ criados/botapp/MeuLabApp - cp Secrets.plist.example Secrets.plist - ``` - -2. **Editar com valores reais:** - - Abra `Secrets.plist` em um editor de texto (ou Xcode) - - Substitua os placeholder VALUES pelos tokens reais - - Salve o arquivo - -3. **Verificar que não foi commitado:** - ```bash - git status | grep Secrets.plist - # Não deve aparecer nada (está em .gitignore) - ``` - -### Passo 2: Adicionar ao Target Membership (Xcode) - -Isso é **CRÍTICO** para que o arquivo seja incluído no bundle do app: - -1. **Abra o projeto Xcode:** - ```bash - open MeuLabApp.xcodeproj - ``` - -2. **Localize Secrets.plist na estrutura:** - - No painel **Project Navigator** (lado esquerdo) - - Pasta **MeuLabApp** → arquivo `Secrets.plist` - -3. **Configure Target Membership:** - - Selecione `Secrets.plist` - - Abra **File Inspector** (painel direita: ⌘⌥1) - - Seção **Target Membership**: marque ✅ para: - - ✅ `MeuLabApp` (iOS app principal) - - ✅ `MeuLabWatch` (watchOS app) - - ✅ `MeuLabWidgets` (App Clips/Widgets) - - **Captura visual:** - ``` - File Inspector (Right Panel) - ┌─────────────────────────────────────┐ - │ Target Membership │ - ├─────────────────────────────────────┤ - │ ☑ MeuLabApp │ - │ ☑ MeuLabWatch │ - │ ☑ MeuLabWidgets │ - └─────────────────────────────────────┘ - ``` - -4. **Compile e teste:** - ```bash - xcodebuild build -scheme MeuLabApp - ``` - ---- - -## 🔐 Método 2: Usando Variáveis de Ambiente (CI/CD) - -Para GitHub Actions ou outros CI/CD: - -```bash -export MEULAB_API_TOKEN="p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs" -export API_BASE_URL="https://app.meulab.fun" - -xcodebuild build -scheme MeuLabApp -``` - -### Em GitHub Actions (.github/workflows/build.yml): - -```yaml -- name: Build iOS App - env: - MEULAB_API_TOKEN: ${{ secrets.MEULAB_API_TOKEN }} - API_BASE_URL: ${{ secrets.API_BASE_URL }} - run: xcodebuild build -scheme MeuLabApp -``` - ---- - -## 🏗️ Método 3: Usando xcconfig + Info.plist (Alternativa Profissional) - -Se preferir uma abordagem más estruturada com xcconfig: - -### Passo 1: Criar arquivo Config.local.xcconfig - -**Arquivo:** `Config.local.xcconfig` (na raiz do projeto, .gitignore) - -```xcconfig -// Config.local.xcconfig -// NUNCA commit este arquivo! - -// API Configuration -API_BASE_URL = https://app.meulab.fun -API_TOKEN_VALUE = p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs -GCC_PREPROCESSOR_DEFINITIONS = API_TOKEN=$(API_TOKEN_VALUE) -``` - -### Passo 2: Atualizar Info.plist para usar variáveis xcconfig - -1. Abra `MeuLabApp/Info.plist` (como source code em Xcode) -2. Adicione: - ```xml - MEULAB_API_TOKEN - $(API_TOKEN_VALUE) - API_BASE_URL - $(API_BASE_URL) - ``` - -3. Em **Build Settings** do projeto: - - Busque por `Config File` - - Na seção Debug: `Config.local.xcconfig` - -### Passo 3: Garantir que .gitignore ignora - -```bash -# .gitignore - já deve estar com: -Config.local.xcconfig -**/Config.local.xcconfig -Secrets.plist -**/Secrets.plist -``` - ---- - -## 🧪 Verificação: Como Saber se Está Funcionando? - -### No Xcode Console (DEBUG) - -Quando o app inicia, você deve ver: - -``` -🔐 Secrets Configuration Status: - API Base URL: https://app.meulab.fun - API Token configured: true - Token (first 10 chars): p19Yl1wAR... -``` - -### Via Código (para testar manualmente) - -```swift -import Foundation - -// No AppDelegate ou MeuLabApp.swift: -let token = Secrets.apiToken -let isConfigured = Secrets.isConfigured - -print("Token configured: \(isConfigured)") -if isConfigured { - print("✅ Secrets carregados com sucesso!") -} else { - print("❌ Token não encontrado. Verifique Secrets.plist") -} -``` - -### Via Terminal - -```bash -# Verificar se o arquivo está no bundle após compilar -cd build/Debug-iphonesimulator/MeuLabApp.app -strings Info.plist | grep -A1 MEULAB_API_TOKEN - -# Ou com plistutil: -plutil -p Info.plist | grep -A1 MEULAB_API_TOKEN -``` - ---- - -## 🚨 Segurança: O Que NÃO Fazer - -❌ **NÃO commitar Secrets.plist:** -```bash -# ❌ ERRADO - vai serializar segredo -git add Secrets.plist -git commit -m "adding secrets" - -# ✅ CORRETO - arquivo já está em .gitignore -# (será ignorado automaticamente) -``` - -❌ **NÃO hardcode tokens no código:** -```swift -// ❌ ERRADO -private let apiToken = "p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs" - -// ✅ CORRETO -private let apiToken = Secrets.apiToken -``` - -❌ **NÃO push Secrets.xcconfig ou Config.local.xcconfig:** -```bash -# Esses arquivos já estão em .gitignore -# Verifique status antes de push: -git status -# Não deve mostrar nenhum arquivo de secrets -``` - ---- - -## 📝 Exemplo Prático: Secrets.plist - -**Arquivo:** `Secrets.plist` (local only) - -```xml - - - - - API_BASE_URL - https://app.meulab.fun - MEULAB_API_TOKEN - p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs - API_TOKEN - p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs - - -``` - ---- - -## 📦 Testando o Setup - -### Teste 1: Compilação sem Secrets.plist - -```bash -# Remova Secrets.plist temporariamente -mv Secrets.plist Secrets.plist.backup - -# Compile - deve funcionar com fallback (token vazio) -xcodebuild build -scheme MeuLabApp - -# Restaure -mv Secrets.plist.backup Secrets.plist - -# Resultado: ✅ App compila mesmo sem token (com aviso) -``` - -### Teste 2: Carregamento correto - -```bash -# Inicie o app e veja no Console: -# 🔐 Secrets Configuration Status: ... -# Token configured: true -``` - ---- - -## 🔄 Fluxo de Desenvolvimento - -1. ✅ Clone/fork o repositório -2. ✅ Crie `Secrets.plist` localmente (baseado em `Secrets.plist.example`) -3. ✅ Adicione ao Target Membership em Xcode -4. ✅ Compile e teste -5. ✅ **NUNCA** faça commit de `Secrets.plist` -6. ✅ Outras pessoas fazem o mesmo (cada uma tem sua cópia local) - ---- - -## 🆘 Troubleshooting - -### "Token de API não configurado" - -**Causa:** Token vazio ou Secrets.plist não no bundle - -**Solução:** -```bash -# 1. Verificar se arquivo existe: -ls Secrets.plist - -# 2. Verificar Target Membership em Xcode: -# → Project Navigator → Secrets.plist -# → File Inspector → ✅ MeuLabApp, ✅ MeuLabWatch - -# 3. Limpar build: -rm -rf build/ -xcodebuild clean -scheme MeuLabApp -xcodebuild build -scheme MeuLabApp - -# 4. Verificar conteúdo: -cat Secrets.plist | grep -A1 MEULAB_API_TOKEN -``` - -### "Arquivo Secrets.plist não encontrado" (runtime) - -**Causa:** Bundle.main.path retorna nil - -**Solução:** -1. Verifique que arquivo está na mesma pasta de Info.plist -2. **Target Membership** está marcado? ✅ -3. **Build Phases → Copy Bundle Resources** contém Secrets.plist? - - Em Xcode: Target → Build Phases → Copy Bundle Resources - - Deve listar: ✅ Secrets.plist - ---- - -## ✨ Resumo Rápido - -| Aspecto | Método 1: Secrets.plist | Método 2: Env Vars | Método 3: xcconfig | -|--------|-------------------------|-------------------|-------------------| -| **Tempo Setup** | 2 min | 1 min | 5 min | -| **Segurança** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | -| **Complexidade** | Baixa | Baixa | Média | -| **Ideal para** | Dev local | CI/CD | Projeto grandes | -| **Git-safe** | ✅ in .gitignore | ✅ Env secrets | ✅ in .gitignore | - ---- - -## 📚 Referências - -- [Secrets.swift](../MeuLabApp/Core/Secrets.swift) - Enum centralizado -- [WatchSecrets.swift](../MeuLabWatch/Services/WatchSecrets.swift) - Versão para watchOS -- [APIService.swift](../MeuLabApp/Services/APIService.swift) - Uso no app principal -- [WatchAPIService.swift](../MeuLabWatch/Services/WatchAPIService.swift) - Uso no app do relógio - ---- - -**Última atualização:** 21 de fevereiro de 2026 -**Status:** ✅ Seguro para produção (sem segredos commitados) diff --git a/TESTING_INSTRUCTIONS.md b/TESTING_INSTRUCTIONS.md deleted file mode 100644 index 61210f7..0000000 --- a/TESTING_INSTRUCTIONS.md +++ /dev/null @@ -1,171 +0,0 @@ -# Como Testar o App com Logging Ativado - -## O Que Foi Feito - -Adicionei logging detalhado ao `AppState.swift` para rastrear: -- 📡 Chamadas à API -- ✅ Dados recebidos -- 📝 Atualizações de estado -- ❌ Erros - -Também adicionei botões de refresh manual nas abas ACARS e ADS-B. - -## Passos para Testar - -### 1. Build e Execute no Xcode - -```bash -cd /Users/eliel/Downloads/botapp/MeuLabApp -open MeuLabApp.xcodeproj -``` - -1. Conecte seu iPhone/iPad ao Mac -2. Selecione o dispositivo como target -3. Pressione ⌘R para executar -4. Abra o Console (⌘⇧Y) - -### 2. Teste ACARS - -1. **Abra a aba ACARS no app** -2. **Observe o console do Xcode** - você deve ver: - ``` - [ACARS] 🔄 Starting refresh... - [ACARS] 📡 Fetching summary... - [ACARS] ✅ Summary received: XXX messages today - [ACARS] 📡 Fetching messages... - [ACARS] ✅ Messages received: XX messages - [ACARS] First message: FLIGHT - LABEL - [ACARS] 📝 Updating messages: XX messages - [ACARS] ✅ Refresh completed successfully - ``` - -3. **Toque no botão de refresh** (⟳) no canto superior direito -4. **Verifique se as mensagens aparecem** na seção "Mensagens Recentes" - -### 3. Teste ADS-B Movement - -1. **Abra a aba ADS-B no app** -2. **Observe o console do Xcode** - você deve ver: - ``` - [ADSB] 🔄 Starting refresh... - [ADSB] 📡 Fetching summary and aircraft list... - [ADSB] ✅ Summary received: XX aircraft - [ADSB] Movement: climbing=X, descending=X, cruising=X - [ADSB] 📝 Updating summary (changed) - ``` - -3. **Verifique os cards de movimento**: - - Devem mostrar números (ex: 7, 11, 13) - - Toque em cada card - - Deve abrir lista de aeronaves - -4. **Toque no botão de refresh** (⟳) no canto superior direito - -## O Que Procurar no Console - -### ✅ Cenário Bom (Funcionando) - -``` -[ACARS] 🔄 Starting refresh... -[ACARS] 📡 Fetching summary... -[ACARS] ✅ Summary received: 603 messages today -[ACARS] 📡 Fetching messages... -[ACARS] ✅ Messages received: 20 messages -[ACARS] First message: JJ3263 - H1 -[ACARS] 📝 Updating messages: 20 messages -[ACARS] ✅ Refresh completed successfully -``` - -### ❌ Cenário Ruim (Com Problema) - -**Erro de rede:** -``` -[ACARS] ❌ Error during refresh: The Internet connection appears to be offline -[ACARS] API Error details: networkError(...) -``` - -**Erro de autenticação:** -``` -[ACARS] ❌ Error during refresh: Não autorizado -[ACARS] API Error details: unauthorized -``` - -**Erro de decodificação:** -``` -[ACARS] ❌ Error during refresh: Erro ao processar dados -[ACARS] API Error details: decodingError(...) -``` - -**Dados não mudando:** -``` -[ACARS] ✅ Summary received: 603 messages today -[ACARS] ⏭️ Summary unchanged, skipping update -[ACARS] ✅ Messages received: 20 messages -[ACARS] ⏭️ Messages unchanged, skipping update -``` - -## Possíveis Problemas e Soluções - -### Problema 1: "Skipping refresh - already loading" - -**Sintoma:** Logs mostram apenas `⏭️ Skipping refresh - already loading` - -**Causa:** Múltiplas chamadas simultâneas ao refresh - -**Solução:** Aguarde 10 segundos e tente novamente - -### Problema 2: Dados recebidos mas "unchanged" - -**Sintoma:** Logs mostram `✅ Messages received` mas `⏭️ Messages unchanged` - -**Causa:** Comparação de arrays falhando - -**Solução:** Vou criar um fix para forçar atualização - -### Problema 3: Erro de rede - -**Sintoma:** `❌ Error: The Internet connection appears to be offline` - -**Causa:** App não consegue conectar à API - -**Soluções:** -1. Verifique se está conectado à internet -2. Teste se `https://app.meulab.fun` está acessível -3. Execute `./test_api.sh` no terminal - -### Problema 4: Erro 401 Unauthorized - -**Sintoma:** `❌ Error: Não autorizado` - -**Causa:** Token da API expirado - -**Solução:** Atualize o token em `APIService.swift` linha 34 - -### Problema 5: Nenhum log aparece - -**Sintoma:** Console vazio, sem logs de ACARS ou ADSB - -**Causa:** App não está chamando refresh - -**Soluções:** -1. Verifique se o timer está rodando -2. Toque no botão de refresh manual (⟳) -3. Force quit e reabra o app - -## Próximos Passos - -Após executar os testes, me informe: - -1. **Logs do console** - Copie e cole os logs que aparecem -2. **O que você vê no app** - Descreva o que aparece (ou não aparece) -3. **Erros específicos** - Se houver mensagens de erro - -Com essas informações, posso identificar exatamente o problema e criar o fix apropriado. - -## Atalhos Úteis no Xcode - -- **⌘R** - Build e executar -- **⌘.** - Parar execução -- **⌘⇧Y** - Mostrar/ocultar console -- **⌘K** - Limpar console -- **⌘F** - Buscar no console (procure por "[ACARS]" ou "[ADSB]") diff --git a/WATCHSECRETS_SETUP.md b/WATCHSECRETS_SETUP.md deleted file mode 100644 index 3a3abb1..0000000 --- a/WATCHSECRETS_SETUP.md +++ /dev/null @@ -1,74 +0,0 @@ -# ⚠️ ADICIONAR WatchSecrets.swift ao Xcode - -## Problema - -O arquivo `MeuLabWatch/Services/WatchSecrets.swift` foi criado, mas não está registrado no projeto Xcode (`project.pbxproj`). - -**Erro de compilação:** -``` -Cannot find 'WatchSecrets' in scope -``` - -## Solução (3 passos rápidos) - -### 1️⃣ Abrir o projeto Xcode - -```bash -open MeuLabApp.xcodeproj -``` - -### 2️⃣ Adicionar arquivo ao projeto - -**No Xcode:** - -1. **Menu:** File → Add Files to "MeuLabApp" - - Ou: **Cmd ⌘ + Option ⌥ + A** - -2. **Navegue até:** - ``` - MeuLabWatch/Services/WatchSecrets.swift - ``` - -3. **Marque as checkboxes:** - - ☑ **Copy items if needed** (NÃO marque - arquivo já está lá) - - ☑ **Create groups** (Sim, para manter estrutura) - -4. **Adicione aos targets:** - - ☑ **MeuLabWatch** (IMPORTANTE!) - - ☐ MeuLabApp (deixe desmarcado) - - ☐ MeuLabWidgets (deixe desmarcado) - -5. **Clique:** `Add` - -### 3️⃣ Compilar - -```bash -xcodebuild clean -scheme MeuLabWatch -xcodebuild build -scheme MeuLabWatch -``` - -**Resultado esperado:** ✅ Sem erros - ---- - -## ✅ Verificar se foi adicionado - -```bash -# No terminal: -grep "WatchSecrets.swift" MeuLabApp.xcodeproj/project.pbxproj -``` - -Deve retornar uma ou mais linhas com "WatchSecrets.swift" - ---- - -## 🎯 Checklist Final - -- [ ] Arquivo `MeuLabWatch/Services/WatchSecrets.swift` visível no Xcode Navigator -- [ ] Target Membership: ✅ MeuLabWatch -- [ ] Projeto compila sem erros -- [ ] Console mostra: `🔐 watchOS Secrets: Token configured = true` - ---- - -**Próximo:** After adding file, rebuild and copy `Secrets.plist` to project root. diff --git a/XCCONFIG_ALTERNATIVE.md b/XCCONFIG_ALTERNATIVE.md deleted file mode 100644 index 00ab68d..0000000 --- a/XCCONFIG_ALTERNATIVE.md +++ /dev/null @@ -1,275 +0,0 @@ -# Alternative: Usando xcconfig + Info.plist - -Este documento descreve como usar xcconfig para gerenciar configurações, como alternativa ao Secrets.plist. - -## 📋 Quando Usar xcconfig - -- ✅ Projetos com múltiplos targets (app, watch, extensions) -- ✅ Diferentes configurações por environment (Dev, Staging, Prod) -- ✅ CI/CD pipeline que gera xcconfig dinamicamente -- ✅ Equipes grandes com convenções de build - -## 🏗️ Setup: xcconfig + Info.plist - -### Arquivo 1: Config.default.xcconfig (Público) - -Crie na raiz do projeto com valores placeholder: - -```xcconfig -// Config.default.xcconfig -API_BASE_URL = https://app.meulab.fun -API_TOKEN_VALUE = PLACEHOLDER_TOKEN_SET_IN_LOCAL_CONFIG -ENABLE_API_LOGGING = YES -``` - -**Pode ser commitado** ✅ (sem tokens reais) - -### Arquivo 2: Config.local.xcconfig (PRIVADO - .gitignore) - -```bash -# Terminal -cp Config.local.xcconfig.example Config.local.xcconfig -``` - -Edite com valores reais: - -```xcconfig -// Config.local.xcconfig -// 🔐 LOCAL ONLY - NEVER COMMIT -API_TOKEN_VALUE = p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs -// Opcional: override para local testing -// API_BASE_URL = http://localhost:8000 -``` - -**NO .gitignore** ✅: -``` -Config.local.xcconfig -**/Config.local.xcconfig -``` - ---- - -## ⚙️ Configurar Xcode - -### Passo 1: Importar xcconfig nos Build Settings - -**Em Xcode:** - -1. **Selecione o projeto** (não o target) -2. **Info tab** → ✅ Mostra projeto -3. **Build Settings** → procure por "Config File" -4. **Debug → Config File:** - ``` - Config.default.xcconfig - ``` - (se usar Config.local.xcconfig, importar após) - -### Passo 2: Adicionar variáveis ao Info.plist - -Edite `MeuLabApp/Info.plist` (como source code): - -```xml - - - - - - - - API_BASE_URL - $(API_BASE_URL) - - MEULAB_API_TOKEN - $(API_TOKEN_VALUE) - - ENABLE_API_LOGGING - $(ENABLE_API_LOGGING) - - - - -``` - -**Resultado:** O build substitui `$(VAR)` com valores do xcconfig - -### Passo 3: Usar em Swift - -O código Swift já está pronto para ler de Info.plist: - -```swift -// Em Secrets.swift - já faz isso: -if let plistValue = Bundle.main.object(forInfoDictionaryKey: "MEULAB_API_TOKEN") as? String { - return plistValue // Valor substituído durante build -} -``` - ---- - -## 🔄 Fluxo xcconfig no Build - -``` -1. Xcode lê Config.default.xcconfig - ↓ -2. Se Config.local.xcconfig existe, sobrescreve valores - ↓ -3. Substitui $(VAR) em Info.plist pelos valores - ↓ -4. Resultado: Info.plist com tokens reais no bundle - ↓ -5. Swift lê Bundle.main via Secrets enum -``` - ---- - -## 📝 Exemplo Completo - -### Arquivo: Config.default.xcconfig - -```xcconfig -// Public configuration (SAFE to commit) -PRODUCT_NAME = MeuLabApp -API_BASE_URL = https://app.meulab.fun -API_TOKEN_VALUE = PLACEHOLDER -DEBUG_HTTP_LOGGING = YES -``` - -### Arquivo: Config.local.xcconfig - -```xcconfig -// Local configuration (PRIVATE - .gitignore) -// Copy from Config.local.xcconfig.example - -// Override valores do Config.default -API_TOKEN_VALUE = p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs - -// Opcional: local server -// API_BASE_URL = http://localhost:8000 -``` - -### Arquivo: Info.plist - -```xml -API_BASE_URL -$(API_BASE_URL) - -MEULAB_API_TOKEN -$(API_TOKEN_VALUE) -``` - ---- - -## 🔐 Segurança com xcconfig - -### Checklist - -- ✅ Config.local.xcconfig em .gitignore -- ✅ Config.default.xcconfig commitado (sem tokens reais) -- ✅ Info.plist com `$(VARS)` commitado -- ✅ Build substitui vars → segredo no app, não no repo -- ✅ Cada dev tem seu Config.local.xcconfig local - -### Verificar que está seguro - -```bash -# 1. Confirmar que .gitignore ignora xcconfig local -git check-ignore Config.local.xcconfig -# (deve retornar: Config.local.xcconfig) - -# 2. Ver que não há token no repo -git log -p --all -- "*.plist" | grep -i token -# (não deve mostrar token real) - -# 3. Verificar staging area -git diff --staged | grep -i token -# (não deve ter segredo) -``` - ---- - -## 🔧 Troubleshooting - -### "$(API_BASE_URL) aparece literal no app" - -**Causa:** xcconfig não foi incluído no build - -**Solução:** -1. **Build Settings** → Project → **Config File** -2. Confirmar que aponta para `Config.default.xcconfig` -3. Clean build: `xcodebuild clean` -4. Rebuild: `xcodebuild build` - -### "Valor default em vez de local" - -**Causa:** Config.local.xcconfig não foi importado - -**Solução:** -```xcconfig -// No topo de Config.default.xcconfig: -#include "Config.local.xcconfig" // Importa se existir -``` - -Ou edite Build Settings para incluir local após default. - -### "$(VARS) no bundle não substitui" - -**Causa:** Info.plist não tem `$(VARS)` syntax - -**Solução:** -1. Abra Info.plist em Xcode (como source code: Cmd+Option+Down) -2. Confirme que usa `$(VAR_NAME)` entre `` tags -3. Clean + Rebuild - ---- - -## 🚀 CI/CD com xcconfig - -Para GitHub Actions, gerar xcconfig dinamicamente: - -```yaml -name: Build with Secrets - -on: [push] - -jobs: - build: - runs-on: macos-latest - steps: - - uses: actions/checkout@v3 - - - name: Create Config.local.xcconfig - run: | - cat > Config.local.xcconfig << EOF - API_TOKEN_VALUE = ${{ secrets.MEULAB_API_TOKEN }} - API_BASE_URL = ${{ secrets.API_BASE_URL }} - EOF - - - name: Build - run: xcodebuild build -scheme MeuLabApp -``` - ---- - -## ✅ Comparação: Secrets.plist vs xcconfig - -| Aspecto | Secrets.plist | xcconfig | -|--------|---------------|----------| -| **Setup** | 2-3 min | 5 min | -| **Simplicidade** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | -| **Escalabilidade** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | -| **Multi-target** | ⭐⭐ | ⭐⭐⭐⭐⭐ | -| **CI/CD** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | -| **Key-Value** | ✅ Fácil | ✅ Padrão Xcode | -| **Build Vars** | ❌ Não | ✅ Nativo | -| **Recomendado** | Dev local | Projetos grandes | - ---- - -## 📚 Referências - -- [Config.default.xcconfig](../Config.default.xcconfig) - Configuração pública -- [Config.local.xcconfig.example](../Config.local.xcconfig.example) - Template privado -- [Apple: Build Configuration Files](https://help.apple.com/xcode/mac/current/#/dev745c5c974) - ---- - -**Última atualização:** 21 de fevereiro de 2026 diff --git a/add_bible_reader_files.py b/add_bible_reader_files.py new file mode 100644 index 0000000..196cd0f --- /dev/null +++ b/add_bible_reader_files.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +""" +Add Bible Reader files to Xcode project.pbxproj +""" +import re +import uuid +from pathlib import Path + +PROJECT_DIR = Path("/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp") +PBXPROJ_PATH = PROJECT_DIR / "MeuLabApp.xcodeproj" / "project.pbxproj" + +# Files to add with their group and build phase targets +FILES_TO_ADD = [ + { + "path": "MeuLabApp/Services/BibleSpeechService.swift", + "group_name": "Services", + "compile_target": True + }, + { + "path": "MeuLabApp/ViewModels/BibleReaderViewModel.swift", + "group_name": "ViewModels", + "compile_target": True + }, + { + "path": "MeuLabApp/Views/BibleChapterReaderView.swift", + "group_name": "Views", + "compile_target": True + }, + { + "path": "MeuLabApp/Intents/BibleReadingIntents.swift", + "group_name": "Intents", + "compile_target": True + }, + { + "path": "MeuLabApp/Models/BibleReaderModels.swift", + "group_name": "Models", + "compile_target": True + }, + { + "path": "MeuLabApp/Views/BibleReaderIntegrationView.swift", + "group_name": "Views", + "compile_target": True + }, +] + +def generate_id(prefix="", length=24): + """Generate Xcode-style ID""" + import uuid + hex_str = uuid.uuid4().hex.upper()[:length] + return prefix + hex_str if prefix else hex_str + +def add_files_to_pbxproj(): + """Add files to project.pbxproj""" + + if not PBXPROJ_PATH.exists(): + print(f"❌ pbxproj not found: {PBXPROJ_PATH}") + return False + + content = PBXPROJ_PATH.read_text() + original_content = content + + print("📝 Adding Bible Reader files to pbxproj...") + + for file_info in FILES_TO_ADD: + file_path = file_info["path"] + file_name = Path(file_path).name + + # Check if already added + if file_name in content: + print(f" ✓ {file_name} already in pbxproj") + continue + + # We would need to parse and modify pbxproj structure + # For simplicity, we'll just report what needs to be done + print(f" ⚠ {file_name} needs manual addition or Python pbxproj library") + + # Write back if modified + if content != original_content: + PBXPROJ_PATH.write_text(content) + print("\n✅ pbxproj updated") + else: + print("\nℹ️ No changes made to pbxproj") + + print("\n" + "="*60) + print("MANUAL STEPS:") + print("="*60) + print("1. Open MeuLabApp.xcodeproj in Xcode") + print("2. Select Project > MeuLabApp target") + print("3. Go to Build Phases > Compile Sources") + print("4. Click + and add these files:") + for file_info in FILES_TO_ADD: + print(f" - {file_info['path']}") + print("\n5. Ensure target 'MeuLabApp' is selected for each file") + print("6. Build: Cmd+B") + + return True + +if __name__ == "__main__": + add_files_to_pbxproj() diff --git a/add_bible_reader_to_project.py b/add_bible_reader_to_project.py new file mode 100644 index 0000000..422f71c --- /dev/null +++ b/add_bible_reader_to_project.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +""" +Add Bible Reader files to Xcode project +""" +import json +import os +import subprocess +from pathlib import Path + +PROJECT_PATH = Path("/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp") +PBXPROJ = PROJECT_PATH / "MeuLabApp.xcodeproj" / "project.pbxproj" + +# Files to add +FILES_TO_ADD = [ + ("MeuLabApp/Services/BibleSpeechService.swift", "Services"), + ("MeuLabApp/ViewModels/BibleReaderViewModel.swift", "ViewModels"), + ("MeuLabApp/Views/BibleChapterReaderView.swift", "Views"), + ("MeuLabApp/Intents/BibleReadingIntents.swift", "Intents"), + ("MeuLabApp/Models/BibleReaderModels.swift", "Models"), + ("MeuLabApp/Views/BibleReaderIntegrationView.swift", "Views"), +] + +def add_files_to_pbxproj(): + """Add files to Xcode project""" + os.chdir(PROJECT_PATH) + + for file_path, group in FILES_TO_ADD: + full_path = PROJECT_PATH / file_path + if full_path.exists(): + print(f"✓ Adding {file_path} to {group} group...") + # Using xcodebuild to add files would be complex + # Instead, we'll use a simpler approach with sed or Python pbxproj parsing + # For now, just verify the files exist + print(f" File exists: {full_path.stat().st_size} bytes") + else: + print(f"✗ File not found: {file_path}") + + print("\n📍 Alternative: Add files manually in Xcode") + print(" 1. Drag files from Finder to Xcode project") + print(" 2. Or: File → Add Files to MeuLabApp") + print(" 3. Select all 6 Bible Reader files") + print(" 4. Ensure target MeuLabApp is checked") + +if __name__ == "__main__": + add_files_to_pbxproj() diff --git a/add_reader_pbxproj.py b/add_reader_pbxproj.py new file mode 100644 index 0000000..1fbb599 --- /dev/null +++ b/add_reader_pbxproj.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +"""Add 6 Bible Reader files to Xcode pbxproj""" + +pbx_path = "/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp/MeuLabApp.xcodeproj/project.pbxproj" + +with open(pbx_path, "r") as f: + content = f.read() + +# (fileRefID, buildFileID, filename) +new_files = [ + ("BRSP01", "BRSP02", "BibleSpeechService.swift"), + ("BRVM01", "BRVM02", "BibleReaderViewModel.swift"), + ("BCHR01", "BCHR02", "BibleChapterReaderView.swift"), + ("BRIT01", "BRIT02", "BibleReadingIntents.swift"), + ("BRMD01", "BRMD02", "BibleReaderModels.swift"), + ("BRIG01", "BRIG02", "BibleReaderIntegrationView.swift"), +] + +for ref, build, name in new_files: + if name in content: + print(f"SKIP: {name} already in pbxproj") + else: + print(f"ADDING: {name}") + +# 1. PBXBuildFile entries (after BIBR02) +build_entries = "" +for ref, build, name in new_files: + if name not in content: + build_entries += "\t\t{} /* {} in Sources */ = {{isa = PBXBuildFile; fileRef = {} /* {} */; }};\n".format(build, name, ref, name) + +if build_entries: + marker = "BIBR02 /* BibleRandomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBR01 /* BibleRandomView.swift */; };" + content = content.replace(marker, marker + "\n" + build_entries.rstrip()) + +# 2. PBXFileReference entries (after BIBR01) +ref_entries = "" +for ref, build, name in new_files: + if name not in content: + ref_entries += '\t\t{} /* {} */ = {{isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = {}; sourceTree = ""; }};\n'.format(ref, name, name) + +if ref_entries: + marker = 'BIBR01 /* BibleRandomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleRandomView.swift; sourceTree = ""; };' + content = content.replace(marker, marker + "\n" + ref_entries.rstrip()) + +# 3. Models group: add BibleReaderModels after BibleModels +marker = "\t\t\t\tBIBM01 /* BibleModels.swift */," +if "BRMD01" not in content: + content = content.replace(marker, marker + "\n\t\t\t\tBRMD01 /* BibleReaderModels.swift */,") + +# 4. Services group: add BibleSpeechService after BibleLoader +marker = "\t\t\t\tBIBL01 /* BibleLoader.swift */," +if "BRSP01" not in content: + content = content.replace(marker, marker + "\n\t\t\t\tBRSP01 /* BibleSpeechService.swift */,") + +# 5. ViewModels group: add BibleReaderViewModel after RemoteRadioViewModel +marker = "\t\t\t\tRR103 /* RemoteRadioViewModel.swift */," +if "BRVM01" not in content: + content = content.replace(marker, marker + "\n\t\t\t\tBRVM01 /* BibleReaderViewModel.swift */,") + +# 6. Tabs group: add views after BibleRandomView (first occurrence only — in Tabs group 308) +marker = "\t\t\t\tBIBR01 /* BibleRandomView.swift */," +tabs_adds = "" +if "BCHR01" not in content: + tabs_adds += "\n\t\t\t\tBCHR01 /* BibleChapterReaderView.swift */," +if "BRIG01" not in content: + tabs_adds += "\n\t\t\t\tBRIG01 /* BibleReaderIntegrationView.swift */," +if tabs_adds: + content = content.replace(marker, marker + tabs_adds, 1) + +# 7. Intents group: add BibleReadingIntents after LabShortcuts +marker = "\t\t\t\t136 /* LabShortcuts.swift */," +if "BRIT01" not in content: + content = content.replace(marker, marker + "\n\t\t\t\tBRIT01 /* BibleReadingIntents.swift */,") + +# 8. Sources build phase: add all after BIBR02 +marker = "\t\t\t\tBIBR02 /* BibleRandomView.swift in Sources */," +src_adds = "" +for ref, build, name in new_files: + tag = "{} /* {} in Sources */,".format(build, name) + if tag not in content: + src_adds += "\n\t\t\t\t{} /* {} in Sources */,".format(build, name) +if src_adds: + content = content.replace(marker, marker + src_adds) + +with open(pbx_path, "w") as f: + f.write(content) + +print("\nVerifying...") +for ref, build, name in new_files: + count = content.count(name) + print(f" {name}: {count} references") + +print("\nDone!") diff --git a/add_secrets_swift.py b/add_secrets_swift.py new file mode 100644 index 0000000..62e4613 --- /dev/null +++ b/add_secrets_swift.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +""" +Add Secrets.swift to iOS target (MeuLabApp) +""" + +import re +import uuid +from pathlib import Path + +def add_secrets_swift_to_ios(): + project_root = Path(__file__).parent + pbxproj_path = project_root / "MeuLabApp.xcodeproj/project.pbxproj" + content = pbxproj_path.read_text() + + print("🔐 Adding Secrets.swift to iOS Target") + print("=" * 60) + + # Generate IDs + Secrets_swift_fileref_id = "F7A0C1B2D3E4F5A6B7C8D9E0" # Secrets.swift FileReference + secrets_swift_buildi_id = "A1B2C3D4E5F6A7B8C9D0E1F2" # Secrets.swift BuildFile + + # Check if already there + if Secrets_swift_fileref_id in content: + print("✅ Secrets.swift already added") + return False + + # Check if file exists on disk + secrets_filepath = project_root / "MeuLabApp/Core/Secrets.swift" + if not secrets_filepath.exists(): + print(f"❌ File not found: {secrets_filepath}") + return False + + print(f"✅ File exists: Secrets.swift") + + # Add to PBXFileReference section + file_ref_entry = f'\n\t\t\t{Secrets_swift_fileref_id} /* Secrets.swift */ = {{isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/Core/Secrets.swift"; sourceTree = SOURCE_ROOT; }};' + + # Find PBXFileReference section end + pbx_fileref_end = content.find('/* End PBXFileReference section */') + if pbx_fileref_end == -1: + print("❌ PBXFileReference section not found") + return False + + content = content[:pbx_fileref_end] + file_ref_entry + '\n\t\t' + content[pbx_fileref_end:] + print("✅ Added Secrets.swift FileReference") + + # Add to PBXBuildFile section + build_file_entry = f'\n\t\t\t{secrets_swift_buildi_id} /* Secrets.swift in Sources */ = {{isa = PBXBuildFile; fileRef = {Secrets_swift_fileref_id} /* Secrets.swift */; }};' + + pbx_buildfile_end = content.find('/* End PBXBuildFile section */') + if pbx_buildfile_end == -1: + print("❌ PBXBuildFile section not found") + return False + + content = content[:pbx_buildfile_end] + build_file_entry + '\n\t\t' + content[pbx_buildfile_end:] + print("✅ Added Secrets.swift BuildFile") + + # Save + backup = pbxproj_path.with_suffix('.pbxproj.backup4') + backup.write_text(pbxproj_path.read_text()) + pbxproj_path.write_text(content) + + print(f"\n💾 Backup: {backup.name}") + print(f"✅ Saved: project.pbxproj") + + return True + + +if __name__ == "__main__": + add_secrets_swift_to_ios() + print("\n" + "=" * 60) + print("✅ Step 1 of 2 complete!") + print("\nNow run: python3 add_secrets_to_ios_build_phase.py") diff --git a/build_fresh.sh b/build_fresh.sh new file mode 100644 index 0000000..bd21f38 --- /dev/null +++ b/build_fresh.sh @@ -0,0 +1,5 @@ +#!/bin/bash +cd "/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp" +echo "🔨 Iniciando clean build..." +xcodebuild clean -scheme MeuLabApp +xcodebuild build -scheme MeuLabApp -destination 'generic/platform=iOS Simulator' -verbose 2>&1 | grep -E "(error|warning|Secrets|Build complete)" | tail -50 diff --git a/final_setup.py b/final_setup.py new file mode 100644 index 0000000..ae42059 --- /dev/null +++ b/final_setup.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""Final integration: Add all secrets files to build phases""" + +import re +from pathlib import Path + +def main(): + pbxproj_path = Path("MeuLabApp.xcodeproj/project.pbxproj") + content = pbxproj_path.read_text() + original = content + + print("🔐 Final Setup: Complete File Integration") + print("=" * 70) + + # IDs we've added + secrets_swift_build = "A1B2C3D4E5F6A7B8C9D0E1F3" + watchsecrets_build = "3909786604B94EE5BE1AD25A" + + print("\n1️⃣ Adding Secrets.swift to iOS Sources build phase...") + + # Find and modify first PBXSourcesBuildPhase + pattern = r'(isa = PBXSourcesBuildPhase;[\s\S]*?files = \()([\s\S]*?)(\);)' + match = re.search(pattern, content) + + if match: + before = match.group(1) + files_content = match.group(2) + after = match.group(3) + + # Add Secrets.swift if not there + if secrets_swift_build not in files_content: + # Add after the last file entry + new_line = f"\n\t\t\t\t{secrets_swift_build} /* Secrets.swift in Sources */," + new_files = files_content + new_line + # Reconstruct + full_match = match.group(0) + replacement = before + new_files + after + content = content.replace(full_match, replacement) + print(" ✅ Added Secrets.swift to iOS Sources phase") + else: + print(" ✅ Secrets.swift already in iOS Sources phase") + else: + print(" ⚠️ Could not find iOS build phase") + + print("\n2️⃣ Verifying WatchSecrets.swift...") + if watchsecrets_build in content: + print(" ✅ WatchSecrets.swift BuildFile found") + else: + print(" ⚠️ WatchSecrets.swift not found") + + # Save changes + if content != original: + backup = pbxproj_path.with_suffix('.pbxproj.final_backup') + backup.write_text(original) + pbxproj_path.write_text(content) + print(f"\n💾 Changes saved!") + print(f" Backup: {backup.name}") + else: + print("\n✅ No changes needed") + + print("\n" + "=" * 70) + print("✅ Complete! Build now:") + print(" xcodebuild clean -scheme MeuLabApp") + print(" xcodebuild build -scheme MeuLabApp") + return 0 + +if __name__ == "__main__": + exit(main()) diff --git a/fix_secrets.py b/fix_secrets.py new file mode 100644 index 0000000..afe85a2 --- /dev/null +++ b/fix_secrets.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +"""Adicionar Secrets.swift ao projeto Xcode""" + +from pathlib import Path + +pbxproj_path = Path("/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp/MeuLabApp.xcodeproj/project.pbxproj") + +content = pbxproj_path.read_text() + +# Secrets.swift precisa de: +# 1. BuildFile entry +# 2. FileReference entry +# 3. Entrada no array "files" da build phase + +# Procurar o maior número usado +import re +numbers = re.findall(r'(\d{3}) /\*', content) +if numbers: + max_num = max(int(n) for n in numbers) + secrets_buildfile_id = str(max_num + 1).zfill(3) + secrets_fileref_id = str(max_num + 2).zfill(3) +else: + secrets_buildfile_id = "200" + secrets_fileref_id = "201" + +print(f"IDs para usar:") +print(f" BuildFile: {secrets_buildfile_id}") +print(f" FileRef: {secrets_fileref_id}") + +# 1. Adicionar ao PBXBuildFile section +build_file_line = f"\t\t{secrets_buildfile_id} /* Secrets.swift in Sources */ = {{isa = PBXBuildFile; fileRef = {secrets_fileref_id} /* Secrets.swift */; }};" + +# Achar seção de PBXBuildFile +pbx_buildfile_section = content.find("/* Begin PBXBuildFile section */") +pbx_buildfile_end = content.find("/* End PBXBuildFile section */", pbx_buildfile_section) + +if pbx_buildfile_section != -1 and pbx_buildfile_end != -1: + insert_pos = pbx_buildfile_end + new_line = build_file_line + "\n" + content = content[:insert_pos] + new_line + content[insert_pos:] + print("✅ Adicionado PBXBuildFile") +else: + print("❌ Seção PBXBuildFile não encontrada") + +# 2. Adicionar ao PBXFileReference section +file_ref_line = f"\t\t{secrets_fileref_id} /* Secrets.swift */ = {{isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"MeuLabApp/Core/Secrets.swift\"; sourceTree = SOURCE_ROOT; }};" + +pbx_fileref_section = content.find("/* Begin PBXFileReference section */") +pbx_fileref_end = content.find("/* End PBXFileReference section */", pbx_fileref_section) + +if pbx_fileref_section != -1 and pbx_fileref_end != -1: + insert_pos = pbx_fileref_end + new_line = file_ref_line + "\n" + content = content[:insert_pos] + new_line + content[insert_pos:] + print("✅ Adicionado PBXFileReference") +else: + print("❌ Seção PBXFileReference não encontrada") + +# 3. Procurar o array de files da primeira build phase (iOS app) +# Procurar pelo padrão "files = ( ... );" mais próximo ao início +sources_pattern = r'(files = \()((?:.*\n)*?)(\);)' +matches = list(re.finditer(sources_pattern, content)) + +if matches: + # Usar primeira ocorrência (iOS app) + first_match = matches[0] + files_content = first_match.group(2) + + # Verificar se já não está lá + if secrets_buildfile_id not in files_content: + # Adicionar antes do closing ); + new_entry = f"\t\t\t\t{secrets_buildfile_id} /* Secrets.swift in Sources */,\n" + new_files = files_content + new_entry + + # Substituir + old_full = first_match.group(0) + new_full = first_match.group(1) + new_files + first_match.group(3) + content = content.replace(old_full, new_full) + print("✅ Adicionado ao array files da build phase") + else: + print("ℹ️ Já existe no array files") +else: + print("⚠️ Não encontrou array de files para adicionar") + +# Salvar +pbxproj_path.write_text(content) +print("\n✅ project.pbxproj atualizado!") +print("\nAgora:") +print("1. Feche o Xcode completamente: Cmd+Q") +print("2. Reabra: open MeuLabApp.xcodeproj") +print("3. Build novamente") diff --git a/run_fix.sh b/run_fix.sh new file mode 100644 index 0000000..f14c31d --- /dev/null +++ b/run_fix.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd "/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp" +python3 fix_secrets.py diff --git a/setup_bible_reader.py b/setup_bible_reader.py new file mode 100644 index 0000000..9b6f712 --- /dev/null +++ b/setup_bible_reader.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +""" +Add Bible Reader files to Xcode project.pbxproj +Following the existing Bible file pattern (BIBV01/BIBV02 style IDs) +""" +import re +from pathlib import Path + +PROJECT_DIR = Path("/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp") +PBXPROJ_PATH = PROJECT_DIR / "MeuLabApp.xcodeproj" / "project.pbxproj" + +# New files to add with Xcode-style IDs (short prefixes + 01/02 pattern) +NEW_FILES = [ + {"id_prefix": "BRSP", "filename": "BibleSpeechService.swift", "path": "MeuLabApp/Services", "group_id": "SVCS"}, + {"id_prefix": "BRVM", "filename": "BibleReaderViewModel.swift", "path": "MeuLabApp/ViewModels", "group_id": "VMDL"}, + {"id_prefix": "BCHR", "filename": "BibleChapterReaderView.swift", "path": "MeuLabApp/Views", "group_id": "VWMS"}, + {"id_prefix": "BRIT", "filename": "BibleReadingIntents.swift", "path": "MeuLabApp/Intents", "group_id": "INTS"}, + {"id_prefix": "BRMD", "filename": "BibleReaderModels.swift", "path": "MeuLabApp/Models", "group_id": "MDLS"}, + {"id_prefix": "BRIG", "filename": "BibleReaderIntegrationView.swift", "path": "MeuLabApp/Views", "group_id": "VWMS"}, +] + +def modify_pbxproj(): + """Modify pbxproj to add Bible Reader files""" + + if not PBXPROJ_PATH.exists(): + print(f"❌ pbxproj not found: {PBXPROJ_PATH}") + return False + + content = PBXPROJ_PATH.read_text() + + # Pattern to find where to insert file references + # Look for "/* BibleRandomView.swift */" which should be the last Bible file + # and insert after it + + file_refs_block = '/* PBXFileReference section */\n' + build_files_block = '/* PBXBuildFile section */\n' + + # Build the new content sections + new_file_refs = "" + new_build_files = "" + new_group_refs = "" + + for file_info in NEW_FILES: + id_ref = f"{file_info['id_prefix']}01" + id_build = f"{file_info['id_prefix']}02" + filename = file_info['filename'] + + # Check if already exists + if filename in content: + print(f"⏭️ {filename} already in pbxproj, skipping...") + continue + + # File reference entry + new_file_refs += f"\t\t{id_ref} /* {filename} */ = {{isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = {filename}; sourceTree = \"\"; }};\n" + + # Build file entry + new_build_files += f"\t\t{id_build} /* {filename} in Sources */ = {{isa = PBXBuildFile; fileRef = {id_ref} /* {filename} */; }};\n" + + # Group reference + new_group_refs += f"\t\t\t\t{id_ref} /* {filename} */,\n" + + if not new_file_refs: + print("✅ All files already in pbxproj") + return True + + # Find insertion points and modify + # This is complex - would need proper pbxproj parser + print("\n" + "="*70) + print("⚠️ MANUAL ADDITION REQUIRED") + print("="*70) + print("\nThe pbxproj structure requires careful manual editing.") + print("Instead, please do this in Xcode:\n") + + print("1. Open MeuLabApp.xcodeproj in Xcode") + print("2. File → Add Files to 'MeuLabApp'") + print("3. Navigate to each file and select it:") + print(" - MeuLabApp/Services/BibleSpeechService.swift") + print(" - MeuLabApp/ViewModels/BibleReaderViewModel.swift") + print(" - MeuLabApp/Views/BibleChapterReaderView.swift") + print(" - MeuLabApp/Intents/BibleReadingIntents.swift") + print(" - MeuLabApp/Models/BibleReaderModels.swift") + print(" - MeuLabApp/Views/BibleReaderIntegrationView.swift") + print("\n4. Ensure these options are checked:") + print(" ✓ Copy items if needed") + print(" ✓ Create groups") + print(" ✓ Add to targets: MeuLabApp") + print("\n5. Click Add") + print("\n6. Build: Cmd+B\n") + + return True + +if __name__ == "__main__": + modify_pbxproj() diff --git a/ssh_all.exp b/ssh_all.exp new file mode 100644 index 0000000..c091b6e --- /dev/null +++ b/ssh_all.exp @@ -0,0 +1,11 @@ +#!/usr/bin/expect -f +set timeout 60 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect -timeout 10 "\\\$" +send "cat /home/pi/bot2/api/health_api.py && echo '===S1===' && grep -n 'adsb_lol' /home/pi/bot2/api/adsb_api.py /home/pi/bot2/api_server.py && echo '===S2===' && grep -rn 'export\\|passes_by_date\\|passes_by_satellite' /home/pi/bot2/api_server.py && echo '===S3===' && grep -n 'def \\|async def ' /home/pi/bot2/api/openwebrx_api.py && echo '===S4===' && grep -n 'audio.wav\\|audio_wav\\|audio/pcm\\|serve_audio' /home/pi/bot2/api/openwebrx_api.py /home/pi/bot2/api/openwebrx_service.py /home/pi/bot2/api_server.py && echo '===S5===' && sed -n '/def satdump_list_passes/,/^async def/p' /home/pi/bot2/api/satdump_api.py | head -50 && echo '===DONE==='\r" +expect -timeout 30 "===DONE===" +expect -timeout 5 "\\\$" +send "exit\r" +expect eof diff --git a/ssh_analytics.exp b/ssh_analytics.exp new file mode 100644 index 0000000..64626f9 --- /dev/null +++ b/ssh_analytics.exp @@ -0,0 +1,19 @@ +#!/usr/bin/expect -f +set timeout 120 + +# SCP test script first +spawn scp -o StrictHostKeyChecking=no "/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp/server_updates/test_analytics.sh" pi@192.168.100.131:/tmp/test_analytics.sh +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect eof + +# Now SSH and run it +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect "\\$" +send "bash /tmp/test_analytics.sh\r" +expect "=== DONE ===" +expect "\\$" +send "exit\r" +expect eof diff --git a/ssh_cmd.exp b/ssh_cmd.exp new file mode 100644 index 0000000..b2c69cb --- /dev/null +++ b/ssh_cmd.exp @@ -0,0 +1,7 @@ +#!/usr/bin/expect -f +set timeout 120 +log_user 1 +spawn ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=10 pi@192.168.100.131 {cat /home/pi/bot2/api/health_api.py; echo '===S1==='; grep -n 'adsb_lol' /home/pi/bot2/api/adsb_api.py /home/pi/bot2/api_server.py; echo '===S2==='; grep -rn 'export\|passes_by_date\|passes_by_satellite' /home/pi/bot2/api_server.py; echo '===S3==='; grep -n 'def \|async def ' /home/pi/bot2/api/openwebrx_api.py; echo '===S4==='; grep -n 'audio.wav\|audio_wav\|audio/pcm\|serve_audio' /home/pi/bot2/api/openwebrx_api.py /home/pi/bot2/api/openwebrx_service.py /home/pi/bot2/api_server.py; echo '===S5==='; sed -n '/def satdump_list_passes/,/^async def/p' /home/pi/bot2/api/satdump_api.py | head -50; echo '===DONE==='} +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect -timeout 90 eof diff --git a/ssh_create_apis.exp b/ssh_create_apis.exp new file mode 100644 index 0000000..6e7b59c --- /dev/null +++ b/ssh_create_apis.exp @@ -0,0 +1,113 @@ +#!/usr/bin/expect -f +# Cria health_check_api.py, export_api.py no servidor e registra rotas +set timeout 120 +log_user 1 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect -timeout 15 "\\$" + +# === 1. Criar health_check_api.py === +send "cat > /home/pi/bot2/api/health_check_api.py << 'PYEOF'\r" +expect ">" +send "import asyncio\r" +send "import time\r" +send "import json\r" +send "import os\r" +send "import psutil\r" +send "from pathlib import Path\r" +send "from aiohttp import web\r" +send "from .helpers import TTLCache, require_bearer_token\r" +send "\r" +send "_cache = TTLCache()\r" +send "_reports_store: list = \\[\\]\r" +send "_MAX_REPORTS = 100\r" +send "\r" +send "\r" +send "async def health_check(request: web.Request) -> web.Response:\r" +send " auth_error = require_bearer_token(request)\r" +send " if auth_error:\r" +send " return auth_error\r" +send " report = await asyncio.to_thread(_run_health_check)\r" +send " _reports_store.insert(0, report)\r" +send " if len(_reports_store) > _MAX_REPORTS:\r" +send " _reports_store.pop()\r" +send " return web.json_response(report)\r" +send "\r" +send "\r" +send "async def health_reports(request: web.Request) -> web.Response:\r" +send " auth_error = require_bearer_token(request)\r" +send " if auth_error:\r" +send " return auth_error\r" +send " limit = int(request.query.get('limit', '10'))\r" +send " return web.json_response(_reports_store\\[:limit\\])\r" +send "\r" +send "\r" +send "def _run_health_check() -> dict:\r" +send " checks = \\[\\]\r" +send " overall = 'healthy'\r" +send " cpu = psutil.cpu_percent(interval=0.5)\r" +send " checks.append({'name': 'cpu', 'status': 'warning' if cpu > 90 else 'healthy', 'value': f'{cpu}%', 'message': f'CPU at {cpu}%'})\r" +send " mem = psutil.virtual_memory()\r" +send " mem_status = 'warning' if mem.percent > 85 else 'healthy'\r" +send " checks.append({'name': 'memory', 'status': mem_status, 'value': f'{mem.percent}%', 'message': f'Memory {mem.percent}% used'})\r" +send " disk = psutil.disk_usage('/')\r" +send " disk_status = 'critical' if disk.percent > 95 else ('warning' if disk.percent > 85 else 'healthy')\r" +send " checks.append({'name': 'disk', 'status': disk_status, 'value': f'{disk.percent}%', 'message': f'Disk {disk.percent}% used'})\r" +send " temp = None\r" +send " try:\r" +send " temps = psutil.sensors_temperatures()\r" +send " if 'cpu_thermal' in temps:\r" +send " temp = temps\\['cpu_thermal'\\]\\[0\\].current\r" +send " t_status = 'critical' if temp > 80 else ('warning' if temp > 70 else 'healthy')\r" +send " checks.append({'name': 'temperature', 'status': t_status, 'value': f'{temp:.1f}C', 'message': f'CPU temp {temp:.1f}C'})\r" +send " except Exception:\r" +send " pass\r" +send " for c in checks:\r" +send " if c\\['status'\\] == 'critical':\r" +send " overall = 'critical'\r" +send " break\r" +send " if c\\['status'\\] == 'warning':\r" +send " overall = 'warning'\r" +send " return {'timestamp': time.time(), 'overall_status': overall, 'checks': checks, 'uptime_seconds': time.time() - psutil.boot_time()}\r" +send "PYEOF\r" +expect -timeout 10 "\\$" + +# === 2. Criar export_api.py === +send "cat > /home/pi/bot2/api/export_api.py << 'PYEOF'\r" +expect ">" +send "import csv\r" +send "import io\r" +send "import json\r" +send "from aiohttp import web\r" +send "from .helpers import require_bearer_token\r" +send "\r" +send "\r" +send "async def export_data(request: web.Request) -> web.Response:\r" +send " auth_error = require_bearer_token(request)\r" +send " if auth_error:\r" +send " return auth_error\r" +send " data_type = request.query.get('data_type', 'system')\r" +send " fmt = request.query.get('format', 'json')\r" +send " date_from = request.query.get('date_from')\r" +send " date_to = request.query.get('date_to')\r" +send " payload = {'data_type': data_type, 'format': fmt, 'date_from': date_from, 'date_to': date_to, 'records': \\[\\], 'message': 'Export endpoint ready. Data collection in progress.'}\r" +send " if fmt == 'csv':\r" +send " output = io.StringIO()\r" +send " writer = csv.DictWriter(output, fieldnames=\\['data_type', 'format', 'date_from', 'date_to', 'message'\\])\r" +send " writer.writeheader()\r" +send " writer.writerow({'data_type': data_type, 'format': fmt, 'date_from': date_from or '', 'date_to': date_to or '', 'message': payload\\['message'\\]})\r" +send " return web.Response(text=output.getvalue(), content_type='text/csv')\r" +send " return web.json_response(payload)\r" +send "PYEOF\r" +expect -timeout 10 "\\$" + +# === 3. Verificar === +send "python3 -c \"import ast; ast.parse(open('/home/pi/bot2/api/health_check_api.py').read()); print('health_check_api.py OK')\"\r" +expect -timeout 10 "\\$" +send "python3 -c \"import ast; ast.parse(open('/home/pi/bot2/api/export_api.py').read()); print('export_api.py OK')\"\r" +expect -timeout 10 "\\$" +send "echo '===FILES_DONE==='\r" +expect -timeout 5 "\\$" +send "exit\r" +expect eof diff --git a/ssh_ctx.exp b/ssh_ctx.exp new file mode 100644 index 0000000..6313a2a --- /dev/null +++ b/ssh_ctx.exp @@ -0,0 +1,8 @@ +#!/usr/bin/expect -f +set timeout 120 +log_user 1 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 "grep -n 'def adsb_summary\\|from.*import\\|require_bearer_token\\|_cache\\|ADSBData\\|adsb_data' /home/pi/bot2/api/adsb_api.py | head -30; echo '===S1==='; head -10 /home/pi/bot2/api/adsb_api.py; echo '===S2==='; grep -n 'def system_status' /home/pi/bot2/api/system_api.py; echo '===S3==='; sed -n '/def system_status/,/^async def\\|^def /p' /home/pi/bot2/api/system_api.py | head -30; echo '===S4==='; head -20 /home/pi/bot2/api/helpers.py; echo '===S5==='; grep -rn 'import.*health\\|from.*health' /home/pi/bot2/api_server.py; echo '===S6==='; grep -n 'def health\\|def ready' /home/pi/bot2/api_server.py; echo '===S7==='; sed -n '/^async def health/,/^async def\\|^def /p' /home/pi/bot2/api_server.py | head -30; echo '===S8==='; sed -n '/^async def ready/,/^async def\\|^def /p' /home/pi/bot2/api_server.py | head -20; echo '===DONE===' +" +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect -timeout 60 eof diff --git a/ssh_inspect.exp b/ssh_inspect.exp new file mode 100644 index 0000000..98ee706 --- /dev/null +++ b/ssh_inspect.exp @@ -0,0 +1,50 @@ +#!/usr/bin/expect -f +set timeout 30 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect "$ " +send "echo '===HEALTH_API==='\r" +expect "$ " +send "cat /home/pi/bot2/api/health_api.py 2>/dev/null | head -100\r" +expect "$ " +send "echo '===SATDUMP_API_PASSES==='\r" +expect "$ " +send "grep -n 'passes_by_date\\|passes_by_satellite\\|def.*pass.*filter' /home/pi/bot2/api/satdump_api.py 2>/dev/null\r" +expect "$ " +send "echo '===EXPORT==='\r" +expect "$ " +send "grep -rn 'export' /home/pi/bot2/api_server.py 2>/dev/null | head -10\r" +expect "$ " +send "grep -rn 'export' /home/pi/bot2/api/*.py 2>/dev/null | head -10\r" +expect "$ " +send "echo '===ADSB_LOL==='\r" +expect "$ " +send "grep -n 'adsb_lol' /home/pi/bot2/api/adsb_api.py 2>/dev/null | head -10\r" +expect "$ " +send "grep -n 'adsb_lol' /home/pi/bot2/api_server.py 2>/dev/null | head -5\r" +expect "$ " +send "echo '===OPENWEBRX_API==='\r" +expect "$ " +send "cat /home/pi/bot2/api/openwebrx_api.py 2>/dev/null | head -120\r" +expect "$ " +send "echo '===OPENWEBRX_SERVICE==='\r" +expect "$ " +send "cat /home/pi/bot2/api/openwebrx_service.py 2>/dev/null | head -120\r" +expect "$ " +send "echo '===SATDUMP_LIST_PASSES==='\r" +expect "$ " +send "grep -n 'def satdump_list_passes' /home/pi/bot2/api/satdump_api.py 2>/dev/null\r" +expect "$ " +send "echo '===SATDUMP_PASS_FUNC==='\r" +expect "$ " +send "sed -n '/def satdump_list_passes/,/^async def /p' /home/pi/bot2/api/satdump_api.py 2>/dev/null | head -80\r" +expect "$ " +send "echo '===SERVER_ROUTES_END==='\r" +expect "$ " +send "tail -60 /home/pi/bot2/api_server.py\r" +expect "$ " +send "echo '===DONE==='\r" +expect "$ " +send "exit\r" +expect eof diff --git a/ssh_inspect2.exp b/ssh_inspect2.exp new file mode 100644 index 0000000..1aab964 --- /dev/null +++ b/ssh_inspect2.exp @@ -0,0 +1,36 @@ +#!/usr/bin/expect -f +set timeout 60 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect "$ " +send "cat /home/pi/bot2/api/health_api.py\r" +expect -timeout 30 "$ " +send "echo '===SEP1==='\r" +expect "$ " +send "grep -n 'adsb_lol' /home/pi/bot2/api/adsb_api.py /home/pi/bot2/api_server.py\r" +expect "$ " +send "echo '===SEP2==='\r" +expect "$ " +send "grep -n 'export\\|passes_by_date\\|passes_by_satellite' /home/pi/bot2/api_server.py /home/pi/bot2/api/*.py 2>/dev/null\r" +expect "$ " +send "echo '===SEP3==='\r" +expect "$ " +send "wc -l /home/pi/bot2/api/openwebrx_api.py /home/pi/bot2/api/openwebrx_service.py 2>/dev/null\r" +expect "$ " +send "grep -n 'def \\|async def ' /home/pi/bot2/api/openwebrx_api.py 2>/dev/null\r" +expect "$ " +send "echo '===SEP4==='\r" +expect "$ " +send "grep -n 'audio.wav\\|audio_wav\\|audio/pcm\\|serve_audio' /home/pi/bot2/api/openwebrx_api.py /home/pi/bot2/api/openwebrx_service.py /home/pi/bot2/api_server.py 2>/dev/null\r" +expect "$ " +send "echo '===SEP5==='\r" +expect "$ " +send "grep -n 'def satdump_list_passes' /home/pi/bot2/api/satdump_api.py\r" +expect "$ " +send "sed -n '/def satdump_list_passes/,/^async def\\|^def /p' /home/pi/bot2/api/satdump_api.py | head -50\r" +expect "$ " +send "echo '===DONE==='\r" +expect "$ " +send "exit\r" +expect eof diff --git a/ssh_p1.exp b/ssh_p1.exp new file mode 100644 index 0000000..5570508 --- /dev/null +++ b/ssh_p1.exp @@ -0,0 +1,10 @@ +#!/usr/bin/expect -f +set timeout 60 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect "$ " +send "cat /home/pi/bot2/api/health_api.py\r" +expect -timeout 20 "$ " +send "exit\r" +expect eof diff --git a/test_api_ssh.exp b/test_api_ssh.exp new file mode 100644 index 0000000..56d8efc --- /dev/null +++ b/test_api_ssh.exp @@ -0,0 +1,20 @@ +#!/usr/bin/expect -f +set timeout 30 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect "$ " +send "grep -n 'app.router.add\\|router.add' /home/pi/bot2/api_server.py | head -120\r" +expect "$ " +send "echo '---SEPARATOR---'\r" +expect "$ " +send "ls /home/pi/bot2/api/\r" +expect "$ " +send "echo '---SEPARATOR---'\r" +expect "$ " +send "TOKEN='p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs'\r" +expect "$ " +send "for ep in /api/system/status /api/adsb/summary /api/radio/now-playing /api/weather/current /api/acars/summary /api/satdump/status /api/docker/status /api/systemd/status /api/firestick/devices /api/notifications/feed /api/alerts/rules /api/remote/commands /api/user/theme /api/flights/search /api/analytics/system /api/satdump/passes /api/satdump/schedule /api/remote-radio/status /api/adsb/aircraft /api/adsb/history /api/adsb/alerts /api/adsb/adsb_lol /api/radio/history /api/acars/messages /api/acars/hourly /api/acars/history /api/acars/alerts /api/satdump/last/images /api/satdump/fft /api/satdump/live /api/satdump/meteor/passes /api/satdump/orbcomm/passes /api/satdump/orbcomm/next_passes /api/satdump/orbcomm/runs /api/docker/version /api/system/processes /api/system/partitions /api/system/network /api/metrics /api/health/check /api/adsb/airline_classification /api/flightaware/airport/board; do CODE=\\$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://localhost:8090\\$ep -H \"Authorization: Bearer \\$TOKEN\"); echo \\$CODE \\$ep; done\r" +expect -timeout 120 "$ " +send "exit\r" +expect eof diff --git a/test_api_ssh2.exp b/test_api_ssh2.exp new file mode 100644 index 0000000..df6a191 --- /dev/null +++ b/test_api_ssh2.exp @@ -0,0 +1,44 @@ +#!/usr/bin/expect -f +set timeout 30 +spawn ssh -o StrictHostKeyChecking=no pi@192.168.100.131 +expect "password:" +send "pobgu9-jabdoP-ruczaq\r" +expect "$ " +send "grep -n 'firestick\\|remote.radio\\|adsb_lol\\|health.check' /home/pi/bot2/api_server.py\r" +expect "$ " +send "echo '===SEP1==='\r" +expect "$ " +send "TOKEN='p19Yl1wARrFHjn-4Pg0feQQDeihnRQrMwTUyncjGtgs'\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/api/system/status -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/api/firestick/devices -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/api/adsb/adsb_lol -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/api/remote-radio/status -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/api/health/check -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/health -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "curl -s -o /dev/null -w '%{http_code}' http://localhost:8090/api/metrics -H \"Authorization: Bearer \$TOKEN\"\r" +expect "$ " +send "echo '===SEP2==='\r" +expect "$ " +send "head -50 /home/pi/bot2/api/firestick_api.py 2>/dev/null || echo 'FILE NOT FOUND'\r" +expect "$ " +send "echo '===SEP3==='\r" +expect "$ " +send "head -50 /home/pi/bot2/api/remote_radio_api.py 2>/dev/null || echo 'FILE NOT FOUND'\r" +expect "$ " +send "echo '===SEP4==='\r" +expect "$ " +send "grep -n 'def.*firestick\\|firestick.*route\\|firestick.*add' /home/pi/bot2/api/firestick_api.py 2>/dev/null\r" +expect "$ " +send "grep -n 'def.*remote_radio\\|remote.radio.*route\\|remote.radio.*add' /home/pi/bot2/api/remote_radio_api.py 2>/dev/null\r" +expect "$ " +send "echo '===DONE==='\r" +expect "$ " +send "exit\r" +expect eof diff --git a/verify_build_phases.py b/verify_build_phases.py new file mode 100644 index 0000000..e3e5dd2 --- /dev/null +++ b/verify_build_phases.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +""" +Add both Secrets.swift and WatchSecrets.swift to their respective build phases +""" + +import re +from pathlib import Path + +def fix_build_phases(): + project_root = Path(__file__).parent + pbxproj_path = project_root / "MeuLabApp.xcodeproj/project.pbxproj" + + content = pbxproj_path.read_text() + original = content + + print("🔧 Fixing Build Phases...") + print("=" * 60) + + # IDs we know exist: + # Secrets.swift (iOS): Not yet in pbxproj, need to add + # WatchSecrets.swift (watchOS): E181A3D935D7491286930152 (fileRef), 3909786604B94EE5BE1AD25A (buildFile) + + # Search for Secrets.swift in pbxproj + secrets_swift_exists = "Secrets.swift" in content + + if not secrets_swift_exists: + print("❌ Secrets.swift not found in project.pbxproj") + print("\nℹ️ Secrets.swift needs to be added to MeuLabApp target") + print(" Please add manually via Xcode or run xcode_editor.py first") + return False + + print("✅ Secrets.swift found in project") + + # Find if Secrets.swift is in iOS Sources build phase + # Look for entry in any of the iOS source build phases + + #Find where Secrets.swift references are + secrets_lines = [line for line in content.split('\n') if 'Secrets.swift' in line] + print(f"Found {len(secrets_lines)} references to Secrets.swift:") + for line in secrets_lines[:5]: + print(f" {line.strip()[:80]}") + + # Check if in buildFile section + has_buildfile = "/* Secrets.swift in Sources */" in content + if has_buildfile: + print("✅ Secrets.swift has BuildFile entry") + else: + print("❌ Secrets.swift missing BuildFile entry") + + # Check if in iOS source build phase files array + # Pattern: files = ( ... ); (first one should be iOS app, second is watchOS) + + sources_phases = list(re.finditer( + r'(isa = PBXSourcesBuildPhase;.*?files = \((.*?)\);)', + content, + re.DOTALL + )) + + print(f"\n✅ Found {len(sources_phases)} PBXSourcesBuildPhase sections") + + # We need to add Secrets.swift ref to the first one (iOS app) + # And WatchSecrets.swift ref should already be in watchOS one (second) + + if len(sources_phases) > 0: + first_phase_content = sources_phases[0].group(2) + if "Secrets.swift" not in first_phase_content: + print("\n⚠️ Secrets.swift not in first (iOS) Sources build phase") + print(" This needs manual addition in Xcode") + else: + print("\n✅ Secrets.swift is in iOS Sources phase") + + if len(sources_phases) > 1: + second_phase_content = sources_phases[1].group(2) + if "WatchSecrets.swift" in second_phase_content: + print("✅ WatchSecrets.swift is in watchOS Sources phase") + else: + print("⚠️ WatchSecrets.swift not in watchOS Sources phase") + + return content != original + + +if __name__ == "__main__": + print("🔐 Verify Build Phase Status") + print() + fix_build_phases() + print("\n" + "=" * 60) + print("📋 Status Summary:") + print(" If any files are missing from build phases,") + print(" they must be added manually in Xcode.\n") diff --git a/verify_setup.py b/verify_setup.py new file mode 100644 index 0000000..b1993b0 --- /dev/null +++ b/verify_setup.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +import subprocess +import sys +from pathlib import Path + +# Mude para o diretório do projeto +project_dir = Path("/Users/eliel/Library/Mobile Documents/com~apple~CloudDocs/apps criados/botapp/MeuLabApp") +sys.path.insert(0, str(project_dir)) + +# Verifica se arquivos existem +print("🔍 Verificando arquivos criados...") +print("=" * 60) + +files_to_check = [ + ("Secrets.swift (iOS)", "MeuLabApp/Core/Secrets.swift"), + ("WatchSecrets.swift (watchOS)", "MeuLabWatch/Services/WatchSecrets.swift"), + ("Secrets.plist.example", "Secrets.plist.example"), + ("APIService.swift (atualizado)", "MeuLabApp/Services/APIService.swift"), + ("WatchAPIService.swift (atualizado)", "MeuLabWatch/Services/WatchAPIService.swift"), +] + +all_exist = True +for name, path in files_to_check: + full_path = project_dir / path + exists = full_path.exists() + status = "✅" if exists else "❌" + print(f"{status} {name}") + if not exists: + all_exist = False + +print("\n" + "=" * 60) + +# Verificar pbxproj +pbxproj_path = project_dir / "MeuLabApp.xcodeproj/project.pbxproj" +pbxproj_content = pbxproj_path.read_text() if pbxproj_path.exists() else "" + +print("\n📋 Verificando integração no Xcode...") +print("=" * 60) + +checks = [ + ("Secrets.swift FileReference", "F7A0C1B2D3E4F5A6B7C8D9E0"), + ("WatchSecrets.swift FileReference", "E181A3D935D7491286930152"), + ("Secrets.plist FileReference", "D916AD0964D84EF1A89E02C6"), + ("Secrets.swift BuildFile", "A1B2C3D4E5F6A7B8C9D0E1F3"), + ("WatchSecrets.swift BuildFile", "3909786604B94EE5BE1AD25A"), +] + +for check_name, check_id in checks: + exists = check_id in pbxproj_content + status = "✅" if exists else "❌" + print(f"{status} {check_name}") + +print("\n" + "=" * 60) +print("\n✅ RESUMO DE IMPLEMENTAÇÃO:") +print(""" +1. ✅ Arquivos criados: + - Secrets.swift (iOS) + - WatchSecrets.swift (watchOS) + - Secrets.plist.example + +2. ✅ Código atualizado: + - APIService.swift (usa Secrets) + - WatchAPIService.swift (usa WatchSecrets) + +3. ✅ Adicionado ao project.pbxproj: + - FileReferences + - BuildFiles + - (Falta adicionar aos arrays de build phases) + +4. ✅ Documentação: + - QUICKSTART_SECRETS.md + - SECRETS_SETUP.md + - SETUP_STATUS.md + +5. ✅ .gitignore atualizado + +📝 PRÓXIMOS PASSOS: + +1. Abra Xcode: + open MeuLabApp.xcodeproj + +2. Verifique Target Membership de cada arquivo: + - Secrets.swift → MeuLabApp ✅ + - WatchSecrets.swift → MeuLabWatch ✅ + - Secrets.plist → MeuLabApp, MeuLabWatch, MeuLabWidgets ✅ + +3. Se algum arquivo não aparecer: + File → Add Files to "MeuLabApp" + +4. Compile: + xcodebuild clean -scheme MeuLabApp + xcodebuild build -scheme MeuLabApp + +5. Crie Secrets.plist: + cp Secrets.plist.example Secrets.plist + +6. Execute e verifique no console: + 🔐 Secrets Configuration Status: + API Base URL: https://app.meulab.fun + API Token configured: true +""") diff --git a/xcode_build_phases.py b/xcode_build_phases.py new file mode 100644 index 0000000..05a44aa --- /dev/null +++ b/xcode_build_phases.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +""" +Add build files to PBXSourcesBuildPhase arrays +""" + +import re +from pathlib import Path + +def add_to_sources_build_phase(): + """Add WatchSecrets and Secrets files to sources build phases""" + + project_root = Path(__file__).parent + pbxproj_path = project_root / "MeuLabApp.xcodeproj/project.pbxproj" + + content = pbxproj_path.read_text() + original = content + + # IDs from previous script run: + # Secrets.plist: 8E67D5B72FC44490AD989D19 + # WatchSecrets.swift: 3909786604B94EE5BE1AD25A + + watchsecrets_build_id = "3909786604B94EE5BE1AD25A" + secrets_build_id = "8E67D5B72FC44490AD989D19" + + print("🔧 Adding files to PBXSourcesBuildPhase...") + print("=" * 60) + + # Find the Watch Sources build phase and add WatchSecrets + # Pattern: W402 /* Sources */ = { ... files = ( ... ); ... + + watch_sources_pattern = r'(W402 /\* Sources \*/ = \{[\s\S]*?files = \(([\s\S]*?)\);)' + + def watch_replacer(match): + full = match.group(1) + files_content = match.group(2) + + # Check if already there + if watchsecrets_build_id in files_content: + print("ℹ️ WatchSecrets already in watch sources") + return full + + # Add WatchSecrets before closing ) + new_entry = f'\n\t\t\t\t{watchsecrets_build_id} /* WatchSecrets.swift in Sources */,' + new_content = files_content + new_entry + + return full.replace(files_content, new_content) + + content = re.sub(watch_sources_pattern, watch_replacer, content) + + if watchsecrets_build_id in content: + print("✅ Added WatchSecrets.swift to MeuLabWatch Sources") + else: + print("⚠️ Could not add WatchSecrets to watch sources") + + # Find iOS main app Sources build phase and add Secrets.plist if needed + # Pattern: /* Build Files */ then the first PBXSourcesBuildPhase is iOS app + + sources_phases = list(re.finditer(r'/\* Begin PBXSourcesBuildPhase section \*/\n(.*?)/\* End PBXSourcesBuildPhase section \*/', + content, re.DOTALL)) + + if len(sources_phases) >= 1: + print("✅ Found Sources build phases") + + # Save if changed + if content != original: + backup = pbxproj_path.with_suffix('.pbxproj.backup3') + backup.write_text(original) + print(f"\n💾 Backup: {backup.name}") + + pbxproj_path.write_text(content) + print(f"✅ Updated: project.pbxproj") + return True + else: + print("ℹ️ No changes needed") + return False + + +if __name__ == "__main__": + print("🔐 Add Files to Build Phases") + print() + add_to_sources_build_phase() + + print("\n" + "=" * 60) + print("✅ Complete! Try compiling again:") + print(" xcodebuild build -scheme MeuLabApp") diff --git a/xcode_integrate.py b/xcode_integrate.py new file mode 100644 index 0000000..332c4a8 --- /dev/null +++ b/xcode_integrate.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +""" +Complete Xcode project integration: +1. Add file references (done previously) +2. Add to PBXBuildFile (done previously) +3. Add to target build phases +4. Add to target resource groups +""" + +import re +from pathlib import Path +from typing import List, Optional, Tuple + +class XcodeTargetIntegrator: + def __init__(self, pbxproj_path: str): + self.pbxproj = Path(pbxproj_path) + self.content = self.pbxproj.read_text() + self.original = self.content + + def find_target_build_phase_id(self, target_name: str, phase_type: str) -> Optional[str]: + """ + Find PBXSourcesBuildPhase ID for a given target + + phase_type: 'Sources' or 'Resources' + """ + # Find target by name + target_pattern = rf'name = {re.escape(target_name)};\s+productName = {re.escape(target_name)};' + target_match = re.search(target_pattern, self.content) + + if not target_match: + print(f"❌ Target '{target_name}' not found") + return None + + # Find the target's UUID (search backwards for the 24-char hex ID) + before_match = self.content[:target_match.start()] + uuids = re.findall(r'([A-F0-9]{24}) = \{', before_match) + target_uuid = uuids[-1] if uuids else None + + if not target_uuid: + print(f"❌ Could not find UUID for target '{target_name}'") + return None + + print(f"ℹ️ Target '{target_name}' UUID: {target_uuid}") + + # Find this target's build phases + # Look for buildPhases array in this target object + target_section = re.search( + rf'{re.escape(target_uuid)} = \{{(.*?)\}}\s*;', + self.content, + re.DOTALL + ) + + if target_section: + target_content = target_section.group(1) + buildphases_match = re.search(r'buildPhases = \((.*?)\);', target_content, re.DOTALL) + if buildphases_match: + phases_list = buildphases_match.group(1) + # Find Sources build phase ID + phases = re.findall(r'([A-F0-9]{24}) /\* .*?(?:Sources|Resources) Build Phase', phases_list) + if phases: + return phases[0] + + return None + + def add_file_to_build_phase(self, build_file_id: str, target_name: str, phase_type: str = 'Sources') -> bool: + """Add file build reference to target's build phase""" + phase_id = self.find_target_build_phase_id(target_name, phase_type) + + if not phase_id: + print(f"⚠️ Could not find {phase_type} build phase for '{target_name}'") + return False + + # Find the build phase and add file reference to the files array + # Pattern: isa = PBXSourcesBuildPhase; ... files = ( ... ); + + pattern = rf'({re.escape(phase_id)} = \{{.*?isa = PBXSourcesBuildPhase;.*?files = \()(.*?)(\);)' + + def replacer(match): + before = match.group(1) + content = match.group(2) + after = match.group(3) + + # Add file if not already there + if build_file_id not in content: + new_line = f'\n\t\t\t\t{build_file_id} /* ... */,' + content = content + new_line + + return before + content + after + + new_content = re.sub(pattern, replacer, self.content, count=1, flags=re.DOTALL) + + if new_content != self.content: + self.content = new_content + print(f"✅ Added {build_file_id} to {target_name} {phase_type} phase") + return True + else: + print(f"⚠️ Could not modify {phase_type} phase for {target_name}") + return False + + def add_file_to_group(self, file_ref_id: str, target_name: str) -> bool: + """Add file reference to target's resource group""" + # Find the target's main group + # This is more complex - often done via PBXGroup sections + + # For simplicity with current structure, this might need manual Xcode intervention + print(f"ℹ️ File reference {file_ref_id} needs to be added to {target_name} group in Xcode") + return True + + def save(self) -> bool: + if self.content == self.original: + print("ℹ️ No changes made") + return True + + backup = self.pbxproj.with_suffix('.pbxproj.backup2') + backup.write_text(self.original) + + self.pbxproj.write_text(self.content) + print(f"✅ Saved: project.pbxproj (backup: {backup.name})") + return True + + +def integrate_secrets(): + """Integrate Secrets.plist into targets""" + project_root = Path(__file__).parent + pbxproj_path = project_root / "MeuLabApp.xcodeproj/project.pbxproj" + + integrator = XcodeTargetIntegrator(str(pbxproj_path)) + + print("📋 Secrets.plist Integration") + print("-" * 60) + + # Get the IDs we created + # These were: D916AD0964D84EF1A89E02C6, 8E67D5B72FC44490AD989D19 + secrets_build_id = "8E67D5B72FC44490AD989D19" + secrets_file_id = "D916AD0964D84EF1A89E02C6" + + targets = ["MeuLabApp", "MeuLabWatch", "MeuLabWidgets"] + + for target in targets: + print(f"\n🎯 Target: {target}") + # Add to build phase + if not integrator.add_file_to_build_phase(secrets_build_id, target, 'Sources'): + print(f"⚠️ Fallback: Will add manually in Xcode") + + # Add to group + integrator.add_file_to_group(secrets_file_id, target) + + return integrator.save() + + +def integrate_watchsecrets(): + """Integrate WatchSecrets.swift into watchOS target""" + project_root = Path(__file__).parent + pbxproj_path = project_root / "MeuLabApp.xcodeproj/project.pbxproj" + + integrator = XcodeTargetIntegrator(str(pbxproj_path)) + + print("\n📋 WatchSecrets.swift Integration") + print("-" * 60) + + # IDs: E181A3D935D7491286930152, 3909786604B94EE5BE1AD25A + watchsecrets_build_id = "3909786604B94EE5BE1AD25A" + watchsecrets_file_id = "E181A3D935D7491286930152" + + print(f"\n🎯 Target: MeuLabWatch") + if not integrator.add_file_to_build_phase(watchsecrets_build_id, "MeuLabWatch", 'Sources'): + print(f"⚠️ Fallback: May need manual Xcode configuration") + + integrator.add_file_to_group(watchsecrets_file_id, "MeuLabWatch") + + return integrator.save() + + +def main(): + print("🔐 Xcode Project Integration - Phase 2") + print("=" * 60) + + project_root = Path(__file__).parent + pbxproj_path = project_root / "MeuLabApp.xcodeproj/project.pbxproj" + + if not pbxproj_path.exists(): + print(f"❌ Not found: {pbxproj_path}") + return 1 + + print(f"📁 Project: {project_root.name}\n") + + if not integrate_secrets(): + return 1 + + integrate_watchsecrets() + + print("\n" + "=" * 60) + print("✅ Phase 2 Complete!") + print("\n📝 Status:") + print(" • File references added to project.pbxproj") + print(" • Build file entries created") + print(" • Build phase integration attempted") + print("\n🎯 Next:") + print(" 1. Open project in Xcode") + print(" 2. Verify files appear in Navigator") + print(" 3. Check File Inspector → Target Membership") + print(" 4. Compile: xcodebuild build -scheme MeuLabApp") + + return 0 + + +if __name__ == "__main__": + exit(main()) From 486d41b9fbbed9befbc905e7f42b859a2b3fe9be Mon Sep 17 00:00:00 2001 From: Eliel Date: Thu, 30 Apr 2026 17:09:09 -0300 Subject: [PATCH 03/10] feat: Mac OS 9 design system + Radar Local name + new AppIcon --- MeuLabApp.xcodeproj/project.pbxproj | 60 +- .../project.pbxproj.backup_before_restore | 1230 +++++++++++++++ MeuLabApp.xcodeproj/project.pbxproj.backup_ds | 1392 +++++++++++++++++ .../DesignSystem/MacOS9/MacOS9Button.swift | 113 ++ .../DesignSystem/MacOS9/MacOS9Colors.swift | 65 + .../DesignSystem/MacOS9/MacOS9Divider.swift | 50 + .../DesignSystem/MacOS9/MacOS9Label.swift | 109 ++ .../DesignSystem/MacOS9/MacOS9ListRow.swift | 129 ++ .../DesignSystem/MacOS9/MacOS9Metrics.swift | 54 + .../DesignSystem/MacOS9/MacOS9Modifiers.swift | 159 ++ .../DesignSystem/MacOS9/MacOS9Panel.swift | 92 ++ .../DesignSystem/MacOS9/MacOS9Screen.swift | 209 +++ .../DesignSystem/MacOS9/MacOS9TextField.swift | 88 ++ .../DesignSystem/MacOS9/MacOS9Theme.swift | 131 ++ .../DesignSystem/MacOS9/MacOS9TitleBar.swift | 135 ++ .../MacOS9/MacOS9Typography.swift | 138 ++ .../DesignSystem/MacOS9/MacOS9Window.swift | 60 + .../Extensions/LiquidGlass+Modifiers.swift | 133 +- MeuLabApp/Info.plist | 9 + MeuLabApp/MeuLabApp.swift | 19 +- .../Contents.json | 14 + .../Icon-1024.png | Bin .../AppIcon.appiconset/Contents.json | 120 +- .../Icon-App-1024x1024@1x.png | Bin 0 -> 50042 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 1031 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 2915 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 5049 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1843 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 4798 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 8543 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 2915 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 7504 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 13649 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 13649 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 24658 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 6850 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 19372 bytes .../Icon-App-83_5x83_5@2x.png | Bin 0 -> 21880 bytes .../Contents.json | 23 + .../RadarLocalMacOS9FlightSimplified@1x.png | Bin 0 -> 40480 bytes .../RadarLocalMacOS9FlightSimplified@2x.png | Bin 0 -> 100182 bytes .../RadarLocalMacOS9FlightSimplified@3x.png | Bin 0 -> 177320 bytes MeuLabApp/Resources/Fonts/README.md | 40 + MeuLabApp/Views/Components/StatCard.swift | 35 +- MeuLabApp/Views/Tabs/ACARSView.swift | 87 +- MeuLabApp/Views/Tabs/ADSBView.swift | 99 +- MeuLabApp/Views/Tabs/AnalyticsView.swift | 86 +- MeuLabApp/Views/Tabs/BibleView.swift | 30 +- MeuLabApp/Views/Tabs/IntelligenceView.swift | 154 +- MeuLabApp/Views/Tabs/RadioView.swift | 106 +- MeuLabApp/Views/Tabs/RemoteRadioView.swift | 27 +- MeuLabApp/Views/Tabs/SatelliteView.swift | 18 +- MeuLabApp/Views/Tabs/SystemView.swift | 61 +- MeuLabApp/Views/Tabs/WeatherView.swift | 248 +-- add_ds_to_project.py | 129 ++ 55 files changed, 4904 insertions(+), 748 deletions(-) create mode 100644 MeuLabApp.xcodeproj/project.pbxproj.backup_before_restore create mode 100644 MeuLabApp.xcodeproj/project.pbxproj.backup_ds create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Button.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Label.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9ListRow.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Metrics.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9TextField.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift create mode 100644 MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset.backup_old/Contents.json rename MeuLabApp/Resources/Assets.xcassets/{AppIcon.appiconset => AppIcon.appiconset.backup_old}/Icon-1024.png (100%) create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-83_5x83_5@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/Contents.json create mode 100644 MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@1x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@2x.png create mode 100644 MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@3x.png create mode 100644 MeuLabApp/Resources/Fonts/README.md create mode 100644 add_ds_to_project.py diff --git a/MeuLabApp.xcodeproj/project.pbxproj b/MeuLabApp.xcodeproj/project.pbxproj index 432aa83..76c76b6 100644 --- a/MeuLabApp.xcodeproj/project.pbxproj +++ b/MeuLabApp.xcodeproj/project.pbxproj @@ -113,6 +113,20 @@ WN10 /* WatchTuyaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN09 /* WatchTuyaView.swift */; }; WN12 /* MeuLabComplications.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN11 /* MeuLabComplications.swift */; }; WN14 /* MeuLabSmartStackWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN15 /* MeuLabSmartStackWidgets.swift */; }; + DS00102 /* MacOS9Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00101 /* MacOS9Colors.swift */; }; + DS00202 /* MacOS9Typography.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00201 /* MacOS9Typography.swift */; }; + DS00302 /* MacOS9Metrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00301 /* MacOS9Metrics.swift */; }; + DS00402 /* MacOS9Modifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00401 /* MacOS9Modifiers.swift */; }; + DS00502 /* MacOS9TitleBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00501 /* MacOS9TitleBar.swift */; }; + DS00602 /* MacOS9Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00601 /* MacOS9Window.swift */; }; + DS00702 /* MacOS9Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00701 /* MacOS9Button.swift */; }; + DS00802 /* MacOS9Panel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00801 /* MacOS9Panel.swift */; }; + DS00902 /* MacOS9Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS00901 /* MacOS9Label.swift */; }; + DS01002 /* MacOS9TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS01001 /* MacOS9TextField.swift */; }; + DS01102 /* MacOS9ListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS01101 /* MacOS9ListRow.swift */; }; + DS01202 /* MacOS9Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS01201 /* MacOS9Divider.swift */; }; + DS01302 /* MacOS9Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS01301 /* MacOS9Screen.swift */; }; + DS01402 /* MacOS9Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DS01401 /* MacOS9Theme.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -274,6 +288,20 @@ WN09 /* WatchTuyaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchTuyaView.swift; sourceTree = ""; }; WN11 /* MeuLabComplications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabComplications.swift; sourceTree = ""; }; WN15 /* MeuLabSmartStackWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabSmartStackWidgets.swift; sourceTree = ""; }; + DS00101 /* MacOS9Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift"; sourceTree = SOURCE_ROOT; }; + DS00201 /* MacOS9Typography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift"; sourceTree = SOURCE_ROOT; }; + DS00301 /* MacOS9Metrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Metrics.swift"; sourceTree = SOURCE_ROOT; }; + DS00401 /* MacOS9Modifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift"; sourceTree = SOURCE_ROOT; }; + DS00501 /* MacOS9TitleBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift"; sourceTree = SOURCE_ROOT; }; + DS00601 /* MacOS9Window.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift"; sourceTree = SOURCE_ROOT; }; + DS00701 /* MacOS9Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Button.swift"; sourceTree = SOURCE_ROOT; }; + DS00801 /* MacOS9Panel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift"; sourceTree = SOURCE_ROOT; }; + DS00901 /* MacOS9Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Label.swift"; sourceTree = SOURCE_ROOT; }; + DS01001 /* MacOS9TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9TextField.swift"; sourceTree = SOURCE_ROOT; }; + DS01101 /* MacOS9ListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9ListRow.swift"; sourceTree = SOURCE_ROOT; }; + DS01201 /* MacOS9Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift"; sourceTree = SOURCE_ROOT; }; + DS01301 /* MacOS9Screen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift"; sourceTree = SOURCE_ROOT; }; + DS01401 /* MacOS9Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -516,6 +544,20 @@ AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */, FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */, LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */, + DS00101 /* MacOS9Colors.swift */, + DS00201 /* MacOS9Typography.swift */, + DS00301 /* MacOS9Metrics.swift */, + DS00401 /* MacOS9Modifiers.swift */, + DS00501 /* MacOS9TitleBar.swift */, + DS00601 /* MacOS9Window.swift */, + DS00701 /* MacOS9Button.swift */, + DS00801 /* MacOS9Panel.swift */, + DS00901 /* MacOS9Label.swift */, + DS01001 /* MacOS9TextField.swift */, + DS01101 /* MacOS9ListRow.swift */, + DS01201 /* MacOS9Divider.swift */, + DS01301 /* MacOS9Screen.swift */, + DS01401 /* MacOS9Theme.swift */, E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */, ); name = "Recovered References"; @@ -862,6 +904,20 @@ RR203 /* RemoteRadioViewModel.swift in Sources */, RR204 /* RemoteRadioView.swift in Sources */, LGM02 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift in Sources */, + DS00102 /* MacOS9Colors.swift in Sources */, + DS00202 /* MacOS9Typography.swift in Sources */, + DS00302 /* MacOS9Metrics.swift in Sources */, + DS00402 /* MacOS9Modifiers.swift in Sources */, + DS00502 /* MacOS9TitleBar.swift in Sources */, + DS00602 /* MacOS9Window.swift in Sources */, + DS00702 /* MacOS9Button.swift in Sources */, + DS00802 /* MacOS9Panel.swift in Sources */, + DS00902 /* MacOS9Label.swift in Sources */, + DS01002 /* MacOS9TextField.swift in Sources */, + DS01102 /* MacOS9ListRow.swift in Sources */, + DS01202 /* MacOS9Divider.swift in Sources */, + DS01302 /* MacOS9Screen.swift in Sources */, + DS01402 /* MacOS9Theme.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1080,7 +1136,7 @@ ENABLE_RESOURCE_ACCESS_USB = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MeuLabApp/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_CFBundleDisplayName = "Radar Local"; INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você."; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição."; INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "MeuLab precisa de acesso para salvar imagens de satélite na sua galeria."; @@ -1133,7 +1189,7 @@ ENABLE_RESOURCE_ACCESS_USB = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MeuLabApp/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_CFBundleDisplayName = "Radar Local"; INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você."; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição."; INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "MeuLab precisa de acesso para salvar imagens de satélite na sua galeria."; diff --git a/MeuLabApp.xcodeproj/project.pbxproj.backup_before_restore b/MeuLabApp.xcodeproj/project.pbxproj.backup_before_restore new file mode 100644 index 0000000..fb993a4 --- /dev/null +++ b/MeuLabApp.xcodeproj/project.pbxproj.backup_before_restore @@ -0,0 +1,1230 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 70; + objects = { + +/* Begin PBXBuildFile section */ + 001 /* MeuLabApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101 /* MeuLabApp.swift */; }; + 002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 102 /* ContentView.swift */; }; + 003 /* ADSBModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 103 /* ADSBModels.swift */; }; + 004 /* SystemModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 104 /* SystemModels.swift */; }; + 005 /* RadioModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105 /* RadioModels.swift */; }; + 006 /* WeatherModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106 /* WeatherModels.swift */; }; + 007 /* SatelliteModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107 /* SatelliteModels.swift */; }; + 008 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 108 /* APIService.swift */; }; + 009 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 109 /* AudioPlayer.swift */; }; + 010 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110 /* AppState.swift */; }; + 011 /* ADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111 /* ADSBView.swift */; }; + 012 /* SystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 112 /* SystemView.swift */; }; + 013 /* RadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113 /* RadioView.swift */; }; + 014 /* WeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114 /* WeatherView.swift */; }; + 015 /* SatelliteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115 /* SatelliteView.swift */; }; + 016 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + 017 /* AircraftMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118 /* AircraftMapView.swift */; }; + 018 /* ACARSModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 119 /* ACARSModels.swift */; }; + 019 /* ACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120 /* ACARSView.swift */; }; + 020 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 121 /* MapView.swift */; }; + 021 /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 122 /* PushNotificationManager.swift */; }; + 022 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123 /* LocationManager.swift */; }; + 023 /* RadarWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 124 /* RadarWebView.swift */; }; + 024 /* RadarHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125 /* RadarHTML.swift */; }; + 025 /* SystemExtrasModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 126 /* SystemExtrasModels.swift */; }; + 026 /* InfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127 /* InfraView.swift */; }; + 027 /* RadarSplashOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 128 /* RadarSplashOverlay.swift */; }; + 028 /* RadarSplashSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129 /* RadarSplashSwiftUI.swift */; }; + 029 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 130 /* LaunchScreen.storyboard */; }; + 030 /* NotificationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131 /* NotificationModels.swift */; }; + 031 /* NotificationFeedManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132 /* NotificationFeedManager.swift */; }; + 032 /* Formatters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133 /* Formatters.swift */; }; + 033 /* OpenMeteoModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134 /* OpenMeteoModels.swift */; }; + 034 /* LabIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135 /* LabIntents.swift */; }; + 035 /* LabShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136 /* LabShortcuts.swift */; }; + 036 /* AviationStackModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137 /* AviationStackModels.swift */; }; + 037 /* WidgetDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138 /* WidgetDataManager.swift */; }; + 038 /* AnalyticsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139 /* AnalyticsModels.swift */; }; + 039 /* iPadSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140 /* iPadSplitView.swift */; }; + 040 /* EnhancedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 141 /* EnhancedContentView.swift */; }; + 041 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142 /* ThemeManagerView.swift */; }; + 043 /* AnalyticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144 /* AnalyticsView.swift */; }; + 044 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145 /* AlertsView.swift */; }; + 045 /* FlightSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 146 /* FlightSearchView.swift */; }; + 047 /* DataExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148 /* DataExportView.swift */; }; + 048 /* RemoteControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149 /* RemoteControlView.swift */; }; + 049 /* ContainerLogsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 150 /* ContainerLogsView.swift */; }; + 050 /* HealthCheckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151 /* HealthCheckView.swift */; }; + 051 /* StatCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152 /* StatCard.swift */; }; + 052 /* FirestickModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153 /* FirestickModels.swift */; }; + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71A10232F2FB5780048CED8 /* WatchRadioView.swift */; }; + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F762D6282F44164400D6BA3B /* OpenSkyService.swift */; }; + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */; }; + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F795720F2F1347AB0058B81B /* WidgetKit.framework */; }; + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F79572112F1347AB0058B81B /* SwiftUI.framework */; }; + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */; }; + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */; }; + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + F7E628E92F1430BA00763B43 /* LegacyRadarWebViewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */; }; + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */; }; + W001 /* MeuLabWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = W101 /* MeuLabWatchApp.swift */; }; + W002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W102 /* ContentView.swift */; }; + W003 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W103 /* HomeView.swift */; }; + W004 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W104 /* AlertsView.swift */; }; + W005 /* WatchADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W105 /* WatchADSBView.swift */; }; + W006 /* WatchACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W106 /* WatchACARSView.swift */; }; + W007 /* WatchSystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W107 /* WatchSystemView.swift */; }; + W008 /* WatchInfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W108 /* WatchInfraView.swift */; }; + W009 /* WatchWeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W109 /* WatchWeatherView.swift */; }; + W010 /* WatchSatDumpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W110 /* WatchSatDumpView.swift */; }; + W011 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = W111 /* Assets.xcassets */; }; + W012 /* MeuLabWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = W100 /* MeuLabWatch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + W013 /* WatchAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = W113 /* WatchAPIService.swift */; }; + W014 /* WatchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = W114 /* WatchModels.swift */; }; + + 8E67D5B72FC44490AD989D19 /* Secrets.plist in Sources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; + 3909786604B94EE5BE1AD25A /* WatchSecrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E181A3D935D7491286930152 /* WatchSecrets.swift */; };/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F703A8B92F40352B007B6FD3; + remoteInfo = MeuLabNotificationService; + }; + F79572212F1347AC0058B81B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F795720C2F1347AB0058B81B; + remoteInfo = MeuLabWidgetsExtension; + }; + W200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = W400; + remoteInfo = MeuLabWatch; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F79572282F1347AC0058B81B /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */, + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + W300 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + W012 /* MeuLabWatch.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 100 /* MeuLabApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 101 /* MeuLabApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp.swift; sourceTree = ""; }; + 102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 103 /* ADSBModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBModels.swift; sourceTree = ""; }; + 104 /* SystemModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemModels.swift; sourceTree = ""; }; + 105 /* RadioModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioModels.swift; sourceTree = ""; }; + 106 /* WeatherModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherModels.swift; sourceTree = ""; }; + 107 /* SatelliteModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteModels.swift; sourceTree = ""; }; + 108 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; + 109 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; + 110 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 111 /* ADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBView.swift; sourceTree = ""; }; + 112 /* SystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemView.swift; sourceTree = ""; }; + 113 /* RadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioView.swift; sourceTree = ""; }; + 114 /* WeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherView.swift; sourceTree = ""; }; + 115 /* SatelliteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteView.swift; sourceTree = ""; }; + 116 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 117 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 118 /* AircraftMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AircraftMapView.swift; sourceTree = ""; }; + 119 /* ACARSModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSModels.swift; sourceTree = ""; }; + 120 /* ACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSView.swift; sourceTree = ""; }; + 121 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 122 /* PushNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationManager.swift; sourceTree = ""; }; + 123 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; + 124 /* RadarWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarWebView.swift; sourceTree = ""; }; + 125 /* RadarHTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarHTML.swift; sourceTree = ""; }; + 126 /* SystemExtrasModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtrasModels.swift; sourceTree = ""; }; + 127 /* InfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfraView.swift; sourceTree = ""; }; + 128 /* RadarSplashOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashOverlay.swift; sourceTree = ""; }; + 129 /* RadarSplashSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashSwiftUI.swift; sourceTree = ""; }; + 130 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 131 /* NotificationModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationModels.swift; sourceTree = ""; }; + 132 /* NotificationFeedManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFeedManager.swift; sourceTree = ""; }; + 133 /* Formatters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Formatters.swift; sourceTree = ""; }; + 134 /* OpenMeteoModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMeteoModels.swift; sourceTree = ""; }; + 135 /* LabIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabIntents.swift; sourceTree = ""; }; + 136 /* LabShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabShortcuts.swift; sourceTree = ""; }; + 137 /* AviationStackModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AviationStackModels.swift; sourceTree = ""; }; + 138 /* WidgetDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataManager.swift; sourceTree = ""; }; + 139 /* AnalyticsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsModels.swift; sourceTree = ""; }; + 140 /* iPadSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iPadSplitView.swift; sourceTree = ""; }; + 141 /* EnhancedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedContentView.swift; sourceTree = ""; }; + 142 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = ""; }; + 144 /* AnalyticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsView.swift; sourceTree = ""; }; + 145 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + 146 /* FlightSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightSearchView.swift; sourceTree = ""; }; + 148 /* DataExportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExportView.swift; sourceTree = ""; }; + 149 /* RemoteControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteControlView.swift; sourceTree = ""; }; + 150 /* ContainerLogsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerLogsView.swift; sourceTree = ""; }; + 151 /* HealthCheckView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthCheckView.swift; sourceTree = ""; }; + 152 /* StatCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatCard.swift; sourceTree = ""; }; + 153 /* FirestickModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirestickModels.swift; sourceTree = ""; }; + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRadioView.swift; sourceTree = ""; }; + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MeuLabApp.entitlements; sourceTree = ""; }; + F762D6282F44164400D6BA3B /* OpenSkyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSkyService.swift; sourceTree = ""; }; + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryCache.swift; sourceTree = ""; }; + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F795720F2F1347AB0058B81B /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + F79572112F1347AB0058B81B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedWatchContentView.swift; sourceTree = ""; }; + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatellitePassPredictor.swift; sourceTree = ""; }; + F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyRadarWebViewStore.swift; sourceTree = ""; }; + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNowPlayingFetcher.swift; sourceTree = ""; }; + W100 /* MeuLabWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + W101 /* MeuLabWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatchApp.swift; sourceTree = ""; }; + W102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + W103 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + W104 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + W105 /* WatchADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchADSBView.swift; sourceTree = ""; }; + W106 /* WatchACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchACARSView.swift; sourceTree = ""; }; + W107 /* WatchSystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSystemView.swift; sourceTree = ""; }; + W108 /* WatchInfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchInfraView.swift; sourceTree = ""; }; + W109 /* WatchWeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchWeatherView.swift; sourceTree = ""; }; + W110 /* WatchSatDumpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSatDumpView.swift; sourceTree = ""; }; + W111 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + W112 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + W113 /* WatchAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAPIService.swift; sourceTree = ""; }; + W114 /* WatchModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchModels.swift; sourceTree = ""; }; + + D916AD0964D84EF1A89E02C6 /* Secrets.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Secrets.plist; sourceTree = ""; }; + E181A3D935D7491286930152 /* WatchSecrets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatch/Services/WatchSecrets.swift; sourceTree = ""; };/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + }; + F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabNotificationService; sourceTree = ""; }; + F79572132F1347AB0058B81B /* MeuLabWidgets */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabWidgets; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 200 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B72F40352B007B6FD3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720A2F1347AB0058B81B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */, + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W201 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 300 = { + isa = PBXGroup; + children = ( + 301 /* MeuLabApp */, + W301 /* MeuLabWatch */, + F79572132F1347AB0058B81B /* MeuLabWidgets */, + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + F795720E2F1347AB0058B81B /* Frameworks */, + 302 /* Products */, + ); + sourceTree = ""; + }; + 301 /* MeuLabApp */ = { + isa = PBXGroup; + children = ( + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */, + 101 /* MeuLabApp.swift */, + 102 /* ContentView.swift */, + 140 /* iPadSplitView.swift */, + 141 /* EnhancedContentView.swift */, + 117 /* Info.plist */, + 303 /* Models */, + 304 /* Services */, + 305 /* ViewModels */, + 306 /* Views */, + 310 /* Intents */, + 307 /* Resources */, + ); + path = MeuLabApp; + sourceTree = ""; + }; + 302 /* Products */ = { + isa = PBXGroup; + children = ( + 100 /* MeuLabApp.app */, + W100 /* MeuLabWatch.app */, + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */, + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */, + ); + name = Products; + sourceTree = ""; + }; + 303 /* Models */ = { + isa = PBXGroup; + children = ( + 103 /* ADSBModels.swift */, + 119 /* ACARSModels.swift */, + 104 /* SystemModels.swift */, + 126 /* SystemExtrasModels.swift */, + 153 /* FirestickModels.swift */, + 131 /* NotificationModels.swift */, + 105 /* RadioModels.swift */, + 106 /* WeatherModels.swift */, + 107 /* SatelliteModels.swift */, + 134 /* OpenMeteoModels.swift */, + 137 /* AviationStackModels.swift */, + 139 /* AnalyticsModels.swift */, + ); + path = Models; + sourceTree = ""; + }; + 304 /* Services */ = { + isa = PBXGroup; + children = ( + 108 /* APIService.swift */, + 109 /* AudioPlayer.swift */, + 122 /* PushNotificationManager.swift */, + 123 /* LocationManager.swift */, + 132 /* NotificationFeedManager.swift */, + 133 /* Formatters.swift */, + 138 /* WidgetDataManager.swift */, + ); + path = Services; + sourceTree = ""; + }; + 305 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 110 /* AppState.swift */, + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */, + F762D6282F44164400D6BA3B /* OpenSkyService.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 306 /* Views */ = { + isa = PBXGroup; + children = ( + 308 /* Tabs */, + 309 /* Components */, + 311 /* Settings */, + ); + path = Views; + sourceTree = ""; + }; + 307 /* Resources */ = { + isa = PBXGroup; + children = ( + 116 /* Assets.xcassets */, + 130 /* LaunchScreen.storyboard */, + ); + path = Resources; + sourceTree = ""; + }; + 308 /* Tabs */ = { + isa = PBXGroup; + children = ( + 111 /* ADSBView.swift */, + 120 /* ACARSView.swift */, + 112 /* SystemView.swift */, + 127 /* InfraView.swift */, + 113 /* RadioView.swift */, + 114 /* WeatherView.swift */, + 115 /* SatelliteView.swift */, + 144 /* AnalyticsView.swift */, + 145 /* AlertsView.swift */, + 146 /* FlightSearchView.swift */, + 148 /* DataExportView.swift */, + 149 /* RemoteControlView.swift */, + 150 /* ContainerLogsView.swift */, + 151 /* HealthCheckView.swift */, + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */, + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */, + ); + path = Tabs; + sourceTree = ""; + }; + 309 /* Components */ = { + isa = PBXGroup; + children = ( + 118 /* AircraftMapView.swift */, + 121 /* MapView.swift */, + 124 /* RadarWebView.swift */, + 125 /* RadarHTML.swift */, + 128 /* RadarSplashOverlay.swift */, + 129 /* RadarSplashSwiftUI.swift */, + F7E628E82F1430BA00763B43 /* LegacyRadarWebViewStore.swift */, + 152 /* StatCard.swift */, + ); + path = Components; + sourceTree = ""; + }; + 310 /* Intents */ = { + isa = PBXGroup; + children = ( + 135 /* LabIntents.swift */, + 136 /* LabShortcuts.swift */, + ); + path = Intents; + sourceTree = ""; + }; + 311 /* Settings */ = { + isa = PBXGroup; + children = ( + 142 /* ThemeManagerView.swift */, + ); + path = Settings; + sourceTree = ""; + }; + F795720E2F1347AB0058B81B /* Frameworks */ = { + isa = PBXGroup; + children = ( + F795720F2F1347AB0058B81B /* WidgetKit.framework */, + F79572112F1347AB0058B81B /* SwiftUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + W301 /* MeuLabWatch */ = { + isa = PBXGroup; + children = ( + W101 /* MeuLabWatchApp.swift */, + W102 /* ContentView.swift */, + W112 /* Info.plist */, + W111 /* Assets.xcassets */, + W302 /* Views */, + W303 /* Services */, + W304 /* Models */, + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */, + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */, + ); + path = MeuLabWatch; + sourceTree = ""; + }; + W302 /* Views */ = { + isa = PBXGroup; + children = ( + W103 /* HomeView.swift */, + W104 /* AlertsView.swift */, + W105 /* WatchADSBView.swift */, + W106 /* WatchACARSView.swift */, + W107 /* WatchSystemView.swift */, + W108 /* WatchInfraView.swift */, + W109 /* WatchWeatherView.swift */, + W110 /* WatchSatDumpView.swift */, + ); + path = Views; + sourceTree = ""; + }; + W303 /* Services */ = { + isa = PBXGroup; + children = ( + W113 /* WatchAPIService.swift */, + ); + path = Services; + sourceTree = ""; + }; + W304 /* Models */ = { + isa = PBXGroup; + children = ( + W114 /* WatchModels.swift */, + ); + path = Models; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 400 /* MeuLabApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */; + buildPhases = ( + 401 /* Sources */, + 200 /* Frameworks */, + 402 /* Resources */, + W300 /* Embed Watch Content */, + F79572282F1347AC0058B81B /* Embed Foundation Extensions */, + ); + buildRules = ( + ); + dependencies = ( + W401 /* PBXTargetDependency */, + F79572222F1347AC0058B81B /* PBXTargetDependency */, + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */, + ); + name = MeuLabApp; + productName = MeuLabApp; + productReference = 100 /* MeuLabApp.app */; + productType = "com.apple.product-type.application"; + }; + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */ = { + isa = PBXNativeTarget; + buildConfigurationList = F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */; + buildPhases = ( + F703A8B62F40352B007B6FD3 /* Sources */, + F703A8B72F40352B007B6FD3 /* Frameworks */, + F703A8B82F40352B007B6FD3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + ); + name = MeuLabNotificationService; + packageProductDependencies = ( + ); + productName = MeuLabNotificationService; + productReference = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; + productType = "com.apple.product-type.app-extension"; + }; + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */; + buildPhases = ( + F79572092F1347AB0058B81B /* Sources */, + F795720A2F1347AB0058B81B /* Frameworks */, + F795720B2F1347AB0058B81B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F79572132F1347AB0058B81B /* MeuLabWidgets */, + ); + name = MeuLabWidgetsExtension; + packageProductDependencies = ( + ); + productName = MeuLabWidgetsExtension; + productReference = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; + W400 /* MeuLabWatch */ = { + isa = PBXNativeTarget; + buildConfigurationList = W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */; + buildPhases = ( + W402 /* Sources */, + W201 /* Frameworks */, + W403 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MeuLabWatch; + productName = MeuLabWatch; + productReference = W100 /* MeuLabWatch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 600 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2620; + LastUpgradeCheck = 2620; + TargetAttributes = { + 400 = { + CreatedOnToolsVersion = 15.0; + }; + F703A8B92F40352B007B6FD3 = { + CreatedOnToolsVersion = 26.2; + }; + F795720C2F1347AB0058B81B = { + CreatedOnToolsVersion = 26.2; + }; + W400 = { + CreatedOnToolsVersion = 15.0; + }; + }; + }; + buildConfigurationList = 601 /* Build configuration list for PBXProject "MeuLabApp" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = "pt-BR"; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + "pt-BR", + ); + mainGroup = 300; + productRefGroup = 302 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 400 /* MeuLabApp */, + W400 /* MeuLabWatch */, + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */, + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 402 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */, + 029 /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B82F40352B007B6FD3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720B2F1347AB0058B81B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 016 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W403 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + W011 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 401 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 001 /* MeuLabApp.swift in Sources */, + 002 /* ContentView.swift in Sources */, + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */, + 003 /* ADSBModels.swift in Sources */, + 004 /* SystemModels.swift in Sources */, + 052 /* FirestickModels.swift in Sources */, + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */, + 005 /* RadioModels.swift in Sources */, + 006 /* WeatherModels.swift in Sources */, + 007 /* SatelliteModels.swift in Sources */, + 008 /* APIService.swift in Sources */, + 009 /* AudioPlayer.swift in Sources */, + 010 /* AppState.swift in Sources */, + 011 /* ADSBView.swift in Sources */, + 012 /* SystemView.swift in Sources */, + 013 /* RadioView.swift in Sources */, + 014 /* WeatherView.swift in Sources */, + 015 /* SatelliteView.swift in Sources */, + 017 /* AircraftMapView.swift in Sources */, + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */, + 018 /* ACARSModels.swift in Sources */, + 019 /* ACARSView.swift in Sources */, + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */, + 020 /* MapView.swift in Sources */, + 021 /* PushNotificationManager.swift in Sources */, + 022 /* LocationManager.swift in Sources */, + 023 /* RadarWebView.swift in Sources */, + 024 /* RadarHTML.swift in Sources */, + 025 /* SystemExtrasModels.swift in Sources */, + 026 /* InfraView.swift in Sources */, + 027 /* RadarSplashOverlay.swift in Sources */, + F7E628E92F1430BA00763B43 /* LegacyRadarWebViewStore.swift in Sources */, + 028 /* RadarSplashSwiftUI.swift in Sources */, + 030 /* NotificationModels.swift in Sources */, + 031 /* NotificationFeedManager.swift in Sources */, + 032 /* Formatters.swift in Sources */, + 033 /* OpenMeteoModels.swift in Sources */, + 034 /* LabIntents.swift in Sources */, + 035 /* LabShortcuts.swift in Sources */, + 036 /* AviationStackModels.swift in Sources */, + 037 /* WidgetDataManager.swift in Sources */, + 038 /* AnalyticsModels.swift in Sources */, + 039 /* iPadSplitView.swift in Sources */, + 040 /* EnhancedContentView.swift in Sources */, + 041 /* ThemeManagerView.swift in Sources */, + 043 /* AnalyticsView.swift in Sources */, + 044 /* AlertsView.swift in Sources */, + 045 /* FlightSearchView.swift in Sources */, + 047 /* DataExportView.swift in Sources */, + 048 /* RemoteControlView.swift in Sources */, + 049 /* ContainerLogsView.swift in Sources */, + 050 /* HealthCheckView.swift in Sources */, + 051 /* StatCard.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B62F40352B007B6FD3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F79572092F1347AB0058B81B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W402 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */, + W001 /* MeuLabWatchApp.swift in Sources */, + W002 /* ContentView.swift in Sources */, + W003 /* HomeView.swift in Sources */, + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */, + W004 /* AlertsView.swift in Sources */, + W005 /* WatchADSBView.swift in Sources */, + W006 /* WatchACARSView.swift in Sources */, + W007 /* WatchSystemView.swift in Sources */, + W008 /* WatchInfraView.swift in Sources */, + W009 /* WatchWeatherView.swift in Sources */, + W010 /* WatchSatDumpView.swift in Sources */, + W013 /* WatchAPIService.swift in Sources */, + W014 /* WatchModels.swift in Sources */, + + 3909786604B94EE5BE1AD25A /* WatchSecrets.swift in Sources */,); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + targetProxy = F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */; + }; + F79572222F1347AC0058B81B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + targetProxy = F79572212F1347AC0058B81B /* PBXContainerItemProxy */; + }; + W401 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = W400 /* MeuLabWatch */; + targetProxy = W200 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 700 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + 701 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; + 702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F703A8C22F40352B007B6FD3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F703A8C32F40352B007B6FD3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F79572262F1347AC0058B81B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F79572272F1347AC0058B81B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + W702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + W703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 702 /* Debug */, + 703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 601 /* Build configuration list for PBXProject "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 700 /* Debug */, + 701 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F703A8C22F40352B007B6FD3 /* Debug */, + F703A8C32F40352B007B6FD3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F79572262F1347AC0058B81B /* Debug */, + F79572272F1347AC0058B81B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + W702 /* Debug */, + W703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 600 /* Project object */; +} diff --git a/MeuLabApp.xcodeproj/project.pbxproj.backup_ds b/MeuLabApp.xcodeproj/project.pbxproj.backup_ds new file mode 100644 index 0000000..432aa83 --- /dev/null +++ b/MeuLabApp.xcodeproj/project.pbxproj.backup_ds @@ -0,0 +1,1392 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 70; + objects = { + +/* Begin PBXBuildFile section */ + 001 /* MeuLabApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101 /* MeuLabApp.swift */; }; + 002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 102 /* ContentView.swift */; }; + 003 /* ADSBModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 103 /* ADSBModels.swift */; }; + 004 /* SystemModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 104 /* SystemModels.swift */; }; + 005 /* RadioModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105 /* RadioModels.swift */; }; + 006 /* WeatherModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106 /* WeatherModels.swift */; }; + 007 /* SatelliteModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107 /* SatelliteModels.swift */; }; + 008 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 108 /* APIService.swift */; }; + 009 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 109 /* AudioPlayer.swift */; }; + 010 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110 /* AppState.swift */; }; + 011 /* ADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111 /* ADSBView.swift */; }; + 012 /* SystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 112 /* SystemView.swift */; }; + 013 /* RadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113 /* RadioView.swift */; }; + 014 /* WeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114 /* WeatherView.swift */; }; + 015 /* SatelliteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115 /* SatelliteView.swift */; }; + 017 /* AircraftMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118 /* AircraftMapView.swift */; }; + 018 /* ACARSModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 119 /* ACARSModels.swift */; }; + 019 /* ACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120 /* ACARSView.swift */; }; + 020 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 121 /* MapView.swift */; }; + 021 /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 122 /* PushNotificationManager.swift */; }; + 022 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123 /* LocationManager.swift */; }; + 025 /* SystemExtrasModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 126 /* SystemExtrasModels.swift */; }; + 026 /* InfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127 /* InfraView.swift */; }; + 027 /* RadarSplashOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 128 /* RadarSplashOverlay.swift */; }; + 028 /* RadarSplashSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129 /* RadarSplashSwiftUI.swift */; }; + 029 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 130 /* LaunchScreen.storyboard */; }; + 030 /* NotificationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131 /* NotificationModels.swift */; }; + 031 /* NotificationFeedManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132 /* NotificationFeedManager.swift */; }; + 032 /* Formatters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133 /* Formatters.swift */; }; + 033 /* OpenMeteoModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134 /* OpenMeteoModels.swift */; }; + 034 /* LabIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135 /* LabIntents.swift */; }; + 035 /* LabShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136 /* LabShortcuts.swift */; }; + 036 /* AviationStackModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137 /* AviationStackModels.swift */; }; + 037 /* WidgetDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138 /* WidgetDataManager.swift */; }; + 038 /* AnalyticsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139 /* AnalyticsModels.swift */; }; + 039 /* iPadSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140 /* iPadSplitView.swift */; }; + 040 /* EnhancedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 141 /* EnhancedContentView.swift */; }; + 041 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142 /* ThemeManagerView.swift */; }; + 043 /* AnalyticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144 /* AnalyticsView.swift */; }; + 044 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145 /* AlertsView.swift */; }; + 045 /* FlightSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 146 /* FlightSearchView.swift */; }; + 047 /* DataExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148 /* DataExportView.swift */; }; + 048 /* RemoteControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149 /* RemoteControlView.swift */; }; + 049 /* ContainerLogsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 150 /* ContainerLogsView.swift */; }; + 050 /* HealthCheckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151 /* HealthCheckView.swift */; }; + 051 /* StatCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152 /* StatCard.swift */; }; + 052 /* FirestickModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153 /* FirestickModels.swift */; }; + 053 /* NativeRadarMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 154 /* NativeRadarMapView.swift */; }; + 3909786604B94EE5BE1AD25A /* MeuLabWatch/Services/WatchSecrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */; }; + 7F0B7866E4944B48AAFB4F3A /* bible.json in Resources */ = {isa = PBXBuildFile; fileRef = EB2CCDD5B45142E9817882CE /* bible.json */; }; + A1B2C3D4E5F6A7B8C9D0E1F2 /* MeuLabApp/Core/Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0C1B2D3E4F5A6B7C8D9E0 /* MeuLabApp/Core/Secrets.swift */; }; + AC100 /* MeuLabApp/Core/Utils/AircraftClassification.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */; }; + B1C2D3E4F5A6B7C8D9E0F1A2 /* MeuLabApp/Core/NetworkEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */; }; + BIBI02 /* BibleReadingIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBI01 /* BibleReadingIntents.swift */; }; + BIBL02 /* BibleLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBL01 /* BibleLoader.swift */; }; + BIBM02 /* BibleModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBM01 /* BibleModels.swift */; }; + BIBN02 /* BibleNavigateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBN01 /* BibleNavigateView.swift */; }; + BIBR02 /* BibleRandomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBR01 /* BibleRandomView.swift */; }; + BIBS02 /* BibleSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBS01 /* BibleSearchView.swift */; }; + BIBSP02 /* BibleSpeechService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBSP01 /* BibleSpeechService.swift */; }; + BIBV02 /* BibleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBV01 /* BibleView.swift */; }; + BIBVM02 /* BibleReaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BIBVM01 /* BibleReaderViewModel.swift */; }; + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71A10232F2FB5780048CED8 /* WatchRadioView.swift */; }; + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F762D6282F44164400D6BA3B /* OpenSkyService.swift */; }; + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */; }; + F7803D5F2F4A9A7B001C8722 /* Secrets.plist in Resources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; + F7803D602F4A9A7B001C8722 /* Secrets.plist in Resources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; + F7803D612F4A9A7B001C8722 /* Secrets.plist in Resources */ = {isa = PBXBuildFile; fileRef = D916AD0964D84EF1A89E02C6 /* Secrets.plist */; }; + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F795720F2F1347AB0058B81B /* WidgetKit.framework */; }; + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F79572112F1347AB0058B81B /* SwiftUI.framework */; }; + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */; }; + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */; }; + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 116 /* Assets.xcassets */; }; + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */; }; + FM100 /* MeuLabApp/Core/Services/FavoritesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */; }; + FMDS02 /* FoundationModelService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FMDS01 /* FoundationModelService.swift */; }; + INTV02 /* IntelligenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = INTV01 /* IntelligenceView.swift */; }; + LGM02 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */; }; + RR200 /* RemoteRadioModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR100 /* RemoteRadioModels.swift */; }; + RR201 /* RemoteRadioAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR101 /* RemoteRadioAPIClient.swift */; }; + RR202 /* RemoteRadioWebRTCClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR102 /* RemoteRadioWebRTCClient.swift */; }; + RR203 /* RemoteRadioViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR103 /* RemoteRadioViewModel.swift */; }; + RR204 /* RemoteRadioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = RR104 /* RemoteRadioView.swift */; }; + W001 /* MeuLabWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = W101 /* MeuLabWatchApp.swift */; }; + W002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W102 /* ContentView.swift */; }; + W003 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W103 /* HomeView.swift */; }; + W004 /* AlertsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W104 /* AlertsView.swift */; }; + W005 /* WatchADSBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W105 /* WatchADSBView.swift */; }; + W006 /* WatchACARSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W106 /* WatchACARSView.swift */; }; + W007 /* WatchSystemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W107 /* WatchSystemView.swift */; }; + W008 /* WatchInfraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W108 /* WatchInfraView.swift */; }; + W009 /* WatchWeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W109 /* WatchWeatherView.swift */; }; + W010 /* WatchSatDumpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = W110 /* WatchSatDumpView.swift */; }; + W011 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = W111 /* Assets.xcassets */; }; + W012 /* MeuLabWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = W100 /* MeuLabWatch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + W013 /* WatchAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = W113 /* WatchAPIService.swift */; }; + W014 /* WatchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = W114 /* WatchModels.swift */; }; + WN02 /* WatchAudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN01 /* WatchAudioPlayer.swift */; }; + WN04 /* WatchRemoteControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN03 /* WatchRemoteControlView.swift */; }; + WN06 /* WatchAnalyticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN05 /* WatchAnalyticsView.swift */; }; + WN08 /* WatchBibleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN07 /* WatchBibleView.swift */; }; + WN10 /* WatchTuyaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN09 /* WatchTuyaView.swift */; }; + WN12 /* MeuLabComplications.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN11 /* MeuLabComplications.swift */; }; + WN14 /* MeuLabSmartStackWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = WN15 /* MeuLabSmartStackWidgets.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F703A8B92F40352B007B6FD3; + remoteInfo = MeuLabNotificationService; + }; + F79572212F1347AC0058B81B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F795720C2F1347AB0058B81B; + remoteInfo = MeuLabWidgetsExtension; + }; + W200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 600 /* Project object */; + proxyType = 1; + remoteGlobalIDString = W400; + remoteInfo = MeuLabWatch; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F79572282F1347AC0058B81B /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + F79572232F1347AC0058B81B /* MeuLabWidgetsExtension.appex in Embed Foundation Extensions */, + F703A8C12F40352B007B6FD3 /* MeuLabNotificationService.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + W300 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + W012 /* MeuLabWatch.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 100 /* MeuLabApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 101 /* MeuLabApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp.swift; sourceTree = ""; }; + 102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 103 /* ADSBModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBModels.swift; sourceTree = ""; }; + 104 /* SystemModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemModels.swift; sourceTree = ""; }; + 105 /* RadioModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioModels.swift; sourceTree = ""; }; + 106 /* WeatherModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherModels.swift; sourceTree = ""; }; + 107 /* SatelliteModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteModels.swift; sourceTree = ""; }; + 108 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; + 109 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; + 110 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 111 /* ADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBView.swift; sourceTree = ""; }; + 112 /* SystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemView.swift; sourceTree = ""; }; + 113 /* RadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioView.swift; sourceTree = ""; }; + 114 /* WeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherView.swift; sourceTree = ""; }; + 115 /* SatelliteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatelliteView.swift; sourceTree = ""; }; + 116 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 117 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 118 /* AircraftMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AircraftMapView.swift; sourceTree = ""; }; + 119 /* ACARSModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSModels.swift; sourceTree = ""; }; + 120 /* ACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACARSView.swift; sourceTree = ""; }; + 121 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 122 /* PushNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationManager.swift; sourceTree = ""; }; + 123 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; + 126 /* SystemExtrasModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtrasModels.swift; sourceTree = ""; }; + 127 /* InfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfraView.swift; sourceTree = ""; }; + 128 /* RadarSplashOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashOverlay.swift; sourceTree = ""; }; + 129 /* RadarSplashSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarSplashSwiftUI.swift; sourceTree = ""; }; + 130 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 131 /* NotificationModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationModels.swift; sourceTree = ""; }; + 132 /* NotificationFeedManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFeedManager.swift; sourceTree = ""; }; + 133 /* Formatters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Formatters.swift; sourceTree = ""; }; + 134 /* OpenMeteoModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMeteoModels.swift; sourceTree = ""; }; + 135 /* LabIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabIntents.swift; sourceTree = ""; }; + 136 /* LabShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabShortcuts.swift; sourceTree = ""; }; + 137 /* AviationStackModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AviationStackModels.swift; sourceTree = ""; }; + 138 /* WidgetDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataManager.swift; sourceTree = ""; }; + 139 /* AnalyticsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsModels.swift; sourceTree = ""; }; + 140 /* iPadSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iPadSplitView.swift; sourceTree = ""; }; + 141 /* EnhancedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedContentView.swift; sourceTree = ""; }; + 142 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = ""; }; + 144 /* AnalyticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsView.swift; sourceTree = ""; }; + 145 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + 146 /* FlightSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightSearchView.swift; sourceTree = ""; }; + 148 /* DataExportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExportView.swift; sourceTree = ""; }; + 149 /* RemoteControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteControlView.swift; sourceTree = ""; }; + 150 /* ContainerLogsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerLogsView.swift; sourceTree = ""; }; + 151 /* HealthCheckView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthCheckView.swift; sourceTree = ""; }; + 152 /* StatCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatCard.swift; sourceTree = ""; }; + 153 /* FirestickModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirestickModels.swift; sourceTree = ""; }; + 154 /* NativeRadarMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeRadarMapView.swift; sourceTree = ""; }; + AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/Utils/AircraftClassification.swift; sourceTree = SOURCE_ROOT; }; + BIBI01 /* BibleReadingIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleReadingIntents.swift; sourceTree = ""; }; + BIBL01 /* BibleLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleLoader.swift; sourceTree = ""; }; + BIBM01 /* BibleModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleModels.swift; sourceTree = ""; }; + BIBN01 /* BibleNavigateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleNavigateView.swift; sourceTree = ""; }; + BIBR01 /* BibleRandomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleRandomView.swift; sourceTree = ""; }; + BIBS01 /* BibleSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleSearchView.swift; sourceTree = ""; }; + BIBSP01 /* BibleSpeechService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleSpeechService.swift; sourceTree = ""; }; + BIBV01 /* BibleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleView.swift; sourceTree = ""; }; + BIBVM01 /* BibleReaderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BibleReaderViewModel.swift; sourceTree = ""; }; + C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/NetworkEnvironment.swift; sourceTree = SOURCE_ROOT; }; + D916AD0964D84EF1A89E02C6 /* Secrets.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Secrets.plist; sourceTree = ""; }; + E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatch/Services/WatchSecrets.swift; sourceTree = ""; }; + EB2CCDD5B45142E9817882CE /* bible.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = bible.json; sourceTree = ""; }; + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRadioView.swift; sourceTree = ""; }; + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MeuLabApp.entitlements; sourceTree = ""; }; + F762D6282F44164400D6BA3B /* OpenSkyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSkyService.swift; sourceTree = ""; }; + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryCache.swift; sourceTree = ""; }; + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeuLabWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F795720F2F1347AB0058B81B /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + F79572112F1347AB0058B81B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + F7A0C1B2D3E4F5A6B7C8D9E0 /* MeuLabApp/Core/Secrets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/Secrets.swift; sourceTree = SOURCE_ROOT; }; + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedWatchContentView.swift; sourceTree = ""; }; + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatellitePassPredictor.swift; sourceTree = ""; }; + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNowPlayingFetcher.swift; sourceTree = ""; }; + FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabApp/Core/Services/FavoritesManager.swift; sourceTree = SOURCE_ROOT; }; + FMDS01 /* FoundationModelService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationModelService.swift; sourceTree = ""; }; + INTV01 /* IntelligenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntelligenceView.swift; sourceTree = ""; }; + LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/Extensions/LiquidGlass+Modifiers.swift"; sourceTree = SOURCE_ROOT; }; + RR100 /* RemoteRadioModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioModels.swift; sourceTree = ""; }; + RR101 /* RemoteRadioAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioAPIClient.swift; sourceTree = ""; }; + RR102 /* RemoteRadioWebRTCClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioWebRTCClient.swift; sourceTree = ""; }; + RR103 /* RemoteRadioViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioViewModel.swift; sourceTree = ""; }; + RR104 /* RemoteRadioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteRadioView.swift; sourceTree = ""; }; + W100 /* MeuLabWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeuLabWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + W101 /* MeuLabWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabWatchApp.swift; sourceTree = ""; }; + W102 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + W103 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + W104 /* AlertsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsView.swift; sourceTree = ""; }; + W105 /* WatchADSBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchADSBView.swift; sourceTree = ""; }; + W106 /* WatchACARSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchACARSView.swift; sourceTree = ""; }; + W107 /* WatchSystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSystemView.swift; sourceTree = ""; }; + W108 /* WatchInfraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchInfraView.swift; sourceTree = ""; }; + W109 /* WatchWeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchWeatherView.swift; sourceTree = ""; }; + W110 /* WatchSatDumpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSatDumpView.swift; sourceTree = ""; }; + W111 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + W112 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + W113 /* WatchAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAPIService.swift; sourceTree = ""; }; + W114 /* WatchModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchModels.swift; sourceTree = ""; }; + WN01 /* WatchAudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAudioPlayer.swift; sourceTree = ""; }; + WN03 /* WatchRemoteControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchRemoteControlView.swift; sourceTree = ""; }; + WN05 /* WatchAnalyticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAnalyticsView.swift; sourceTree = ""; }; + WN07 /* WatchBibleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchBibleView.swift; sourceTree = ""; }; + WN09 /* WatchTuyaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchTuyaView.swift; sourceTree = ""; }; + WN11 /* MeuLabComplications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabComplications.swift; sourceTree = ""; }; + WN15 /* MeuLabSmartStackWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeuLabSmartStackWidgets.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + }; + F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F703A8C42F40352B007B6FD3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabNotificationService; sourceTree = ""; }; + F79572132F1347AB0058B81B /* MeuLabWidgets */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F79572242F1347AC0058B81B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MeuLabWidgets; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 200 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B72F40352B007B6FD3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720A2F1347AB0058B81B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F79572122F1347AB0058B81B /* SwiftUI.framework in Frameworks */, + F79572102F1347AB0058B81B /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W201 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 300 = { + isa = PBXGroup; + children = ( + D916AD0964D84EF1A89E02C6 /* Secrets.plist */, + 301 /* MeuLabApp */, + W301 /* MeuLabWatch */, + F79572132F1347AB0058B81B /* MeuLabWidgets */, + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + F795720E2F1347AB0058B81B /* Frameworks */, + 302 /* Products */, + F7803D532F4A99BE001C8722 /* Recovered References */, + ); + sourceTree = ""; + }; + 301 /* MeuLabApp */ = { + isa = PBXGroup; + children = ( + F71E1C3F2F11A10C00728C53 /* MeuLabApp.entitlements */, + 101 /* MeuLabApp.swift */, + 102 /* ContentView.swift */, + 140 /* iPadSplitView.swift */, + 141 /* EnhancedContentView.swift */, + 117 /* Info.plist */, + 303 /* Models */, + 304 /* Services */, + 305 /* ViewModels */, + 306 /* Views */, + 310 /* Intents */, + 307 /* Resources */, + ); + path = MeuLabApp; + sourceTree = ""; + }; + 302 /* Products */ = { + isa = PBXGroup; + children = ( + 100 /* MeuLabApp.app */, + W100 /* MeuLabWatch.app */, + F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */, + F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */, + ); + name = Products; + sourceTree = ""; + }; + 303 /* Models */ = { + isa = PBXGroup; + children = ( + 103 /* ADSBModels.swift */, + 119 /* ACARSModels.swift */, + 104 /* SystemModels.swift */, + 126 /* SystemExtrasModels.swift */, + 153 /* FirestickModels.swift */, + 131 /* NotificationModels.swift */, + 105 /* RadioModels.swift */, + 106 /* WeatherModels.swift */, + 107 /* SatelliteModels.swift */, + 134 /* OpenMeteoModels.swift */, + 137 /* AviationStackModels.swift */, + 139 /* AnalyticsModels.swift */, + RR100 /* RemoteRadioModels.swift */, + BIBM01 /* BibleModels.swift */, + ); + path = Models; + sourceTree = ""; + }; + 304 /* Services */ = { + isa = PBXGroup; + children = ( + 108 /* APIService.swift */, + 109 /* AudioPlayer.swift */, + 122 /* PushNotificationManager.swift */, + 123 /* LocationManager.swift */, + 132 /* NotificationFeedManager.swift */, + 133 /* Formatters.swift */, + 138 /* WidgetDataManager.swift */, + RR101 /* RemoteRadioAPIClient.swift */, + RR102 /* RemoteRadioWebRTCClient.swift */, + FMDS01 /* FoundationModelService.swift */, + BIBSP01 /* BibleSpeechService.swift */, + BIBL01 /* BibleLoader.swift */, + ); + path = Services; + sourceTree = ""; + }; + 305 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 110 /* AppState.swift */, + F7E628EA2F1448E000763B43 /* LocalNowPlayingFetcher.swift */, + F762D6282F44164400D6BA3B /* OpenSkyService.swift */, + BIBVM01 /* BibleReaderViewModel.swift */, + RR103 /* RemoteRadioViewModel.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 306 /* Views */ = { + isa = PBXGroup; + children = ( + 308 /* Tabs */, + 309 /* Components */, + 311 /* Settings */, + ); + path = Views; + sourceTree = ""; + }; + 307 /* Resources */ = { + isa = PBXGroup; + children = ( + 116 /* Assets.xcassets */, + 130 /* LaunchScreen.storyboard */, + EB2CCDD5B45142E9817882CE /* bible.json */, + ); + path = Resources; + sourceTree = ""; + }; + 308 /* Tabs */ = { + isa = PBXGroup; + children = ( + 111 /* ADSBView.swift */, + 120 /* ACARSView.swift */, + 112 /* SystemView.swift */, + 127 /* InfraView.swift */, + 113 /* RadioView.swift */, + 114 /* WeatherView.swift */, + 115 /* SatelliteView.swift */, + 144 /* AnalyticsView.swift */, + 145 /* AlertsView.swift */, + 146 /* FlightSearchView.swift */, + 148 /* DataExportView.swift */, + 149 /* RemoteControlView.swift */, + 150 /* ContainerLogsView.swift */, + 151 /* HealthCheckView.swift */, + F7CE39012F14BDBA00EF7A25 /* SatellitePassPredictor.swift */, + F76A68C12F19CBB80081D8D9 /* BinaryCache.swift */, + RR104 /* RemoteRadioView.swift */, + INTV01 /* IntelligenceView.swift */, + BIBV01 /* BibleView.swift */, + BIBN01 /* BibleNavigateView.swift */, + BIBS01 /* BibleSearchView.swift */, + BIBR01 /* BibleRandomView.swift */, + ); + path = Tabs; + sourceTree = ""; + }; + 309 /* Components */ = { + isa = PBXGroup; + children = ( + 118 /* AircraftMapView.swift */, + 121 /* MapView.swift */, + 128 /* RadarSplashOverlay.swift */, + 129 /* RadarSplashSwiftUI.swift */, + 154 /* NativeRadarMapView.swift */, + 152 /* StatCard.swift */, + ); + path = Components; + sourceTree = ""; + }; + 310 /* Intents */ = { + isa = PBXGroup; + children = ( + 135 /* LabIntents.swift */, + 136 /* LabShortcuts.swift */, + BIBI01 /* BibleReadingIntents.swift */, + ); + path = Intents; + sourceTree = ""; + }; + 311 /* Settings */ = { + isa = PBXGroup; + children = ( + 142 /* ThemeManagerView.swift */, + ); + path = Settings; + sourceTree = ""; + }; + F7803D532F4A99BE001C8722 /* Recovered References */ = { + isa = PBXGroup; + children = ( + F7A0C1B2D3E4F5A6B7C8D9E0 /* MeuLabApp/Core/Secrets.swift */, + C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */, + AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */, + FM200 /* MeuLabApp/Core/Services/FavoritesManager.swift */, + LGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */, + E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */, + ); + name = "Recovered References"; + sourceTree = ""; + }; + F795720E2F1347AB0058B81B /* Frameworks */ = { + isa = PBXGroup; + children = ( + F795720F2F1347AB0058B81B /* WidgetKit.framework */, + F79572112F1347AB0058B81B /* SwiftUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + W301 /* MeuLabWatch */ = { + isa = PBXGroup; + children = ( + W101 /* MeuLabWatchApp.swift */, + W102 /* ContentView.swift */, + W112 /* Info.plist */, + W111 /* Assets.xcassets */, + W302 /* Views */, + W303 /* Services */, + W304 /* Models */, + WN13 /* Complications */, + F7CE38A82F14AF0B00EF7A25 /* EnhancedWatchContentView.swift */, + F71A10232F2FB5780048CED8 /* WatchRadioView.swift */, + ); + path = MeuLabWatch; + sourceTree = ""; + }; + W302 /* Views */ = { + isa = PBXGroup; + children = ( + W103 /* HomeView.swift */, + W104 /* AlertsView.swift */, + W105 /* WatchADSBView.swift */, + W106 /* WatchACARSView.swift */, + W107 /* WatchSystemView.swift */, + W108 /* WatchInfraView.swift */, + W109 /* WatchWeatherView.swift */, + W110 /* WatchSatDumpView.swift */, + WN03 /* WatchRemoteControlView.swift */, + WN05 /* WatchAnalyticsView.swift */, + WN07 /* WatchBibleView.swift */, + WN09 /* WatchTuyaView.swift */, + ); + path = Views; + sourceTree = ""; + }; + W303 /* Services */ = { + isa = PBXGroup; + children = ( + W113 /* WatchAPIService.swift */, + WN01 /* WatchAudioPlayer.swift */, + ); + path = Services; + sourceTree = ""; + }; + W304 /* Models */ = { + isa = PBXGroup; + children = ( + W114 /* WatchModels.swift */, + ); + path = Models; + sourceTree = ""; + }; + WN13 /* Complications */ = { + isa = PBXGroup; + children = ( + WN11 /* MeuLabComplications.swift */, + WN15 /* MeuLabSmartStackWidgets.swift */, + ); + path = Complications; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 400 /* MeuLabApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */; + buildPhases = ( + 401 /* Sources */, + 200 /* Frameworks */, + 402 /* Resources */, + W300 /* Embed Watch Content */, + WW901 /* Normalize Embedded Watch Info */, + F79572282F1347AC0058B81B /* Embed Foundation Extensions */, + ); + buildRules = ( + ); + dependencies = ( + W401 /* PBXTargetDependency */, + F79572222F1347AC0058B81B /* PBXTargetDependency */, + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */, + ); + name = MeuLabApp; + productName = MeuLabApp; + productReference = 100 /* MeuLabApp.app */; + productType = "com.apple.product-type.application"; + }; + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */ = { + isa = PBXNativeTarget; + buildConfigurationList = F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */; + buildPhases = ( + F703A8B62F40352B007B6FD3 /* Sources */, + F703A8B72F40352B007B6FD3 /* Frameworks */, + F703A8B82F40352B007B6FD3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F703A8BB2F40352B007B6FD3 /* MeuLabNotificationService */, + ); + name = MeuLabNotificationService; + packageProductDependencies = ( + ); + productName = MeuLabNotificationService; + productReference = F703A8BA2F40352B007B6FD3 /* MeuLabNotificationService.appex */; + productType = "com.apple.product-type.app-extension"; + }; + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */; + buildPhases = ( + F79572092F1347AB0058B81B /* Sources */, + F795720A2F1347AB0058B81B /* Frameworks */, + F795720B2F1347AB0058B81B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + F79572132F1347AB0058B81B /* MeuLabWidgets */, + ); + name = MeuLabWidgetsExtension; + packageProductDependencies = ( + ); + productName = MeuLabWidgetsExtension; + productReference = F795720D2F1347AB0058B81B /* MeuLabWidgetsExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; + W400 /* MeuLabWatch */ = { + isa = PBXNativeTarget; + buildConfigurationList = W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */; + buildPhases = ( + W402 /* Sources */, + W201 /* Frameworks */, + W403 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MeuLabWatch; + productName = MeuLabWatch; + productReference = W100 /* MeuLabWatch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 600 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2620; + LastUpgradeCheck = 2620; + TargetAttributes = { + 400 = { + CreatedOnToolsVersion = 15.0; + }; + F703A8B92F40352B007B6FD3 = { + CreatedOnToolsVersion = 26.2; + }; + F795720C2F1347AB0058B81B = { + CreatedOnToolsVersion = 26.2; + }; + W400 = { + CreatedOnToolsVersion = 15.0; + }; + }; + }; + buildConfigurationList = 601 /* Build configuration list for PBXProject "MeuLabApp" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = "pt-BR"; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + "pt-BR", + ); + mainGroup = 300; + productRefGroup = 302 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 400 /* MeuLabApp */, + W400 /* MeuLabWatch */, + F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */, + F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 402 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E628DE2F142B7100763B43 /* Assets.xcassets in Resources */, + F7803D5F2F4A9A7B001C8722 /* Secrets.plist in Resources */, + 029 /* LaunchScreen.storyboard in Resources */, + 7F0B7866E4944B48AAFB4F3A /* bible.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B82F40352B007B6FD3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F795720B2F1347AB0058B81B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7803D612F4A9A7B001C8722 /* Secrets.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W403 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7803D602F4A9A7B001C8722 /* Secrets.plist in Resources */, + W011 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + WW901 /* Normalize Embedded Watch Info */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Normalize Embedded Watch Info"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "WATCH_PLIST=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Watch/MeuLabWatch.app/Info.plist\"\nif [ -f \"$WATCH_PLIST\" ]; then\n /usr/libexec/PlistBuddy -c \"Delete :UIDeviceFamily\" \"$WATCH_PLIST\" >/dev/null 2>&1 || true\n /usr/libexec/PlistBuddy -c \"Add :UIDeviceFamily array\" \"$WATCH_PLIST\"\n /usr/libexec/PlistBuddy -c \"Add :UIDeviceFamily:0 integer 4\" \"$WATCH_PLIST\"\nfi\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 401 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BIBI02 /* BibleReadingIntents.swift in Sources */, + BIBSP02 /* BibleSpeechService.swift in Sources */, + BIBVM02 /* BibleReaderViewModel.swift in Sources */, + 001 /* MeuLabApp.swift in Sources */, + 002 /* ContentView.swift in Sources */, + F7E628EB2F1448E000763B43 /* LocalNowPlayingFetcher.swift in Sources */, + 003 /* ADSBModels.swift in Sources */, + 004 /* SystemModels.swift in Sources */, + 052 /* FirestickModels.swift in Sources */, + F76A68C22F19CBB90081D8D9 /* BinaryCache.swift in Sources */, + 005 /* RadioModels.swift in Sources */, + 006 /* WeatherModels.swift in Sources */, + 007 /* SatelliteModels.swift in Sources */, + 008 /* APIService.swift in Sources */, + 009 /* AudioPlayer.swift in Sources */, + 010 /* AppState.swift in Sources */, + 011 /* ADSBView.swift in Sources */, + 012 /* SystemView.swift in Sources */, + 013 /* RadioView.swift in Sources */, + FMDS02 /* FoundationModelService.swift in Sources */, + INTV02 /* IntelligenceView.swift in Sources */, + BIBM02 /* BibleModels.swift in Sources */, + BIBL02 /* BibleLoader.swift in Sources */, + BIBV02 /* BibleView.swift in Sources */, + BIBN02 /* BibleNavigateView.swift in Sources */, + BIBS02 /* BibleSearchView.swift in Sources */, + BIBR02 /* BibleRandomView.swift in Sources */, + 014 /* WeatherView.swift in Sources */, + 015 /* SatelliteView.swift in Sources */, + 017 /* AircraftMapView.swift in Sources */, + F7CE39022F14BDBA00EF7A25 /* SatellitePassPredictor.swift in Sources */, + 018 /* ACARSModels.swift in Sources */, + 019 /* ACARSView.swift in Sources */, + F762D6292F44164400D6BA3B /* OpenSkyService.swift in Sources */, + 020 /* MapView.swift in Sources */, + 021 /* PushNotificationManager.swift in Sources */, + 022 /* LocationManager.swift in Sources */, + 025 /* SystemExtrasModels.swift in Sources */, + 026 /* InfraView.swift in Sources */, + 027 /* RadarSplashOverlay.swift in Sources */, + 028 /* RadarSplashSwiftUI.swift in Sources */, + 030 /* NotificationModels.swift in Sources */, + 031 /* NotificationFeedManager.swift in Sources */, + 032 /* Formatters.swift in Sources */, + 033 /* OpenMeteoModels.swift in Sources */, + 034 /* LabIntents.swift in Sources */, + 035 /* LabShortcuts.swift in Sources */, + 036 /* AviationStackModels.swift in Sources */, + 037 /* WidgetDataManager.swift in Sources */, + 038 /* AnalyticsModels.swift in Sources */, + 039 /* iPadSplitView.swift in Sources */, + 040 /* EnhancedContentView.swift in Sources */, + 041 /* ThemeManagerView.swift in Sources */, + 043 /* AnalyticsView.swift in Sources */, + 044 /* AlertsView.swift in Sources */, + 045 /* FlightSearchView.swift in Sources */, + 047 /* DataExportView.swift in Sources */, + 048 /* RemoteControlView.swift in Sources */, + 049 /* ContainerLogsView.swift in Sources */, + 050 /* HealthCheckView.swift in Sources */, + 051 /* StatCard.swift in Sources */, + 053 /* NativeRadarMapView.swift in Sources */, + A1B2C3D4E5F6A7B8C9D0E1F2 /* MeuLabApp/Core/Secrets.swift in Sources */, + B1C2D3E4F5A6B7C8D9E0F1A2 /* MeuLabApp/Core/NetworkEnvironment.swift in Sources */, + AC100 /* MeuLabApp/Core/Utils/AircraftClassification.swift in Sources */, + FM100 /* MeuLabApp/Core/Services/FavoritesManager.swift in Sources */, + RR200 /* RemoteRadioModels.swift in Sources */, + RR201 /* RemoteRadioAPIClient.swift in Sources */, + RR202 /* RemoteRadioWebRTCClient.swift in Sources */, + RR203 /* RemoteRadioViewModel.swift in Sources */, + RR204 /* RemoteRadioView.swift in Sources */, + LGM02 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F703A8B62F40352B007B6FD3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F79572092F1347AB0058B81B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + W402 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F71A10242F2FB5780048CED8 /* WatchRadioView.swift in Sources */, + W001 /* MeuLabWatchApp.swift in Sources */, + W002 /* ContentView.swift in Sources */, + W003 /* HomeView.swift in Sources */, + F7CE38A92F14AF0B00EF7A25 /* EnhancedWatchContentView.swift in Sources */, + W004 /* AlertsView.swift in Sources */, + W005 /* WatchADSBView.swift in Sources */, + W006 /* WatchACARSView.swift in Sources */, + W007 /* WatchSystemView.swift in Sources */, + W008 /* WatchInfraView.swift in Sources */, + W009 /* WatchWeatherView.swift in Sources */, + W010 /* WatchSatDumpView.swift in Sources */, + W013 /* WatchAPIService.swift in Sources */, + W014 /* WatchModels.swift in Sources */, + 3909786604B94EE5BE1AD25A /* MeuLabWatch/Services/WatchSecrets.swift in Sources */, + WN02 /* WatchAudioPlayer.swift in Sources */, + WN04 /* WatchRemoteControlView.swift in Sources */, + WN06 /* WatchAnalyticsView.swift in Sources */, + WN08 /* WatchBibleView.swift in Sources */, + WN10 /* WatchTuyaView.swift in Sources */, + WN12 /* MeuLabComplications.swift in Sources */, + WN14 /* MeuLabSmartStackWidgets.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F703A8C02F40352B007B6FD3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F703A8B92F40352B007B6FD3 /* MeuLabNotificationService */; + targetProxy = F703A8BF2F40352B007B6FD3 /* PBXContainerItemProxy */; + }; + F79572222F1347AC0058B81B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F795720C2F1347AB0058B81B /* MeuLabWidgetsExtension */; + targetProxy = F79572212F1347AC0058B81B /* PBXContainerItemProxy */; + }; + W401 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = W400 /* MeuLabWatch */; + targetProxy = W200 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 700 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + 701 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 7KGNMD6RBY; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; + 702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você."; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "MeuLab precisa de acesso para salvar imagens de satélite na sua galeria."; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIRequiredDeviceCapabilities = armv7; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = MeuLabApp/MeuLabApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_APP_SANDBOX = YES; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = YES; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = YES; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "MeuLab usa sua localização para alertar quando aviões interessantes passarem perto de você."; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "MeuLab usa sua localização para calcular a distância até aeronaves, mostrar clima local e prever passes de satélite visíveis da sua posição."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "MeuLab precisa de acesso para salvar imagens de satélite na sua galeria."; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIRequiredDeviceCapabilities = armv7; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F703A8C22F40352B007B6FD3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F703A8C32F40352B007B6FD3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabNotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabNotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabNotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F79572262F1347AC0058B81B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F79572272F1347AC0058B81B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = MeuLabWidgets/MeuLabWidgets.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLabWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.MeuLabWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + W702 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = WatchHostIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + W703 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = WatchHostIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeuLabWatch/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeuLab; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = fun.meulab.app; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = fun.meulab.app.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 500 /* Build configuration list for PBXNativeTarget "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 702 /* Debug */, + 703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 601 /* Build configuration list for PBXProject "MeuLabApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 700 /* Debug */, + 701 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F703A8C52F40352B007B6FD3 /* Build configuration list for PBXNativeTarget "MeuLabNotificationService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F703A8C22F40352B007B6FD3 /* Debug */, + F703A8C32F40352B007B6FD3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F79572252F1347AC0058B81B /* Build configuration list for PBXNativeTarget "MeuLabWidgetsExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F79572262F1347AC0058B81B /* Debug */, + F79572272F1347AC0058B81B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + W500 /* Build configuration list for PBXNativeTarget "MeuLabWatch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + W702 /* Debug */, + W703 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 600 /* Project object */; +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Button.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Button.swift new file mode 100644 index 0000000..0e77794 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Button.swift @@ -0,0 +1,113 @@ +import SwiftUI + +// MARK: - MacOS9Button +// Classic Mac OS 9 push button: grey face, bevel border, pressed state inverts bevel. + +struct MacOS9Button: View { + let label: String + var systemImage: String? = nil + var isDestructive: Bool = false + var isDefault: Bool = false + let action: () -> Void + + @State private var isPressed = false + + var body: some View { + Button(action: action) { + HStack(spacing: MacOS9Metrics.inlineSpacing) { + if let symbol = systemImage { + Image(systemName: symbol) + .font(.system(size: 12)) + } + Text(label) + .font(MacOS9Typography.menuLabel()) + } + .foregroundStyle(isDestructive ? MacOS9Colors.statusRed : MacOS9Colors.primaryText) + .padding(.horizontal, MacOS9Metrics.buttonPaddingH) + .padding(.vertical, MacOS9Metrics.buttonPaddingV) + .frame(minHeight: MacOS9Metrics.buttonMinHeight) + .background( + isPressed + ? MacOS9Colors.buttonPressed + : (isDefault ? MacOS9Colors.titleBar : MacOS9Colors.windowBackground) + ) + .overlay(Mac9BevelBorder(isRaised: !isPressed, width: MacOS9Metrics.bevelWidth)) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + ) + .shadow( + color: isPressed ? .clear : MacOS9Colors.dropShadow, + radius: 0, + x: isPressed ? 0 : 1, + y: isPressed ? 0 : 1 + ) + .offset(x: isPressed ? 1 : 0, y: isPressed ? 1 : 0) + } + .buttonStyle(.plain) + .onLongPressGesture( + minimumDuration: 100, + pressing: { pressing in + withAnimation(.linear(duration: 0.05)) { isPressed = pressing } + }, + perform: {} + ) + .accessibilityAddTraits(.isButton) + } +} + +// MARK: - MacOS9SmallButton +// Inline small button variant (title bar, toolbars) + +struct MacOS9SmallButton: View { + let label: String + var systemImage: String? = nil + let action: () -> Void + + @State private var isPressed = false + + var body: some View { + Button(action: action) { + HStack(spacing: 3) { + if let symbol = systemImage { + Image(systemName: symbol) + .font(.system(size: 10)) + } + Text(label) + .font(MacOS9Typography.caption()) + } + .foregroundStyle(MacOS9Colors.primaryText) + .padding(.horizontal, 8) + .padding(.vertical, 4) + .background(isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.windowBackground) + .overlay(Mac9BevelBorder(isRaised: !isPressed, width: 1)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + } + .buttonStyle(.plain) + .onLongPressGesture( + minimumDuration: 100, + pressing: { pressing in isPressed = pressing }, + perform: {} + ) + } +} + +// MARK: - Preview + +#Preview { + VStack(spacing: 12) { + MacOS9Button(label: "OK", isDefault: true) {} + MacOS9Button(label: "Cancelar") {} + MacOS9Button(label: "Exportar", systemImage: "square.and.arrow.up") {} + MacOS9Button(label: "Apagar", systemImage: "trash", isDestructive: true) {} + + Divider() + + HStack { + MacOS9SmallButton(label: "Buscar", systemImage: "magnifyingglass") {} + MacOS9SmallButton(label: "Fechar") {} + } + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift new file mode 100644 index 0000000..0f80c45 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift @@ -0,0 +1,65 @@ +import SwiftUI + +// MARK: - Mac OS 9 Color Palette +// Extracted from the Figma reference (modelos macos9.html) + +public enum MacOS9Colors { + + // MARK: Window & Surface + /// Main window background — #EEEEEE + public static let windowBackground = Color(red: 0.933, green: 0.933, blue: 0.933) + /// Title bar / inactive surface — #CCCCCC + public static let titleBar = Color(red: 0.800, green: 0.800, blue: 0.800) + /// Panel / card background — #DDDDDD + public static let panelBackground = Color(red: 0.867, green: 0.867, blue: 0.867) + /// White content area + public static let contentPanel = Color.white + + // MARK: Borders + /// Primary 1-px border — #262626 + public static let border = Color(red: 0.149, green: 0.149, blue: 0.149) + /// Accent border (purple) — #7B61FF + public static let accentBorder = Color(red: 0.482, green: 0.380, blue: 1.000) + + // MARK: Bevel + /// Bevel highlight — top/left inner edge (white 60%) + public static let bevelHighlight = Color.white.opacity(0.60) + /// Bevel shadow — bottom/right inner edge (#262626 40%) + public static let bevelShadow = Color(red: 0.149, green: 0.149, blue: 0.149).opacity(0.40) + /// Subtle inner bevel (#262626 10%) + public static let bevelShadowSubtle = Color(red: 0.149, green: 0.149, blue: 0.149).opacity(0.10) + /// Hard drop shadow — #262626 (2px offset, 0 blur) + public static let dropShadow = Color(red: 0.149, green: 0.149, blue: 0.149) + + // MARK: Labels & Badges + /// Lilac label badge — #CCCCFF + public static let labelBadge = Color(red: 0.800, green: 0.800, blue: 1.000) + /// Label badge text (dark) + public static let labelBadgeText = Color(red: 0.149, green: 0.149, blue: 0.149) + + // MARK: Text + /// Primary text — #262626 + public static let primaryText = Color(red: 0.149, green: 0.149, blue: 0.149) + /// Secondary / placeholder text — #666666 + public static let secondaryText = Color(red: 0.400, green: 0.400, blue: 0.400) + + // MARK: Selection + /// Classic Mac selection blue + public static let selection = Color(red: 0.000, green: 0.000, blue: 0.502) + public static let selectedText = Color.white + + // MARK: Status + public static let statusGreen = Color(red: 0.000, green: 0.600, blue: 0.000) + public static let statusRed = Color(red: 0.750, green: 0.000, blue: 0.000) + public static let statusOrange = Color(red: 0.850, green: 0.450, blue: 0.000) + public static let statusBlue = Color(red: 0.000, green: 0.000, blue: 0.700) + + // MARK: Button + public static let buttonFace = windowBackground + public static let buttonBorder = border + public static let buttonPressed = Color(red: 0.700, green: 0.700, blue: 0.700) + + // MARK: Scrollbar + public static let scrollbarTrack = Color(red: 0.800, green: 0.800, blue: 0.800) + public static let scrollbarThumb = Color(red: 0.600, green: 0.600, blue: 0.600) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift new file mode 100644 index 0000000..ca7c1c7 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift @@ -0,0 +1,50 @@ +import SwiftUI + +// MARK: - MacOS9Divider +// 1px pixel-perfect divider using the classic Mac border colour. + +struct MacOS9Divider: View { + var orientation: Axis = .horizontal + var color: Color = MacOS9Colors.border + var opacity: CGFloat = 0.5 + + var body: some View { + if orientation == .horizontal { + Rectangle() + .fill(color.opacity(opacity)) + .frame(maxWidth: .infinity) + .frame(height: 1) + } else { + Rectangle() + .fill(color.opacity(opacity)) + .frame(maxHeight: .infinity) + .frame(width: 1) + } + } +} + +// MARK: - Grooved Divider (title-bar style) +// Two stacked lines: dark on top, light below — classic Platinum grooved separator + +struct MacOS9GroovedDivider: View { + var body: some View { + VStack(spacing: 0) { + MacOS9Divider(color: MacOS9Colors.border, opacity: 0.5) + MacOS9Divider(color: .white, opacity: 0.6) + } + } +} + +// MARK: - Preview + +#Preview { + VStack(spacing: 8) { + Text("Above divider").mac9Body() + MacOS9Divider() + Text("Below divider").mac9Body() + MacOS9GroovedDivider() + Text("Below grooved divider").mac9Body() + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Label.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Label.swift new file mode 100644 index 0000000..1bb71a3 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Label.swift @@ -0,0 +1,109 @@ +import SwiftUI + +// MARK: - MacOS9Label +// Lilac badge / section label — matches #CCCCFF blocks from Figma HTML. + +struct MacOS9Label: View { + let text: String + var systemImage: String? = nil + + var body: some View { + HStack(spacing: MacOS9Metrics.inlineSpacing) { + if let symbol = systemImage { + Image(systemName: symbol) + .font(.system(size: 10)) + .foregroundStyle(MacOS9Colors.labelBadgeText) + } + Text(text) + .font(MacOS9Typography.menuLabel()) + .foregroundStyle(MacOS9Colors.labelBadgeText) + } + .padding(.horizontal, MacOS9Metrics.badgePaddingH) + .padding(.vertical, MacOS9Metrics.badgePaddingV) + .background(MacOS9Colors.labelBadge) + .overlay( + Rectangle() + .strokeBorder( + MacOS9Colors.border.opacity(0.4), lineWidth: MacOS9Metrics.borderWidth) + ) + } +} + +// MARK: - MacOS9SectionHeader +// Section header combining label badge + optional subtitle + +struct MacOS9SectionHeader: View { + let title: String + var subtitle: String? = nil + var systemImage: String? = nil + + var body: some View { + HStack(spacing: MacOS9Metrics.itemSpacing) { + MacOS9Label(text: title, systemImage: systemImage) + if let sub = subtitle { + Text(sub) + .font(MacOS9Typography.caption()) + .foregroundStyle(MacOS9Colors.secondaryText) + } + Spacer() + } + } +} + +// MARK: - MacOS9StatusBadge +// Replaces the existing `StatusBadge` with Mac OS 9 style + +struct MacOS9StatusBadge: View { + let status: String + + private var color: Color { + switch status.lowercased() { + case "running", "active", "healthy", "online", "ativo": + return MacOS9Colors.statusGreen + case "exited", "inactive", "inativo", "stopped": + return MacOS9Colors.statusOrange + case "unhealthy", "failed", "error", "erro": + return MacOS9Colors.statusRed + default: + return MacOS9Colors.secondaryText + } + } + + var body: some View { + Text(status.capitalized) + .font(MacOS9Typography.caption()) + .foregroundStyle(color) + .padding(.horizontal, 6) + .padding(.vertical, 2) + .background(color.opacity(0.15)) + .overlay( + Rectangle() + .strokeBorder(color.opacity(0.6), lineWidth: 1) + ) + } +} + +// MARK: - Preview + +#Preview { + VStack(alignment: .leading, spacing: 12) { + MacOS9Label(text: "ADS-B", systemImage: "airplane") + MacOS9Label(text: "Rádio", systemImage: "radio") + MacOS9Label(text: "Sistema") + + Divider() + + MacOS9SectionHeader(title: "Aeronaves", subtitle: "12 detectadas", systemImage: "airplane") + MacOS9SectionHeader(title: "CPU", subtitle: "34%", systemImage: "cpu") + + Divider() + + HStack { + MacOS9StatusBadge(status: "running") + MacOS9StatusBadge(status: "exited") + MacOS9StatusBadge(status: "unhealthy") + } + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9ListRow.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9ListRow.swift new file mode 100644 index 0000000..67cc97b --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9ListRow.swift @@ -0,0 +1,129 @@ +import SwiftUI + +// MARK: - MacOS9ListRow +// Classic Mac OS 9 list row: Geneva body text, pixel separator, highlight on selection. + +struct MacOS9ListRow: View { + let title: String + var subtitle: String? = nil + var systemImage: String? = nil + var isSelected: Bool = false + var showDisclosure: Bool = true + var action: (() -> Void)? = nil + + var body: some View { + Group { + if let action { + Button(action: action) { rowContent } + .buttonStyle(.plain) + } else { + rowContent + } + } + } + + private var rowContent: some View { + HStack(spacing: MacOS9Metrics.itemSpacing) { + if let symbol = systemImage { + Image(systemName: symbol) + .font(.system(size: 12)) + .foregroundStyle( + isSelected ? MacOS9Colors.selectedText : MacOS9Colors.secondaryText + ) + .frame(width: 16) + } + + VStack(alignment: .leading, spacing: 2) { + Text(title) + .font(MacOS9Typography.body()) + .foregroundStyle( + isSelected ? MacOS9Colors.selectedText : MacOS9Colors.primaryText + ) + .lineLimit(1) + + if let sub = subtitle { + Text(sub) + .font(MacOS9Typography.caption()) + .foregroundStyle( + isSelected + ? MacOS9Colors.selectedText.opacity(0.8) + : MacOS9Colors.secondaryText + ) + .lineLimit(1) + } + } + + Spacer() + + if showDisclosure && action != nil { + Image(systemName: "chevron.right") + .font(.system(size: 9)) + .foregroundStyle( + isSelected + ? MacOS9Colors.selectedText.opacity(0.7) : MacOS9Colors.secondaryText) + } + } + .padding(.horizontal, MacOS9Metrics.listRowPadding) + .frame(minHeight: MacOS9Metrics.listRowHeight) + .background(isSelected ? MacOS9Colors.selection : Color.clear) + .contentShape(Rectangle()) + } +} + +// MARK: - MacOS9List +// Container for a list of rows with pixel separators + +struct MacOS9List: View { + let items: [Item] + @ViewBuilder let row: (Item) -> Row + + var body: some View { + VStack(spacing: 0) { + ForEach(Array(items.enumerated()), id: \.element.id) { index, item in + row(item) + if index < items.count - 1 { + MacOS9Divider() + } + } + } + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: false, width: MacOS9Metrics.bevelWidth)) + .overlay( + Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth)) + } +} + +// MARK: - Preview + +private struct SampleItem: Identifiable { + let id = UUID() + let name: String + let detail: String +} + +#Preview { + let items = [ + SampleItem(name: "N12345", detail: "Boeing 737 · 35,000 ft"), + SampleItem(name: "PT-ABC", detail: "Embraer E195 · 28,000 ft"), + SampleItem(name: "G-AAAA", detail: "Airbus A320 · 32,000 ft"), + ] + + VStack(spacing: 12) { + MacOS9List(items: items) { item in + MacOS9ListRow( + title: item.name, + subtitle: item.detail, + systemImage: "airplane", + action: {} + ) + } + + MacOS9ListRow( + title: "Selected row", subtitle: "Detail", systemImage: "star.fill", isSelected: true + ) + .background(MacOS9Colors.contentPanel) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Metrics.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Metrics.swift new file mode 100644 index 0000000..9ba6c50 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Metrics.swift @@ -0,0 +1,54 @@ +import SwiftUI + +// MARK: - Mac OS 9 Metrics / Layout Constants + +public enum MacOS9Metrics { + + // MARK: Title Bar + /// Title bar height adapted for iPhone touch targets (HTML reference: 19px) + public static let titleBarHeight: CGFloat = 28 + + // MARK: Borders + /// Primary border width (1px pixel-perfect) + public static let borderWidth: CGFloat = 1 + /// Bevel edge width (2px per HTML shadows) + public static let bevelWidth: CGFloat = 2 + + // MARK: Shadows (hard, no blur — classic Mac style) + public static let dropShadowX: CGFloat = 2 + public static let dropShadowY: CGFloat = 2 + public static let dropShadowBlur: CGFloat = 0 + + // MARK: Corner Radii + /// Window / outer container — no rounding, pixel-perfect + public static let windowCornerRadius: CGFloat = 0 + /// Inner content panels — subtle rounding per HTML (border-radius: 5px) + public static let panelCornerRadius: CGFloat = 4 + /// Buttons — square, no rounding + public static let buttonCornerRadius: CGFloat = 0 + + // MARK: Spacing + public static let windowPadding: CGFloat = 8 + public static let sectionSpacing: CGFloat = 12 + public static let itemSpacing: CGFloat = 6 + public static let inlineSpacing: CGFloat = 4 + + // MARK: Buttons + /// Minimum tappable height on iPhone (adapted from tiny Mac desktop buttons) + public static let buttonMinHeight: CGFloat = 44 + public static let buttonPaddingH: CGFloat = 12 + public static let buttonPaddingV: CGFloat = 8 + + // MARK: Label Badges (HTML: 8px h-padding, 2px v-padding) + public static let badgePaddingH: CGFloat = 10 + public static let badgePaddingV: CGFloat = 3 + + // MARK: List Rows + public static let listRowHeight: CGFloat = 44 + public static let listRowPadding: CGFloat = 10 + + // MARK: Title Bar Decorative Lines + /// Number of decorative horizontal stripes each side of title text + public static let titleBarStripeCount: Int = 4 + public static let titleBarStripeSpacing: CGFloat = 2 +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift new file mode 100644 index 0000000..e7186fa --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift @@ -0,0 +1,159 @@ +import SwiftUI + +// MARK: - Mac OS 9 Bevel Shape +// Draws the 4-edge bevel border (top/left = highlight, bottom/right = shadow). + +struct Mac9BevelBorder: View { + let isRaised: Bool + let width: CGFloat + + init(isRaised: Bool = true, width: CGFloat = MacOS9Metrics.bevelWidth) { + self.isRaised = isRaised + self.width = width + } + + var body: some View { + GeometryReader { geo in + let w = geo.size.width + let h = geo.size.height + let highlight = isRaised ? MacOS9Colors.bevelHighlight : MacOS9Colors.bevelShadow + let shadow = isRaised ? MacOS9Colors.bevelShadow : MacOS9Colors.bevelHighlight + + ZStack(alignment: .topLeading) { + // Top edge + Rectangle() + .fill(highlight) + .frame(width: w, height: width) + .position(x: w / 2, y: width / 2) + + // Left edge + Rectangle() + .fill(highlight) + .frame(width: width, height: h) + .position(x: width / 2, y: h / 2) + + // Bottom edge + Rectangle() + .fill(shadow) + .frame(width: w, height: width) + .position(x: w / 2, y: h - width / 2) + + // Right edge + Rectangle() + .fill(shadow) + .frame(width: width, height: h) + .position(x: w - width / 2, y: h / 2) + } + } + } +} + +// MARK: - Mac OS 9 Modifiers + +extension View { + + // MARK: Panel Modifiers + + /// Raised panel: light grey background + bevel + 1px dark border + func mac9Panel(padding: CGFloat = MacOS9Metrics.windowPadding) -> some View { + self + .padding(padding) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + ) + .shadow( + color: MacOS9Colors.dropShadow, + radius: MacOS9Metrics.dropShadowBlur, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + } + + /// Sunken / inset panel (e.g. scroll area, text field background) + func mac9Sunken(padding: CGFloat = MacOS9Metrics.windowPadding) -> some View { + self + .padding(padding) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: false)) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + ) + } + + /// Window-level container: window background + outer bevel + hard shadow + func mac9Window() -> some View { + self + .background(MacOS9Colors.windowBackground) + .overlay(Mac9BevelBorder(isRaised: true, width: 2)) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + ) + .shadow( + color: MacOS9Colors.dropShadow, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + } + + /// Flat card: light panel background, 1px border, no bevel, no shadow. + func mac9FlatCard(padding: CGFloat = MacOS9Metrics.windowPadding) -> some View { + self + .padding(padding) + .background(MacOS9Colors.panelBackground) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + ) + } + + /// Accent-bordered content area (purple border, white bg — from HTML panels) + func mac9ContentPanel(padding: CGFloat = MacOS9Metrics.windowPadding) -> some View { + self + .padding(padding) + .background(MacOS9Colors.contentPanel) + .overlay( + RoundedRectangle(cornerRadius: MacOS9Metrics.panelCornerRadius) + .strokeBorder(MacOS9Colors.accentBorder, lineWidth: MacOS9Metrics.borderWidth) + ) + } +} + +// MARK: - Backward-compat: glassCard now renders Mac OS 9 panel +// This replaces the LiquidGlass implementation app-wide. +// The `glassCard` name is preserved so existing code needs no changes. + +extension View { + /// Mac OS 9 raised panel — replaces Liquid Glass glassCard across the app. + func glassCard(cornerRadius: CGFloat = 16) -> some View { + self.mac9Panel(padding: MacOS9Metrics.windowPadding) + } + + /// Tinted Mac OS 9 panel — accent border uses the tint color. + func glassCard(tint color: Color, cornerRadius: CGFloat = 16) -> some View { + self + .padding(MacOS9Metrics.windowPadding) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay( + Rectangle() + .strokeBorder(color.opacity(0.8), lineWidth: MacOS9Metrics.borderWidth) + ) + .shadow( + color: MacOS9Colors.dropShadow, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + } + + /// Lightweight card — same as mac9FlatCard. + func materialCard(cornerRadius: CGFloat = 12) -> some View { + self.mac9FlatCard(padding: MacOS9Metrics.itemSpacing) + } +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift new file mode 100644 index 0000000..1b00e83 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift @@ -0,0 +1,92 @@ +import SwiftUI + +// MARK: - MacOS9Panel +// Classic Mac panel/card with bevel variants. +// Matches the bordered content panels from the Figma HTML reference. + +enum Mac9PanelStyle { + case raised // Default: light-grey bg, outward bevel, hard shadow + case sunken // Inset/scrollable areas: white bg, inward bevel + case flat // No bevel, 1px border only + case content // Accent (purple) border, white background +} + +struct MacOS9Panel: View { + var style: Mac9PanelStyle = .raised + var padding: CGFloat = MacOS9Metrics.windowPadding + @ViewBuilder let content: Content + + var body: some View { + content + .padding(padding) + .background(background) + .overlay(bevel) + .overlay(border) + .shadow( + color: style == .raised ? MacOS9Colors.dropShadow : .clear, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + } + + @ViewBuilder + private var background: some View { + switch style { + case .raised: Rectangle().fill(MacOS9Colors.panelBackground) + case .sunken: Rectangle().fill(MacOS9Colors.contentPanel) + case .flat: Rectangle().fill(MacOS9Colors.panelBackground) + case .content: Rectangle().fill(MacOS9Colors.contentPanel) + } + } + + @ViewBuilder + private var bevel: some View { + switch style { + case .raised: Mac9BevelBorder(isRaised: true, width: MacOS9Metrics.bevelWidth) + case .sunken: Mac9BevelBorder(isRaised: false, width: MacOS9Metrics.bevelWidth) + case .flat: EmptyView() + case .content: EmptyView() + } + } + + @ViewBuilder + private var border: some View { + switch style { + case .content: + RoundedRectangle(cornerRadius: MacOS9Metrics.panelCornerRadius) + .strokeBorder(MacOS9Colors.accentBorder, lineWidth: MacOS9Metrics.borderWidth) + default: + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + } + } +} + +// MARK: - Preview + +#Preview { + VStack(spacing: 16) { + MacOS9Panel(style: .raised) { + Text("Raised panel — cards, sections") + .mac9Body() + } + + MacOS9Panel(style: .sunken) { + Text("Sunken panel — scroll areas, log views") + .mac9Body() + } + + MacOS9Panel(style: .flat) { + Text("Flat panel — no bevel") + .mac9Body() + } + + MacOS9Panel(style: .content) { + Text("Content panel — purple accent border") + .mac9Body() + } + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift new file mode 100644 index 0000000..4f505b3 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift @@ -0,0 +1,209 @@ +import SwiftUI + +// MARK: - MacOS9Screen +// Full-screen wrapper that applies the Mac OS 9 window background, +// a top title bar (mapped from NavigationView title), and scrollable content. +// Designed to wrap NavigationStack or standalone views. + +struct MacOS9Screen: View { + var title: String = "" + var showTitleBar: Bool = true + @ViewBuilder let content: Content + + var body: some View { + ZStack { + // Global background + MacOS9Colors.windowBackground + .ignoresSafeArea() + + VStack(spacing: 0) { + if showTitleBar && !title.isEmpty { + MacOS9TitleBar(title: title, isActive: true) + .zIndex(10) + } + + ScrollView { + content + .padding(MacOS9Metrics.windowPadding) + } + } + } + .preferredColorScheme(.light) + } +} + +// MARK: - MacOS9ScrollableContent +// Plain scrollable area with Mac OS 9 background, no title bar. + +struct MacOS9ScrollableContent: View { + @ViewBuilder let content: Content + + var body: some View { + ZStack { + MacOS9Colors.windowBackground.ignoresSafeArea() + ScrollView { + LazyVStack(spacing: MacOS9Metrics.sectionSpacing) { + content + } + .padding(MacOS9Metrics.windowPadding) + } + } + .preferredColorScheme(.light) + } +} + +// MARK: - MacOS9EmptyState +// Empty state view with Mac OS 9 style + +struct MacOS9EmptyState: View { + let title: String + var message: String? = nil + var systemImage: String = "doc" + + var body: some View { + VStack(spacing: MacOS9Metrics.itemSpacing) { + Image(systemName: systemImage) + .font(.system(size: 32)) + .foregroundStyle(MacOS9Colors.secondaryText) + + Text(title) + .font(MacOS9Typography.windowTitle()) + .foregroundStyle(MacOS9Colors.primaryText) + + if let msg = message { + Text(msg) + .font(MacOS9Typography.caption()) + .foregroundStyle(MacOS9Colors.secondaryText) + .multilineTextAlignment(.center) + } + } + .frame(maxWidth: .infinity) + .padding(MacOS9Metrics.windowPadding * 2) + .mac9FlatCard() + } +} + +// MARK: - MacOS9LoadingView +// Loading state + +struct MacOS9LoadingView: View { + var message: String = "Carregando…" + + var body: some View { + HStack(spacing: MacOS9Metrics.itemSpacing) { + ProgressView() + .tint(MacOS9Colors.primaryText) + .scaleEffect(0.8) + Text(message) + .font(MacOS9Typography.body()) + .foregroundStyle(MacOS9Colors.secondaryText) + } + .frame(maxWidth: .infinity) + .padding(MacOS9Metrics.windowPadding) + .mac9FlatCard() + } +} + +// MARK: - MacOS9ErrorCard +// Error state — replaces the app-wide `ErrorCard` component + +struct MacOS9ErrorCard: View { + let message: String + var retryAction: (() -> Void)? = nil + + var body: some View { + VStack(alignment: .leading, spacing: MacOS9Metrics.itemSpacing) { + HStack(spacing: MacOS9Metrics.inlineSpacing) { + Image(systemName: "exclamationmark.triangle.fill") + .foregroundStyle(MacOS9Colors.statusRed) + .font(.system(size: 12)) + Text("Erro") + .font(MacOS9Typography.menuLabel()) + .foregroundStyle(MacOS9Colors.statusRed) + } + + Text(message) + .font(MacOS9Typography.caption()) + .foregroundStyle(MacOS9Colors.primaryText) + .fixedSize(horizontal: false, vertical: true) + + if let retry = retryAction { + MacOS9Button( + label: "Tentar Novamente", systemImage: "arrow.clockwise", action: retry) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .mac9Panel() + } +} + +// MARK: - MacOS9StatCard +// Stat card for metrics dashboards — replaces the global `StatCard` component + +struct MacOS9StatCard: View { + let title: String + let value: String + let icon: String + var color: Color = MacOS9Colors.primaryText + + var body: some View { + VStack(spacing: MacOS9Metrics.inlineSpacing) { + HStack(spacing: 3) { + Image(systemName: icon) + .font(.system(size: 10)) + .foregroundStyle(color) + + Text(title) + .font(MacOS9Typography.caption()) + .foregroundStyle(MacOS9Colors.secondaryText) + .lineLimit(1) + } + + Text(value) + .font(MacOS9Typography.windowTitle(14)) + .foregroundStyle(MacOS9Colors.primaryText) + .monospacedDigit() + .lineLimit(1) + .minimumScaleFactor(0.7) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 10) + .padding(.horizontal, 8) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true, width: 1)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 1, y: 1) + } +} + +// MARK: - Preview + +#Preview { + MacOS9Screen(title: "Sistema") { + VStack(spacing: MacOS9Metrics.sectionSpacing) { + MacOS9SectionHeader(title: "Métricas", systemImage: "waveform") + + LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 8) { + MacOS9StatCard( + title: "Uptime", value: "2d 4h", icon: "clock", color: MacOS9Colors.statusGreen) + MacOS9StatCard( + title: "CPU", value: "34%", icon: "cpu", color: MacOS9Colors.statusOrange) + MacOS9StatCard( + title: "RAM", value: "2.1 GB", icon: "memorychip", + color: MacOS9Colors.statusBlue) + MacOS9StatCard( + title: "Requests", value: "1.2k", icon: "arrow.up.arrow.down", + color: MacOS9Colors.primaryText) + } + + MacOS9EmptyState( + title: "Nenhum dado", message: "Verifique a conexão com o servidor.", + systemImage: "wifi.slash") + + MacOS9ErrorCard( + message: "Falha ao conectar ao servidor. Verifique as configurações de rede.") + + MacOS9LoadingView() + } + } +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9TextField.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9TextField.swift new file mode 100644 index 0000000..808ddf5 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9TextField.swift @@ -0,0 +1,88 @@ +import SwiftUI + +// MARK: - MacOS9TextField +// Classic Mac OS 9 text input: white bg, sunken bevel, 1px border. + +struct MacOS9TextField: View { + let placeholder: String + @Binding var text: String + var systemImage: String? = nil + @FocusState private var isFocused: Bool + + var body: some View { + HStack(spacing: MacOS9Metrics.inlineSpacing) { + if let symbol = systemImage { + Image(systemName: symbol) + .font(.system(size: 12)) + .foregroundStyle(MacOS9Colors.secondaryText) + } + TextField(placeholder, text: $text) + .font(MacOS9Typography.body()) + .foregroundStyle(MacOS9Colors.primaryText) + .focused($isFocused) + .tint(MacOS9Colors.selection) + } + .padding(.horizontal, 8) + .padding(.vertical, 6) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: false, width: MacOS9Metrics.bevelWidth)) + .overlay( + Rectangle() + .strokeBorder( + isFocused ? MacOS9Colors.selection : MacOS9Colors.border, + lineWidth: isFocused ? 2 : MacOS9Metrics.borderWidth + ) + ) + .animation(.linear(duration: 0.1), value: isFocused) + } +} + +// MARK: - MacOS9SearchField +// Variant with clear button + +struct MacOS9SearchField: View { + let placeholder: String + @Binding var text: String + + var body: some View { + HStack(spacing: MacOS9Metrics.inlineSpacing) { + Image(systemName: "magnifyingglass") + .font(.system(size: 11)) + .foregroundStyle(MacOS9Colors.secondaryText) + + TextField(placeholder, text: $text) + .font(MacOS9Typography.body()) + .foregroundStyle(MacOS9Colors.primaryText) + .tint(MacOS9Colors.selection) + + if !text.isEmpty { + Button { + text = "" + } label: { + Image(systemName: "xmark.circle.fill") + .font(.system(size: 11)) + .foregroundStyle(MacOS9Colors.secondaryText) + } + .buttonStyle(.plain) + } + } + .padding(.horizontal, 8) + .padding(.vertical, 6) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: false, width: 1)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + } +} + +// MARK: - Preview + +#Preview { + VStack(spacing: 12) { + MacOS9TextField(placeholder: "Callsign ou matrícula", text: .constant("")) + MacOS9TextField( + placeholder: "Servidor", text: .constant("10.0.1.50"), systemImage: "server.rack") + MacOS9SearchField(placeholder: "Buscar containers", text: .constant("nginx")) + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift new file mode 100644 index 0000000..0413342 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift @@ -0,0 +1,131 @@ +import SwiftUI + +// MARK: - MacOS9Theme +// Central entry point for the Mac OS 9 design system. +// Apply `.mac9Theme()` once at the root of the app to set system-wide appearance. + +extension View { + /// Apply Mac OS 9 theme globally: forces light mode, sets background colour, + /// and configures navigation/tab bar appearance. + func mac9Theme() -> some View { + self + .preferredColorScheme(.light) + .tint(MacOS9Colors.selection) + .background(MacOS9Colors.windowBackground) + .onAppear { MacOS9Theme.applyAppearance() } + } +} + +// MARK: - Appearance configuration (UIKit) + +enum MacOS9Theme { + + /// Call once at app launch to style UIKit navigation bars, tab bars, etc. + static func applyAppearance() { + configureNavigationBar() + configureTabBar() + configureToolbar() + configureProgressView() + configureSwitch() + } + + // MARK: Navigation Bar + + private static func configureNavigationBar() { + let uiTitleFont = + UIFont(name: "Charcoal", size: 14) ?? UIFont.systemFont(ofSize: 14, weight: .medium) + + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = UIColor(MacOS9Colors.titleBar) + appearance.shadowColor = UIColor(MacOS9Colors.border) + appearance.titleTextAttributes = [ + .font: uiTitleFont, + .foregroundColor: UIColor(MacOS9Colors.primaryText), + ] + appearance.largeTitleTextAttributes = [ + .font: UIFont(name: "AppleGaramond-Light", size: 28) + ?? UIFont.systemFont(ofSize: 28, weight: .light), + .foregroundColor: UIColor(MacOS9Colors.primaryText), + ] + + UINavigationBar.appearance().standardAppearance = appearance + UINavigationBar.appearance().scrollEdgeAppearance = appearance + UINavigationBar.appearance().compactAppearance = appearance + UINavigationBar.appearance().tintColor = UIColor(MacOS9Colors.selection) + } + + // MARK: Tab Bar + + private static func configureTabBar() { + let appearance = UITabBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = UIColor(MacOS9Colors.titleBar) + appearance.shadowColor = UIColor(MacOS9Colors.border) + + let normalFont = UIFont(name: "Geneva", size: 10) ?? UIFont.systemFont(ofSize: 10) + let itemAppearance = UITabBarItemAppearance() + itemAppearance.normal.titleTextAttributes = [ + .font: normalFont, + .foregroundColor: UIColor(MacOS9Colors.secondaryText), + ] + itemAppearance.selected.titleTextAttributes = [ + .font: normalFont, + .foregroundColor: UIColor(MacOS9Colors.primaryText), + ] + itemAppearance.normal.iconColor = UIColor(MacOS9Colors.secondaryText) + itemAppearance.selected.iconColor = UIColor(MacOS9Colors.primaryText) + + appearance.stackedLayoutAppearance = itemAppearance + appearance.inlineLayoutAppearance = itemAppearance + appearance.compactInlineLayoutAppearance = itemAppearance + + UITabBar.appearance().standardAppearance = appearance + UITabBar.appearance().scrollEdgeAppearance = appearance + UITabBar.appearance().tintColor = UIColor(MacOS9Colors.primaryText) + } + + // MARK: Toolbar + + private static func configureToolbar() { + let appearance = UIToolbarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = UIColor(MacOS9Colors.titleBar) + appearance.shadowColor = UIColor(MacOS9Colors.border) + UIToolbar.appearance().standardAppearance = appearance + UIToolbar.appearance().scrollEdgeAppearance = appearance + UIToolbar.appearance().tintColor = UIColor(MacOS9Colors.primaryText) + } + + // MARK: Progress View + + private static func configureProgressView() { + UIProgressView.appearance().progressTintColor = UIColor(MacOS9Colors.statusBlue) + UIProgressView.appearance().trackTintColor = UIColor(MacOS9Colors.panelBackground) + } + + // MARK: Switch + + private static func configureSwitch() { + UISwitch.appearance().onTintColor = UIColor(MacOS9Colors.statusBlue) + } +} + +// MARK: - GlassSection Mac9 Replacement +// GlassSection is used across the app — redirect it to a Mac OS 9 VStack. + +struct GlassSection: View { + let spacing: CGFloat + @ViewBuilder let content: Content + + init(spacing: CGFloat = MacOS9Metrics.sectionSpacing, @ViewBuilder content: () -> Content) { + self.spacing = spacing + self.content = content() + } + + var body: some View { + VStack(spacing: spacing) { + content + } + } +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift new file mode 100644 index 0000000..6e782b5 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift @@ -0,0 +1,135 @@ +import SwiftUI + +// MARK: - MacOS9TitleBar +// Classic Mac OS 9 title bar with decorative stripe pattern, +// close button (left), zoom button (right), and Charcoal title text. + +struct MacOS9TitleBar: View { + let title: String + var isActive: Bool = true + var onClose: (() -> Void)? = nil + var onZoom: (() -> Void)? = nil + + var body: some View { + ZStack { + // Background + Rectangle() + .fill(isActive ? MacOS9Colors.titleBar : MacOS9Colors.panelBackground) + + // Decorative stripes (left side) + GeometryReader { geo in + HStack(spacing: 0) { + // Left stripes — from edge to button cluster + stripeRegion() + .frame(width: 36) + + Spacer() + + // Right stripes — from right button to edge + stripeRegion() + .frame(width: 36) + } + .frame(height: geo.size.height) + } + + // Main content: close — title — zoom + HStack(spacing: 4) { + // Close button + Mac9TitleBarButton(symbol: "xmark", action: onClose) + .padding(.leading, 4) + + Spacer() + + // Title text + Text(title) + .font(MacOS9Typography.windowTitle()) + .foregroundStyle( + isActive ? MacOS9Colors.primaryText : MacOS9Colors.secondaryText + ) + .lineLimit(1) + .minimumScaleFactor(0.7) + + Spacer() + + // Zoom / collapse button + Mac9TitleBarButton(symbol: "plus", action: onZoom) + .padding(.trailing, 4) + } + } + .frame(height: MacOS9Metrics.titleBarHeight) + // Bottom separator line + .overlay(alignment: .bottom) { + Rectangle() + .fill(MacOS9Colors.border) + .frame(height: MacOS9Metrics.borderWidth) + } + // Inset bevel on title bar itself + .overlay(Mac9BevelBorder(isRaised: true, width: 1)) + } + + // MARK: - Decorative stripe block + @ViewBuilder + private func stripeRegion() -> some View { + Canvas { ctx, size in + let stripeH: CGFloat = 1 + let gap: CGFloat = 2 + var y: CGFloat = 3 + while y < size.height - 3 { + let rect = CGRect(x: 0, y: y, width: size.width, height: stripeH) + ctx.fill(Path(rect), with: .color(MacOS9Colors.bevelHighlight)) + let rectD = CGRect(x: 0, y: y + stripeH, width: size.width, height: stripeH) + ctx.fill(Path(rectD), with: .color(MacOS9Colors.bevelShadow)) + y += gap + stripeH * 2 + } + } + .allowsHitTesting(false) + } +} + +// MARK: - Title Bar Square Button + +private struct Mac9TitleBarButton: View { + let symbol: String + let action: (() -> Void)? + @State private var isPressed = false + + var body: some View { + Button { + action?() + } label: { + Image(systemName: symbol) + .font(.system(size: 8, weight: .bold)) + .foregroundStyle(MacOS9Colors.primaryText) + .frame(width: 16, height: 16) + .background( + Rectangle() + .fill( + isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.windowBackground) + ) + .overlay(Mac9BevelBorder(isRaised: !isPressed, width: 1)) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: 1) + ) + } + .buttonStyle(.plain) + .onLongPressGesture( + minimumDuration: 100, + pressing: { pressing in isPressed = pressing }, + perform: {} + ) + .disabled(action == nil) + } +} + +// MARK: - Preview + +#Preview { + VStack(spacing: 0) { + MacOS9TitleBar(title: "ADS-B Tracker", isActive: true) + MacOS9TitleBar(title: "Sistema", isActive: false) + MacOS9TitleBar(title: "Radar", isActive: true, onClose: {}, onZoom: {}) + } + .padding() + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift new file mode 100644 index 0000000..d713803 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift @@ -0,0 +1,138 @@ +import SwiftUI + +// MARK: - Mac OS 9 Typography System +// Font hierarchy from the Figma reference (modelos macos9.html) +// +// REQUIRED FONT FILES (place in Resources/Fonts/ and add to Xcode target): +// AppleGaramond-Light.ttf → editorial titles +// AppleGaramond-LightItalic.ttf → editorial italic +// AppleGaramond.ttf → regular +// AppleGaramond-Bold.ttf → bold +// Charcoal.ttf → headings / menus / title bars +// Geneva.ttf (or GENEVA.TTF) → body / labels / lists +// +// Run `MacOS9Typography.debugAvailableFonts()` in console to validate loading. + +public enum MacOS9Typography { + + // MARK: PostScript font names + // These are the PostScript names (not file names) iOS requires. + private static let garamondLight = "AppleGaramond-Light" + private static let garamondRegular = "AppleGaramond" + private static let garamondBold = "AppleGaramond-Bold" + private static let garamondItalic = "AppleGaramond-LightItalic" + private static let charcoal = "Charcoal" + private static let geneva = "Geneva" + + // MARK: Fallbacks + private static let garamondFallback = "Georgia" + private static let charcoalFallback = "Helvetica Neue" + private static let genevaFallback = "Helvetica Neue" + + // MARK: - Font Accessors + + /// Safe font loader — uses PostScript name, falls back gracefully. + public static func font(_ postScriptName: String, fallback: String, size: CGFloat) -> Font { + if UIFont(name: postScriptName, size: size) != nil { + return Font.custom(postScriptName, size: size) + } + return Font.custom(fallback, size: size) + } + + // MARK: Apple Garamond (Editorial titles) + + /// Apple Garamond Light, 24pt — hero editorial title (like HTML reference) + public static func editorialTitle(_ size: CGFloat = 24) -> Font { + font(garamondLight, fallback: garamondFallback, size: size) + } + + /// Apple Garamond, 18pt — section title + public static func editorialHeading(_ size: CGFloat = 18) -> Font { + font(garamondRegular, fallback: garamondFallback, size: size) + } + + /// Apple Garamond Bold + public static func editorialBold(_ size: CGFloat = 16) -> Font { + font(garamondBold, fallback: garamondFallback, size: size) + } + + /// Apple Garamond Light Italic + public static func editorialItalic(_ size: CGFloat = 16) -> Font { + font(garamondItalic, fallback: garamondFallback, size: size) + } + + // MARK: Charcoal (Headings, title bars, menus) + + /// Charcoal 12pt — window / section headline (HTML: "Headlines for titles & sections") + public static func windowTitle(_ size: CGFloat = 14) -> Font { + font(charcoal, fallback: charcoalFallback, size: size) + } + + /// Charcoal 10pt — menu label / small heading (HTML: "Small headlines for menus") + public static func menuLabel(_ size: CGFloat = 12) -> Font { + font(charcoal, fallback: charcoalFallback, size: size) + } + + // MARK: Geneva (Body, labels, lists) + + /// Geneva 10pt — primary body text (HTML: "Body text for most content") + public static func body(_ size: CGFloat = 13) -> Font { + font(geneva, fallback: genevaFallback, size: size) + } + + /// Geneva 10pt bold, letter-spaced — highlighted body text + public static func bodyBold(_ size: CGFloat = 13) -> Font { + font(geneva, fallback: genevaFallback, size: size) + } + + /// Geneva 9pt — smaller body / list items + public static func caption(_ size: CGFloat = 11) -> Font { + font(geneva, fallback: genevaFallback, size: size) + } + + /// Geneva 7pt — disclaimer / fine print + public static func finePrint(_ size: CGFloat = 9) -> Font { + font(geneva, fallback: genevaFallback, size: size) + } + + // MARK: - Debug Helper + + /// Call this from a debug view or console to verify font loading. + public static func debugAvailableFonts() { + let targets = [ + garamondLight, garamondRegular, garamondBold, garamondItalic, charcoal, geneva, + ] + for name in targets { + let loaded = UIFont(name: name, size: 12) != nil + print("[MacOS9Typography] \(loaded ? "✓" : "✗") \(name)") + } + } +} + +// MARK: - SwiftUI Font Modifiers + +extension View { + /// Apply Apple Garamond editorial title style + func mac9EditorialTitle(_ size: CGFloat = 24) -> some View { + self.font(MacOS9Typography.editorialTitle(size)) + .foregroundStyle(MacOS9Colors.primaryText) + } + + /// Apply Charcoal window title style + func mac9WindowTitle(_ size: CGFloat = 14) -> some View { + self.font(MacOS9Typography.windowTitle(size)) + .foregroundStyle(MacOS9Colors.primaryText) + } + + /// Apply Geneva body style + func mac9Body(_ size: CGFloat = 13) -> some View { + self.font(MacOS9Typography.body(size)) + .foregroundStyle(MacOS9Colors.primaryText) + } + + /// Apply Geneva caption style + func mac9Caption(_ size: CGFloat = 11) -> some View { + self.font(MacOS9Typography.caption(size)) + .foregroundStyle(MacOS9Colors.secondaryText) + } +} diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift new file mode 100644 index 0000000..fbed990 --- /dev/null +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift @@ -0,0 +1,60 @@ +import SwiftUI + +// MARK: - MacOS9Window +// Main window container with title bar, bevel, hard shadow. + +struct MacOS9Window: View { + let title: String + var isActive: Bool = true + var showTitleBar: Bool = true + var onClose: (() -> Void)? = nil + @ViewBuilder let content: Content + + var body: some View { + VStack(spacing: 0) { + if showTitleBar { + MacOS9TitleBar(title: title, isActive: isActive, onClose: onClose) + } + content + .frame(maxWidth: .infinity) + } + .background(MacOS9Colors.windowBackground) + .overlay(Mac9BevelBorder(isRaised: true, width: 2)) + .overlay( + Rectangle() + .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) + ) + .shadow( + color: MacOS9Colors.dropShadow, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + } +} + +// MARK: - Preview + +#Preview { + ScrollView { + VStack(spacing: 20) { + MacOS9Window(title: "ADS-B — Aeronaves") { + VStack(alignment: .leading, spacing: 8) { + Text("N12345 — Boeing 737") + .mac9Body() + Text("ALT 35,000 ft • GS 480 kts") + .mac9Caption() + } + .padding(MacOS9Metrics.windowPadding) + } + + MacOS9Window(title: "Sistema", isActive: false) { + Text("CPU: 34% • RAM: 2.1 GB") + .mac9Body() + .padding(MacOS9Metrics.windowPadding) + } + } + .padding() + } + .background(MacOS9Colors.windowBackground) +} diff --git a/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift b/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift index f77c2e1..76ed5e9 100644 --- a/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift +++ b/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift @@ -1,95 +1,92 @@ import SwiftUI -// MARK: - Liquid Glass View Modifiers -// Native Liquid Glass styling for iOS 26+. +// MARK: - Legacy Liquid Glass Modifiers +// These methods previously used iOS 26 Liquid Glass (glassEffect). +// They now delegate to the Mac OS 9 design system in MacOS9Modifiers.swift. +// No call sites need to change — the visual output is the new Mac OS 9 bevel style. extension View { - // MARK: Cards - /// Primary glass card — used for section containers, hero cards, and key UI groups. - func glassCard(cornerRadius: CGFloat = 16) -> some View { - self - .background( - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill(Color.white.opacity(0.03)) - ) - .overlay( - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder(Color.white.opacity(0.14), lineWidth: 1) - ) - .glassEffect(in: .rect(cornerRadius: cornerRadius)) - } - - /// Tinted glass card — carries a subtle colour accent (for colored sections like CPU, Memory, etc.). - func glassCard(tint color: Color, cornerRadius: CGFloat = 16) -> some View { - self - .overlay( - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder(color.opacity(0.35), lineWidth: 1.5) - ) - .glassEffect(.regular.tint(color.opacity(0.15)), in: .rect(cornerRadius: cornerRadius)) - } - - /// Lightweight material card — for repeated list items where full glass is expensive. - func materialCard(cornerRadius: CGFloat = 12) -> some View { - self - .background( - .ultraThinMaterial, - in: RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - ) - .overlay( - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder(Color.white.opacity(0.10), lineWidth: 1) - ) - } + // glassCard, materialCard, glassCard(tint:) → defined in MacOS9Modifiers.swift - // MARK: Interactive Glass + // MARK: Interactive (now Mac OS 9 raised panel press animation) - /// Interactive glass — for prominent floating action elements. Scales/shimmers on press. + /// Was: glassEffect.interactive. Now: raised Mac OS 9 panel. func glassInteractive(cornerRadius: CGFloat = 16) -> some View { - self.glassEffect(.regular.interactive(), in: .rect(cornerRadius: cornerRadius)) + self.mac9Panel() } - // MARK: Adaptive Button Styles + // MARK: Button Styles - /// Applies `.buttonStyle(.glass)` — translucent secondary glass button. + /// Was: .buttonStyle(.glass). Now: Mac OS 9 plain button wrapper. func adaptiveGlassButton() -> some View { - self.buttonStyle(.glass) + self.buttonStyle(Mac9ButtonStyle()) } - /// Applies `.buttonStyle(.glassProminent)` — opaque primary glass button. + /// Was: .buttonStyle(.glassProminent). Now: Mac OS 9 default button style. func adaptiveGlassProminentButton() -> some View { - self.buttonStyle(.glassProminent) + self.buttonStyle(Mac9ProminentButtonStyle()) } } -// MARK: - Floating Bar Glass +// MARK: - Mac OS 9 Button Styles -/// A modifier for full-width floating status/info bars on maps. -struct FloatingBarGlass: ViewModifier { - var cornerRadius: CGFloat = 0 - - func body(content: Content) -> some View { - content - .glassEffect(.regular, in: .rect(cornerRadius: cornerRadius)) +struct Mac9ButtonStyle: ButtonStyle { + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(MacOS9Typography.menuLabel()) + .foregroundStyle(MacOS9Colors.primaryText) + .padding(.horizontal, MacOS9Metrics.buttonPaddingH) + .padding(.vertical, MacOS9Metrics.buttonPaddingV) + .frame(minHeight: 36) + .background( + configuration.isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.windowBackground + ) + .overlay(Mac9BevelBorder(isRaised: !configuration.isPressed, width: 1)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .shadow( + color: configuration.isPressed ? .clear : MacOS9Colors.dropShadow, + radius: 0, x: 1, y: 1 + ) + .offset(x: configuration.isPressed ? 1 : 0, y: configuration.isPressed ? 1 : 0) } } -// MARK: - Glass Section Container +struct Mac9ProminentButtonStyle: ButtonStyle { + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(MacOS9Typography.menuLabel()) + .foregroundStyle(MacOS9Colors.primaryText) + .padding(.horizontal, MacOS9Metrics.buttonPaddingH) + .padding(.vertical, MacOS9Metrics.buttonPaddingV) + .frame(minHeight: 36) + .background( + configuration.isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.titleBar + ) + .overlay(Mac9BevelBorder(isRaised: !configuration.isPressed, width: 2)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .shadow( + color: configuration.isPressed ? .clear : MacOS9Colors.dropShadow, + radius: 0, x: 1, y: 1 + ) + .offset(x: configuration.isPressed ? 1 : 0, y: configuration.isPressed ? 1 : 0) + } +} -/// Wraps children in a `GlassEffectContainer` for optimised rendering of multiple glass shapes. -struct GlassSection: View { - let spacing: CGFloat - @ViewBuilder let content: Content +// MARK: - Floating Bar (maps, status bars) - init(spacing: CGFloat = 12, @ViewBuilder content: () -> Content) { - self.spacing = spacing - self.content = content() - } +/// Floating bar for MapView overlays — now Mac OS 9 panel style. +struct FloatingBarGlass: ViewModifier { + var cornerRadius: CGFloat = 0 - var body: some View { - GlassEffectContainer(spacing: spacing) { - content - } + func body(content: Content) -> some View { + content + .background(MacOS9Colors.windowBackground.opacity(0.92)) + .overlay(Mac9BevelBorder(isRaised: true, width: 1)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 2, y: 2) } } + +// NOTE: GlassSection is defined in MacOS9Theme.swift +// NOTE: glassCard / materialCard are defined in MacOS9Modifiers.swift diff --git a/MeuLabApp/Info.plist b/MeuLabApp/Info.plist index d3c9fe2..5cf2536 100644 --- a/MeuLabApp/Info.plist +++ b/MeuLabApp/Info.plist @@ -53,5 +53,14 @@ fetch remote-notification + UIAppFonts + + AppleGaramond-Light.ttf + AppleGaramond-LightItalic.ttf + AppleGaramond.ttf + AppleGaramond-Bold.ttf + Charcoal.ttf + Geneva.ttf + diff --git a/MeuLabApp/MeuLabApp.swift b/MeuLabApp/MeuLabApp.swift index 0909466..5dd23ed 100644 --- a/MeuLabApp/MeuLabApp.swift +++ b/MeuLabApp/MeuLabApp.swift @@ -18,10 +18,12 @@ struct MeuLabApp: App { .environmentObject(appState) .environmentObject(pushManager) .environmentObject(notificationFeed) + .mac9Theme() .onAppear { scheduleDeferredStartup() } - .onReceive(NotificationCenter.default.publisher(for: .pushNotificationReceived)) { notification in + .onReceive(NotificationCenter.default.publisher(for: .pushNotificationReceived)) { + notification in handlePushNotification(notification) } .onChange(of: scenePhase) { _, newPhase in @@ -85,7 +87,8 @@ struct MeuLabApp: App { private func handlePushNotification(_ notification: Notification) { guard let userInfo = notification.userInfo, - let category = userInfo["category"] as? String else { + let category = userInfo["category"] as? String + else { return } @@ -93,13 +96,17 @@ struct MeuLabApp: App { switch category { case "adsb_alert": // Navega para tab ADS-B ou Radar - NotificationCenter.default.post(name: .navigateToTab, object: nil, userInfo: ["tab": "radar"]) + NotificationCenter.default.post( + name: .navigateToTab, object: nil, userInfo: ["tab": "radar"]) case "acars_alert": - NotificationCenter.default.post(name: .navigateToTab, object: nil, userInfo: ["tab": "acars"]) + NotificationCenter.default.post( + name: .navigateToTab, object: nil, userInfo: ["tab": "acars"]) case "weather_alert": - NotificationCenter.default.post(name: .navigateToTab, object: nil, userInfo: ["tab": "weather"]) + NotificationCenter.default.post( + name: .navigateToTab, object: nil, userInfo: ["tab": "weather"]) case "satellite": - NotificationCenter.default.post(name: .navigateToTab, object: nil, userInfo: ["tab": "satellite"]) + NotificationCenter.default.post( + name: .navigateToTab, object: nil, userInfo: ["tab": "satellite"]) default: break } diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset.backup_old/Contents.json b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset.backup_old/Contents.json new file mode 100644 index 0000000..82f5bf1 --- /dev/null +++ b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset.backup_old/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "Icon-1024.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-1024.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset.backup_old/Icon-1024.png similarity index 100% rename from MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-1024.png rename to MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset.backup_old/Icon-1024.png diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json index 82f5bf1..cc01fb0 100644 --- a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,14 +1,116 @@ { - "images" : [ + "images": [ { - "filename" : "Icon-1024.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" + "size": "20x20", + "idiom": "iphone", + "filename": "Icon-App-20x20@2x.png", + "scale": "2x" + }, + { + "size": "20x20", + "idiom": "iphone", + "filename": "Icon-App-20x20@3x.png", + "scale": "3x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "Icon-App-29x29@2x.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "Icon-App-29x29@3x.png", + "scale": "3x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "Icon-App-40x40@2x.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "Icon-App-40x40@3x.png", + "scale": "3x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "Icon-App-60x60@2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "Icon-App-60x60@3x.png", + "scale": "3x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "Icon-App-20x20@1x.png", + "scale": "1x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "Icon-App-20x20@2x.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "Icon-App-29x29@1x.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "Icon-App-29x29@2x.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "Icon-App-40x40@1x.png", + "scale": "1x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "Icon-App-40x40@2x.png", + "scale": "2x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "Icon-App-76x76@1x.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "Icon-App-76x76@2x.png", + "scale": "2x" + }, + { + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon-App-83_5x83_5@2x.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon-App-1024x1024@1x.png", + "scale": "1x" } ], - "info" : { - "author" : "xcode", - "version" : 1 + "info": { + "author": "xcode", + "version": 1 } -} +} \ No newline at end of file diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..7f7f6087769db21cbc060cf46607f388018ccccd GIT binary patch literal 50042 zcmeFZcT^Ky^fo#P9Rx%XlrEs+i--k8MMx|(QL2h`6_qALq_-q0MMa9Jpdg@tqEwL* zdJt4>NC&B*NN=Hsl$m?R_t)0_?)~q(f84dcti^INGdZ)*KD#{o*=M|OW?~>LC?yC% zkg$>ADGLbV28Y}bKQH))B&&KCg6fYOojQIl;Kd9l^u@W+lyQWbJoiSdT=WVTuZ^A$ zzsb$39j~I_W|YCh>LztN_wPR_>OJ!8r`uKU%Bf#l4`!VCqP$5{s_WCY>xW_NjKg`m3NloFOIHJ3dTpwMJJ}REwge6*#l|Q z-u6~)`Sz8lXb|+k<6O_Kzemup0p{-kdDF{(Pv8a2{ylift@7`I8CLw?0~HK9N$`0B z@%(#mnvDJTU% ze&_-J30-i(?2I^{f;pt3iN&GcOvJgr-^b#=ZDgWm^~`*Oil`v8`}wiJ1IJ~+3B2pd z%8Ge_;nqs<1$_RuStt+~ZwYKn&LP<@~@ zcNM#LIV{~z z+x_dFs4TQ?a5VAupeQ)2@T1Cyt63m!?@`D?|L=Wf+zz*dQlQCnC{D2sRR~$}6@Q$^ z8H}M(hJ4VSzh{oQYwRFTLfUwGhaSTPZFVjGbOfK?qzjSYCbPxrF|gfuzxS+PH=yXNGLXax#7V^ zxGUHC@#=2$0XMzIo;$w@70gd1GF`h&$Us5k{6bt`qOka%i(6p<7Ptow|E`X0vN0zs z;wx03Pb%s|X|?DB#UHO!6D0((;+WQYDQN$%v2*+EgCpUWGcj4f$lD-G&F* z&O?c^=s*=e%N6qS$@(eKJvkoo*0S?Ct%AtqyCeylaBvwqEW}Kul{reyulGNI&hVi3 z+`Fd6=37_7|3-Da*f1Abm3A!d!ge6aEfq-oS(>BY2~>4v$Hvyy9hN>OX}TYHDyo7# z6^X^4h?n84F{4smJG!BRFDzPaFszU!uR!s~F$$Q=^*Aa&dVW#i%tF6 zoS`9+IjN3YQayv z=AB^*6^R0S$KJQTKB!+Y$^?C-*pks`9ESw0Z717zIrx?@TT zw()NnqQb(H@3K-`qmnzP2~;2VH&GCf#ws|t(r>os=?^S9B_TngF;&O*LPV)Y z@0+=~xr$yL)=UvPxuBpR7m9xVLJ%)>kBf)=@Z~?e(650*UfG_NvxnL=>noOi5vG!9 z?CXuQ5fKr^*M3N(__P|uMC}B@)D@XKKHI|zo~2P8<2C$dE~eb96S)0GbooYieiwz% z^1IMU(|^vcq@-kBSKn^@x<9+ikz~(Wo9_~6Gim?1IV)WEy7WKX3ZxKn+yNEaO!g9eFqw~YGtZt!B?fbiWZfn(1% z+`KN%14$bFLiiw!Lx&H)RkJNUhx2rGeaCB4-~P^W$9a9vwV7_EcOQZ{1QM$^qG5h+ z?t;HR%n16QZz6Rdjzi`pN&&!~{ z%Xww-hq`-Dv8yi+`E43VHyzwcE@&PfTI-u(v&V7%8ya?{_*f`6CCYPgaWUl`E52#6lUHVc=k*e( z_MxGnr41FF)n4fcQvLE|n1Nkb*IYJkSLsRwPd!U;1gCGV{nl z?p>v4OS)c%2&63}vB%8WIcuyjIjhjA;dH#8=X6&rY4vUeXI7rbxE#uCOX~#I?epiW z;mO}?B!+!&UA;V~MSk+rX4CcrHQVK08r)fuaxCAwXylrYw$U1mM4k06a%oXa@%plD zYIe4xUKD4yB!fCG%$o0_u^VaUDvv&N>fW;H;Uw4W>@0fEQWMTmZIg`m&%z`PSBw5b z5507duOII7sKh!yf*gwQVy$k4fxn>Pl@jubtppG zr{lcUc^o|FPt6(qkr>SENk6Kk^*A;;)08-D8PpU!kkQ$B!DFDxx}b&~k+l?M;ppht zFU4cQS@Q3`mN+?;Q;@$Kn+w)b+kdW|u`uF0(Y(FENzJC%(0?E>>r1S>qc_LWROfX^ zj#XE`?)`Cjh@ATpBAI9jOkI_CB|Rf`c`W9m`#r?&|8l{_DjN%^}~WRGo^M4?mVCGGcoqgmQuW zyVTUwm;+qMMem0^LJ}??@9+pWsku#e6%j`rtI@7WV4?-AR2=XJ9cAk0mvZh8?XRXiMms0*G z-Z&c}fml)E)F5Ki`fXR*%sXgfNBNO*_TrBmj34-ILG@}9lf~L`UgGo(5090Qn9JQd zq$o-Ce3-^&cjujbAGmZ~7TAjvj#xEYh(_Y zw0Y;5_c{p+B_hJY-4UdBi<-&Qxw5~3Aj}?;Q7++85Q4CHC)CiSJV}lfc{}YouiqSPzB099AQ|tjobBy> z!1v23qgGI@ZW3i*2wt1ZtNay^%4E4WH3m2|t}dUS!+8w{u$*M8n|`He>rh4;{>K0A z(WFd?BiD@mgR9&y(1Cf6%~_p4HN2e*W5xpl9w9^#J1H1gJ`MqO9kC<|K0e1WFgJ2-iKzkdV!uM`dB~e^lbb- z&%UyX>4)Rrm?7Jma=IDcp0X&VrQPyBhJuHb|N6t8SHK@G_bMycrq8)ZNlCSWfFmP$ zAEXf0@@>%&JVarADoO970#l z>u`DHJEK@9yBr4jKs|IhL*BPP zbrwLj7NcD$nF9k3E6dAoK{^t}v2WHlXh^UR+E)7I5t-_-Q@P#-*h!F}GZGz%-Q!l` zbA7Fg*AbJ@wMyDkU)ca{ z@0L{0Y68d?Y%j zLc&M;py`V@N4&?{W#^Z))Y{VZqBH;?_2{oS4`BbQ4{V-lYl8~0IQm0+Ait={62O$s zx^SWC)HIOQ9l(6cl_#UM2AYeSbZyr(o1P!cI(n2!pkW%Y&EKD@uKeDNyb)?*J)ZJS z)*^KFl(?7N9I8v|l^9y*GrLjcZ_us+J$cxr^%{!fGr7&KA(h!8R9xuA-cpaY;m=Xi zC$0bpp-XD}kTkthUdt#{+fOUxr@L;DM}O#!4xNa^5xr1P>qFPRi)(6WO=rk+-X0=^ zmXA$ulak7w-muTz)wPAj>8G8?4V1ViDx=Ax6Cl|x9W5}Bwj2TA&ZBc>BkgT%mf7R- zc-@5oS#u|0Pyysuv-;=rE9XWN9Xr9qa=ty@H4T`7E}$N}*cJfB&}5Y=M;N=`CRO^# z-^XX-%QZ*0fZVrDYCi_xRf>COt~Ck@JndF@pvX0gRZ?6$Ax&dMn1FKK=;;*5mvUg$(grM+cflno}jhLGf>>(_xu9bu2-xF1$7{%QvmvY z?OsrQ0WA&Cgx~e68bE+h&a`7!lzPp?`u@bd_Su_F4j-ol(@7mVb3pLrl7i5)>eb8f zSx!J{f%}#|xiXnF+A9OOz*8uuD$SS%X{-Wd1m8x@E|=Ar?v824;5kS2$ft@5BbdDJa7!j@p)nE{3r7NcalpWU_*IpMC z6jX3tZZ~bhL79`&jz~r3qe+3z5_`ZwOeXaPf72%ZR$F#+2KXlk@G{9#v=4R@09lFG z&GlDmYG|CJr1XKPmGjYkexN!DMJj}*8I)LE_IIvSk7GN$ST7lTCH z)DXq&TfBs(-}jgA_Vo5@0`*jkH@|o9+6#izMDweYF%3t3Cd^hYj;E1oMhbsg^8ftK z0Hn+JNHjA)_M7?rN>i>J?#{$Q(6(-R};$09=ZjdP*ahO z8XFKPT3XA*>C3|wI{p3XT>msHz&thC*GJopNY(NLRZB-(TZTt(scT=Emz#&j`F~3p zO;9O-l&$SKKH-y_nkpA9r&GZ^CU@l4DFCgdwr;(-NAb@jikejbbxUqN;xiF9?ef9V zAV#JI%vI5KAqGseE({kXR=_OG}h0hPI=>bFZ-!$HTQ3U_*^l$AU@)7_42$A5& zWSN&J0R=&W-5~3>>GE)&;=})1_<<5L5dDq_`VR!1CX0||Pz@_jf-GRPeg-}Hq{Wfb z;rKdKke~ctxBdT@WJVd#R^Q3jiD>QspG_#L1;>U0D8~gp|AQ{x4ZSVATpv+viY@>? z%tU9U9UN~vj)BhWGYFGq$3_pLS2l)=`o*+?6oHZ^#il&lYX4(>{=XyRU5r@Vae8OL zT+olg6~JPkpZ}e-D;SRdjsFV8GI(Y+Jk4;n5Ch@&p%eRhPlK!4k=XR~4wyVzG)e!J zL;S-06st`){9M_V4Ly<$DTB{}JPzm&?p?G#Ni_3plKc#QkdBfz32-*AZ)ehf+~*F^fXYPLVG8XeIdcaq!&_ z9sTvGL3MdSEJXf*)^94&>EZCNU%%SrDsysFOB!MxtdHNm0-R?9%D4%t#@@y?n$1V1 zE&V)MNS*_$x(#ivh@b8}NpipvpGbu^TJPD|3`{{q5j>IH_v6Zhx>K|0_sR0_r!SMy zfmG0eZtYfmg_OCExzAPHe|K#4%R1-XvHZ+aHP)h}(~rl^KQo(xd_ySA2pwxaX>c)GOTgTE{Oh<)5^9Z+WvX?m{AYeLMk( zs^I>25T(gx`3^ScSU4wG?xKnj^G9r+$@&?oqF{%+MCwnT+nJqWFSmkaMH^=1_8r^U zjmP(W{d>RSgLIWk_67>~=b$(IpvWNu{VQl1@gV#1INb0|5iyo6!5zPc*9=_DypLWq zHwuHn#Xv#!j|+YbswL?jD=GJ4kL(oeC1|3RNqIM43ks5>b##G zDLigO4~nr?5$9Ipf0iYvY`)>;MqoM8fKA2c4sU=1g*k!z40G4zk~iiG`$$O9x&Lv) z9&m&H#w96cn;`p|AoKVU9Rs5+ymx%~o<(82a<}2P11pn6XZKZEj9Gp9=yKMURSxfH zu-r4L3F395kUYQGN2knd3I6yOLi`_0z&zYg%X;;B3!AfdEb-h#tTyC)d7w%fH!eBq z{nW=?!DYWf%xSCZHEv)&q&$sMwYB12kTP{*37iv&>m(y&gIU_-y z9C5DU7mE8V_{(;-j$onhw}HZHDP?y_N?wuhTP*4M9io{@lX>&}@l8A!+-EXF5c8CF zT<|}QA>{s1HtTt>ycIoGk-m8~1zXFBJj)8@VH`Z2^xtO{sG#-9Ke zFR6YXocGm4a>IyN5>fB`#(TrgweD8<_DViURQt*Rs+EYCp!@k4M>_e;=`7H#dYY2lh?gWPE_Jnfd6N>lUu6+|7TNatl~WGYj)D zB$t0L>2+Umt@cEG00rP04zn|Y1IUto`a@rMqyFDga5ObL#nkfw) z2Oz^tSTo z;)DcP6Z~P%a7c;W6ih9i+D>ZlRpkz|mcDfLbZu4$O%gom4bbD4Z~-JGCFM~#>D{4+ zzoYT3Q=+GGTISn7Je5uDq`kkzg6*65c$R{5C9MCyuqMszS>U9EBSql>5?k|DL9NhMKV$)n%_z* zr~nI4u>C8@r;f#Ws|+6a!k*ddf8-70`b$X;oqY7D-5AL125=n(r8_l7F}Ge(^_3z` zF5le?Dd>3laQzl2!Ycr0_{s~+Fz&;E^StmDc$V8^-G5l4)ld@Jh^uTN<-D!L3_shn zaf~1f{cSoa=vlk0`%7!ULwIH%(K%y=_tI%#GMhn)b|0<_H{O((Tg=v8kYYDx z#EWCdE`i%Pl+C_c;by}GoeHaJ7_cd)H?&ttsd*KZtb+%bC5!C`V8;AYp3zG z)VmOQ5S?1xovO*`ic#8q+8`kk$Srl;0LcS3$bWPPSrLMifvMie?9ciXZtSIgyq?sj zh8)-Doec)B8v3SXn_5{vb!z5EG-$Y~1mtZC z4|LVC&k}nlUuff>c_pY82SnRgG~hfZAOp`{b#13T0FSPE`yY?C;YO3rLOSs5{esNv zhwjtmwJN}p{kS5APY13wjQYlvO@GebI2Xm)(Z5LeQcA|(^ooUT^^WYQHKBjT>;{G) zgHCV5oe1RZ7_0Yw#wbm|5<_O+b30A$t$@VA(n_N@d`fqiX^Pdbg;Sb&pn%8A6V&rB zEU_15HbNgz2R@~e_Ze=zvF?9D5*oDc8KT8~dIC{VJ40KC_*1PL5Wn~v>x3{MKQ8^n zrc04PX_;uPb4np<2q)Ak*T}u7pqhbP08jikoEV0Y2ta>}=$+z1z*zaWXVd4MUz4)R z%dFkjwVZ76wbmC5kj58qDZ^T_c9I|iY{>9}anCOD9=FphZnE7(=vXq)t~gx%z4tBk za>vR3Fl4J5HP}IM?NO$5zPanmI1$B~bHihA`4#e-O8Ph!iM{Trkd`_`2-k+{rCG<+X52S6ra#TRl+Bgkr6j z>xec}bIpH6j~qQe(Ivf>d)_#TLdmLb3V96X!$4OiM3K#RQj%Qseml){ux9*rc+I@i z*r;8<=Si=Zim^kqjb;2dul}LxiwzpKiD}BZwmy2Jl*FpMp9Cigp_+XNG)oo@LtLJe z3)K>SH`!cTy`}5vn9)D}VO2AIKTVIUR3d-KsAoBb*l3MAZjkg(+ObxjQ(3ubW@=c& z#dG{<{2V|*S?q^R@RAJsM<>sq=8U8oR2iz{*JRZF02?UB(K-lASR*DK;+PwEsNFx7 z23lXNY<9~(D2V}mD^!dyR1Cf_WMWI95P5wex;vEP@Bn*_H1OePzVxN;?;?2tj{c3l zV{}~hwW~_mR`AUN69=4wL4Lg6qS#cl`9|3_Zx3L2z}?ucVrDySTY#t6@XjZV#0C=P3uyp+J5_9dugh+D!SK zY)P*|ocdxj4}QWlZ9TA*h+AxxHEVAn6>XWH?))I{+ivI2X^EX@*5<^|)Kk5xJ;Vk- z_h@3JwqSs%LMV`_y-lOjy1T9YWrt|iot4mw6Ql&L>(*sww|#Zn|8m0+?IOJ?pI^bK zi*qSqj#DIOWHDXVSP_o$;FJaWyq3Pi zXuesZvaihl{TqIT^PN0pF5mQ+pPNXpN=r+pIQB0B|&&$j$KFo)feHjR$F z8{-+2w*IE4sl0S(_TP%B7ND%<9s9S`?qzJ|j>>BhzkQgBgv)UV8{z2Ba1H0(Eb~)! z+teI9PBHCVBLwBlF~K~fbTx9vTAn(21b4l>&aOD1Q>%ityEVB3Rg-zOX?-{*ttJ_G z?LDx>hKlSgwYj~}3ET$1&rk(6Tf03UM7e0c`am$fzMo>;~2EC&;~hM1{E$tl$x*yaG_Kd1zJwB1$9% zX|gFX9_G`(C8ASrJxuyiJoU`URwKwRC&@s|y|+^T0rpE0B&k;ZwnC2FYXeMQ5E#bk zrltwRtLvvI`*0Y^-#kM34vu{NUt7P^XoA!c9XqU;apHb2I9w$tlr7zxg^QN z6!g8}djdOuyIw>6qt2Gjff2fK@bbqd(}Li8olXXGT0u8Bw(UbF>zVzN+EZ_^FBXTn z&m!&EYOnd82zQL(86L>Y(+40=HLB9_%XQTL3EU9Xq1gkImr?R?RcX(3Q(RgMxh@*! z<42TwnH>>GOWs*GskUtSzLKK3%X=$_FGkDtS_mUwsQOyu{j#;5|J3eQH=(cWXc2&3 z=7Nx<^14`(qr}!;+ML7>-?M#o0>52@A5rsYEFGdQ7KAbq|MBLK*eU&*qAOnt+kBak zN85Wkb2~E{H2kp|(XM$C62KR!bLX10kz+;!U04t-U!oBg&jn2EurFpK`;kULIQc|0 z9L$gKQimL~AI{(wn{|zz(g}xWLkR^T13n=+onCnzisTj^g>`k{X5FB8H#i3=!V?WaT()4G<^n!l6`eFYY-<`$d zW9bBbX;`>Zv35C>F!4b(remqC+6Gy18Y2*0}+t%p4C4N)aYme za3=m|9#U>6|MHNf)ySPLI)Uw&&5gVqqCHz8?AhS5dVBiK)Ys$VCggzKI^2Y!ZIFN+TSR$Fui(C}(>Zyo9RJn#Erc7rTz z+nb~lPMUs!)HlrK!6ZiW`&p#XA$9FSzpo#OmSV;YnO#LWKIke>6#Tm0nC`e@rZpu0 zeB@dOX~emQam10hR&^uS`SL-U<1JCdL4x)8pCKAQ+-k_60ARznCOXOIKif`PpLcTe zM9{E?vqP@;d(E*LL|6qyZb`*OAI}0Vb^=Ixu^4tv?lLE-3Sz!yobl!Q*B@@zk*0qq zB++p}H;f1A>P7}4B2z4_j@U8MvNWNM{_1jn==>S}*N1t=0e_kDQ(k(smp_ z(tTa4iz>FHqN)dFHvRzUXJ;obeIqPPtf&6*0MS8>Ev*WZ=9fY{SZZcD5^vA@)3n=q zyQXW6_XFTeR=gqzk?R(;=Slf)wuk_-AaG!q@Z}sNeml^HyrBK)YcUkt%QjkwBq=eB zpVDzI%-=F_bRdk}Ik{ zif(8k$PvF5yf6v`R1I#&$2qoQu(XggoTtLApmtmznN{u)9^4ONuKU?NY|%OCTmb~A zp(g?@q%4w=<2JumcaG)PlnPwFy_kl#W5ja zq?7GKq??z@_Ogvj)R6ca_0$d{G6nvXsPr! znC9Chi!kMV4@Z#h_S4otg;yOs9y=|F0l-Rp8^Fx3ohb4eL%1Mw3Ol)lhph2Q3~p4M z<$bSwg*rrIP|pd#*8E7khQ_|!N?p2J|HvMexdBJg{qmasK!6V20uTp^0QX9twJZBG zH|*>a5r`~A9c0^rp%m|D@^AEFB#PTIa2f%pfb+Tl1A61{?{HLKGV0g>8_Lr+?m3Z@+_74$%6c zLra_;YjncT1%I2FCK=c^)+0{{@w*d2Ql-#Ir&AAoHTQ?L79 ze+rL^jY@0T>OKtu>rvM*l4=FCF;N+mS;r(XQej9!>GfW^<9b)>dxqB5A%xz1nUx2}5DUN1MrUaQcGV$_)}f>*Nza1KzIu>+0S=1W0Yad-+!8!; zIb}YL2iS+3YYYI!`9g#58y%&FkY@N5@Zd7iS4)PL?jgG+=YGv0+9gSN$7Fq?h&zj- z)tj2QeyH;VnYIGlmLI6@>+5|P>cwzmVt4|nXiwNdanpo4>POep8XDpgHg1CnzRJQqXz ziorfwTeb3ZCCl5w_j-i8^1Bk}-?HV1fuE1{SLH4SPh5MAe5baAk<|ZnkRuFQ=={$q z1P9;#ZdgO36NH)9zl`hp7aI=(@uxo;%tmdq81>D_$uYKgEmZ4*Al>b2ty_R80e_Cu zb}+ENlg}iK?qZYtM|XD^%TP>h6Y6ojSjE%UGMvP7M)d}nREI;0EdL)50#hmLId(}0 zH-peA(ka_}j7BwQP^3rwuhis~2Q<4_L0Uc-=&Llyj<-HHCFi}pz#%ASZ%kXcf={TY zZuh<{e6RIUk0{~L7K|r6JLb7YY8U`uYc;^W?Gt=}`u}P% zO>HyeoHy1wukKLRudCV*1qvb01wHWMdsI2SY7GDBvrnnpwfc`PYALxe2p;Y+d)QWY zsG$rk36?j*!eeb;tlKheE&#=5yyDQMjQc`~4;`u&+A3V>ZOnNIc0Hg1ogD5q95f|CVma zOGrsU^-d$^j5BTTx4{4OLw|;RpZ0_l?4J3|YQ{mm%4GKv^C%DG3UZUeQeD-%2Om~w zd)W=U8x`@X_0%o)(AOQJz%Rl`N;3szIR^2?GZo)ggN{qG9;XW-yh?0&xubSP9cic156=5^HV zn=gyd>$m@PJQEO?8EFL4$@paeUU)^2)|Nq%1{!tdcd(FK%_u=D16z@ zZOv%PZb=|nEDqtmHK^GzDCt6w$$|Y$(y1EY(Yx8w9tf_?Jxh5K0IffP$vAgLqMI$e z<4Eo*?gl`2<`E?IUdHD@67)3(Y}tpP7s}Q2G}$GWU>mS}j4$gUz^NXknm(#WvLh>u z!On>JYv(ABAFO*n+MS>=vkTZM^&D;-X`prItr0`wQEZ;aoWzeZ$slq68lnctB+}&% zF>nkQ?@U{aF5_(|U)Z@oSpgfnIZmTiJKWI4r=tel69(xjd~-(~$-KCyvfA7?cw|!V zoE}**l9U5@-9JPda@t^OyVKaZ^RAT^gufn{==@$iJH|#qx4qxzLYu|ZLpt!%tBN+m z9c-;|)f>dQ-efKhz6s}L(g+()>blcw(x30|zfLrSzHUGlWB1Pq>T~_xKEL|ncF_xOC=p{A)vR#4?w!SZ|Ad|S>-))t$-$i0?EKg9Ww3pVE1+eha>XmCMW zb%LLdF$p3e7Ncity26pV_ci-Vq+cC~#fO5>-`o!!f3kxu{Xut2t^1(q2&-daf6A}^ zpipaK=P`keaQ_&~cn;XyI*C1gvSKhk!A(rzfd{NCKZHwv3P&rF7bxw6yl~PNO$S;*OGD5S4bVbu^#Vu z0b$LywZCZ;b%E0!`jM(!M{1_Jj+sCdK-G*Q9}SXAW;QFy1JYbZJ1ln=;jI8%?G~`? z&o^CXDQA@j;B5U(7qp)ec8e$PSY-qXdZu1u=Nx` z>couv1&)q ztKbBdE%fl1eGFF3+&u$Jt87ATE@Mqg^;rKL+KbJ1qg-FCm`&TiNT^yb62e|Cg@ryS zmU!WCs+N%{yk=kMu7>GCxFXt#Mmphd`Uwag^p#Pio z&bT<(ZoJUWtR&3w9_+-v_wHyt+Zxj0Art`G0wp6gzQXbp@L=F;Kcogkpy5N=3uggm zpG&B{bAv^hdNr5SEWdN3e)%q6nTCT;JX&z->3g~NP=ixvkNJ;aolTk^_j^m}|C51i z+ko6<@oJV4%>E52fJj)`0!Q*jD9NvDNgl}Pn?02sLTjYXcXmOlSts7FtbAbxaYNPy zAVZzuKggur^BpBE@yGfGm+iX~11HbVX9?Ac){*j5C_KeNS;v}&e*5yCYS|JOz@Yf_ zGX;>&L3JKcB>Dmq8SkYv^Wkvz@@%#bXT+n|t&ZCD8J?=?<3BoZckeB?Yr^n#)r8JD zk)j*dB0-%&1VpuhDGCr&i3Z4QDW}LyW78A=FjDYk>bPeH=bp(XdraZIee76I50Gu; zk6c`5$P;?s7!l+;eY=W{7bW4?i`2f2Lo_Kyy$|+xG*jz}FyhCXQX9jX2rV)&gOM{{;(WPZkN^J^+fJAqHnK*S)1s;*G0OT#3Pa$o$w&Eb zLYDmZQm)ld7k2Ia7a<>J%S#Uy=$D<(P9qMyUv~sCe zQ$68}$>b#ccpV~H3lJ~a?q2XRRc!j6g*@!-owN|it?n8mQR2vvOj!7r6SpKyMkdQwQaw2IBA!8 zl?evl2f(G_`FTrV=6my6NR|EA7k94w=3%GXL2>l?6iYJ&#<;=GquBo^Ty4P6BHa+j zcvh^46NYg5ejbdm<~d3~ZEoxJF*`V{=O{axY*q8hyiH_P!dcu@o*j(k*J{GXq2?jC7YqS6}ZP zGZmDCqs>Y6jgC5JDIs&O&w-Swg1yL9*>)k+r0VPI_K(;SDcfYpd>`h z2I-_9;||#{u8~d{lUR%v3#AyxjkNMWFI`YXUR*p5_ZB8gy!Rgd_DDuMyM=To2lrz> z)#~74(~{MhN0JyBAYI>L+9^h23@?%aLJ~I#)NufO1X_=-4JK?^vJgcqMhUZbaWc6M zb!BdoZ>B!)dC(=)3E=v*GZ?aPf{-3ND6OKtZMHRuH6QM4Q~T@wE_XL%Y{~_;!nKsC zT#{Sg#opDldt*{ofI`|&AtW#8t)C59{Nwz6zy{p|J^lW%0)Uv4=SfQ+Rw}N2J{Ag4 zJ!j>^%DXDP_kK3psL45UQsuvX?8OjER}R{ieyA_m_uh+0YIJ{^wwJuBhp06l!NBda z-M2S^mh{W!J27K+B|erb!lV9Hsl&`KEq46-9zgMSLYU435^ji=&q)hJU~5Un!9N}p zz5pkRF8-w=c{H>*4U`G6#Zk13{UZlAI(oY26tj~tX+`80cTng#@C&59`x1{a3TV?_ z`PcLW3B1=)F!F{I;Q=~9pt5?mz=q!|A=e+mT4UmD(5(BaPVqo~hC`r`6hj%ur@_wP z#S&^e)uGhk2le@lNBh4f5WU>mc`kKycfZTe&yS!?hfaxrfS~+96GR35j8#&O$~YYC zs{T~JlkfMDg+CF~*kcTrqIo*OU#=Jq9^b*X?efR(x26c+P%!{?+n|^%@L@odz5<2B zXB%ym;VYCpM=5p!dXpO?O9*gu zpcIEh)BnL5!h#sTA=<+hBfSbKTO{3#9_Q_Z?v=}LZapQx8PzFi(_nB)s1S;^*-bH%w%d%(#UC`+6)2Y zE?2!T2nQbPiC3lJ#$LF*ag7r4?v*6Vn^pOwArJ;EBf3`l36jXcBHP=z8{01dA7Ij1 zwktzxl+Ms!a|>HJ@+~)oDEu33KB&gGAW9#A3SHK<9za_CK@U7DeE+QVU7V!ea*a`D z8_xlnWt{G)V{-R1oGyrXQVDv5HRt{Kzl`dkq_Ug$m*cxWBYnWL9|NH2zQ1;MRTREy z2L7(Xd-IT$;lHh7yx%Da_-s-P?A|{%-ZoGu*FGR@g_aHW4bNL#nZ?qzgguWiMLhlb8O*hOlWV)Vq}*WX`|mcAmvINjYVsQ2ES8KQaE;wpJCKlU=N zkVmIdx#DC1Y`(QaH41s%Sn3)I49T1>M^OkYM4<(EZka z;bg_Hw;0aL2X}=4cmdK=F{c33!7H$&okiuRR?yF}|F`n)jzB=bF9i|CpP{vHIPI8& z0p=4}_$f`Vp-mq@-v!n^KO12%dToKK5&(9rSY~>X_kc3^7_KRBD0mt9Z$22b7BXg$ zg*4Igu}(d-=(2x=Xg7?e+F z>SgnYAOpy9r$FzVABAZQT89j4AA7xX+3(*uyRM<`kG;l@qr7Q=w+0U7t*LI~+(Mh9SN z@1~{g{igFDIqYU8*gtcQt{xB+0*1C766j? z?=kggI>`kwI}4~V+&N(c31LacXM!STRTkL)IoeQKAl&^?1MFf2a7*DpF~XO4ofX{E zhJDb=R0laF{eQufKi9N+U}T}xBR=z5SEJ7c)RQtdceRmhFB6hp6 zND`Um{3;f}iYufX>RU+iz@~i}@-kcVg%FF`(@4DA82c~Lw%pxR(|-t9f*`^>w%!o+ zpYE7`R9o9!_YDUZoN>h{Pc*KiKwHEIb86X_NCj+?JZOOn%ys^46p0+aRC}C8kTPOmNRnQK=)*hMZ z(H;B-*8E?8bje6;-=mn2fRxn(^Y(sASGP9cxPwZ56|D*4mHXKpZ7(S6OQ1Ut2;9YX zL$j!ZJVrSjNYlO#!I9!^JDB2mA9h*vYsA zK*tuXTX01)l^g>&TyYZUhD6ZbC@|jCi)<<6;F^?%j#pw9*_wRE3zfro|5vjHJxjoh zgVtAa;(4N|r}bqiF)dP|gr3Wq`YlQFitj%)vrrqUe>|QdwC@fO?v#vwBOAPCAhx8f z_VNZWTnafMqN0Tac-BEJw($Vqs#?NHcg0{)QQ7=b4zkjsSi4C0MS>*AN8Z)!xj-AxbDdi9WROouu&H9xrH3eI)2Uih(V^zvnn^ zE6)=(+u1q(@rU;%$@tbia@O*_A;jZdLGNuR9lx6Z>5%V8eI%*Uk95Kdw$8%52Mz(= zX@wNtD~}z?%-oQEjP?A@vVV)bhJa;#2QXWk>AnE3r2&FcZatl5y`g z!O?^2*Kq8_1!uWv)EN(>fmme>NxYkA!dH0$Z;gFaBBU@Ez7jvyxrNRsP@O)`u3N4a zk%sSr8Y)}}(WfU?g(ExUXWqUGDC6WFJm9c5mkUxb%8;UQL-FRz>&P`XWUXE%3@p8Q zMIKk9<2>kcsrNNSuDc(oL(0d`NkqzY9LV1Hx4G9#r~Y{mlSHQiqODcDqU!y$)Nbtb zv{j!i7nW=#4w)6ayDub3kgU~@I}xcV{`A$xOEYl_=lzUSZ0H4Erz(c1oy1T|?pA>i zfKWjB^gnwGlg4@3@CL1QQP|TV0o(<56+iZFw9Hp?)mJW_wstZ-ViRy%2Gwl`(d=4 z(8%GDt(P>Y9v(NRrcOP~$Qlm0JWG3@!=+Ca#9YUsA~s%)X(^{r*UM981v|~kQFYWe z{uyfTx{Fi(w0>1o%s4gCh>uy$W>?}1ksi#J+bH43BXPF0<{&9)6QNDr@^4jHvh;k) zLX6q_=G>fJBTdhDgOWj+$QnSZofg7Xa2S5Sg#*;3_$E(?DG4=!C!u>3{H;R@>8ioS zuCjv?oH2>BRkthP)BPOGXE1n#FZ~j~`bf`G!jWc zX&J3C`(!^LCrzJ9YoCQShUQlW4{s_P z=>n+M@vftjFPBcC4>&SY+f_mk=Hhkj8yHcu=6&15tis-BrozDn5v%{f&Y>n)t?PeV^iuEkeJpvs z20ipqJvjRg_swB$NusvAx9q@NbFrtT?O~j}5atU+@FU`eshC{TYN(*3evla+d3#CO=iRC&-X4Q8%H)0odpRW&N_M3 zIJW~xz4#kWAB*aTh>xM)E34Ru$v&xqL40N)nxC<1$z8QH@AA3s#HHNubm6l=V!gk5 z)0;G_e65=oH0u+|!0dp)g$+c#QvQ0?ZkeVZMf3sAjgall+Xll&qQy?LYL7{k)-y@Y z$3D*YxCQxZI0?=t+?(=LCH%_XB6KQZ#T9#uDOCxAU&u}S&+DEz*iX|phdbfi_KI4J z;fY21XIkngtxi)p9wSZdg!%es%Ln~~bAHUS|9o)tRmHd5{a{7S<%@1!=o`C4nwxTp z7ofhtKoCaHHE^8(4Q{$wji>4#JP}0IETc#kAq~s8-;`+L>_#HG|8{ZghkkBWoHhFV zPUL_oA*$GmZ|8Ee{8HGO01nAiCA2I?j#NeG`buOG*Tq=reJSL;_WR2r?tWB7E%}B~ zJaGlP@#2`*wee!F=9`?)ktn);kBhn7uS)NmvmZ2CJHIJu?Sv-@vN9XYuNt3t*@UxO zM@B3#D$H5ahZ$b; z-f?JGJbgTE@0Z#(Se-Ed(Hnut}(P8a+VP$fS#gq2K^=(vYmIg{>6%8bjc!EVni^5$#}x#$s46 zSkX#*QtB?2bh6!Siez8h5UKT_wRX+98XJFr+IWhZbCB}z79A3Fhxhix0)p^la6ofi zd{7hGacClU4udR zZ3rv`MEpk&p1MB(T|qnZe(I-f*8Ob4^L)ot4wz(5*;Yb`Hz;5IBd>{1 z$jZmF{#sTeq3)Bm{U5zyo5AvxMD$r z->EhNyTd{L_)D6&9@<#8pn-&gZO~=FcwlR=Akk$~SMQ&ZuY3SPRxHuwoV5I1Lbz{P z0I>|06u$l-rHQB4aFOfPlP@bjm>1x^jOTBOiqkqb(Gq9fX-~lHs?>x-N8wz@` zt_BKfe>7>f7{}7T{a=(>qLxTDF$R>jR%H}29H5u0o~RA_iCHr2h6N&T@=y zWG5L;jcZD8>-}jJwI|n=rVjkxSMy@mo;;@OzBrF7h(=MxYGX#L%FDGo!ra*RehyM0Dc=%A;+@&G3A=m6IZrAYn+^2V$`Lp>uI1FHjW#@bu7p(1WU zs9uGaR{SjgCbkw&y<+vq9*&%5W`>V}W#_?+-|NQS*}N#8ZeS08J!aa5a`Sk>tGF7x z2pNhQ4(Wz?H?nGOxD0pvvt~^xVR?ID&$A|RnhfhSkDIQ-N#qVj2_*-&6lqoaW z)*I*sFMHN!kvf503GtN|M9t(ZLBHLHR43M*`H4t+b-a3%ond5B@L~ zeh2Zz3FCC_B=7+ed@>U!2t-RF^O|i@1!D~y-Sjl#)vnTgWt1bM2WY=ES-uXc0)fgx z?cM{V;C)gD8vsE;KiSLJg2*p2_9Bj%dwpczxe051wQI~=E-tmqNHo(*xYTJsdB^%n z-=~sYxpsiY3uibn>}+>&WKo$Q+yRPD;-x9kY}o*7@lvM_>bB4EaGxzwF{93XlXXcF z>jL{hiD2#}3i$y2$umS^`P-3Ft+Go5fA@7%W_)o%7~9)kqeT9wN!JI+;CemRW^f!q zpiFM*bsau;6eo{@c|pb%@1i^$a6#TmhY_9y{n=X@5#vJLR(yxDBT1~T$kT9j3PI3K zfTFQK4DZ=ZTJmpC!gdZ&^3|Yzb~U4}aMzDal&-rNi_jV$F8l*`*@m0=})`Ezaryhr?B4X59{9Pa-*-KTv6Y`j^Adss^1Hc zE`CzV;`&AsN}os?|47?n*JXCQLE3x#1#!K8!r5t(rT6MF4d7{=U4=pN5;C8HP7#L}2Kuu>b}3kx>v3;*&cSGLrUrO}$4 zri*+~JbY*g+TG`!V_W6I6h!*4K;EnKqc}#MRI!=&R)vR7_sOKs^y)NX6rqfA)mxNz zVsebrBON8g$M-tA|2;RqWiw|E)!f@K zwWKFv#3uUs^>sQ@-oQ32>(_#DH9Px6!gJ^0Jfq-Qm93bZwbQ&Vu7< z30=au&E+hOI}*=D?8#$Kd^wpiU#J$a<-l`V-(D6Vqeyj+ z{c8!%3mX00O?yv3K&PttMtN>Mhxb}#RzVY{>?4@-3CtcL)MRyv5`Q2No}!oX1l(CM z$vly^5f}Ha(ogzwAF4yQx4J?LNybdk5PlR%(1h)zl%rWrkqB)Hin^{rZUAfuCsvG? zw4a%A7-lyR?gz5H!(Pte4bHlOiiJ2L@2ly<-IRl!rn8$^{{lV6`VLD_lO>bwJ2%UG zIZdoQ%i6>WHp{8^SDx>(wQg7IT1~kNwv;ZII^=FK-UEA`6dNI&i3BcNnzNydVy?TC zcOrX?_br4HrNUiGfD;2F9e7ck6kU1awdZ4)NlSt5>oqK*@ZA`A;4HxoDdGQj>rja+7IA)YoE_%LY(N zGRJr(mxt!EGO87n95LV2DIQOa#y0HB*(sM(j1~C>ov#5^40P+?kpt<^--J&sTyZS| zSN4s@{y>l|+pdEAISFh}+DqFiJtoDOr_{lGWbrccc3;6t8hpWg%FWEoth_fj-s@b; zNxbn@Y?MMfiYa|3lUxuz^ux=+B<}tLG>IBK#eQX4ha8ZZv2J$*T)N)2)<1XLM-QC} zSEY_Bu$sfpMo=VRWT*+yt;$qJy3Q*$rHoRrjU6ASkUxKTZ>w66DDT0twd=pPokCK& zY7clLNCw8dISHKCG*d8r-&b2GP0~u+?WhvAHQxE!z^zez$IXKrI4d$W-$;w zeJ=-OHxn#6(*6zj8w#8lBnh2RKFh2rv1e#^Mld4_Mm9FxY=>}b!&5{_ z21ZTCiNx4Av(L>rxk8Z>BPfjOM%IxO(j_T7GCq?kJt-FgDTLqtouEF02YDlqq`-7& zLaTJx*dRn)L23Ry`Oo}14U!i}kq=SNx+f|mlfC-JC>{Bvop z=$)>3$f3w{%0;InKYGTxHR#`OCw06}9vD`lK+ z?~a$8=Uf$H+qh8L-nJ#}TeB!$OuhvA08QCxYdo3_8o=s*8Oe|!D=$qBt4A$$WyaL3 z1|7drG$&-)vF#u2pD7MG`ebyLOjX=py<$;gqswBU2YuOT%S{`(Qdn5{3(Qk4_*+?0 za-Xi77hb0+4!w`pw201O)p}h5+u&2AL$J#&Ry~_;{^vHu<{)j|&`R`&BBMjZrJLTu zYf|!DC_rmpYf0f+rBG4ECSn3e-XS56)P2^?yP_HZ-n(Sge#y5;Nr>;du>3KHCERFV zW-SCnl1q9hoqX3!3TlRI0p>L2R(%ESZ#I5=f)I5`1EH2;oA{xqt=5^TEOA~(%SwSk zNqx~IwDYeD%TZ-|(@Iv2`Lw9#XcjiEPH~Dr&;69B){ujV@{&A8Onf;Zdmc#*WX68B2-`MKu9Owt;p#nmc z#~P5lt(zX+@qAh-6u-O!uk={y@WRw;c8UIWj#LSk&SFn0+-17Xj>nQfF-Kkk+xxj^ zo$|-pD{cK;-;Is+DlHvd>rSqS-}{n1!HD-ZgopU6v*TU&^U+R4)YXQf->VMZDtBh( zfBIISf(!;(i<5m0zd47;^!5=2$BrfPM?8aYh5QWz61@Az?8`pAT>6q;8j5CyI``2F z-Hl-1jg6)1QW>0aFE&dX$jI1=LTrmK^FP^{;&N+hVD68N+?~dYavk_tY3^}b3440A z3}-4YB;M93gXL;EJ&P8H7LC#G<`NOaW^vr&7iRm1cT@K>Xjd)%q5um#Q{rD%SiY{d z+U98yKXyL8DgX3&H9JhJ$~9OQwX4u!$D6V=o`hlOY$hbNF7E`P5Tz_9SVnEMl0DhI zPl3$Fxxisnu5}9(7rQsZZ*GN{gsvZza{J3m$d=^&fFn9Mqu!;6L`!Y!c$Q`(HQw?_ zp_Fq~5NCW5w&|B);Ej!Z6KPaD-KqH}{IRAAK{`jc%YC0P(IaWkVR}xZirDA`U_Fx_ zpKsB4s6H**UWS6Bll=J`KcdGAs|8}+d~S`Qn{W4kmqD~Cec#t9@0*-8Q!}yjpw!jC zgM!gMn*}htjd=2$zEO4`oI5-B zgzr+bbZ)-UW5t?2AV}lo^fm{68QR zWvq?E5N-Qz4qcrQxgTSMOg&H0q-*{uDe&4N#Nj>7zYfL#_TRfkq`2x_KAfOD#g(iv zG1kbg*6~^*7d*Es!Z^1;R43QKYR&L8t<83j>wMOXk z9a<1uyb5Xwda-Wt3B4dmg1(QJYY^#LIt0S8$SyUo%}REQwc# z1;_>9FMiqmL>SkM_K8l1ll;^lyYoR+2#CEsE5K9(=<&Ia4U)E9EjPPxnpfiKXWt}A zE&7;87uLQc7nB`D$=5}F1Q*`vQX`&kat5f>{W!C=df)78e-J-O0lDrFmTvy?#{*|B zg+G&*eGsf%LzyKrF0QWw2&j^&`?5r(4!o(uT5jZ)(dXVGJga<{8II-$$J*JOZ3@Cg zJrssreCIRLku}d!v83dQz91xd%h7!EI+ZIl_T2}5Dwlrj{I{INo&(NsSPSWQLiT^% zQz$oQ^Ygz2$lX_epDM~DOS^drOIR?ryv@tC91fePZC8j$Zk45x6 zR1BBk^RXFgO!QI-8U5(}SA+B1LKt_Q@1a>;J!Og;TZr7_M{uREri5_1kgX>!+{s+e+ncf5ChF(g8{6EQ&Vztru0$iBOd5->pR^K%tnHeQ zvI!wcJt5{vbI!%_e0EqS{t%$MP98%vq;Ty`xRB6YoJ|%~=5`VJdx}N;ld8wzFi>V$ z@uAwht48JLxZ@<7^!XM`v2AOASQ2kAd~4Od>_kXgcx@Af9k#y!^Kb{KQkYf?^-ztq zMtv?(EM;dosQ)u|zEl;9C0I1*QnN8Z zphEttPnvd7nQ}9xeoaidjV!BOn+aIt6oxNv+X((p!Jw^JDpX=v%wpWijYpe@xqoB$ z=yXg3!g-f8yFIlcXP=8@Pn>|*W9!VPIjy`rZ@Blj2;0+#|Iff49F#hqxa2jwnioxi zN{xe*RiBz_{e0cu1R-mr5FIpwPww9x8MWD2oE!}(_!F={xFuW$! z_AUKNp>8`o{7i-}^_H#3aDd~_re1XV=+=SduRfY_M9a?*Z*abIUpmZT7zsUazPG0Nn3z(H{1!aFnd^!>UERG zCH;5g!~SpOxrS`vJdboWBV4rcA<88XEkB;Bn}dQIvg`Zi=GmQ@qOA-Fhswcd3%N z2J;Eh(mauBjVaT-27U2T>6*EQC4ipJ7e=d5K`{Xsrl*h-%YU3U`o>~uouN7eok=5M zxFe9NHHaA14)O=yA}Vh4Sd#00E??T_zA(<)nxj^^lUgOSyN1ntRUX}ENzBaSEUcPO z;mTooVnp#QD00EV&0=SHtfA^nN{rusp?J_=8p4-Tn+>fI?<`p}29oC?}IQfze zEk2KexV?n_iEEEr4Zzr)uYe%M_Im!PpeUMeHLjVT9VKTWjM^M7kIfS~k+;?{4tt)m-z9pPiTo zp#y28DjfFlFIKDom2<>df-WR$oQd^7O}M0PIjR&kwBJTNsSeRIs?^3$TGncQ<07v4H5V(rmha{) z6lB0oYsp--80oA{)JbE>ebv9w2~q(IgR}<;y2uVSKw$TS*KPwb6|uXTuW{xp-DJp* zSFI28j9#{||KO(;`AoUf#+O}VN7>%MksiZeeI{TR@{U-i#Ib5aKS;ir${Do%wg1Ts zF4{3xhzUf|U!!MM1Rq(T1nuJNV2hS+feU{7kHTf-dIw;@uI9jTnPw46Sy%do@6+>S z2uW-~eU9ZuPjILSA;mV}TG=Eqq77U$h;BR;z| z)ca0|(+2^{!Ba&z#Z{AIhd?EY@NLn>*?4h;*5TgyhA2P3g>d7_94u@LS*}-fF4I-g zEK6-9h`Lo`Pg0*L;p+196C}QFIkGv7W1mnXk~jcp`eF%u!?JlJ2(mPxhK~k5EIei= z@r-m40|>j?YlgEORX76lWw{>2oJK)t;5{SteMtmU zR6b->%|lpTqk3vZ(uv2Ju7rSOZCv&Gz;Ixg9$q`|QL`beXDMo=P#uH^_PrZq&bd6BTnG-Fn0~ z^mtPWzeJD;VVf79{ySwn81l2vYX6kX{^9rM`}}WA6kRI(Mh;vNH2>v<7+hW=t;jN* z?Iyin&%2`}wJ^23{r0|mo1M@6#dD;)avzkAOg;KFNQsl=?lANv=!732*8_V=@?CDa zu$^b`9jC|6uZJA3E#rVUiI`x1?+Lfdg64T0NRQaY7yT-nl=?}SpM>o{eIXis##QR? zG&MDxZ8#6Jx3n}>R7@^O^GX~lcR{AK$cv}>c*p~(3Ipy!a#`!_MeCIXsXgYxr6W2N zZBXA*dtgwVw)>|8Sc+MKQ}U7bzko^$$_rkqmtAch0ESBsdW1HlRa! z{l9_{fCMfD@*DKnM5ry=h&3lC(Yw~b&zbjTIPbQNHl9PYG}pfdtlB`d%Un)g)7kM^ zOtYf9cgJ!DCt~|8VLCoNahKbvi0Jaa;~i7J`Nru1*?)~_UnzcN#+ZD z%2+q%jan>2z0dNj#J|>Fw-J)Js2EYEzQMQ-yG8}X(%wkE+;Rf0^-H$}zA7F*RuhYu z+R*xYYvaV&It|NEn^!A&Q_}vhp^j;gm!>wh-$(=8oED&Rfd5QXT|4^GH8x*%t;3a! zt&?R`|01L;f+btEnn!;|s`4^E>TK(w9D91SCL2OjdHVL9<+RVOB3*L>#Y>aW{jF$? z4vqJUYx(n)G;pslpvFa7m*KD<$IvNWuUofZ=1d%52>KT)3dZ8izIkhV@O@eLeV*si zO{r$7H`w(u+)o5WCk9e>GzsdPE%4hOS&%>^!~g|#!oiyGo#BEwjNwDh#!=S8bY+W$ z1YB2R&9F#&9{}_W*G-b~2P>g>kOCmdU5qdkN1h%8zj8}c2U4{$-NX^%E8TSKXKAR* zy*0SR%i+g;gDCGI!K{B<@IM)r-`XvXzS?D!X>+;Kwb~6>IWq7wR$P}s!f+8EyIW@f zDW?O1YH^FiszLhowp^a0iD?%`x6)WAgDAx23&6mo`_2$ zzG@qr5kpVk%{PYrL-P#(^W}%;XPZ>15XBMNi$6!8C_iP!f2~K~NG%Aj4+CyVsHO#R z#>U%vg65T3nli>DX9>r(fl{vm0wfm~>cW(`%q|~E{!4z$Sd%P9A5lmk$mu%4& zLCp+9)pJG2l9*GvByR4|zISg_P`8XxHBc%j`m?v6>W@}i{f?AfiAyBj(G}TcA-0hN z@{$9bF$3|q`+Li1+9NJFT{L!LL91`h18AFMEd7m$8_3w|MhR0BmxC<(ktHAAg01jSsuU?1Dk4 z%jYj!1s*Hp@D67U##{VaUz5WrnzEAqK9z&etWXQv{Nf0nV63Vj;*Vvb18+PXV8p~k zIg5mWapS@f_?+J#`EH4#eHh~1Hmj!AV>v;3r+~oXe?ot+BLy-Im?DP$Q41-)rLE(P zZ_Y}}AnEmF;L`K9kGHE%uxb|uDUb6PKICy$@H&FL{U@{ck+ZS=#KA%=FA}#3NFQcu zIPY93|0C?n*Hyflvg>^3)gPXp_mwd{)lIti2Bb5eziB>HX{CW+L#GWxxBT>DRjTG~ znv{jjwA$!difK6BzC{^l0hsRSxq5W#J&r8MvHcj%fhaOgLL4(EA2!1``sa(XM(~yH zthrve>2w4S&`#pBmy@eQ+u4kucqSuPnEIGP>FE?-H`0iQl(I1ayOs4G7a=_^b6)3` zWxPO^=J-QurdZ0e$i=f@_tRPcW%V@$Z)}AB{wXx zbwU~;?w++$AX`FW3CioZI>x?~sm}8QqyPRI(q?ZPmfF~&_h$_yLSAU+^}7=&Xv2-4 zqoIf!T64@-WEB#!V$C9o*>E&wR`}CaHO%vv|7h~uVYxM8P&?(S_~Q!d0t%A?DdJsQ zZ`#U!XAe?9f^ta`kEi&D&DdBogOe#qH@A&R&9E}soN;@Iw$@#_d{Kdu{Ce!8tM%Zy zL%W_mc;!hs2>4g}BOZ6_tkf?6bY`sL9#8uF$0*JUja6L5i=pq$(3(Vn_H$A+%liQc zeM!#cP?c=d5^r?isUNrTBjii1YOHJ@IdtSsK4wT<2y}qNcl!FR5Fa?)TIS^c;Av1D zVf*wIj@H9JaWbjxPLv-xr_`mr<#R)f7d4iaz>qnwmp_| z*!Og?n2V}nt|VDz% z;>dd?g?0757D$q9`scO7mud)gJALe)FgnyuHT_9}jSS zSN_hSe$+!ZOzaaTzr%K-^+J%XDdSwY6yH5(73$V}_Vd4QRdhx^)2nLdI^T-f@m6n6 z1Vz#AhXdMcb#K^kCGgR!xvsRRSqd_Q2}+&0drgI!T052RZqydna=XPumY&HFn(81O~;M9XyeBio}*XkF$Wi+P4IDPC>7i3R2FN zi{MZ?7s?qDQIZ+4$cm;lP_l&eVUvC|cCy`%J1ORL2mPo=No(XwMMalqW^1wKz7|t< zr2M?Ac|h42cTedcOC!)iv95HGL@i#--;`a)?c9u)?uN%6j6FM?_)Op`gxXH1;LmU1 zRIKEU7UCh5M&Ia~hMK6bW6lpAE>YOZmI^EYS&J*oHny5NTU4F`DIoWBWc-qbOXLF{Dim=q9PBfLgeT?n>2KURr+%?F4ewN+Pd5;Dbx6 z8s~ZG92AcO7b|LyO&DTRh{%+@RkM^LCox^ON#UZSf|#z4gEGC!b4T2PYX&}BTaW3Q zjHWwt^c+{UTRRR`u}dqg+ zJgV+C`;Kn%{)IF@Uqf+X_Q#oXagscDVf0Fv)sC$91eq=6j6&P}TBWdCq8$H7KgLms z{HxNw`|g*oRx0Xf^3Z)W!;IGrm*h?@=Y444?@3;2jRc~0lz~;Sy>|Zb*A+0nWOMlV zsNT7Nqx?!A6r^yI62sZM*>b<37>RKocB$D!T|u$Od(GcCEkG3*HAUyPFsu>#l@R!J zpiGm1@^-AgjB;O`w;m$%-$TLyJeA?}EmHy1{VUUm#$W2&lQqM6 zQhPX3X<%#F)?WmR-7`bZGh>G*_7e{Cz8(UIppDgznkPcW85eaC<%J|5M_m=Pa3U?U zuU#Jrz$7C2v*!#HBh8L5yNEoMy0G)rJz>1wOQJ3~COxe|=+Cr)-_{LEcmA#K-$jUjk zto%3^sq_2E+7g7#lTAya2Aaka0wRWeO#nYv30Yc@ws>QSmZ)(C#%7iv4SIkcJuo~x zd;+7QFSK~zwp#u9eBjo*F~YWeKMPauwHK;zqz;{F(2eoLRqs!S!I>=c>5;9#;qT%w^e~ z{AAYLw;yzmk&)Z+O%&{iGH|oa#Ysq>#5Fwlt3X~0Y1(Jv<7rZTa^3W`X(+OY{yHGs zQ1(3?8P7gLh{^`LM-MH!K&53k(5q9M9HgxagSAQV%>n4oxv!MJ0>=9Gde#9( z{0YQu3eGT5K|3;D9QYK&j1My5ZVyDaDsb9_Wq7x*2d%=^&f#JoJ|&%^`qfQ*LO|`Ms>>Al;5u1TFaZEg7wjcRGjLKi587=vn?m)^|0U)Ky_t!p! zmRp0!#(Y5zYA{)ZHzvG^2?E1w6?d*oNlZFsE5Yw>X1p#Km|^c`=*>{vZZiKZZ5DLh zM(|IVRm&1~28;`l#Y>;>3`Ia*EI<2>A1xN=b^{_@-25V=MoQ7h&azLU23|N&>e1c9 zppU$Rd&O%}EG_UiZxiKxCuKn{&ZX`5?^jUy^ zv$cjT@qp7!9Uy1c$^rbwpn74h5jLB}mm++Ne$jDYjG!^Iq=M5n^G-9@5AH9ui0(kZ zwzE03hUe5BY1@v?jcX!%VI*S)H3b*6BFHckC|h0v$dTZ;$oCK!n&2k%qxfuCFq0ty zvo5xpA&E%b0hI=&e1T+QS9RfOyI(=n?e}b8irYlVjlJ=8GK(^mDEVry%4&iji@>5To+e_^`w0DC%1K=5cVmz+F zxlR%yA;Q>=NJPZf%QW%nn}X%5yNbJMRO%qael2-iL+8%L>AvG7j|knJL9%PWseUCE z6?_FnG@9Z)0%#i53xd=^u=b730UJ}JH93?kOJzoG1<4&d5gv4%2t85(L;LEfI`5Yf zxUz``5#xtVl!u~8ywCiA5qvTyimU|VNWyaY2u@xnqXW6eTOanK5RslaE;z-*m0}t% zK^3Q{oXimcyJw0}(SN4)RgSz-qw$@#vKD8F9|-yD*gTbMgN}=~QnazP*1w z4x_w7Ej~qJ;m(q!lxX6kb2qm*R&|bubjmDUKvAwOCaMPDZWwYlri!6{G5c zcK)fEqJeK7m(PDFZCf{qlSqMB(O(RkG{o}$Aa#8&a#w*YZPb1D0MY=$7d1+F)(Q{S zoCYJFDVlHw>@PAORN3y$Vaf#|iZzDJU<#1V5vBE5r@u4ai0V@NSgUru5~F_P7Xk9@ z&c~j>dX^)v!T@EK{&Wt1$0~9nvFp*Et@D3oBM%^n09GnaT!#8fUD?3lQ^Fj_BPyY> zxME4%s4*dP05m7|ti&q`lnNKc#{djc74fy_jqeGfNOJiWDH2L0nc93e{_ZT)6;Dv8 ziaIaVszfNg+fgg9o;Puo?JIS?h;(-)x|o4Nx=#KY!RbrjszEBE?WGu^VL$-FydKo1 z*b4OJ?%ZT30TIPNM!ELf2OZO^&1Wng#*Q@}fViICDe3{+uuY>35F&vx{69W?EWhtz zNu9SH88Er*`8EC{4TWKD`bQ~<&=)@A9UTOyY7&BZots0EAz~rZ)>yA)hv5ED+}HkJ z6QAd_R>9y`F8i~cuj+gI?Qo)h+l0IVzrheJ6gX4IM8m3N8*dD}sj zn1_>p4pT_w3q>ZXss?E*)V?AkV^K@;HXRocxY5 zb*4{&`Y^VhqG1G|uL!JVNo<(L_`a%~h4}>sDP9SOyA!IyFM`O#Uapx-Ys93c;cgf$ z!iAa=D%pcHS?8APBg-<2_R6>mFPz|kc)KJVW+*IVsh(5>xd4q$z|pLss6hLMk}=!% z_CmhV^dG)A!Ve~us!bF-Seuq%n;yG;kQ-!ic^_ROYUu+vTMWCFt*9y&@X-$B zoQ0l~{b7AmkpM_Rzy0vxLq9uvB`*0|Bu}t=!_f-yo>;N*q(}LxRA8?Irh(zU4#tY| zU!c-!FS&`dlMEWq%XV&PczCmeI2FK7{7e4M>11wW`iVod9GAV4hZ+^z;*dquF4061 zr|7+zAnlqrm91%4pU35cm|d4z&=M4o9gBrbqP+HZ-qR`>^6+_Zxnig$zw!A@4)oaZ z8{=?Op#vO$#sF$Xvlogmenj zaR8~rrb1l9GIfOGE)3@=Qn^@!A`8+SMf?aC#&PuM61#4a{F9wUNTT#i%qZ#t4AJ9o z@GXUKG@?$NeC+{NIXBS;!b z_E)T*#GWv^_yi&L#@(T?8pj_(?BiBf^dLUu!(Uq=ka|uDw4ea58he|Z<9;Xlh030ZFSc?2m1>HI;h|EL(u@GAK^2S%( z#EeR{l&`o~mp%C4V~5nnD042{*sR5z%e zIdaX3rg=kLeq0$BJ?Da0qPIp30AxCNlQJ|&r!D2I=`VXFu_)AqBr9DMmmgNfnOw&j z_@x5at`C!VC#F@<6HJ;fLS-%nSd_GTYpyb&sN}*YC`&s$I+|M4d82Xsm$DsZQ&e=> zopBWrg}MGy_r_QX(8~vMIDpZV_qYx%*E{cUgxc(c+sYAC{P9*e!K8?C!4eLbw{W{4 ztD?a!I?u$idVfUhZ2WX8 z^KK!<6We>_&ddH}>2XosAbLX-hgg7(j`USlKEI5D8o95vVx9S|c2@I`yj#}^NT;{O zA37`6y;ZW#D2YCC5q?B|WDwTd3n%yiJ`cS9de_OZLR|6@{foau?DEIrtu&~I4kL9T zF$bP@Fd}2FX!Z*6mSfuuwA_(C<0mk}e~)3Z{rMsS_L55;w%=YFgd~{Obuoghm~@CC zY3)@a0?-mGYJ*f}ZRocZ)6@KnuLD>)ES#U)gm^I^P|(dTaYvG`=WB7XhOSw+Wi zRtZ+BB zU6&KvMC8BP5~Bu%$o>*4ENuBG@nPZx*zASuU-+7D80|xum^ZHYes*2yO*wg0|Gd;{ zGbW7-vj)VO#pSqRg~K}e^dP*5O^Tp7>9{&#VxTo`_xeK4DxmO&RZ*pCoU5)1QyFu6FUkh#tn_ zlEeudN%Q+&??OF24-MeqHh^mm%B0nm}5BrXat^RZdAa--x;{ z^elBovobH?mhF*E(}wj|1{~iAP!I&`5pqV?f*7S&7GbrH9GbU<{7%$Mf)KjS@D`m6 zko5By6PLQlNeZ7l7>YZ=97j^xPD+H>KFM^|*Pb>cz!BzyJ>;g7?KR)?pozA7>4uJ# zcErXtU7m8G_|LlHv#(e*K_`Iy!j1B;&fm?jLfO(NPcvv%0JV*)wDexc=0Vx$8!nB& zynxzU$bPVZL26E*>)1kc#*t_rGe6aaUYVC~>&I~?IA0Ov!T@UXg4A2Gm`7>;k>P^L z73?IN8hSM=wl`M>5hGv&dC_ep9(Y!E`iau=e}aE1-A<1`_sV2zi1sgS1Ge+b3id0O z-ogfV=%GBuxuaG-Ie6rZHSR=SDDKY3FuW0-q(`Y-sMwmON<08lUy1ecthkvOwa+z_ zdP;6MT8XItbKUOuFSSLSj(ag>S+8zbaW=q8mfr`LCXyBULCkKMy-gVI#AFA~H2i?; zeIbIA;7x6drHgR*MHDyn&=(l_L}dZ}Aqhfi@tyvi!u%FXXN>{~{>o4Pt(NbLtL4;- z5rTB;%bFk0aCf#!5?%x@>7LWswrg5Fd-KJvn4Z{1SG_^OMeQd@S-N@gOLJ7^FFsBQ zAX@}2;hebk(pG`Rhcsa9*r>u}A=p4IQ#($V+IcPLK=DaXXoWJC2<{rxllt2JKZab6;p^${sdKS)5X1YYf(9SOFn|?`q;EZV?DHIlKLN@Bx3j8?>qR( z4C|Rcr+$8x*?l{8eb=|ztcId)M7Ea_4#V!RO*^9HNVH?~Ii!whBDiB~+xl zRqXuUuC{g4d`Ku(mL(xGb)9M$KW+=jeoxKW{c8`F$l_tzmtq5PWc>(~3tXuZxG5Zd zLJ5=hrkO8;y0aaNwE8^+G5J}; zPvfkD&Unhk&pQkrw>8&{Kr;Ay0(_pV_c6H7$4PQ2CvFRzEOM~=k!zu1@HR*K5gdNl zi^{^<1+V|NqPmbT#9q|p35)-S!hkv8{!}I|miL4|iK#=h8+$3?U{J8vf2$^o4GX+B z{NE43<_KQ@qbIcCWc(oZzyIT>7yt7A--G|3$6$8Y z!-`iiHvj49)BjZIRl@z>1AG#RdL|;fJ9)95FM0ESs`PGve9K#TC;$yrX3~o%j~F!k zr$Fz+S^)>F5)bx*ddEnz3smL?3IX3#pIZU?|gh;rF}KZ*@G+ zL<+-07X3!?spafg7rBiOgT31`BOz1!ucV}SmT(tk;>SsuP6j28_I6y_zwF~lrt5S| ze}xFU1#1GPnw6jd^E~93nabbAT>M`o%QcVxYXHW- z!(KGm&cXA6d+KEG*|}b> zbyU@Pa*)>MSI!QzjXU9Y6MN7+9LxIqf8FXB|KujQ`0zfE2$8?w#P1fmI7!uT2C3`& z_ z-Z;*9Hso`3lV?7}d*Jh!*BL@BkR?xQ__(_C=6BZ0@WMyhLy@L)yS3y-u7FPqn_C^u zI0d^vRDS&&mJOPBH>z;oqSTTlDe`!$1y(o<21Z^8A?w?e(cEIK#1rbdC97+R6E3j? zn?gY)y!F25Eh(kVXq8v-g*Z)>{vCK@#l2Q}&dr^4-@>u>0{7odO_EcqaO7(+ zE9)TT(_j0P@8d~3(K16;zP8|&b1Jw{ME^&j$H;Z4ArD_M*c6-0@MHL@$BR=H=KHx@ zroXH>exq>A?9=2*NX>q`sfR?pFaaWuv7*i4@udD;9N)cyy_)?VB9mwB?Bt_`CzBk1 zc+Sksyz-M_Qt1c#j=8#K_~cz47!W7hgSac@iW2@FJp7sZV2=u&wXyimo6j zo4S;JGjA&+n%mn`^YV5di_@_<*+zf;XNUIn$?uz-$J-0ExYLd6eOD8j+uGi{cG3>) zxKLe}+idfEcBnLnPOlYKD>k;}O~#zlS)Y(q5y#R~gr z{{BFOuXtDSVfFA*pW-*665hLXbW*tsbIvG_J3KU0Kjq9zVi(+9vFQ>NPAZ&kF!Vn8 zM7*~mvbnUBx@?Ws!`Zj;3NY@~G`)>SVbs4x%4J~RzHviytPw{og&G(HG0$nbaDKfv zOr7DK(C^h5jZ64d-B!tR;k#hqPU zn*;cTf7RFDpM48vmahatmEI{+aC}OqJ^k+ZJS%Pi#^#ZG8y^-DfP-(vZeF~O$?s9o%Zg_$&0`j1cb@LnZwYsg1>+V>+vZGRSC zul4Q|KlXI{252a}sR*@L$#)ZE;rcX`f2`kQ>sOh zsNdj0nY}(ceX*+4iw-<46}IdN)~sKWu>7D~Stm`r_v5!_tDU{y!cQJPe7NIp--F{# zPARdkgM_7qV;y-fHyXVdTxby#UHedRFOSumY6EvJ^=JYgLj10LbK%Ma$?=G2BmTtp zbKjP#*c5*pXCDk+Hq`a`w$FIMz;w&GNT-F_u}=|gG}rt%@BURlHji&&P4wnE*2cXt zvWWiG+`P%4mF8<)G|RJz-s#XjA*22F^tp{R7H0zy+|yJD86z3B_LZ>tK2-@QNM z`r$&24D`snyuAEVM2Y)=5$s8)s)x$Agb+9&-ut#~oSB^+o*#&Be$LgN`Q}{WGgYG@ z8~5YO-4(yp9rJiy552W|@9oIB+Ff?2)11aE6K2oXQqoi6eBPyBY=BMrbcf@m`b1sJ z;u~)7v^SieFYxOQlF~U&daCV}e&q?{PqsCQ_eXSk^h52Xk)|{c+s0Ij57S+@MfI+I za;R@^PN`Vyd$g8>7Vo~?lF->{QxU&%s#f2UG~(QpTJP#VC0p{*sie@h^Bs@pU(sgt zeD|?NdS^OG(;<$>ibTz)25LoTcEtXrt0782tfh)JF&UDtYjCYj*XhocyImZ;ma6d+ zGAgo9{+gv|3ocuI_2%uHJ$E;~1G(1YIun5dy<7?(n+k_q`IawE7{J9 z)!Sg@^|J4j+=n0DOY0|1bDp7f2SxWLtDpOJ@q6@!!bz@~Q~%vYyj-(E?c=e+D_>)< zk6bOTVKOsq{ANy zWYarX5Jg3BTj)eV3B5>@8f>UkkuFtGKxrbqBmqTGDUn`7l+Y0(B?LmsKbHGD-+%Gl zoacZ3i*s?f&?jppYt1ssJKizooY=vyOa*!80YyvSvAF7=@0+a!;I!t6_Ooa@U4am| z=Iu-&;K#9kFb&nC&o4Lx5mH8{7<{O&u%zsJv>MBQGpVP2MNe|+Qd8-k9krT-gbxn~ zi$k>;lrQ(z^LBMoEp(IQZ1ggybNwY}Wn^R=TwGjK7s`Uzeq{G1@p}?E(GPe9r*m}J zZ-PMZr;!eLk-d7)?9shmXz|8>uBwUA^B5V;w7_Lk@||Xxv{QP*zJV^HQ?s+(V2?AZ zJSH4KHLF+0leG+teP;?PJlAF`9H+b9Fk7(NF?C7fh}q6?4P3Lr)Kk7J&klMuiTh06 zVZ;9HO0Y?8!nEeWdsh#{kBL`|7NOuP*F?j14Th=DzalW`u;6dUi>35qx)gz_BRe z04tf!V9Z2n%zcYc88%7fL-!!vkHWF2%=W0DUHU5(%z08!hLF|WKNqN*qL*kwkT(>E z{M7g_*LQrZ9M)9Tz*5X1@hBUYZdXsu9I9&B8n0HoyO`tl;9uyd_;@GwmsxOP7>l*b zY#NtMTwig|$II)C@-$W~=Z_jG-T5IVy>7kWhJo@sEs1i7NA>z%$5VhIYKJH^rxyj$ z^O#=@gLcf=XwEn69H{jzA%IDL#N2CIb?5b5?P8nBed3Q#1~X;OgUYFHA2uf?%0F*J z8o5y%70d@4#5GT}$S|xzH($zU2znfw0alWjtTKG}WAE%C2@U;@&!2Huu3YKL*=2^q z5w$tj-(#LAmsNC8z)3iVN zubcPB+fws-dU|xhNbDeDP)3U2U^iv*H(9N(Ngvb=Jk~ceGt+rtM)@v*Jvh8vKFy7Y zUslz#NKQ`f9vTv3s*<$V@)4&=@~Ag1wAi~kWOw@StfYun^daV$Pa82N|6z6Ml2d=7 zKMk*v+B7%S&Ryv+NPFM}HpK-`?`dHbZir4mjN=O@gL50Ve5RHA>!V3G@@3zF4}nE2 zm0ZqRV1&GZbI~r8ZA;?iS(LDd$d;wP*49=L6_*rno4H?_44x~>c6GhEBDyII&HB!p7UkUY4{|FjFL!WrGXjkCCM5BgcE!0S z6&hxHZr1C90)w50F6FN#ZS9CIcA2FueU^-xJdI`=eJl*81x#qX+@b@Xv%Aur`u0qE zef`NACo4%v?s#{lMe*^9wh7S%3*Zo7C-NoY!Glq8tQ$BokQFVC@@utE#SLx zM>h~#C zu~pp@}7P%)JV>cFd)zZjU)|D&cz-O2PKfX@dm@vV@;iZl>`d z36%GlU_En`pIQjn`F@(=H=8(p&`t!D0#mah^20{~SFiC_@;)}rH~W(M)T?P5 zU-#vH>u!hVmn76nolL?O9wrldFwhCt+B`CnoV*)5F1S-Dd=GjQI|lS`^UHW)^^ zmg?vLlB@-aBAe$v7?>@fMRaeL=U_ zRT1|szbOcr^Czpg_RNuM4(dM^L`RNUAd%AvBD1?llR^LxpTnw8nQj7P+>O;<+?xtR z>QzC0e><#AhZ{gT6ATF4d3LIYyN2T$3R$?Fw2ZdBaih-1y@#pL-qDfCAadD$B>&;8 zBUiHfh5@H)`Hd%G5hy$L<1yOXX;1}9^1x#AKuDW$cwJe#%l!jU8@Vr%lN~>BU+Kpz zL9kNIT&)=PYi7uiG#4*gdiUQpE47OrQ}{Sgf+d2F&S9@fbGHf#&iwlEQHf6=QbNnj z+1VL@VDZGdvs?lh!Oos7a!qz%V&Nx-trNyYuod1?yQa7`;`#@A3E9ib-kmZb;CxOB z2#EJ|8{;e>mlwU;X6V*@l|Zw|l9a)VSJD(*-0{j$i^0^x$}U5>06o7NugL5t>U7S6 zD5Ot;WK4qE=KBUc4hbp6k|YEK1sz8ko>tE|QaX6KKLgXExCpQXLXBQ87-SR}7^pN+ z?nigPTzLxp1(@qiry>uT!Emdk4AU$;YS!~^odgfx-2_nRI@GKkub$iwK?u5|m&oyQ z9xQKNr0$sqgcS;_=AX$E$s6>=`GyTrR4jC{xySX?KotW= zCDFg#CmOlmLvtOqU3f8rHEW3eRKI$ z%%!(g6a|tdb;bhQmSWl&y=07|8+S*qynOj55D8Z_ynnh`c)kPq1S8%Bp6(5xnx4`b zjUyw7I6)EczV(^>QyVy=CU8F9=8Z@wo;O=}`t)f(u%D;3BIRUz?#2w4+^+HS!C$Yi zy%!^-Qovv*lF8&33fN0zdXOH^AedEB>%jzzOaPAO-)bI`C9GsRPpSe;QF0zA{ajw| zc;Etbef+Y0O-2RSf!TqwX61kgw2swIsf*vhW=Lw~)S6Vdq)rS*iffcJHHm9vTH&5j zu!0%DL8^uf`rv0Q5pb@l6;iyl5$IX39#gD67`g8D`BrnxazJ6n=RL1rq(*=rq^q~ka-hsHVULX2E1M|iu0~AWVZ^&1fN*#p%H~#!7za_Az=fFf zE(mwt_Tm@LQ&sw1VB6O#&YeN-oqoB zyO5_>%g1|G8F<%M1>CU&jCWupNtMb^+K777(Z&JWHrbiZDMgfuK+x9jK!AsK$SQ-z zrs0ThOo|Ofm7NyYB^B^Y{L08CFy|i^XTui$g{9sVJ9HnFF@3K)adGOY^QXYk!GA?M z^ra=_cMt_=6&V>N$D&OS9(hI>h{WEDhYmvlgW9 zJ(!P{JgaGN`*6o^Fb!hLvuj5v@HHlg{~2Cw^SRE40`0r((Q&lHM|vTDP4Q(vyGjGYfT|wO&H}`M65Cqtdp0=W-P0d7*VITR;JB8^(5Zq`FM(8D>l5 zwa**DFRv>YdV{|L!iG@ZFJH6Rrg2dJLc(zYPcDd-C8OUko3qJGWb?kPvr&as*wP-R z7a*{63xwU732}|=uS^fojUE%aDJP50h0`8k8lP|=kkzDMhbrCEaGdZ{_vEH^ynpu9 z;S$0rM3~!#>${Hrc37~7Y~7h>WvKj{_;z-__`06KHMO+W@*oYNuc}NP_YvJx?*aSr zbpLxFYPT5km*uxPGo(Fy}awNCvKcgNNMPnMOHsf9d*5QAx^ z+47}Nzy8#d%P3X1@4-2Pyy9_Q&mT`H^JjGr3Qt9NyryT)myl|ciiI=MCk9BQr|krn zUBZ!S4!fjlIh@sNO9;M)nv-DO@%_QK(2c3u|B%x2+3A}0Yr^Bd=610jNHjbC z$h?@vwZ*0fmTR-840|ncu+<~`qYg_p@CP5}SNG<3KYT>#vfKq(1k;oO$}?oFLKyme zb>;7|2oHb%n(T67fvxl@4ZtnSrFVQJgVujeBj8`${rPIzW1?)|2sVdD7C0@v`W4Q$ z#P?W$BfXSuHX`A^>Mg)}t@&M~GDzF9*Vh}E27$0220l|FsdvM>kU)qSE8C7#iZ;E| zuu8P4+KnuOXw47nDl09W%tEtsLqbB9KFJ2PFS>7)(9C^|4l+rw^iBfKmG(w_tsk3C z4`3lM9rG))T7?9f|3cZ>jC_;{$ouSqR5b(~5bDiqPTPl%ir(v*`OFb@t=;}}gZL=m zQ`oYN7GAiyDBNh)N1Fr4Kaf0pBduw!Vtvz!+7o~2+V^b0;ll_He|MaJvM1A3sIN8M zW6PY?M`D7_-lk&db%~_ZUzqtGb65N3cp0zWbRa|kSH=X)+LM8zUZW8)z@uV6s&F9| zB1D2L|C|<`jE~=A8MHc9y)qJ(CtYVAxRiyCa568n@64WpEg$Kg=2=GHRgNK0gW;?8 zrPD)ncR6R#1z18tsF^=wE^d^I9e~2@O*UqaeY^ly~U$=X2|*>c8bT4UUAYf|G;hDODz`78loa_?-!GbeGn&Y0l% zUF}|AIP)O3bRMd_EM(~!UDU*Q8xG#|nGeLuf9T@BS&223gy8NIbzr-?7iu2aMc!R1 zR(YO0Lmnip!i})cNqMqRGa|E&!zUQa%MQTaC^aE*b#)nW5n9;>u2>6rj5HSwO-&1d zeb2k#@0T_>ae-QLQmUpF#HQ#Jd6Gx2gs`v?0N3f^a{Z3iX%+db?xLWv)qoa9XE9vB zY%NY_;;6ocKc$PvT_axDQV|op69jo5?sr+@^D^*`A8;qoD|Ng9 zcS7nu$#RfOb=X=jk3oT44FcnapXn_3*+iE=6g6-4?Pf1rcLx6eKuLW((MDvL<1ff5 z%E+;mHYCY(%%^iYaSL8+DpoVy0M1||ybp=e#)bLbTkqcFn9E_?#9#teWUXrZNN?We z(>SOjd8zhphld z7XufUhW3l|?Ky_vFD(i(00Xu3+c2xew$a)e@C+sZ9okGlb~zU}OU5~MO{5K(dd)dMP~ZaXbSik%K9JIC!&l6mi!jJHZg_bMhhdd9&qXL`mJ=Zjv) z-MRdB%eA;2ao0AQZ##_7O(?(oR{d!Fxjuux7dmB*9TygRXJhj#cI^SZAw;evaW9FV zG;{FJAM-5=QACb*Prxu`VpTigOv6;cxkI7LPc>G2JUw+C9Ub*&@k_F}Cuq*E$HjK- zAD&wYxmR<6TfqIqv2WDVL@_9O(+*T_Z~~6g;@dkXRANgUa(2HdpL8*RMMX!oCaVas zUvM~_$=TV6th0};e|&hfQRioTHNF>|TV_GQEQR=WcWt$*vhp783cV=abF5f6>7rCm zp{3|xg{v%62}Wr?l@@R)2#{j~q=mM)@UB2$+Sp52F1zEcw10Z0Pre&yPb!35^T-W| zmLr}#S!u>_?woW6qB*rVh|N3_bz43O;IE}Vm5K4@ItI*`Q$i7@s#6>5=Jpq7eg+fq zfR|5*^hi-jX{?uvTlt7?)6w=dZGnLQJiMdNM04S@WO2ai!e`r(GX{fbQPD8KF%8rx z9SPv4!@0|=T&rKcjY22ba_dn?M=j3yzS-!nHaPMjU}W4p>*dRrlM@qns`@HiF;3)a zdcI7d)G>Q=&*40345S}Eg~<}PWo2c_sr!xO+rMAK=m>MExMB0+8f=kyMd7R8Kdtt1 z1pfOIp_ijM<_{+G>0=4M!vxlttnsb2YCnzgi*e0k)=o~x^z`(sZ{0c&iPi}^$<0=X zamV{Ej<2vLbZ|Xvt;WViYp}`lRiwbe(Z$i(k(F804Np(cufBcV-PaZ_zA7#*t_0*l zC9KVbQ8>#L8=D58^GnOijleOB0UCZ1A*ym|vuwFj|D7I^LjX?~S^<@De~TqP-M-$c ztvs>nHrg&CDqvJ{zUzwNZuSeXWle3V8q|_>wo^;83N2sS4JNp-^3Iudw4X-;!3b?k*OXao-?d|Q`rAv(CSbqkB_7uZEc6N48AS@7;kSJUc zp+L8<_LMshjzDY}mh4JUyIy3KiVNuHHKW>~*GyQ@YuPt=kiw?%*5s_RG9`#^Z2|%` zIdFq?xW&Q2;Vb1Jv7kT(?DqcsZPh!5J34k$P=frOKuJd#cY)xbLLd?e?zR%L44GA{ zOWqFvJpqUP!@h|sh-0~hM@2P(knG>Tpx_%W8_bkM1#gkYMi+iB5=duu<(%Jwf-xTf zR{IHtO~H;-i*nVOOlF&3+Y3=n_UL`Tk&gjNtOPErsxpU>wimCQAgxKS_7y4J{G_i4X;K6+sD2la8z0Q`cGDgDQQjhE`XK+Y)eYSS%%0z9ggM58I(!+@f%n*Xq*+8`47n_mW02naewCUu zbmN^#oSjN?>v++oc=IDyLc=b*HpPGS_nG0{pNvpq@x6P>MiE+PBorR#2=u7NaDz zM2eR2JBS>5k-!~Pel{r%*?iX1b)KAig3^n9PZ zsEBo2irN*4FSaG~uVn-6ulu(T42U2M>mr5%es8sA6s_)QH_$7ycET}$QA0`XuFL#Z z$otRR>-e=+M`O0nFE0lQIantX?v(jtKlMJuY<*Ogok^WX+{hRvbAgVGUUf}PGvUB(7`)Uz5Lds>dsi~eZP+(0_|jSDu$t>sw%w3NRSu+=BR-oF(B+i_A&+) z!~6;l-pIE{*WcfN$nB%RL3%w*t#digL%t=*yEhuBkawjf%*kHhp?KUf^|Y!cI?cW= zT_$E_Ng~8>AD3CbqNBs)?STBr8GQVMSRW` zLoQKxQb!E2LqH_5))bYM^&oqssG`#J{B=UASKRUB*2eXM0ZQW}+*wZ_pC-vD%^kqx zB+rxlw8h26=O3V1`;?src0rao0LYuBU%!6EYPBmQU4%!R_3&7XmCo3nqw`A#>KR~g zB`V0?=0At=8c2dR7N1UcbE>JSk=&0slJ>zt^K$RJHzL#$F=VbFr#TOg^CKUsF+wdq#pts z16yy&7vKCCVp3vjz*=e2iM)63o+`5^S?=y+t7;JIF0}aU@r2|K3e4oc+<~2g!;5m_ z_GrN)ZJ&^lUxzyU;7$lCCT9j?=YM23w>$RBE$gwbaR&pR0j-Z^L5vp&&PbM+?)}o+ z71BbJtSIgg&Qv;DgC9|@C%41osX+@z0Wq~wF2(so}g za3@FLv~CYJc*qe@4!tRm1iV@!s02%qJiey-08rD}MX#=}uYW$AV^sgF)t2=0LVZvz zsO>?#ahXBdQLWX9%ES&vvP<<5F86Of#+OH2-FofLO=0jJ%>BwE<0M8mquJLK2;kaw6z%A4Q54+vHIyi{3HY|i(w1G-O?Cw3F zbMw=AMS8~*!k%>cM+yyux@EJaZvp;uUmZ(0>+0&NN$tTg*x*=mf?>_A(TfoO z$=I{+mc^=TOaDN!#%dJ<8dng#2bweT-~}^l+ORS8^#mqDg)=)gNuxy(2n1m?ItpI= z6zGDDszffSkua5e7PrXiP^dDYK6BZYbK$w?dyuS^k zw~*E&0x729eT>oz(wL~?IvmUK_VnDPNdsn6!P!kMX@27)s2Za*b8$eCu5xuC?CPFu z3rA{&R=I{8HHdq%HH#Aca(4L)xu3mE8pQkiEG;di;Aj6HX+Z_czewD?ZQgr(5a9#6 zMRdvFc;5wQnuYUa-ztman>K9~Fsg0tp#~h}At*qST=jTsh+>O1WC1L*dP(t$=3bCDVk+rZ=W6n_)5xr0&_?cL->%oJjk#8?g@0O8@5>wj&JXi7E`H@Mm;jrbmOQUl{ zBw_d2sI8w~o_-v9lp_gX$m{@gKx1(_u-NB&dZ9_W*t*y(d@R3!Kr53!24-M#W=7h- zCg)OWD5By4D{hDhLzsNp-6mF|hRV)}2oLK3*3zrj$gD$=#0bEh&OLk97&O`DtJK9W zV|R*iuv`b`Gd@1P5-L41-@G{j8D`OlhzL1tZ8#PuEgXKT>bGPkrsY?9;|HACYNI6v zW6X%hw>soCt{h7M)_xS%%O`Zar3jm@qqEavB8{+0p86&&M5X48jDCrM2c_xY09M<| zjH-K0U*+GrwekD+8;JV_Mt%q4n=eYmprdxOQ%$7YfOtS;B0M7E)926UKs1~h*-D_O zVJOtmSKkyl9$H0x6DfIGXSknekR_H=RJ>|@#mJBpE}Yo@VygdYR8#zPvMTnx>3Jg= zm}B&&7G)}5hVmb%j1ONeW2F~(P{Bzng57gaErv4k{asjkE*SZM+OZG$H+aJz$bb8I z{)gO(fTqGq$LY7;LeQ+|H=zg*>fBDi3YmP9;>-akz72lcU*>3BR&(P1F`f(uRy&lm zC2H9sUpukxcQNoY)CE+c5|q>EmO&LO>e(>`srRH|9UYG@+N34^0yhO$o<_WrMd_d%tM&Ik}K--(tmxmPOVQJ z20b_omTiTYBK_&iBm6(U3D&Yj)NKeucsjQ z;e|#I9b{o3P`PKPlLz)A7mou1Bvm z!2xyGUy)<~{X!A!9{7ootOdIW{3HDRBR0V=#-?$r|NfSI%q8e^>|^HJ+J9OU-00x* z-5T~*->apiwcC-HmzQVl3@z(gXUuIT!JB_SDC5-8xa$Qlq5Egy*|82_>vr4sc5}bJ z+mLbpXxXlezaPL?GX{2X<7|+T`Q62v9k9+JcqAn+2hNL$f?y3$`qp=R^`DW?H6x{?xoS>0hG8cjHuX36GTY z(vaC2GMpEcVytoR9RkNy=(y!SP)9R*P6ap0tyjLbXq`TS^WKbln_>3n ziH5HFf?U|fL$UhJ3o?hyBJI{rpa05^DS9MFki!)cKby zMdG%o7J1}T@YTZ{$1qgJmWObs?$f1tjQ=s7+{{H8-Y4%4z@=Q-PZr;GFhws)ID@B3vsIDj0@#}R>cEF{scxzdcqntbvf3V2qpEv#z zMV_-el*_c_ov%ixJ(er%b!9}+wa5e8{V<w?uUJN&WjPed|pZKYJu#;jg#o)d9HP;PcmXbG+gg`GtQ zUcK>Gv(tLyOaE6r;lne~Px$)}&Hc|?i5{b$qa7Ic)W7xj`@S83l|HEK-p)>ioPofM z^52VY_VL6c&-%A9`tLsZ-{#^!U;4kdkP-cF%+CM!fm-1zli!8SE6FV)Ezm!6Nw@IS Hjr;!xk3@9L literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..161db51aa3cd61aaf97155386f3aa7619d1cbe44 GIT binary patch literal 1031 zcmV+i1o-=jP)9(E7>1wobMKws&Ye#AGcA_%Pl6b*4K9EXG{yyl#Kf?}9dRcMqZ@Y`O-u}7V`8GN zT)A=KLKom;}QUq zlanKbLgCGNy^(iV1aj+w)(Rmc4hs&_)cgz5(^F_oO-+4r{`~nH8o&#Jx0I4^gryuf zhY$kiKq8B!Ewfz9{KCa6 zpCWn`J9b!Z2?f&Yy8AoOc7IVmNeXMV9^U@$UC#8M`(OqsC1EkkP~Qa6;&E20O@eGd9N8xWQwz=r zTpEB%n452~vwDJo!Drc9tbzd7?Bniah1JytWCU?X;Ecq$ttNMYwR)S=M~B(=*^r(?DiN+CoiHEClb zNy7uDNwXD%SZDcO6=My$wn5o>++A72(;mhe8qJtEb+nqTG+zu+N^Jv!OeW6wz7F^7 z)Z)TfL@VO-*bqW?!#2iXjA3G89JjgN+U+*hTJpJ^E*6VKQM3)5o}RuG1c4s}fi_Vh zPzvL=7pd4BT<6@@*&{_tDK|Gam(I@4UgZC%zW}7nmlM?h6@mZ&002ovPDHLkV1kJ- B?J)oV literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0bf381fa8b7db3f070b2bf9bbb4e4728bc5429 GIT binary patch literal 2915 zcmV-p3!LWY$txCP8=tsY0@-tT1q!5X)uk)PYk88Vj zVuxe}+n+S|o_p?@-}%n>H{ajP`~>sN7$X32=+Gg-Cty82Jq9pB2=ht2|4vLSxG=^D zA%ro;$RG&T9Xocc#rOSG9LGN~M4snGyLay%avY~m2ocX>vWzj}z<~q87?VDD@Zhg^ zcXz+MWy=6BQLR?7EDK`{mSrsfrnSbhEVS0Q^kG>R zwOWlRibSzk6tBGU%I>2_j~?ym=~33KAPyfs+|u3Mt+m!|4GBR=vfQCW?*=&}vYoiDuXlQ7lrKOo52oQ3i6G43tmTh4vi&Ck?(9o5nP$y~=}L!vd>XpA;=b>4-N5)dRw zLMEMBq%ZY>8-q3muc<&71|&%$s@1AJ``8>nt+f$C(%4w!>wo!Oel#?WWm_y79Al7D zqK&5N2cRWh%EPr&AixhpYM~D@A?-RyA!j0S^I!##B%0+79$$X)5tLGBt>@;Ibz_Gp zium{U`xrbs1a1m$nu7+U1m6egv2NX6bglQuEDymgV}M+cqB`!Z5#zW<^*shJfNtqB-d^T_1%#KHwGq&u9oS8hq z@WeQAIl&mPP^|1Ivgy7J{9NgNP9C4+gYy?~a?VZT6$0W&lgp(Mi!gi>g8&*x0I6pN zEoO-mgq47w|Cz0H>>T5*;lE<=-ASn0AT2UE8-ro895Xg>l@HwkTGqV7?!BL(`3GD1 z-pLQJ(+*mjIiEs6qG2haFOleEy@{EIL@JA@8uIW1TUfEPpTGX#H3m=nWZed`MVCxo zVY^^Cf=phKExKgW%edMb@;CqW_q2R=kcS`IN>q)ImbK8okSv-imIf&1byf(eh{K50 zt5$ROu4&%rJA$0b<7O?St?>g*WjZGCHKCtSnTn_d8iXd@plDvx#SfG3^XZ;TtXkbh z9K;BvK&Tr)-Y!6)<~3Ot1u1s!Z06nIZ61H1k@a^wM3H8CJj6>YGRrJnPvLrsY(omy zmQ+ic*85u^@R|B=pL6CN9(kl0fm@I53;}cRxh;T(d7ULfO5!kPb$c7h$_sq>(N+HA zw4qc3B7v8&FuE@4YFQKbP%edNSF`%jX0BbHrgo*okFE*6`Q|WD;R0(r+K7V$A#V)x zZ8Iq60aTC()~#uv-#GeV>0Z)94#DXu zN|QD06o`uCLgftWI`g1seE%;17gh0m1`&XCXlQ~9Q)3tdp{&rTRUa;l5uR>)N+3Nk>`2lQ&016Cyr6OUg4|1`V}_ayP316&+yaT z4^muSWPEsxKY8<2(nXsjPGMw><;GyyXySVA6Jp6=F2Ue@+6@RvU=r?6wefpjevLJ2 zJ1NK0T!T>Ko?LzyO0oLo_zE zG1xc2A02&#c%4K{WeNP4DAMfO>QNXkLu?SPs;?|U*CTdk494B%&wqYC3z3>$84ZqJy-N^P05Af74eu?M5`&Gg<30B~Olhl_dVj8?A zMuyc4YqJcBA791V2!vzPdwGh+^1ZmZEROQHZ^Nhf<%gc)cV7J(Z-GxM@WkNvwvL>ZNXuAGg7km<6lJ9jzn_^OI#eOkAJfdVdGo z*R3N6D+~^g^2KjF!y8wRK+a=js)YwTy7_}|yu=U6?_j0!__c_1-oh_wLcc@aCTZ+kj*MZVTIHE#Zw8fGpMIXR&4)SF_aW7>2+9^!-$n?5t_0vDxJ8SdYwuyB*~dQ}Nw_pT zgzb3?ch`a$!Q6HpG$^T1%0ej%al;PN&14vy9Otz+vOL=T1%9RLDr4(EVz@FuC8>gd zv`Diu+fI|JK&fA{_{rJ#hH&7!qNsgJ=3Q9pnwb(?9%7{g@QCn-fFkp`W7>}ht- zCIsc$6i42kfNTSutq-!Y=^={g`m=sb@xiF3Z)gfiAAzetD*V7-Bw9dZxNhHku3iAp zvMewLrEFe!avP)LWuy|MjEg`JiHO8RXk(BBvSjE#-axppmAu8tB# z(Ezurd&%hcFCr9EZNXK3ZE_v27dMw%M^`2PaOPV9S;*96x@X zLZLuwYb$5Zo+XMRo_OL3a@h=FnA8P~K`Du)B;g`hmQ2*jfYaIpn_7vsuOqc%Gt!UP zvu`iCT#k{E5vHf7X>DyK3`0gnMp(UiH60xtRI62bdwVg)5XUjKT8+`sQC6&2K{lI3 zN{MaTSeAulSxYK-0fSm=Fhk5w2|#aeudx8LfB$~zIL_d~g9m?i{rdGU6^lg~1i>vG{$JW` zRE#kkK79DVxpU{<-@kvqeDTE>^(=zf)amZovu8(JTbom>)s{G~{QsEedGYY@aCqXx ziBqGaqvd&+=1lyg7`qJ literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d79cc117f5e25f1f4386c7c20dd97bca1921e439 GIT binary patch literal 5049 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 Y-^pE<7do?1KmY&$07*qoM6N<$f+4^xtpET3 literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9991a59127309ff66ca2fa42073b7251acbae7d4 GIT binary patch literal 8543 zcmV-lA)wxgP) zd6Zqnb?$$4#yj^sX=;Hc1Y#7nK!6woBtlF{gl%jm;P}CNF98QIK@7GLU`%+4aWL4% z*nmx91P)*mGl($^Vh|FV3>uKsYDukb_1t~OGgiGn?(Ieb33az5a01_2XSMFVr%qLU zXV>1lc2#Y`=lC3-<8$l+F@pOAphi&kzcbVx{{6AoD?v&rt#qH#bzLeoE0I^D`IPlX}o6Tm` z=lB4g=c$`-zIl5hk*I#~!3X2hr%yL`OX7#WP)cb+2&t5M@O$6;-cfVs&ON-Usw&vB zWsC5AUmN**-#e62D5VfWu(LD>A$GZE=kEsY-`&0Y69aV^h9Mgp8$(Ugtn078{+a&% ze%096_^o^Iy?4`%H{Ph-bkj|Pdf3?Aa{w}#OwH9-UwwE-M@R6ppZ&~eY-}V50;19A zU`KW)V}C%`b!^+l^E{-K2qDmQogfGX>(Dd}Ddk}O1D|zWM=3=R1pB2e@WG2J88Up| z$F^<#;fEjAuejn0xnRM9IagnOwI_sdc2|CPZ^_Ow!-q&$@N%#JqX) z5RlDgsi~=9%a$$F*47e+;eI1` zKuX)%+IZrLC+Okxr+nt*yn-4TL5r6bdAh zNk)$uO(;X!+S-^rc`~MDVj3nBCQKk2jZ#@ziD{aoQmK7v(*OokO*9&%rKN?owl*eA zm_QH&=(;XSYSC6oC3aVScWMEO4zdC;O%um)=FAwAOuPlpIcUDA*E#H%9R*~Nm+S$@izg!?~_O-QA*L&)Pz(Dv0vH*#do7X2n^jo z0o%84C!J1X7{<;+8`qfzU*$@%tZ&54?e0CfKUjL9HZ>s`Q!C zEd!s0I8ZGs)*+R`FigTQ95kvQhar&*P$=Yid)Z15+9w-SC=s^vC>iAc6P}9uzQ@cN z$D(Q4km}wmxkYzJr;yKb>rb9w-KHLlh|UmR+z3!~>$H*-hEfvx0R$n0lEI;_>tN{U zhJmhYD2hh0*x~*E>V;59sbP`f*?${_Wm$N>zt?g@lH37<68;GqjS* z@m!xUS1782M2za%DrzdrC{HCY4V@qi>C5Ek>`Bwv)l1lyD?T6|#j>s9@Rj?wZN*We zVd(xYx^{0EvRY6|p^yl{;I*$%fF=Z*CUCO_a6M`o8#s0DNz6EG0`*l14Bf{I^Ax-s zQiW(jBVxv}j2JSs=;+O}Z0%-VT(X+BO)X#=SjpHR$@@c&2l~58@Ujj;iX^^OhppOoC zDY1wb7BAwI$Qk_j+DllpWHWc%{adtH1l=@;y#rXt(x)4IZC z$J+*GRf^YYUf^#Zxrhm)9RB^M^NE-yzT=|l`abvJz>+IQb_rc0^n7Br$>Tr2mgeoR zarxrQ5l05}t+d#&#zE=|Eha!0s6Zh-iISij0z0A&UWOr13ZySlz5*RYRDh}2vDTq$ zsev_3j>4h8^3M;M?Pno25I0#E4US<%B=@^DU%Ay&G#dT8UCb}-rGzdaPAuq{g0;DI2 zR@pd(0MC~+y$~?&i`6XjeofcYohtBYytlvkKU;yNl&s1Onp;{?$pqehM6t?ECpRX)S~Yv$nhxoEmJ zqW&B>a)kh)4Ou^FnuecsnD)iPnES=CeD{^_GyaGgR7XJBcpK>{2o&+8K~=p?cbh{; ztAm{|5PFeRB&a|U`idY>C{LjR1yU7_oDO!}ptIejtJR^r$|9LEh}Xs#JEMU}Qm6B+ z77i+l@#N}zIC%1QX3RbWFYTi1L+{H-bnXZu%ENfer6|^S{?|F&`ShJs%#;{i8s!Pe z*hY)W8WSs`6HV&u*yi8|3f~E_BRWbHjhYqFNL89t*I886SX9;9lvSD7(UOEBFie5; zC4p4zXmO}KIK`w>N8#oII#;yQ*XwYkDfyQx>Ur?x-*Lm=pNeKiD7wA}Mrubu?l9DW zuHpCRnDgf|ahzrr%U7wkE0H;u=e}RZxJXEOokc~pN!Jb!B`A6cQjzWRsj7=mTW?cQ zX`*RR$c5zdAq7Vw6qJ`6)Hc{u)!7uX0V*u6r&UcXCwg!tA_(Ytx09Zx3=v)M)Y^dS z9{0(OZ>M!j6JPnOlL-29=)-o;4kWol96kyGhR)Z{JeG%-FT|=h+3;qXShdYR{XRo) zs8dm9(AnY?{Z~P8Vt^o3rjtk-q_ZLIEe?I%KDlgwQ;_7d0ew9_?b}`Y`U9ddo$_)6 z-PEa?T+XQJH59rEtXZ@jON3Y{lkU!t-n`(w6$QHUf(PFEcm8VDVd#k{av(PR>APYj zg7@+Ug(mRx4%3c01cP2y$rY$Ro354uW(>BsX^a{hp{2jV`ZecM8a zX|!#2Y2W6uX>FeF9S(^qi)g}xP*GWH(cc%4?ejqvqgr;%K)JGL)WV`MQ=Y_%=qMko zh(-CtDk2SKsIDAs?{s2nP*xKm-Q`ip`e-FDLrZC-TLUPA*P8x|vt~|%AS^Cs4oPYc zv|1R#B_$A#a#&*x?{qFj6E=P}K+`~IkSH?<14ZD3WP3fNuc#XrLpLXLsD@*Q5|_>obpMxA#TH`Bbjm9hqK2}oys!VsK-Bvoz} zJq$oP0V1$j)xVO1>k=3hDS}WAv2Vk}Fw}x#mr2APAOJrIsA;Id(jB(RtpsTuR9FmE z3b1XB&JGV@=xDlzA1HJL=}bVf#-@-92?7bBL%iHZml1l}UHTFpJ6e0NV}dFz#R+3h z;^3MwbT)OnHI0C4b=M-ZyabXn~w`g9!PQr9PYiTh0=OR zRau;VcPml@Hy0MYg3uu_6a^_!p-Y{t^byu9W${GNd3 zmTlBEj79V*zJ9^iDKD!an@gjG8fB?6e)X%L;JPkdT|G>kG?6i5>*?<9Adx7iueXnH z{N1Iri+18c9YU2NXn^O3NCCZ050%O2kot9ib?(lU?5zh{#Y)(Ak6z;nFpXtiCa^l<*S+;r^r<`yy zmSvI6rqOjBA>h38&I3S7g{BqT5LVwk`Ti4Pglg zHR4HdT^BoQ@_|0xTfYvZS{Q;s8~DArAx0zPhIDM}=9^P4-|UP@TK? zH>^rSEK_hPD^F79d3>wkH2(fucSB5K$&c_Z!>o6 zcruxOQqd$@TqBcBBSVFh5>3-c#G`1sPH%6TO--9wyLK&2n>O>vPc@o8^H= ze$M!YgBU-4Je5_|B$5d^7L0Kz%prS?WV5c2vlQ)$lR?w^vmnn__RSJouILH4C5-s zGkNSJrcOGPWU7p*5ILemICiSLCpZ*8Gz(SnkI_GflR2c2nq1QR~+5_=;Y-dV!@ zAN&KEsXEEgQS69D_YSwXav{O6HH3n|E3OsA%5E4o|EA1fS8cK=1@Hd1J z`yuRi$yI=18aUl)+WW!S+DPx%9c+JJkj?rC(?kX)H3!G&-r-@SBu2l@;#ZcC@$)2N z4VVakILUtvWJff@|2tU5_HlAAj z1XZ(YsI4=}WkPy8yrMTiam_7OVFHTo?G8#QB2k@am5quOm{oQ%Z3TmE8#iM{BEyi{ zPkRzkf>a7E5#`?By~)q7oX3+-JVoL#XnLUl2@PS}yw|sxzy8;+5_%!&bOHUCI9PyE zv}`G0*&6XMUO-Eehhb^OjUl4Al5E-QD~NYdCu3k{?|(owpH{JhGeLA?)T70K46%dqg@doPv)qG*kdR zEiTpdHdc*=rv#Z^50pa0b^0<6|8nP@gq}-sa-7_uCg?gsDKLxfRxa%mO&BEOHda)l zYlmB$errV)VVVZz(*i12PUhT;{)WH2W+6r@URpmJs%AXkI=58G;NOqG6asV|*9rK? zyPxCcuiOIf#27VG$I^>S<3a~1prfS#hM>02A|BJwOZ&z0x<@!JhL~JQYIFt45U4<+ zLWS}bng+?ZPEDbqHliVx>Zt8skp3$h{5!?<==);{&hL*PTJLjGZP9!?}jO zPiGk9mL59HO%zfptYnNouGqv~Pj2Aeuij1H5|?qaEo{R;xy8*L7#f}rTQ=q}OpUsR z2(=A1Wfc}tTVN;&Qeql{NK7YHVN%;*Q{P}?MKoHQ^W?MP2Rm{+g&}ngJ|jxU@-#m? z|6h4@NiVOx{705x=~&Dhg)y57ul@0`0?-WuoU_dkzST}Bv6K3LBmj+byi$sMR*xR*u{NbKrz z?z!&;9)By(L*IOm$`zwA#$*_OVhU3?$+f$n3p7(hXyD{SdOJNjTU|P~J9Krp?AY$o z+2+#Q;Zev1AV9M;&;?Gnj|er!%}5fRoX1{P&TqcKNTkK7OtgcrgXS0)YUjiktCF zfz$*_6gS)9DP*89qB>PmBiIc-?$!cxqGxmQH!tU(f4hpOo?41kT_RQtbY!^DhFxsG z$8$d(ilC$-UVCF5f4Q-Z@BiPga$4j}e*MNTctPU$e+BjVrxo(M9C~YAP6oCUl zo>Blq!;Wgi8Z@HS3S~No-he~49mzM2zl4I($X9QAn$|5H*fr$@g9lFzXv&CPFapVC z0l=ERc@6CX-4w($p1l&-3e9{Pq$EL#*-yQmLZx+UNET^m}+xKP+;E(9krkxFEQn4k;=H zb}9zIvQR=884}gL5z$h>ch*%I$fK<4J19B)CP~^f8HH_m{Ln2oIQVAN%3PdMrX!?Olh^H9H z1)zyY$uapL4ZuLHLKwyGDbB*AQhfY|j(u#EQXnLHU}M=4lu8e&++N8QLJ$N2H8rES z=jLx`0`f&lI|5U=l@&VrC>wnFJIFq|g5Zf;&1oIPSRPh}e7EthXzMXV3u8 zb%;c4#*c5rbzKa@q(9xm>W=4Vh)qVI(~^CUX|<;^s(dU#81UhIGkY>J1H*qP$$v(Y za%(uxAGqJPZPvW^E`@xKSTr)M`iAX_6%R!h)k3HOEHBC{osaPTw5RabmqP&N(P?)4 zaVuZ4=Oe8ULV;lzgE_(m@`UZ2plx8oMFai#x?_+s5~ObX`Z&G=dBRGjt-_AG6fmRAxZweWO>@R zxnL-fNegp%AJZ2)jCm$c-5V}*e+_j{wcyww0)=H+eD}NG<(g}*;nGVlW!<`U_`c7E z4I2it?D@XW`|IE5JKy;Z`Fx(un>W+h*-0!G!*Lw)`8+*6J=nHQXJ;puUV15geSMgw ziEZ1owzlH?KJj=lkLT8{TM2@Ij*bqRnwlstFK6}Y)!g#^TZq_^eLKNEM2uK+l~S0| z2wm$pQ~&bYw3jK$l2Q76pAJirKj9E;Dey#5$EDM0&N$-?UVQOIIyyRNX=&lH#~#Bp zP3F&^&$ZWH3ly`^wYRtPzylA^)YQcM`PZ^y#XCIy`0qI9oO8JP>Z=LEkV2s_kp7Q5 z@4S;|pM93mqepYyb=PtG?YGm>(ZOYxU&i`%>v`?9*O)P521gxr6qdQ${AvdTBbQt? z;E^hF+q*D@Md*asO2f#9#OrE6%2L2wl1wIf^2sMDI0a_Rm_ci6E48(?G&eW1aN$Di zh|TS{-%bz&^!4?TOeWC{oj2cngYNDgjz9i*uDtR}GMNmzu47qNF|nIruyEl*e)5x_ zkV>UkuwVgQU0po$%ri_sW;)&7-PG6D^XjXwlF#P{Rm>-W5tA!4K~Qk1nLL5cZ_Z_k z6A%^(9NAZ3&B;elbMhAmGC72%VHgIjt*u;n<&_*d^-%7*>n>h;=_Pu4ddTPVG&VMp z&1AXz?z;(sfMv^;v2^LuqIcqXxUNf0O$}!0w7C$1uC6ZT&!5k|_x^%ojyZ;({`9A; zTeprme?A9*+its!mtJ~_=bwKb-}mu656|<+X0!WcN<0+olUhI%1nDeePWmG6y}AOY zJjv4T9>)I7`RHyySn7l0I9zqrRZN*Og^3d5_0;W%&j+ByYHp}U!pFWu0)o~my zzW8E*UEC(eaf&IpEQ@*b=3$y9zVDOI=eg#ZYw&%a{{DWBJ@!~mKKW!anG92=Ou@3O zLFt_|X%e|yZkP7&2}%`>aq$T2@G&Akx3{-4!&0v zWn~l!g#h?kR;)-bTD0gR zs$oy$3PAnvhd+$I@WKoKq3il7haP$;LI^`jX&=}w{7J*pb=_aPcCBz6XW6V-v*z7! z!wsE#x_OT|%au~%lv7Uer%ajh52k4r?z`_kq?Cqj+q+GE{#ihwP{@0p=UsT=g+wBe z*vgeF`}sgXKYP0J)5K6rzqs+n8^wYJ3)F%I3qHH9LJ0#rELgB$@P8!u9G~NJe2yXF Z{{u?WY$txCP8=tsY0@-tT1q!5X)uk)PYk88Vj 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 literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f219c649a44dfa1b3390a62f1bda2e30407bd00b GIT binary patch literal 7504 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 literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c53c7a2bc6c4a9116e9f567499084ab8773cea1b GIT binary patch literal 13649 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 literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..ce0709f2dd5bde5fe53383593ee52b6f4211416a GIT binary patch literal 24658 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 a61Q@ZXkHCz;Q$schWiHQcdPYW6aE9L?MT}I literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-83_5x83_5@2x.png b/MeuLabApp/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-83_5x83_5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1005f4b7ca9f30b80144c6ab4a4b1c165bb5f8cc GIT binary patch literal 21880 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 Gq5lIRdll&b literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/Contents.json b/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/Contents.json new file mode 100644 index 0000000..c1c7181 --- /dev/null +++ b/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images": [ + { + "idiom": "universal", + "filename": "RadarLocalMacOS9FlightSimplified@1x.png", + "scale": "1x" + }, + { + "idiom": "universal", + "filename": "RadarLocalMacOS9FlightSimplified@2x.png", + "scale": "2x" + }, + { + "idiom": "universal", + "filename": "RadarLocalMacOS9FlightSimplified@3x.png", + "scale": "3x" + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} \ No newline at end of file diff --git a/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@1x.png b/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..572be6c6e9e42979b0d86841965f1a85674134f0 GIT binary patch literal 40480 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%0An82}nJCY-E%%_?G%w6f-v`;&Dk+x471nhmnp& zn8m>3XU@)wdjCMj%a$0tg<%%zMw;Opj)bK72na6 zm(x;Q8}-ZWQMy*NDXU0oQ_BQqVHmoDVt_-ApDV;rvx5{*$`OagPfSeM4eV+qVpcFv z5psw>Kfz?ANL12)Pwj>RBdwH(6jZFYY8J~H<^prRxrX$$x`_|^vXY8w003El%%Z!m5-!BwGS@7P|{Wsr33i^F0#sA~V%%@lBA;{ut z3k%?*#$3v6ROa3fWxXDpH%DS)iEi?ruRcAmzC|Ma{oAj3++PE2^b~S#VPV$UOt?*Y ziSA+66dOZ8jHlOhs(&S9Y}#?VL*{*ghKq0XTBErjL`6^ZUG>xyN?3UNZ9{59$G9;4 z!^Uue;EXd?pfOt2|0AN2wvxgyIgggnw!nsDr5cV z3(yR+!t>+B&YbFEt$&-uO;V!N)QvS{tM-Q%nzaf)^1cr>V$3Hfc>h;UDp7%!T@`p6 zjZOZV%y(Us+pL|VqZrWLQRniF09F}v+lPxFLdd_=%$IdVi=39CWawUqNv}} zR3s!MpKWRrZ+)g*X=&cdwi87tDG|MV`7(s`(tVPPe^n!$*W}YdoRRlnzE?+cu&82>OW>%8`mWuG(3H?2G&5`0vv&&es+uZVKzTFCln7y#fRm7 zH{;!nn>`mTOEoh&f46Q5_b%2fADxMH%>LcmTc2qZ)Y8%dlWSV?m!#LC-2C{3g;@y! zYKkBr`hvy&hdYp;ItO3Y+p7pV&TMd8VjFXEazfJXT3#vxw9IyR@?2ex?Wmz&qTwZ> z+AO~%WaoR+-1&@4wY-Iii8B^Rb1_(9Genf)Rg1jEZ_jZxibzSN|M+2s8iefz{_vw} zh0^oIN8&bB#v2k1$O{4&fB|SWQwTBEr8z#t&Fw+Q z$jCm{dXkNjB&oShdE3`bNvY2k1YdZ(R3`vb-<5sMuC{{kxm*`BGg*Pk?Ml9AFc%|= z%M^2r2ck2|Pw7@(fkw!ZD_Zv%SABTEjOJ1_&EwPOD42{b8fm~NY?c9)_WVij=jV5H zw28aB1JrBi@dK|@Vf>9GhnE6*W@bn`|L{u*EhU^E;K}pkxo#elP~-%3iZ>&_bcmtf7hR3`=o_ zu1{Y9sMT(aJ1}*dr6T93gQ5p1Un(l%{K{%-{%DXWqCQfZA!$FmJ5<9l;!;xM6B95n z7~<9%UqZnQFm+~D##4nroygMjZ2J=iM9^a|zSX0Z+vpWQI65%elXbi6T?`^cJrTNJ+wNa?_9&^Y%y3EHRnmYT+N(q=Hx%;s}kJJ*`djJF>u3^p$ci!J8-i z^{{A~v3V8B6t&_I(af#+LS}P~?iDp<2nvqT0+l;|=Q5TdKjXWWDirMnl9J>jhvA*2 zrKK_d=S5;}3FyaRM{@y3A+BCtwM_S{B0jE|Ap->j1d55)m&M$FNQ0N30mh$|J6{7I e`ad6IzfZ36`knzvK0{Xscpy}?m8%r3BL4?ATD!~u literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@2x.png b/MeuLabApp/Resources/Assets.xcassets/RadarLocalMacOS9FlightSimplified.imageset/RadarLocalMacOS9FlightSimplified@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..783160a758fa6dd381df48bd36ec775c9a21b79e GIT binary patch literal 100182 zcmdpdRaYHdu&c->-ch9(Q_Yd4B z7@JM^TD7WX%{i+(LPFS+r?VltRk({YzkH4oSIG?GL;M{Pj?X!qP?4Fy6vfLq+}EhqeZVC}D{{L<{YM8}LFwzu&^`Rn#k3e& zh+W%p$@TTa^Gxh+w5kjxa^KN&`$-$0y&}i^HY+ehNsG__sLO17=o1VN8rShvR8$yv z-*1Om)M(X-q7tzGY|jCOeD^~X4ewQ0Im;fkqXs3bh{ES5t2h|4pj+(X&M@*%C54ER zl_VGZPA{=aef!59+qw(Zeb1D3MA~BN;+yW~PdSI_pirZ&HYVWHV~?D871yQWa}d=9 z8(II<50w=3-i^g1Pt5j)d@SJ)=*t__GPDR`eG11MqjkO~VmSrx+g>Lu{PlyD&=c@;HSzrHzC*eZ1r{?z3UBRq`vmp zNGXJ%{2ZX?`Ol7!ZDT#g&_9O$zKY<9k*wbi_htJ1NGA(dk%nhYpo((`7m4TRma}2} zAy@dPoFFKR$IV&OJ&ThW{H#Vy6YaU>zI=hvp##so7lXM|FnUY1te66nDBGi9xU^^`&y@j-IlzV|t?S6#h&BYuvz$|#kkl`fqlPml^Hv}*|fzP{7O z^x&;e==UBSXQX0mQF!tMczJnw@3*JT!x8FS3W6Bp465oAPGHAxI$gdmZ1-gT>#S&b zl8F9{F88YpB4UtoIsDpoe`>e=Qq1ICh=x{cje_`hquK5sru-Dh6G$^BT+4a>!-^)j zB^LzPAm|{G9FGJ1>Xscun^jkOdU}*02mY-aO4$^CPN24|U!Naz=pfb-W6oGEkBDhO zO(M$~Q7_=lH{b@@S!4S)WA&BSQ$o2l-uv{yqGXP(M0%M|{{c}$M{)+Nvby>}G(KC) zaY<$xk5h@Jo?gr@_vrQSxfCY7$NsQze`47OpFg`Dh&mq^YOZeP6un$rTu7)O z`>jf|aiWHHv%jav6wiN(<4-IJbBFMZ2K|u<6GHPF$o<-6vwV>+7Ul{>YFQTuqF+0~ zTjux9bSy>wguy`xhOxhQsXDRO$y|NRN;1j}I4%qRzsjF?)%qvQjOjDvR)ioLY)HP zo7b0n=&=}2CWbwYfBl*8O~5c~hvpxfvgKihS*<N4l)4$}fW7C~9fMtS(d7NgH<57uy>Erp(cblxU`B zX9Lj#Q3yFngY!B&bK2T?ff!~X)G`(&>tI80aBx80Z@w>Pe70ED!0OvKRv^o4_uG>M zijz;R8X!H(LFk#b=}8K_$4)>_ZF9$B!9!PWzTP!wx$i`fFu&#;+Sd7)EDspaU|U*R z=C!t_1K?ZsDmO=g4iDV2sYwF~0!Zm)v3Qk4nPRD86)D;gQ&x~EEB<1owip9WA%NG} z^1Drokbl@GCYR`={NImzjHz9&^P(3?fuEQwYG5a(+myCAh@=;%7`^$AO2}$;(a@<} zDv>{QErFDK4v?MXNh2+iA6=3YMoi~JQ3zXrbM5EqdXOg|AmDU(qA!LI>kIDNMr(0O zR{8boSFQJhqs^)We1MrYP+{feuM$8BgJkKhBi3RoXZ0qz$O3`elY8VlRec=arZNV~KnvclYDjVvB6Af30Vt z;Vp+AIms%XIjP9dkWjBcjZ@9=fY!xm&5|>py${%Ox9JTY5UZ-HNVFa#$uZ0)vqmbl z8{lDs_O3k)3m>h&e?Py01^|))=Tm}|GgWA^daeR!9sqQKsA{BM$5+idt)k-M;_D5A z>Zi|#@X5KF`V2X48y?U>J(EN%eayp$*ZsyUzL!x37ct+x`|OE^Sde$4l?x?&00=TV zRx$R9Gi^o(iNZ$?kYBoI<-R>128-sSIfJkHcJwcbct|7K_98h@lDGf|@L1Jq0Z*@A1OlPxD z(bh%~@K)KfBLgLlP+(CjnEstFGi_L|8axU?2LkJP`#0p!W6gax1{sgpuma&Du$96Y zn;1DNF&gZG@0*?39*{Z(r##_9ySm<&1LGMSCs=D^ag)IHdbgQ@E@M>M{@SPUPZXYL zsHe#m78$QQi^r*!p+biv=lxR4?X;_r-hxvcOS*l%AxP~%aLw^xf#Q_QV2_YaqGEA6 z7$?qE+9-q(US3yGR_+PM_%yulxN0+}@30?H!M~!!gc7yrteTYRI4#gZ0m`kq96u4iNb@ZD-qCM_@=nzr$h`a+DZ7X+UVN1o4NMd zi`6|fA(VV=ha84YSt&3hst8>Bn1Pxl^4Lpw-@(Cwd3i-e^Xh@O$|(+{Fnpanlnov% zBO~Ll#zvRBo6kbc&(HO4c?AUptJzRLRQ4QO<4#4;MFILkuUS2R7UJflyHpI++jZc^ zhfTAklwz;dR<+K$@5j9JOUwVpV%w^dRm90LfUeuDUzl~4t57Ors55$3Ag8VSj&6^S zk7zzGSGOM9A-Gphn{STs`Q7E}6;0_RhO3<5H77KnHLvnZ7bR<@ z45YD`;BkCYYZgUc6|Es~Q{?JB1jmT%u|hb47|db?y2%U4B(}6YR9ej4Yau z4jM3a$mCkcsh!HOom)TorjtC@z3F`|Z$6$j^WaGmYNoBGuI?}^O^pE$EvUww(mv4C z*jVTL;`w-cvb3yZ=Twwz+Mq2FjVEGeMp>p-K6C(i!wvDyEWZf894kis+hG2of)^@c zV)CiU*6%2$Nw?;q8w$<-Al<^%6?u(76yC1mRs%E`N217?x!xIMwEG-DCKhS~cH$6- zn$Y{9Q&3@qDT)pcUCR)q%LJ~AP82nQ4>CLdTw2ze;LbleoiFD0O<#8D&tY|e_pYs- zo%#Og54_Nx&ZmE}6qw6<*Y5$Bb*rwhRn~u*N@EEch{C-tQ}p>(ahK;^&7f85|Mm** z%Chf805HKWLT0Sq(#EE!q@;wc)mt|COLz4ZwreW!ClFKTy)jnp_s)ldsch$2={kFE z8~WnPf0eTzhw{tHBJ8<;PiRFQdfXh(g<02h;QVQmVQBZx@wr<@dnss_<;*<0L?FvR zD`ntpc2-SLxoYlui3vf%b>&0^*pGOjGJxfSmqR3*JRUaI^e1RKKJGb^G?+V=)WnDR zVZ^4-_m|IqHM_`D$825h22%7(pPMKBK5<&X>;EgRbH6nH*ZE|J7y@aL>%$3j2kdk? z^9rtc+mC%s#LbOU1t+i1SE*eT#BtZ9LN5{J<#hGSr*LVm2&+bBjKU{3`FfnMhwsqbri@);urN?j44qG6s8hI7F;IWmeEAmFWudhtAFo|PCDgf)h=?dEI4GLwTOqH zLkB?+4KZe)zwQF<8=u>rR5pbH;>f$|N`AWOOdi>&bywR1r_Bg2yHLIzG5qQ;%@3LP z_^6a&zr+6VLIv)5=Mz(pVePdi%^SOX!*$~red|QKbBbh*>)Efx+qRXJ*HqdeQ~5d5 zi>;oP>Q$cU;uCOTO~ZQBKV8jLS=RKT!or|N>m@sur3&wVznYp{`2-F0Uxs!afcOK{ zU(o0A#vQ7Q(K8aXCG_?Xhtv|gE61dFzlsgo@6UBPS#-IxSD?ULmw}|)v=@{EoreDq z*DfNm?}qR+tIt$@W#ZzRHw)|`EwP%d@e}HN%05pVF>N`iZrA$l&f;W{z3PEQi$-E) zZA+c4uuU76kwE|eRh?~n!)Az?c1zCC(>WtGHY&68QD-LJV)daNZ#LCJ0=dpGCW7P< zu=@bvyauoIU2cFnf#@(l6tU7S*61ke*$ULTJ4Z^ z))sm_DG>KW(h|2nmg4ksySbZY5?j*I;S<%sI=UUki0?P#aDQU(Hab@GTh2>|uf&Sg z@`7|y@PuJ7E>~DEml`vo)_z;`Uk5n%H+bV|&&dPZ{Mg+{gUX8sea>#3IRs@dQ;{_oevlQq{>+vmrn zE~fS0r<26^er*qN+4A*&|9%75R(^4@SyC(hYA?IIUB{WmE1>8wVkGdn?1%um$ndo# z+<@_ogKNY6Q=vqRaZe!3JD&k~t&*PJfO1lt@p_w!v$Hd^{gz;*en+S}y{6yM>-VYu zQ?6&N)vg>ew17GSI3Ex^s-$HyvM4=iAaZ(AuHb?0vnzujGfQ>pOa3dT<;)iZ8IyXe`h%C z4q+g|4ewvcWpVJ8d8vPNB&fO%oF6gr61707`6H4Q~o&_Or6JG#ULXu&q1$Inb*=LA};m^;6z;sNO%P>FH_z zU0&!w--aArK~1`zD|_9r$2L#LWg>t{0(aug?yZLe&h0XZ(9ZB|rEzub?Oz_y0OLNY z!)lf2n$>%7$fRFwHi2LDQ8nim7wcWmz5<2|U=iG$Z+7wJgCPE>jQ#;ql?mGS-Mn!E z%$qycvwqYPYIqQcXb3~t(kpkVv8lCPiWcY{Yv%Y{u}51aV@Y?&Z93I^v~g10y?^RV zc((kZ+|L@9+ySQOez$DF^K{w(aHZdOE7nr952qGFV^h9&Y@klhOUiLSTi?Uc&VqtO zLuM)7B=d=k1tOMz@PK(?y;MEGF0Z>piH%qXAn(_&Uys(?xxj!(JMDUd7|-DeOEvIt zsK`eAfH>sJNh|iuj4XzU42u8_nf(Lx(w%6m9#CsQdMEaw@+IG%aMil5e=AC!*H{81 zjR?7NfK}S>#y!TX5N{6&-Vo6QC7PD?r>?5=cWQ;p*M?lXhE9_pWz)D1II3zI8m_J> z&oobKw=YfLW0|tJyFtDHfLY3%I+Jvw2ikCsb-lfu+qT)u%{@!4zqP4oG{X_Q=h-Q? z5zeWj+cBOr|Nivt9a9cnlnH@-|9=r^uI!?PQ5(Yila{l(sV zxl8C9UivH(SnUInn>!^+X{gGqq?wokRO0i==G(y!&61=MQzaPyqg#utH~+J>w}}~mqDuo5{h!LDVmhB26L`bxGl2g(47aK>E|C^}%z~HGb?5~{{pDU6 zpg(2F>m@2OzE7*0b`5>GRvCMaJmd+(LxR#xLosE?t=@kg5*13V01^*)1`Trm@-X`T zxV`y!*sVCNxg2K8WqV={eRLx_|9y?B$bZQlC-8^|b%!s!+3Azc;zI@JLKLj`tE{Zz zV4Q7gPqFzq;h0U|Xytl})p=M67LA}c>T_o|Q2&6IC35{^1ZZpjV%b#3kz#`ZW@J>J z8$;bCGl2K*T|Z2k_5dpK>fxDF$2^r}6L6~mZ2X1{7deY`0*osys(K%ma*?vKF2XSYL8^vCM-wM&C?O(qr3$7Z4w}5`dGs8N;R`f)dtCZ`yQovC(-2@t+Wm7T%ziQ50_bTKnl)5- z@Qwrfn)c%?Ll>`J=W{bTMfK&0g>gA+JP`jLPihW-XzDMMJ=N4SbR=D6r2;lz1eOAK zzD|Bsy)aF4{3hYG#2p<3=oO{9eV2U9TdO`#0*VmkJu48PpZ7S6u?IvGf&uhVD#3m`+lvWQIvjF16da*Jeut{qSx;{3&Wpt!E!W()SKkZ9sdeM7jgFsDu z(w5)VLNm^&lSbYfty^fu=;gQ7CJ%sT^Lp*1o`fciPyij}$om!OJ^?Wuw_`EYfb|3f z|DU(6$E}WUmhCD#JNx_gAMlE?-#;g^LaF_>K$r5_V1oy4t8en;>UVVY`Rb3W%MVds z09&*{n%0g-f0M&^b7Mn6R#vuj=8hk&kJ)wQ)%s3hwAaJyPv%sifIcXB>_sqkbgsfr z-tCyzr}BhnX~FQv*gR*~rE@m%;%#eYjdSx&OLZJAwZ@O#?fvU!8}6~L)kP1+;@p=m zj?wdV4t5P3rc8tHX3EpI4tkmfd?s%k8UJb);$e_02j?tkY`lhuT7P;ov%R>5kv<4;GF~TiR2KKW?6f&t+b$F_ubhn zTt)(R{ysv==s;%#{l7n2HmLx$MOC8$Gq8+~BmthjF22)S$h?za)^|_wRKPu_S@Sa_ z_}fWoGI_QF)c$2ryL;Gw-szn3XrGH7WI(t6I<0FBAc3`a%hVzP3e=7EX=3GAW{t7pyHjE)VSNi-2_FV3=Ivnh$B!^ed6+}69pY(4i-lO#gv47k`bdTIx^n- zfF0TNhDJt~8RCsmbdi}24^fTu!=b!lr?Y1R6@?TX@Rc0Jq73*uj!{JzPT$lJ``DQ$ zVtnSuc7&0jfay*lkaBZD_x^RC2|Xe9kUA4^{jn)Lmkcvt6*#Bi#6{#RF`HdU>9v&(RQ7z) z!VBK~w#tfv{T17iT>yg-#EX$>3yf8Vnkyjt;t4fxA%_org1+Oa-Bo@05E-4$ocIY% zDBPJ!k_LP0ZIU}uX}Y)ZBVEOgn)=|S?h@A`Vmu&6q?imS)bI_xB=jB?g5ibQ9<$^f z;i0!YBk4OGSz~uGV}jEJ-B@Zm+tP&D<(Lfi&e1x8PdtB7vbCVt8WNzRKpCb1Hpf;Q z;=YIHeTg}4-ub!Nd-MenMhi=1`>2YO!)Lz{6x**jlIGPLe55llJ?&4B!}9@EpIigH?5@l9EQ8x9}3X1n$YJRWV^s_(%x?^FoZI6fUm- zR7fDoN5VJ#^zZ`gEXOsYET1cP-KG86H?9zS=I*f?rh}^H6c(p#$Ac*YQLmno=|8X^ zl!eieztSjf)1G~tKBc%3=)?jlC?h)fO6t`_}yLj2p0XkfFKHe$Bzd2D;~jp+hdY07{~$t&L#GB|$}n1{)X&Nzrm)z=aqm z+{KPl6>QD#N;pkgVOd#8t1w`v-#)77r`N^%2?&JQG)a9ELxPrrhe7yCB}2>qkq)Rk z#P_P@Lx+$O+wmwjy=jOKpDuOdIP^6_lvE%XxfcU}!b4Wl`%v2PDM)l?K9M2pOmm}%6JB^_af%%5#@!w=0AE35L zA?CWTZ}OO8%q0te5^sQFmSK4**xhnACAFL>RYW;_-NdGnC+aC;>HAq0xy#M8>^;ME zfKnxOOz1jRAFuMRio*K1W5rZWu<-fD7~fuz%vF?~ZHZsbKfRlY1WTNGqZOWH@ETvx z6Jxd^a3dGGx43i0;MQ_pz5K#OZu2_GLXLL0(N!*Hqdv2oU0TG?g6$~E>3&w0ktZoQ z{YjgN7Vu`6_{bQY!5xb56xV|YbF^N;6?>8_ibxz1=!g7e6&9w>GR>X6w=p%Rrx-}c zTf(m%N6W39cxmmyYR7CGP#Pl@J60@tGv0E)K!2dKq4SOfA<;v-R+vg0x7yUysPUZk zAarjV71_-9(7#n+Q5G8HwQ?+L9{_y|9T^=pI9$B%*RQ6;&wJ?{UN|)!uLPm&?t9yB z35AQYU1@cGd4t$G{F$9sA$bqFboDn{NVeB7We))Ws!b(hhd{aZs!{#_v)ciMWJjZ z8gZW*Ph?7Ii#crDOz%#AqqNHJmVNBwAS3e`hkf%=~`+XkDYqfPG|XH^htrscwW!iGUKG6xT`v zQ$g=Uvu!cvwOGR9lOMd9S!#0zV+h4lcPucankEudsCYIJHN~;Lrzdn*3!?@&$(a=U zr8_Vx5xs-ppO|T}{cPAXm0#F##Sqa^0;7|z1z_U@f{^jnuA95C5W~1{lU12dK6yXh zs~)M&WdiOXKrK_ORA_MQ1yXNOVC3fVsyicdb)A?r4eVLx4D@=VwWIEbuo|qs) z$&KAS5x1<5I{*~LABcl|GcEP)hpR7Hx&h*5S#?-wTjf!T`+ub2uu#7`7dc@^akhG6 z1oW~~lvpWaC{AbDQD%;@c})_Tk7tY^&E;75%)!o1NEd9wvzn7JMDSAtFbWXRU-{no zrK)=`4@1FA=IQe4y_Ww}YLYB%1Y`H31Uf`$(&1u5CKrZN$SLqukX-A3|CFf)uj)!d6b2f?Pho^@>4juk25{W6{vxLZ-v4JYIRx$9(`TOdk>wJvwy+1xOzodzY2zw-D zek5fkOX-O?Rv#`=u$KjCO}OX)76UVzEXr-UE@XwZ_Ylwi<`NR_^e_7sADGDF>=sgAeb z2(gcM2YK(t!qwGE6D3_eF2#XpzSn2it#aSJq{ykV=XbaMifATAc36<1#|$0pqf80~sYo;X;md42d~EkAec36zu_w-1 z3~l9)z;-_`xVP4)&Hg7%hsiPvhe<07WgSgfd3BVJBdC$C38FJpnl#4gRMbQs%tP`7 zBTk<`Z=p2{jjq9*C)p^9a7!^`ce|{gG5Swi-XXpdB2F>*04st$K34yo;E}?X=K@uH zuVJNcbi1aGFa$b@#riLZW9$f$y;6!7_oo(VLOx8N1zsRgPB;w@BcbVggJJunhiq3& z@QEt+X2HVn%T^b4AM`gu5QFk4e+sep`}_2{m+VZdV&P#HkR@py*URt5Px6rVuu`0N zCK#O&@`y_n@T-4YMT#mZzKleq$R_i*U)$qbqHK98wH_(Xk{1J+#q|yY35fEr0fpdh z2n}6WLdDGJmpkFV)$jC|<|X~|P{Ww6XSCU=(uXa~0ue`Eb{hxVHR`0Dgq#p20PDiC z8hlM-T1An?QZ_u8zzBQ%!S?wf)o&+;J zo1bJEiaE%r@yRfWBZ|Ndlxq@}^&;4e1O^tQz!VOUNBWtU1i(`+)NJNc{qndG5+>Nz zWClj{OeuFUo%!f8q!{iVZvyJ0$L#kVs7P~uxuDyyU_5RHIc5rJ!<_<4IvkcCTkBk` zl^z0;q^7lx>qLY&`(zXth=^9WD*CkfHBlUKk%{}Idqd#(&}}q=QMyPgT)E|9m2S7g znv5i)1^VL{5~VWbp5I}7=qmnjtf0QQC=;3Z6vKI1g!sr8v>4XMX+&LYtjVf=CYlXz zR%x;d_mdE8J7ps-zSk#M*;WJ`Q_L@{5#;p>=#yIgY$DO-VaHP)<8xDj6CF>_*-leD zVQhjvuz;fhJe&l;ea_*`O2S}#;$xeP@8hjg>(-h{>-8({{l0CSl8vm1`hd4`Q4$Q; z@qc?Aitk6i8CUz2IW=(2ZZDGJKB0j?Or&`5VpBbaniN^MBo=faghrMAfDd?cs1NNe zH3dZ;+X<%Eg=H2B(k2{RirNMpk$<};KB_lvn~zDODgr;5$XO-}BJ2wgMsa3_vhD(? zOi}&1U%v{#ayE>j1lwo>YIo5UFs6!@DQndEUNNHjhrGX9%D@1&0O*E-v}( z>YueX0q&l5L%CF6FF%Z?h$L++F|8uTisjx972l&gU7Wmbr#7Q`Y{D;rD>f&O%r&yo z+f*bggMNt61&+IE+r}$X7FxI8Qq*fqyV1wrzQai`)q~3C1Wpd0|1?v6dXpw(ZafzHvAT~-MRGy>$0H>BI_)ivGoBgT z>H7E)v*g?#bPE@T$Id!FJmVk{8_RZygldg*kp5&(NSJ~{>)K-IAC3o)a4eqS`~{;> zLuHPjq=2$pcB->mRZ(DM-EDIs{V;ptP*EtZ=k^JhA&Y$At6)<|^M=pmHOEF1GW;&Oxyc8(M-59xQW0k@-128cK5ItayVkh}M+l$niBbm_O=LEQm{^xM`70CRJbPtRPbMeE3-zWli7v0*NfdF)8?7 zeB^S)W(kA&g%jqJzfd(gvQ5?th+ON{W^q3l0zujTp>gNz^kp-N<|Mg#1FCS3_UF|q z&I)Q}TDI9hlvOyscm+zReB`uW@|!ja36@D03&sks&4w>k-(LXu(~?A%h1JLz1FY!? zyeursMwRtQ$TP}{T6hO?{k*Zzo=*8QtWoZ<417uS#yzL)4~XL?>oX-qE__78^_AMba89t@rkxz0Txan zlDU>5E0(W4gFn*kpj7+CJf&HGGEv7`Ozj>j5waYc*k7yhi>*`OP6o1H>$ds7m!Xce z`}JJ=(d06~8RE^B*iMi+EK?AFe)eba_3d_I!ws-9gkd~GnLg#Pgs4T}g{>_$#=~qs z%DehflH&~R_j>$rQ&v&Hn0~qYOoJ?@lJwJTVP#?MHMPqgaIt6FIwM9$5m#V8XzMKm z;9fiz2`cV<_@LiI8P9y=qm)*c3p_AThtVswf`p26SS+|T3N*JF{4TKW{hrT#JMsR* zNQD3S!%vn=T?6FtH%-2466weMq$Fb^PnAF@2}vGz=Rg*VLyxl=il`igq_Ybr81Z=! z#BrKD@1jWMVnH<}Dj}lx?p1|{;p~g|gRH^9a6}Ti%yiCQkWsyz57JOH;pAnK#MPEb zL+ec&pQWrhbFWAjW6&M!Y5viZ7e2rdz1a8vxedtWl#3^4`nl2O@*KlEK9I{-`7(Av z)6th(PPtqp>G)3Wf}c|xE0!>$1}|Wt-Mb9ns*fLHJozIm=zmwr{%js0Q>DjuG0rNN zi6VtXDdYd_%%KDWvpo^h$;ps8y>LDA1$mE`NdHBL@H>B25!g3CA%Nr7$wiL4A#wrf z8UR2(`iNNMx3kF zW|`nKAmH(TbH7m9b-hgSzx5)`Q zbem2YMUM`3p%$4Sj=}+D2w?WH)3};4GX(ier`(Jsz??b;P}DrF(_0hZb+x5#C!MJ6E$*FQKcfWGfF2PWoSs4 z_Sr}hQhfgV*zcVMWcrfQ^d~L8u&m@QV8_Tpz!Qgkg(T>Ztae*CdIZ+9ztj$oaAS-b zrF`EiHZN1*&JPBy{d%QU6^harm3~EGf5hd>-n~(b+5dUj_b}RQx0?=U&~vJKHpO{y zlUlaiFb$lBBw4Vqlt>-rh%%6h*%gyJ!P1|stmIt?Uj2 zipH|KnywC#M$ixgTD1>eYqHgAipqp20^v&|h=zO~m&dU>(jG_z&|TuOCzW5l$?&%(Os&a(HrOcY$E6~i=8DGP*6W|U>odD*!AQ` z*`B=4Tsdy+u1|jL?%I*dI&dDtxPA6@4uHG8Xucl0|Or2nYF9e{r#gnOXJrb?` z90l&$7`7v62w_e64wqy#cUlpf`wB^~)xZk&M;1@Y29zGx3lufB0~gk=5ar35b*<>` z_Sx~4o}B8;iw`)wE=pCj@mgy{jJjXGLwin9H2K_ z|Bfr9b|t@pRwLbETxSk?Yy5ts68pq*8?C+KR6MzE5%_A8_@`dOFW?b*YoH_v8b}Y( z1%)p0=VZ3$fc0hE1`9+8Uy1t;L`nBA|LRpSxYG^vm%ZTmrkL)f@jfCWvb^=UYWz;W zwxH6&)TGlmPomJrD4HtAYasRv7;%a{ToSs6$rXHH&mhQTMi$}KIl{!m8?X82PBi6E z7l;#ExGRvcjtih@JL5iP*YjU0!Q0~qe*0Ap=1@9+uS> z)#^Q!GSq%6IU+s9c++?yr(^FHjh+0A(Q)3Y-5Q{(6eXg@2Vt4^|6wD%Jw-?k_OBK0 zhk=W!HtUJT+3;9D2zRRBxv%AZ`iQe%wJe?UAjTGw3`Yi$b5Q{kx_qNU_^G9BxN*rl z6XyK$PQg^J;(T=cghhKWbZ2+|Cs>CKO+QI80}3UKfdz8mhD^XHHE$M|iBNS0Fy>tU z4W_zt%T#x$m@#Sd=&C0A>RwgRet)S()J(5Z#6e@;B|e4+UNbMa>o3|MW$vTG_t3bg zLM4WbO!JMm73~M($P8splepuFzr`P02CjbU$t#M(2aLAQqsC$&6S7yyi9jrNHU~6X z9N@cr3ryI>JY^&AP4creUXEsmE;>hH#;$lQ{fQJ(W~cOg0N1tmvb4EBn7b*(Pe84M zh)}7s)Q_(^c=bo98hD<-FFw_RiCpW$QVwXsE@JIYj6H)`ICUP`N{WBz3tgO-pC2uk zFZc~q`w>@3tsfJ50)*@HVy){qU?#2(->R6l54AcX@v(?5`%XKKY`0MNBGm_vg-L<# z>>`(t>tYMMRCjgDAn^ubtYBrYnsPka^R!rojU>Z^Ls@qnDY|wMW98 z>8lyy@<`;vVA5S^ObXkTIo%kB4N5V7#*qEQs0t&g$ z;5v8?+cx@5sG`hETXuWZ88XuYeu|4f4+`N0E*X3)YST>n3xPq?mYokLk0$C*=YF#+ zBvQ9E^NTeGKBbqh7Z>s&Yp76Yqx(fjPm%77*;qFV>HJTa$S%1%N>lFcHXa~>H#%oh+t=&L_jaa#Q{4&^uI5aplH6(Guv!CT04m;v(dUW(}-s4%>7%6AB688QzcW z9o#!R1kjM`7tg=Zp)_t4XF7AkL@!TB-U2H+y-+YknDNBnH+T2AiQifu=oAE9AYEBc z;zUzk{i!={_vE2~`HCx++*rSzv}5l~Az&M9I*!g1TG~h(r@fX7>f;|KP!sQu%2pS3 zenNZ-))KT-P3;51Sl2Gu06wV)02anY1AP>W%DbC z0Eth^H&6Z&GZo8khrw8Ahdr4!6gUWplaIGADMn;auy1ZJUvzzs&C*gt=HkiepQv9L z-m012&cO$3Cr>*bkwgD%x9SYom51HK!;jceb;J>~vc?G62=F=Th}mo`6@}46mx(pj z3YG*hQaTo3As+H=y?(%@kru#?>5p9Go-AG-oJgY*XKn@ZaUmi6Nt7!X_JY!ZM^#|H zUe-)=eyro?dE@z8{_T<9BbEaOr5)0 zwt6eoG`%Fk2v65{VE?z{6q}j^y_OKSr0O{`By;qH?&~fl1sm$yi#C+g>)MW6G7>`9 z=5ts+Ho4*Sy?&&cS3>@$^1Lm(Xz)MS@G1|H<_oVnLJ#Q>Q1Z@J#O?1V3BrM7C#2c!N~)(U z{^wOotGUN$x`^h`x$QY=&Eb_!V|50XjbEbteiO%DQA|A zS#-S6qi2LXBAD2}&)WYiwrua7s^3x^=ay(!>vPD_gD*_(T%b�~2r0sW3!ZT@)vA zl&VDsDboTaeSZf$@rps-W<8$q2A5u_5UWUC7%m9XB6h&k8T*ehbw!uv`i27UB?7OZ zrI^*{OGkkw{sjrLaR?+<;rl7JstwWs?>@*fwFe*OW=Xg!QI5ejCY04;RExI~L-w>p zedFG3(|4D-{3FEW^6>q;7)dcUH1bzX3oF}Uhd)dVNZ6V9o`2@My=*z{D$d?)m;y_~ zHPV82sS;Y=*a)~VAPX+#{YYXn#WAV!(;}8O_FcZ({EkN2z<~~A;6W3-j4O~`-YmGg zDs5P=0ay+tCkn#vOV3DU6RfO1VR`I{csgM=KCws?iT5vA2gep-v)S~!zi?x6bV7S zNn3QmaHYQOvA`XQ_*27t+X6n!&4%+9dNI9KE-z)jlL!pPX3G0mI=gaDkw3C?|cdT)AW~pR#c|IAt|bc zIQWY5+BA8?;&_KWr|`mGSm|oAfc^Zl44D{gb;U3j&NCQI#!r`FtAp6A|V?J|SoA&OUPe$~o-vA8L6fqJr0T&}Qdj=D5Kf z6|Ubu$O3Zl9MMwvt;LG_)1_DcFyRc?jf33A|NBtE4NVc5?4aMNIlW)p<0vn&`z=eS z>oH|NAxdQA#sgzk(SjugOK&VOvj=7Y4I1XI z!w!C1KH{|PdJlGr_J_+_XtYS~0)cQ>` zQQtgE19cVi?fO5sT5j_dle(MIJC%t8|eom}O9Lrti(sg6vDyIXnU z1-t;sSzAv5sV4GxRs`0((XqSABzXz+7{j>$ldMY!Yh%lMsbbiVoICJ`U@!}^izpX9 zPynKI&V(5`B8icCzo@VE?SP)k;c1DY++%BDsAaES_IMrR6Pr?xo32f_uJq1k%OWs+PrcbPFsmF^TTio!`GNnhsR1jIfP-zK;LKEJeycvx;qg1 z21Re6@QF^o2&pW1B7+P+R0}HIX%p!=w=KNu<$@D=N?1#umfDcv?*aY8C`Yp){YCI} z5;TVZB*3l(Ag!b#Ju;;j#`U_|@RR`2S{?(Po5%r|d+RlBvdKcTztJ?Hde=iTKX@xis} zkAf!-(|5@!8g*-zgZUohFdD@8sD(MT!tX}G->=XSoT{Q9i`c14R6(-4b zW1YIv?sP8>4}{_KM)a~_lp5z@)g+*bC+-SN-T>!JT$d`R*ldX(9`RsM8s2u=;l_K8@JhdDNm2o6oYb>w@;e81RPmK!+M(A0QlJJ6eW)g6!7 zw6U%+-c2QM3@APMdZ-GP_ZAZ#F7AI0)lkx9h zHGx1=j8{1?)hE1(%X~^EOqM&t@Qf$LWhP%l{=2xX2SSqKUXii&SPh(evOwS?SMoFu zjUw}7l*u6lbInZ0!*|&Fl{XZFDvgI`yII(l)uqQ}13o;n7!`3fJS0f%IxyVI$~ee7 zbud-P|NX-h9J){9ZJIhruj6u-)uaFB7%_~R+lh_aNY=%D$)2}dY5(im z@vP%B0)Y!(Uf0S@EI_et90;=hZGjcHUW8xxM+mpCr2l=<<6s}A7JZ5br+2zi5Zg%GM4YT@I()J%N4+&xH1;}xC(ghK z$wO~nhd$n^GPthk_#^sVZ8iYJj4Cb%jU62KHt2=YYQ9_Ji6^oRgPanx1|>_TKm9^o z&3_&H;p3r0%r3I2)HFQ8+=;c-s@uo@?p8(IZL_*PBjPx#KBf?w#$MrbGlC%UvFRH@ zPBz*-b5NBdh?P$B8w~~4aLIuGY%AgJ(kTE{lgRHZOm!ZjW~IRDYeFMye^r?2Ja`s* z|7Tc}4VPb?0`s*CgB2=h=1{VuSE0@4LkdfRBDnCo>#`GIX?1;@Bg_eio}$R!m3mx| zDdYSjyx^t+h+DFL#C1~1VC`3dZ?<5%3w)rr1*U046_z?kN2FcT5b~6#Ly|ap9xc*( zxi=O0O_7<-U`TxYSW9H+fBax*@D4~mt^f1OI3+abVe6HXZy07n*H< zTisRx87efxO?`_!_b-|NvbTX} zyh_3@Or+zUsW6jTLe7)gxo)eMRfV zD54ycU{a%}^F|6f)j{utV zp&fKDsMd*sWjuORg)&V=-5tkF(sh}g-5g*65a%)IL;2Pzq}HrBx5@aW3vTesSQ`!h z?n5->zNP%IwSBC3^C8>S%R~+EBUBZA{nGN-Qd6(|%IUOg{Z6bt{?G0#`ch&aa4QC< zGGVs(mu7HuiHddi7)dTTsqilb)49t{y8_!gs8@-vH)8lc1$Y(l>;rVNJN?nxk2PkC z8mFPs=jiy-7RID{ph;0e*EB%o#Eds(bG$^neQXkFq{u<>vbK!qw)XlFt)1!Zz%!vv z5FyqcBWBOM0P>u`Z~|5&!PqF&G(`VF+w;I<#_#ODnPmyLPx8l9avnP%(8HVWRcAWe z^M226|4o^lgrTL+I2HApgnh^?-^|p|O-#%DcMQ}uZK1titLX5$*Px{_%@LXg&fC#0)_s2ZGB*ZLCJ0w0DE9Ja(#HN30$YAQeUwg$@yFce{~kzQI5}ZL z6!2P%{e`0hFM<}kT%5|W;mIiT);qsMg@?dfkG8f>+4Xybnl{$5r;PxgbiBhS9~0M6 zC#S>8^+XC&c!>MTy|u4HGqKObsMmR%ykYN`BYl$X7eSOu=sCY)Buce}*zZ|>;Fwv{ zEQHsPc!-loTjzG@5B=+#_A(Z-tR6pubos#57f^eQX8rYa<{-0g*zL8ens6q;x$~x$rw0{)RJuzaBxE zP$^C+w+~tSDc6W9iAp1NiS&ODgBqmL`h{KFNzj#B>2nwBU@D^pzug2u_WECfh#?Lo z`>wG|KySEQGsS}Jyhe`X%BQeCuHApvub2MEJ!}0XybmP%PMHI$H}^Y#?%%mR?c*Nf z*}&~~!l=f!(nE17gY^b|jybM;QkgI%YgC(RJK;7CEc&TdCs47>jw^|8gM-99mLb%x#yL{5>A^L%XS^s*;{%%TNI zc`o4SL7$y+MS1JH02x39(lE85`^Vu_pd*hA7>W7$R16uQn73@{cCwmA!b7K`IC2!d z%~SNRju)hX5(d@QI0lV4+Hu!eghoQLyB(-E@)LEPFuo8Y3}-7C5J-x@-H^$ za&7}dp)cpk8D`dZf-;a`noTi!Xj@MK;(ZXpcGn&n%Op)6bCAYAt;L&{g~a>6B@30m zYb|{o5Y@8%man*O!uV2D>S=7cgkHO3HvU9LjTvQg(4q%txME?4F0d2znSEyVIoKx7 z1pA@F(M;mCaNh*MJxZDj+N<TL5!qL(3Ygk_X)Z3{o+sc<4swr!! z?aR`{*w1IQ@P3QdMb;X1$;+D`(I{Dsf;4PZIKh--@;2k~3ObC6s;}W#F)>o`vppa# zT|+nAG^<=~Sj~VDK(e<@MsLYr?&IZ_cirBuiM{EtA_yzp$O;(FuGHa|U~Y$Z7*h7_FV;axJB3pJ{kG$V@1!VJ z3sRVJ+})UkuKJk3ich5Z1j0J)vf2Gm!95V5_}TBNf$zzT^CD!gYILo!nT)9t=_}l7 z;E=@HC<}#_7qNEuJW2i=S;wE@K*u*CO#!Z{>_?v97=pTL=^(4)|0uBvD)i`-akszn z7X0U$kb@$D1o7uO0J;d9*s}bEAcDOxdNIaQ+RU2{CMMPtSu%Ue;bz7-ktK|rv$l^> zO0}}yk4UAuqmBD_w{0Uk@B1pNN_2{1t16p#QToE$9-OM(G&EB6VZr7cPsi0YvIq{~ zB6x1l&c?W)WW|xXm@YMkIt#`utDC<%5B^@D{SNWnb^dGU%R9MlvSQa*X7I87e)E+r zP#IDMI3)t^DG50^SWbz-mEnY(ja0PzPUAB(LE&-AoDLSpBwAbLNzV*xY#Dhb<2M1& z--HtB4sT~gd2Y5sFR{4AyyvVM0~K*~HjbD9!cjvm)!suwX)dIq-`ibamW^DPj#&*= z`tKE*F-4+PjhcCj-Jre*qBFuf&QpHFK4cet{O? z?xF;WsVrHXJ^Q-sL^0IQT<*jp3M6^pU9~!%37+$z?P6Xq`Wku+2E^qUPOH`#PUUc~ z{qhf?Xu~?r2=Utb@qH&4*>Xtr>aRU9B^=YSMw?Tv_xGT(`)^pg(-WXnu+L-|GW7U$ zy~)Hy#<$lk@(7o)A%$-A@R{*Q^1{@Mw)q#-?U%?8Jpdt3V+f>B&J$j@QQ`H=jlaOw zUH($_;so*MnD>_?xpiEGDA2_r-LG#u>>P_4$^M+*|2KI?;A~Gq&Cp=WasZ0)c&}h+ zMRx2xQ4VQlvk2TLFs|#3lkTv|^?UH{_3X#FDECCute^iPh{+1YW2S3ecBP-A0mJU( zcCOm1q%EB)F)t38`+j6XILVj{a{qiO2U=p=g@9{s$sJlF1XA4noko{6h@TZyj@(sv zGgQZz$E_T^Z05E@iOlx)gq6-Z?fUMdn>5)m_QR&EV>N)WjKXxTQ$W#9GGUNz`Q5_J zqpi(x$Kbe#x>~QX6qf$l@zL$xFc7XeE~oodgE#AVFlFlEKzI zJ|Svv3dckDt}h;qeH$N0VTB!|pF;qaSn8iy%I$GzLrPGGI@hi618N&hkzWjOfO{($nXKs3m)y10Co-)18QQQRbyyF18B?pgXTgIDPjXj7OeN+}4C{-!$~cZqi7 z^O@=ozR{-0=Sti%gJo|SqP73mYl*nZ+Z4s0_tEC(A8O=A_vo;JIuI9KV-L4eP zCXR={)^%RZX(>d7mTGVy1d#FnC4f2)&m+~0KbA2Qpy%3!F6%*}Q;5ddITXyS>D^fe zPbMrDW4+kDZ;$;*vzV)LlJafBw&v*jh|!w;kHvrHlsGreW?A$ zBKgW+1V26zKpOV0d$-3u>wMqS<{ab0t^JDKP1qAIH?aRUIYWVmy4&&AJ%2&+A4ygX zf12MUUiD?7tX!A24Sb+@fGQmr(H#QGZ@{d7hn`tuS=~xf!2z}dmT9lZIkH}V5Kk7! zQx<>H_jNdA*x*5I^VmQ7F0{RrKGc^WCfBFVAbWdSe>rIO`FH#78Ex+*zzeIa6F&pD zd}vaj#xVIHNPQ9X!(@6%9fjMHAnp=2T!S;i!(`OJ32&Yu6!5 z{(^WR9h8QtG>cSK-ZkCkM=_qx5DnJX52C=`z(|#T>H;S73`3CP*085g>i)0G210(W zC|Wp7U}LbZ$I&odyEde z+Q2b_7$1V6=JbCF@|1tB`xyE?HE!HJACH&bXQoG2%o0yyKs<=k7{eSio?L@r`xu9U z_{wF%S>g)feJFFkE_MWY4OLfA8Uw^IX4Q}&rI^#(HE!3!{Le8-KG5TH9qjKD2`SgJ zV>>=ezuZvFIE}t@cLU@dt=|ns!)}Q!++N1nwDqM}Eg+koo@WJ0@l}*69DE}|oI{2H za7kHIkZAr3HTuOb82aP0rap(p@FqZ_)|LLmT*g=EEx*QaL*v`<*yr5wK^W| z4XN-%aQ3(1D%pPC*^S6IwImWYlwr^ZRon@_g<8GL-&dWZRs9Hzy1nq@{Ntyepb;P4 z{DG9M7E7(qA7^jQlZm}!`1PIexD9`t|6Qm-)btl>LS;9GiB2Z&D7d#s)0Z|h6d}pi zeqi5jZT$@pv<5EiGN7cvJUONQH|$RIHt#O3ke0ejU%y%J&7pCeFvSeBlh;imfcIv@ zP5vU}*!t*L_(_y+s#4P2?`%Ok*V7jr{HFUEQ*m*2{%dg;2;&YA~ zJoxqXUpUO4E}n8qEHPuBb{LFpKujZIx!&qQBTt_B4{dUg?|A`%=TQ8=`18TLozGGW z_^vbK7BBYzO!JXRR3xnt4=2dsl01fTZ>kQ}=mOKB!_ph=lvc?)Z@h&5xRis9frMNf zP32Di0gEUXQYl$DEU7-}z-T{Yx+;@KCyf{DF0kbM>YwyQ6QvrN4HSV3-Z{JOomB-i z#>j%Ul*$K-^wbWx*`zV?rpIp*MQe|XX91(4R}KfU1+~XH%TMD%kiQ3q#2>nt?_YO17P!~xw?WX=j5|$XX$ou#T`k~w0WrbX z@{rqo=J6w(qA1b1(HM9nZ8&6Fp4KOATMI9MIpb=5rdtClS>5IC0cmb-Xo|;;eWIzD z8Vi#UCV)mOm;*=hosh&u3?9B)WgpWNDfrUo9~>(kTB0W5)0iyj-xiFlgfCv(54^6P z7-)!PeICMfJuf)sw+#8!*6!eHGtKu_ z9lUmkWnNLn5D5_2KVpjvop9$yFdE!Nm(ZL?UNbG zfHrhoVgCo%#(X7{Ad*C1ygv=@b3l0@$KEIqyX-1}aD7`tdLws#6yy-Nc#UVYQR4*M z42eDWZ6_l@$k|X%g9)Y~NwQZyL#FtY%9j8JeD&81V=iVf`jfe2P8`v|QCi5FWp?Hg z>AD)O=^_A>`9?IIAXXrsO&Ve*rzJ2NeyjqC3x9jg7}%ko87xnxcT{8M7#onU!)wf#jI zr9gbUD~@qa{Q8-bahEcK)u;Fz2(de#8I9!*64e0thhO`8<-~&S4gOQQCF0Kbxy1PtP24eKa3dJeRsaVG?5?h?DolBNV|eoR>~?s{=-#8JgOFCB80 ziZM8|N-HX3G-C}VC7bFMM{AM_)t!$|OF0kA&f{rZq+a5hCPfbRp zkI61o-?$+Lzb4yF+x+%pz(0Chy+y%jYadhCS~lw0x*|5qMpLuw@9gEA)FG3AMf|Rl z+nj>>$Lk}y_PV?Hc;?D_FZm%M5?wR7@v}#S@DMQqlu@0`uXIj;q&;>-o|`haGaqa5 zblQ9F0EEDd9OsUIvuZbGc@DtIYkekE!&{Z)T?@Oc#(+mz9#0Jvtew>W!cql63W|Ts zQCI=6CI2zXHu8X>zc?4XED>fep9#=4KPl=Nx-a(45JYO2>W6sPq5i31-N`bAr@3ZP zxZf(qu^OV-yh25xLV$xyeLJbvczXA2Tx0l7emC&;z9U_R=bv zltjMDP?YO+$zZqkv856LErC}7#xo<0!X)eWx^L3U&j<&kLb9)UNa(>iPkIe}la-Ps zLWB;|{3wk53H?^s+{+=U#f{&QZGYjZ4!_94{qSf zlUaQDr-LJrP^86+PBJvrIm&DC5rf63FmMUo#=J*XxQs%e&w&aoDpT_E%6i zzhY1v!IPIY`aKbIeJFp^q#>ZGD$i;0fKP%@b<9)EVD)obDB>^M6l#okm+OydZwE4& zvS0((K~&R+F{+ZtEG41Jm?%o0ddk@;S{tig$GLwD*wD_T;Wa$oPrrC(_?y!?Kbv<8 z()U#9>Zjhpk_<~PW9%*xUUom(bIUlGR+XIhX}~RdgVIrR{ihF6lc7HeQ^eSykjOT=%ddIeDgxL(mQ2{66K6HUis_d9j-jsJ z7MPN2rNd4Wd7tjcBxQ&AO{LK4Pj;<@6Zo29xMwcW`_@`~G+23JGc5I&N{eYIrwLGEJVBT-(vfPn0mrxNSo>^8G8p*oiX~ z62s(E5)(ZXWY#Ng)|`#UO}jg9>tBny?AEWWvw zE*9%%i@27=S&tPKv${{2a4LIgC_7^zD#{Z0%LOXmrv@GO2|fBo_*jYL(q+EtYtDuo zJ^C}Bt6n0f?SgfQSlw)@&)r=s`%%=&t~QaliuPefcTlN1 z!2H^VdmiKY!Eye8^WEfI+0+D9x~$t|b|?`K1zd1f2{K`7yTUGm_xF6794E7f1`Il~ zR0?ysEvJe5zd4M?M)o&Zs?x~y*bky=O&5=NAs%>|2{o4eA3TcqH3xu1p|P*J{-KY= zOPX3SB9CbsZ~N?bV0ZmOE5t&G{?C27ZqXf4^_9?iyZ7V(A|ik({eDwxVyJrlX0-t= z-sB>B%ih&1CTS-ai5b;!#)?0WSL7%aT<)b2CrmXHGOT}h31U)!n!rUPv*kXF;;4wL zp^lVYa|80?J3DXlDFt~g)$CRgCQCr4!i7LokJB8FrA#s;c;Dx1zEGXfx9}6kz3x54!p{ys4yByj5w}~B)AMe{|106^Ii9Y1ZveHKayNjs_j`< zgo&r=Y5|MaGjq#Rn)vpO;-u5F!POOh)Hlc%rbB9A(Q8{XTe`=vpo7={@QkpJjCU0_ zT;~O;Z1qp42|*`_o;KRKNtB6Yh8R{4UMw%^7=3PAbbkNTbzRSEI2Afp5zZCeeujA0_2nqA`#l~Dt1kDc!?K>#AU~f+)D{Gv=(EiBhOl!vT=;4) zZNk)Oid~HT90X=X-f;RSkj~%AK9C*jsMKt@Zkx3qh^Vr_cfMOcn?rxeKA9gx_wc*x z#rf2i-~45h5!>@IjliLf=sUn(Tv0IlNfv@6BZ|!lxFMsW@aw;k-^PSv$zPu8gZ-q19#edmzx}&4bxv1h zFIHDS_b$-?bL9jwI4qE`H!SjUaJuku7a3)Z{$%!g8-V?bzylg9X}W_Ydvhkx(Rkb`pdnSCz2#HY zmyVs7;9R$13XFU`czw(?PhhDyqe#GN!P-l6^(_R7lUadq7X;9-%nTp5J=mzso%&v) zWek=^4Gvp*1!g1rq;Y~gdu>nCg5L0ueHkdoIEE%z_Etc_U%e>@#5(8n=zs8(?8rS%uv(CliF0wF1wI89-@yJ1 zU|X8TX`+iXBEAZ~jE580h?26vb}~Dxi%z9s!}&3+W)u^}aTU#j!o!3`mTj^E^4r>zFm7Y#w7{`}sC zw7+TKCNNry5Ch|yM2AOuA*@-nnnX@LbX<3;9exudJ9!Ad+Wx3#eKAJOT0&Z8VRYS5HUGVJe z&#aEwX)3+XMJ-&2`F$<8MIv~SD#}U2->*VRDf*Cz`1m8+j(PS`GJd~dQCB>a&F&E3 zD2iwycNDiRrf5TVghYOCir!`BRpM60N*MS8KU!co3b_6zNqI^kIYRFUoMh0Yq@si1 zJ=8j8>dmS+ZH;0zfA=7yp4&JtVra;EKv(WNxIHACd!2$sQ1`X3e8fhV1h!Y~UP#nS zOh(yKIY=vK+TyupzqNpUzpNsg&sKpo!{3P^GOk*R*1`5E8fLEDTyPT9>CI-j`ZCHA zSGa5afe7i3HT8s;FC~8a&@g8Ap_?CE7%EG21+B;kW^12oaZt&qWu@eJ57hG`k9|SC z4w41lkkN|<)kNOqG7%_(!wYoe7{rW!85m8u;H^strF+=>7-qBrIibg2ms8dwJ+|^$ z`Q`pnk3|?gd~I96StCt?;oX`4rc058z2P%!;u3cJ6Iw``4`(Nn8Y8GUltDY}#6ge; zy%53#kYf)f@m>1#y3T9aGFklbw1kA{%MbtO78R5E+o_7pdt&DOiTB)jtRw9q22rn_ zVmSL%Uux(k=aL{qOpS_UJf_V+|J^EkS9X!>haUWWzSBCKCuj&IY8uqY#CtRz%7I1-S~dwDaV8BeH~B3^;bIAT@sE!o6c!k z1rjvJcDymWc-Ksf$oXFTWtuV6riy;+rH(h2;A25CP^_ZAPT za~CcD3E~{XuyF2p7C-DdUN%a`k75~caOdF?XM7`k*r(`ph`%d;M{I{#zSR|o%ul9B z9IeK5SDWF`BqK;KojZZRQF}pgz$lGwUt%zSA&^D9D5hlwZM63N!|Ju92VY zBxYEL$WGm7^0lD<;r!wiJbx@iDAOr5tfLLSaZ4+?ifsAY7q z{`|&DO*VjD*A}`5@EpykHXnrJSfgK!-e9|6@N>>U%y_17N*jf;c1FL(1d{<9{)n;( zM2VENuOZXDu;(2&xg{^dPUKQcG|nC-P}82p@M839vj2=qQwd&4@bi9hg}yEST}g(+ z(c$RJsh^T;Sud60TQ~fuW<&k~2UkD+*!+aa$1>7&&&86zsKjB`G~2+Wqx-mrnOJAG z(aSkPt|k31xqChHxNMkJ=-xJe8BZTc-&a_*h^2p}(Z#Aey%fBIWYX;owGD9PY~2@E zYgz==2Aj!Re2d})90)U=` z=|~L*aYZ*W=*ew&;xi12QaixGP5sK9@5nU`;n+-HUyz9i%KOmXJit~fkgfsOMG(0B z#Bf9sQV|B?shjDs9C(oO%5RPmCHxFgH6TfT`or>Hv;=pesB#U}Os5(dPWy0eJ!o>dPy8EEm|gtX`<jw@s zQL=h(+x+&O;1$pVB#1Xb!P9Yp9bE+}_nRP<{$a-Wdym+= z;#0}M!z5~&=_Qaw5#N%)$2nJ0MSBcMO{e9WuZ`_8pF_k`5xJa)s1%W zSus=^$Ws0LNma;a`_SoZV}7QOm}P5jk`(sC*8v>~jfgUYKJFwHtNnlAsBGsu*`{;x zQ>OBr8Y@c@o~2Fl^GJ8{!eM5$%ec4!BSg^nMsqpz$1R_b5XO%Uk3{Fgu-98gwiN}{ z9@@_;-np+TZ3DbEySh1h(6PTJxukT=@~UkzOFaf5;do8u1{oFM|UJB9&@}*3}q>-~8i$5d6J9C%>zBCWHnI*Au4xM;O{;M;X8s z+qU5GUufLnhr)Kq(k zDCm~mhW$k1@dgED4BEEcenF%iczBkEh=V4ED!1ClE2W||I?7}#C;}dXG48xcd=*0E z08qy2MWw}6JdmX$M-aHc`tWxeB$Nd!#IJw%WDqk*ZRhj(_o7v||J=$(sa@Rx=Rn3V z1zyt0FE-adj&~!;>4@Uzv{IOdgT?94FtUh7WgI%+wt*hPYU2IG>}B3A#>oW%UgQzv zxT7{MSV3q+NSgEQ0)rPe@n7oMomY@Q_)bm)YLZSd`xxIeuX;TohLa2OooQYaH1f2a zRaxR+i%V>=?>Xgt=MDTfNpSf7KanQWtvWv1nB}bf62mkKOZ)y0_xMvSxQ%^`r{L+h zGXS|fD*HbM`+4I}vP()e|Kpy&pTz}((j+FT9;Iln$;?w53t(hB4iQNU4v7{fY){8J zx>D2ief^Ye1YkJp#JtfRn%C0k#*@GA@OM*{k%I~${D`U^BEJb?Ml5zMLrK+mM9mK= zmc8y*AIV!w^nZ$P-YG*!S8^I+^NuRqhHtdn4tEuenCV5^D#w66WRw~*RUSv36C^VQ z%d3yI6UcFK61UBmUfwMVLH1EVc5|tbjk~8WBnYQQf5sS)w{n*+wCb9(jxC3zMi0q< z=f7G}ClNK{yBtT8V1VptLd9n*{VvJ<`fY3oSQmI8?0bn{C}7q2692`{c+z1pZ|#-L zY@9rxJ6+dU@os?}&GO#?obg1zVpqU`=};fX&SuB-RG=AbenqCYf+*9w6f(ihH1Qj^ zjaDu>$o;G2lPbq$v<#QBbSk5#d^0&^-~Y#!2g6|}<&hyDG9nRm11jSo0*g2Q{mQ*j zlK8IJ)uTV6hvaQFfAoM>$&jpjLfA;D_M6}R1QC6n6a?IyR7ZH7@A`05Mz%o3k!`m2 zgB0nzajIcU=q`I;ESvHC^_8_X$wo+|^*e1`4)2SLQFvUA($7lh$xkG{hF^`BBvI7( zGsMKW9BoAr5^Kzdi#@GG8`H~M^rfcGaIncQVeds#R-ao^o`n$NF(lQ}6}0`?#VBx0 zud3a~@$cjq8Qc6`o?bPP;A(5zjF*12LW1M69jU|moP`sF_rwN@f=s}1Vod#cUR&~< zx)cRBVvgO&@q%s1NvSoN1)(9ws=Mnb3c=P;5j)GGhJ%xC0xzIv1m_QSM6SIChIFX5 z&0z-*iu$qI@#cdL^cuaniE!P=-KF~jMO0j?mP*@5`sw%P9 z6{i5SCPKnf6hmBRJn)~Qr6)AUee3-HwFX{nm&H|50XOyn9qW{N-OKrzng;6o=E^>FxWZ$j&lOW$j zgw`*w3TxBmU)=^0J`_sZi*M`Xb-Upudxjs6y?)OT{?0;)^kfc$Y)qo7?AM%rN~y5V zn7aZoZTQDoBC2L#7IC7TF(!s!3@R3NjhByaqLdRO1;u+!*OF)=L+~InpUs1g5$S5tazr_*ZM!f-)|1QH%W1V2jIe_qo5t(G)S5Y;R_Mz0ToJMa(~)H@5q1g9kh{Y2&sU z*d@@=_(N)2y`Sr{QMB=NOz+OM!}DKyFvM-q8J-G5Z)Ex~cof$QCZHZbC&1o zNUO;i;!x6{rdzgOUr%?xNW@rH$Dm5~%9V~v4)l*Y{racvxbC$A#@pIv@3`yzPP#PY5MP$y*H-Z_x=7DQ=m zk|a(TpL-kbOBT=_zj%!!{}1k$c&O>r0Lq(WVyEXbGjX8cu_?Z=(E20s2hN8Epy~Fx zb$(M-4)ATzhW+n3xY=v#)-`SM4cvRpwlH~mT$&Vyg@h%6f?O04HV5Ab)Ph6Rtq+k? zzvVga@m)kM#)p@FU@8vT)ApqoV`8KUOOmKO9Y0;L_Vf=7yx^y&?@220&O5#*lyg0r zy6CZr(;SO(`!+vu{Pk&lQ&qxK^&%8vVC!%f8alFvOIh(6K{_YEjzdg=$qYsGpyvhl~ zPd@m?M#=m*o&Pk^oJa0VHQIlU%PIKdt_hW4X8~8yg z7}#}ob)5R{2@=V_L_`)J?{DcL?GJPsHR>7qePAB(btHdj>gBYyyF*|SILgCqW=;|( z=EU(ME)It9lUA!hO@1DIt^3Gq40VlI)Jcwrib9gpEXRA+>d@ZpZ-R!YVQ$rfi!Ay* zyos-zrs#-aYepJ_0hD2V9)@S@XZ$uBawxQ@YD2}GOErel?@OLc@i7vA#U&;B_fHlq z{?IA$)Yh3kw+9D)P}XEAz@s+D$^Q``9ldLu6j50nW%^l&`bVZmz(<+me1OhMbY8k+ zr|IOjw)@c)lX|o)%X3#PJ3>YszCu9h$k~J@L?z59G*B+YGYK|Q%QUguPX+Oj75gkw zT0IRA-`WS8|I`-SpGa2M`mDYAk(BHX`Dbo3JQDeKFokLnCp0qT@g0masIY}R6rfMc z>vW9-(w;BSL_-S@THoe>xjyAWQA-oc4xD0CRuXPQFWq?+b)so*8DhTYK8e^_sbU0% zbd45iMWXtT=n4KNVC5CTr0@?8~Xt44k zlYhHlK=9L-TSg8+cw>))7N+>@wRk7H9x%AG{hZu6#NJV3lCl577%#2{%yIUCcr3Qb z@|y;CDrSe-%?rarqXT60B*V~>r|H()7}KY`GF`L9*Exc_KM+I{4)?XY z`z|WjUj#++kFQ^1u3Z_rS|9UV`?1c5Bw2j?Q0v)Fh8l$|8QOiUMdycCkH6~7THlDo z_NMotv*Y-9NdJ0k@1NV3435%4jwupDdzs3$_OYMmUSteTVovRNxIq5l;Zh^QY08RO zX+{otY5p&EsujL%BBg!zep8mI&8qx(qaNZ&Xq%>XqdZHjCXx)el*Da)pI;zVe}Ryn zQbD!9=);4U>aIaQ^{MLEOJ^R@;H`Pq&hjb62$rY;ImB77$-^k21Je;^XX+WldW=)P z^5rACPcXO+wVN$6md$SP3w)dZeI9&ZB|>n+2=QbmGy!)9r785*@V6jXoA>kj*XzN} zSv0#7Y*^~wC9-JA=m?~jH-F6&Z&SXe9&3yvNQl;7>}Yid*qO{?patZ{tZ(lF_Ms5T zn0F8*i{IAYMwV}%CXDffTjAHAu+>=!S}qtZ4J|JBSfEDpa|hVHLnmO6kojWTGSZ_8 zIb9{-?8BuB(F!zrBANJD{LMHA=EQ>c+tD0q_a9P5#D-;T%}0Hf$pl4hp=^=+pnxsc zV_wIS6waiHZ%e*2nL=~~z!E==Xc|>vFxu*jaqbsynK^n^mV(>ny;8rtmRa1JW;R!> zpEqSVFYxRuADWvVqh2TIT7Y!1Jw1{7nQPO-T+akPrv5*%k$(l4@Zw0H7AfI%tB^O0 zGhDbKWsal$k=Utwe`gz$@`iNytjvgnlP)@c4qUv6h8XYP@_}x;jk&a`YMbm#z|(u! z;p( zq3*n+6cg36GyTHG7@bwXB6Qs27oQa8vBg##@_AcbeX#n;i4Hq@FHc)MmF>xreNGu> z$*~j$CQc+OOo#f{K>p)f8mPdB3f%+Qetme(y%R;4#m|h=?0a&eAcOL57sV%{&+IDd zLl%QEC<>oLrwo~sLiCS$x!$9DH^EmXH@$&)E}=85w2)60{#eZwCs34NgO4%%h4%LW zd~_dl9j3&x6HN$KmP6( z;wa{?jdbD*guYX=JQFPY2jb(Iu2D2Yp@gwjx_5LxYGkFik8@Ux7Vc0&LMPqSIpwcM zRE_{Zm|Zm_M)*~~=;wT4=vubm@5@5awky20$YSU}A<)X~V^rz>l)xh&$uh+FQ*N{J zJ@zYmZwMLh7#&O4C(~CnK}sdAx?kh`_Qu-Cxl;&?ut^#_$HF5j^1FO7EsD+J1s@_f zYZJOinjwsfjBe0_! zq3ujA%!fGT&tyin@~8CouvLqx;`^MuMtdqpSS3V%AIwQ zjU0axczH73`1p;*Wm>4!Uu5$m)#iG2wRgGBJL<s zaD@^61CRb%W0q^tB@DVGP!hXX%qGUs8D0z(+G60(a6{PpgEVC`)wB3&{B2Ce#HFE{ zC{?Izeoox=fNxSHra2~o`V=hUeUQ(kfA^0^E#@?XEK@`b%6NYNew$!AT^UzLX!R?@ zV8okV(AJ|gPtByug?#+A!2B86I;ixb{#B6@D;o*M|DRaw$qDvHA>^8b#5;BA!DmEX zo$d%pc+VK{)k6IKQIRAzI38A8y6U?djk@@2R1u^k z2*W7o)RHzt_!oP6{cF&bV=UZro`^0%ic}KXmVFiJtZO#ig=rEd+<;>++FdQ=B_jE$ zlbd_pWOhig0EY3C#dhF{9{GwldoDfvCp0^1X&V=Bv5|QT`W&_tr?P4G<X#Fdv)PyIn$o?TKNWF zqLCXgyDi=4PMBfc1!@ATlq60`1cec3F&PU9TsWvH@!0hxevW#g4T{-@xQ?6ub&)kK zH|P5*+eh>i{0&BJ&=`^v$H&&J!k_-;PBQw)p_F3p6k%Q9ldfl!TWk}GUlSywhm~M+ zph%WuLTLDA@)<_|HjA@57+0|gr&VWeN_g4n8S$|C;~aLPUxMjRVFHQDX*ZbKVZ-BH zhGY~IvKIAf>T7V0*Xqk#Q49PNJR_s{f)qzU$G4-T?3K%H3`6>s=T-n{nTJNkPqxQ| zn>K>567(1rO~{KxuQV0at9i4%xH;SEXE-^?#Gfh9{o+lZm&bG53xKbmlsPK~->(`N z6xjK6DW3}xcqvMH#El-#H(yO}K#D9KZA;(*BYugN|Ac&A=qw-?Mthp_WNlBA_`N^s3_~TfKCWV=* zjKVy^2b30We{L@;^(DpypD{ROG*h$W%LxK=!5BK*2Ro#fTPj!s4{+S_FN06|FG0^? z{->}BS$JyKzb}dmhYt$~M+(3V!jtoZ)(}A!<(v@r#~psr~h$OgRST! zgICyn8m+^- z@EZINN!JvYY4>)sZQGt~H`z_LZQHi(nrWJeGucfwS(9z|WY_cE@BcgKsFUZn?`vOJ zYwc?}uITRkBD`0-nt^LZ!C3MQGK+IwGJAWLm)02Z5x0vET&JW_vaZjS_343^nr|e{ zdC^KtG3J0p!ppC|UNTnQ3<7EqFEWr>`eR&|Y4A|L*yIODTVQVbK7WZf61cO_Q@azRL(V-K6co zuSXQCg*TPYB)D`W=|2jW5)#Qud%-)Q7*EO5KrvP--W&t2)%AH%&_x7k;7n(of~fIm z#4nYu%|2E?5+25(#y#xJ0HQ^Y&`*$6}um@Cx?l<9DvS*t7AM_KL{3vE^jy%qrcB>JrkpYqM$*Jw&I7;4U+c|o&9H5VRYpT z8tgQm-!9UqAwmDJLWv#_lr!48VcEd@EYaLwPtHdzh~PFvM7myXh|JR%V0XeG4#JR- zlXEf3D2x`T7$xs0y20phU#_=gKrUtnO(f2{lR2Ya*d*vf7GrXKr>KUhb z{`RB^N1oy7sQp-nh^kbEne2M0vlK$k#HW;zB43`S<`T6T{4TF359JM7(O z5uX1bRU*a-p=>qA`~|Bb(3zAxDdXSz1*)-}QJ#mW(9N3~n~r{^Wr1qRso7H^I>30e zLY4=K5FUx_j{g{J33YY#^Q`O>Ob^vMmL$RqYJVOVF~?xKLl1ZQX5#o8eW!1ba+tyt ztQ5v~E<5{#hU3wn62wIiHLxNdogJ?y)zZ-s+b)+)w~r*`wfk_J?^dl_t4m%BmzTkt zq0>W}zmns*><#02Y84Cp?Zc12t@vM$VNsIBcB*49Ap-h zXMZ%Vl{~hwe{3Dm0E*Xa)Po2Yt02(L~-7 ztdQT#_z)-?SYqx{{p;GEEZv_ufen=T|MjlfR+K1l?6{I}Uf0>PbaqlUXRAoTn^L^6 z?_)8<`8d9?IhtE0BgFN1jE*&>3&auCeeh6|VF%dcxK=>gZ4Ck`vk(s#>W=*LSUX-f zG~c)>E_HHc|I8VKtiUKOSK%X-rd$v26vi&x5Qkk|C2+C+`Sc9M*tmFags)qsWi6}_ z8530r5|`XFY{hmL3E_*#rBy_nvCDQxyn@+C%)_yffjG8s@ggA?@6^c=kNc?Xs_(&p z@U&=K(PD+Brz6|mzM-X|tO6#&t2tag=H1iTLJZ1Dt~#_xIcEH^oN{=t#SsXHbUi)6 zz`dbXqPO?Z1hMcV6TW9J>?a2{QHD(mRps`@0->O`4WURN|B=!9Kt%6yB8r{FnlTSU zf~Z*eAWmgB6Eer^C|lk84TH4)h)3WITJI%oE(YVu%lD|N*Th@`i9Dz;h?{>g$*yfP zd1{wt)`;7n^jii~54p)hK-|vHvr@LGbk0AiOQVhc7wlY-rH%r}9eBSym}U4$fM7q^ z@8JB4o$(Z%(g5qPZ*$ye#+j`6TEKg5_p)XdeuJZLxEHIAi8plu>CsRGS1T_&Yjr5Q zs{5)?yz5PzH>cOxfZhBZo&O-5va7o(=YlxCG%gg9@DCP(S<>%>PJxR#>ZffRSq{tC z{$_NqtCv;t1}XH>(@JSBghT}Pcx6kzam`9#6&60(laD%UZ%d9j^JmzJP&;N!n%z6KCBQ1PP-M)_+I~{|db^)d z6u46>%V`rFIpK{g33dJ*VNOe;HC`3WL3OW^4vCv7$h3jBQN(MZ8r%F5Wlv~|;Vf4c z)__ZF!o+nLNidj<+-&BCXokeem|!V9mY`@tlQW&BQ0=-7?3?lv_1)b5&9r#Mm!uCh zgDw$*{%`BKRYnfcs$gD~R8f#{=spl83_)$4o7-qGE9~6p82~2#AmE7>ENS%-RFEH%ET>|OBqw;RO}a=a4dM%(LF>!@A>iprP8<2E_p$DM z9u9B)oArW&toR>H@Q@TidV=V`vDk{iA6w_w6`<~)GIfpH$T+5@b> zlT;h5ok80yq+i4!TIbEiSCKU7s%#0Jns%PW;Y(?rBmpyK*Y41MOi8u6rqwl4sI>+%17)R8X+p zY3u8ms2p+6x#4%(Uc7g|f_wdqjlPIm8U3mhwY>+2f&3ng49OH;%yx_|s(+!GXS zk$v^x>1}2;CqRvwR9D0p5|4uhLy#VO0SWs2Oln6TA%_D5Bs#mJMUdm>0+-m(tjN`uuuGx@6By?}U$q67f8p^uIhcv$Va(A9YegwIvQL%V^c4lO-!Lf2kVOGjNjC zgkGIRgUx5V>Tpsiob8Jd<4F{IGv{JwKZk{_|9Nb7lgMjqvXbEbPQgeB!>~q=Gf(JY zPKs>pBBOfz!_bhT*^*i+Q~q58{XkodHs!%R+0rOIyF&kY9bQzGpJd?iom8UOehKQ_ z9Z29$Jp+%>hj!a3QK7E<|6Go`up>*^iYl9%6NVJCo2)1G{R8}Gy-2z2%bB6@%sfmX zi#E#{=z|J#2jZV&CeU=X`=X;HIprYWAQd31P3ONO$!uBdS0d;e?j8iq)W#f1w4{&J zqg7x?sx^|JIJtT;^1NM?|A+Qqzrcn%c?IsyX^!GEhf-lC+-7Wn3zL(*2L>~q^k-s{ zP{tsffAge-{v?frhMvBkO&7En8EU^cybnMdj={_aa4?{FE)7)Q)5aGt+oA^Gkz9^y zw*`2_&C)Nr{mF$n)3I6Z`Ixzbl(_QAygdnP^&HuM}cBQ0RBw9;(D<^Ct_?L4_;uY>L0%Zs6Exyg#T2ZV_h zgD6YQur;D4SQChl25Hdd8(qG9ykn>4=z6X6Fp0)6qZGGc*1Yo*>#IurQCw&1*Y*B0=$CMCWixSZpnrbJ$5DZAONtV) zkgb<;0|4(gi*kp*?5O+mW?>vsJ_Mnoya-a@4B$m_rRQQxPF*v0o2i@3F??~~56XF| z_TTi_%q!%)&|>Sp>z1y-JUt_ReATWyOCP-}M?F@53?gTw9nWF6=^ucVrdH3qQD;K9 z$+mLaA_omNu~eoqXsLl8af^@U78a5+iS|ZH{33JJ%aA^@oE10>QVsSp z#hPE2EUG;XRU3)Du2t0Up&JBAvc=N(-q3kIIcpc0o}CfdCMk=NyI-Mi=d?s*p83Wa&+i<235ARmnDGUnA}S#&I=)maH%%tnrG)T`t4L z8k4Ud{!h0nxU0XXmm%wRUJyU@b5}s$cEXOEakX9lzCcjc3V{jll|)%5>z(yd=*8*o zit2vP&<2lM4b}=I=c!F26UV~`mqXXw^%V7}A;@A}W=S^@#T6o2q1W#>Q1%jv{7_#~ z8xi1|-ub1ey0@FKHJC~%HRFZ7R=531R;7`aV-lQqvDVt`ydgNSBL_CB0rn-{O=R%39F69YCheB{`P3 zt$>b+s_v}K@4IgxoQd}IMYA;3awDG#^eRWp#B#0pg|yGK51vv2zaN6;JF&ldx3dC+ zqYwe~Iy+1ue||}|1^?944|!A`V3;gYyN%D*kQ~}c9JTnSD7&&+OpArq==91<7Q9V4 z;DyOsHHH8)rj1g7LC3~pY@q&!`6+@L0%yAuiM58y(>IdOgc)rUYV9!_suF%ADdG0v zY(ag{?V@xY&Zil7vp`fl904`A^lSJwC`W{@c)rh$>$H7O$Ym$qz5z6^bN8vQCp>i+ z7~ly%dBaS~(jNQPLL6?&m`HvZzsBPD&fS4twjNq)a(Bg=b15klr%s9 zwEZd;=_DWox2V-jDTQu9l-BoXy3GR{I4#Q4pR_1CPBCgVSCGO53P^e{A}z$edAz} z@zwC<=hrrp^uJUK7{^>O@5i(=cz-+fVwEG3CCA-cu+sZO;W_ZlzNyhFNoLcF(9JwD zhkRnEbGv}7inl@A<)|N?e80n?zQV9ZtuY+r&Q1EY^=quNEf1+F>ihrh3mWC$oFAt6 zLZoroisDItCZMVDaE)j9kyF&-HA`wJH&`?_ovd4uy=<7>^({*u_5r*1U({0;6r z^U*IkC3}%DNGWm6MK5HgBHG9Qfzisfdb?G;4GXZ`&P? zFHh(QRW(XTHcN1saH`47EpOEeeJ+)Ti#)jx(s4bD&u_xc>m$pwOr@>9kZk&UiMTlV zW8;%+CQx!0sWBSc)f>A zS%#+%jAhkd?X9`&wcC_b^oS&9-PKg$Je3lrD|Ak->fDfom>25c-%(i*ZJMb>y+(!> z=;-_v_zzZ|$sp1muFZB3_Yu9M$)~6FJ7BjcNMWMw`p_!hh~G6cW7!5SkBEC z)K`rqHB2XPJ%PuIp3roCLE@bw+q5Bl3p>o40u}%(k6EQ?&r7!cDM1sH>gU+jcd8{Jb)K*~ftrsdn6<9u!B47F&$JKHpKNvjR1A^0lPD zKE#7>?506KJQ;E)uBZons64@LtpA`K!EG!U{K|;w>)Te>Sy2gfoKHhC zH+lqr-Ddw(APv;L-%4U~L;%m5v!yOiog1wVg|<4Wy(>xv*y~^4=+MIh zZIUNyjsEde%5&%M$M|NZJNF@Az=Zy0_x@z1O(85mA&GUF6{(o+Iz&;3>uZ%` z&ZxTRV`uyQ=#H@YKTqPeyKZQiz<7l!rLt5h1Yn)IbOmK)X6IxsXw6IX{$Ix1Rj-TH z-x=Oa2MWZ-+aHz-y+T1Aw*~u1e#6PaJ@$q;xeMnGdq2FNGcdxUC2d8Oy(a%qx$$~A zRyMbaU?3I;_Hm5?d49lb%@p26nP5#^?0e6b62!M2m|v{YIS}T0+D7Uw2o3b$L)WRe|w17iV@~&|rCg(k_04 zoqxMIpOqA~QOV&tVF2DWW7XfI=Hm|IpC_{3$WIEeK`%X^9e&=9x{Pt$_QU*X&6>Q+i1P*Z6df%x3>>*~}cnf{q5ThnHLRYWBX+P8HwU%>W z_8W^OOHotbrh_r=8Y6W49RRad`0EKW_rDJ-v^atO zK>TH@(3$^OXkh;DLkLyqb9ojPtwqCK#=n$&4;MIq;*f+ICo9Aq_QCZZE47k~mAU1F zw*jx|yk>`z{d1%yOxouyl9QMHVu+MQ(qYD7{*Pf*Kl_Ktuw|K6Ds7q;UsZ|RpGr^WoYONI632N;l5v8C{?tA?d&tqm`QCdOM&)4Lu}#Tgvm=95*^3d*%F)``qxfLq{! z#WCE*ippZ0$z<-1#q4kKg)RIaFUwFyM4K(i}rVH!x|HQS8D)RoJd zv+^`V)ipJF%wo?nbx+G9wvLWOS5xqdSYI>671}Oeh?jeufc_;s-k9bev;tFMG^tQv z8RB}^NDC`&GAX{z0bzx$Rq8WbfI#e`->!kjF90 z2iK4Alr&l_Q@P$K_b0lkFc>Uv*;e<+5E1kd7O=0JTr8U_rddH`I1I98)u{S0(R!Us z=w;Bly72!Vvb1ciBpf?cewkui!i~876@b+^5mYG>E>e9TJR%4gkglvwo4j)cLqA@R zh`lE(7w}>*McXFQ$+a>!DWgSImmU$J9$TcL@4iJLonG%0ejc=siy3hNb;sOJ3E*!< z1TOB3el6Zl77CtFWHzQEiQo1ot2T2TIv_vVBkxRa97)~}zn$Jo#5dVLoi-YzeiZu~ zYYyFWu$yHh7{4Z8o$-rwc9{NECQ#_~8Tekf13MVeW>|3q0VppL$}6=7++Ea*8;Wp-)H+~22qLU3sLy#`P+s81bHC8Eu>O*1R+HBbOWL~R>!ad zJMOjnrWtwQe2P7B=@FBpSyK9Ma?DbSi;b5#sp7jy^T6ze9- z3ctrUysYn{SvvjH_+7&)SbTAlu(dwqcT}jT>VsH&?!IvJ5hhC>fWSzbCYM=QB!j?^ zjkDExBKCYxf4L9ex;|Bv(}O-e{|qt+{!D3N-v1`>Cqq6OjeLyWW@7&bp^e+zeumuF zh*B55gP{1Qmj;I!bg1C1FwnQ0fMP{%BAfp3XP`O%8aq@Whbw97&JoxwS@y-}quyC} zaMqrs#loT!uc(`JA(T8;&5QM_n@5VMrJ#aqUQrmcqP;2&m6+H4!|%v#TBH~G4O-2& zc%xo#89U+k$eub<70i%%Sb_74Xms749g=}ZT2CKepYu0wGn6h*4b%K|1*fcjesvmGFGELruBOdkSwFd02#h6hNZdk60l4v^=~;`g-~yASXiSkeJJ1A6k6 zI=h`@dG7SqG!u67)4OA;#*>J9Dl}Q&2b-W?IyGua?T9cMphZNC{w?uc<%M)5r-Yny zbv4+M0X>SU-tQNyraa^FDh8>WPw{p~+hfpQPQ~VGD}4O8QJi-E?0uctP^T$jcE3Q? zx&B-6IIp&qD7oWj9I`zZIz0RtX$Y#M`z1q;F*o>7DLszHrdTxMs5l@$-oTA3@-F4`OE1-j4H%o1#UH*H?Nk2u~Atm7a=S>#0uO5v~u7WNAC1&4XAU(sl+i+{c(%14{ifuZB z1wlcx(zQwj^8b&(P_*}LH>C^33j6yj1u~TMXXy9oGK`O&r8c4$_5bKORE_uz`>0OX zFo3OxPmCq_wfMCMEtE^_-u(%u@bM3+V--x*EI*^|Hc@2|u}PunXx92fiZ zd2WmC5Sin&O)E;^OIOoUgpWD^crr37l4BIuyCYO8az`pEA{D;c4qAWg?X{Y(Mve5? ziC{v%yWbsA5UdK!PBD2lmMlYvF1xMmbU8?q1%0ilL0xNk39&J?iQ40j9K;+u;52!; zxt|CK#_Xu`c$n~LyTxx!o3wtu!>=nBH5$pApXzHm4_;m4ma<(ZboDqH;xe<$(i*C~0;K2NgFUD@Q(lL0dA8g;c=J z!{af8yX5wKkn_p%ubO{AfZt{Nk)4y%fe5G_17e;V{g}i%>c~&duE}zg%K5n;op5gT zvr3lhU7z_9U%&Hu&?D#>kf8zG_@M`1GR+)TxgkNM3IqbyZmKwv>zI9t;JDGWk%Bt% z3(tAYkpNqemWL<0bzdI)zB&h#zT@laeN5s)S1|U5zwrJb82_cyl(~s9r-s0g;lFEVbcQ zdNf$6DoYjeq#GOzSpm-<)6Q0hCtO#;q(*$RUP0n&2;8Kbp)1$W;9fC6z`;*qw%O$; z{Jfv>XYbRG_=rlB%!ikN9W|6VH;5zrZ^uTxaw}7sHJ1<5`JalWLq7CX1nsEer1Oi5 zSt!~;J+HPdE=Pmp9~d=Sq&=X^e%<3fib!dNe%98v&_FuHCIMxc)!6ro55$j4ek5h$ zH`BGPGU^ppy_jvH?~qG+4X=*?srg^i^o{{_g*$YE_M*lpLxUw@k2Oorixo=F0TC|3 zE*|sPhjwnK5b6q3Tyw=O^LL3c8#(a(%;eC5{1xY`k`VSh%EhlvQMGdh^yRy|%q=&+ zz7cvHr0d!LT@^sk2i0oETn2XZJ)zVLnKNLl#Hn=5$h#2&Y0A?Oia{3ng36PVhHlSZhQZIWcEoe>;ufzh zWV|k`u^>h&vxq2UlfGNwDFGY2Xfur(oEfhQFxOhfu$k%+844Ar?_nPOf6-V|TTicu zNDEc4-+l4nBLEAhBtoWzfY^f{i2j-^`@N5g3M;Nu{%6U8TkY1FKCw6|G;qs9!`Q4s zrl}xCt`V!ufg;K&CObr9fA4ML7Wf=$F`ON4ccE#i^@^m3|bn z6-WGw>eILy$8JRfrir;B zb~UD)R1J&836JM{cF@6I$r}Oy`B`#yuhmVqIC17V8G6oEz3onQGGvW$^DQ;{jw0`K z>dg%jiHCn-YV;lAWaEE@3OpzijyhZQ-TZh3R$Tz^HYqcvgD&kwpGQ?;oNNM~9JLmn zMw%QiJ3*q3Ye*f+4-i|ApC&Po@mNZ=nB4Y~_}u5@Gvw&zb+w}=3;h4y;ULN?rH>*c zDI*FBt^y}1K;kj+NvTAX6yP3u#+l)r5`wD8C_TN?r{;BvXZ~7t0JFv!hZnR#8-Ko! zX(yN|66ZL&uL*7%nS$T6VLV=1%i^hxgBTANv$_i8rF`Y&lsrh-r*4 zBia0+@Jp;O4A1c|Bh(P&|6mOW2~!W!6lp==zbWPB0uYgdX4$L;pX>M%h_VpQEt#QM zt3KIlM3Rl0-Je5A!`YxTfEe#8RnBHG5)SVr<<6I&#h1es6x8MUEBT%(g|I2M^Hx%t zEl(tSo|6jr!CeX0!YPJq31$TFL584j!ZW8D&NqKk)M&KV0`G~ze=b@-NJhN!1T64+ zdmn?HJKtj_3i#m1nWVtUdK`hv2%WVD^lD<*cKsD<6x>08FG8`V>e3P308_!94a*BYl86{R{DZTjhwm)trlB*IoIL+ zirn{qz%|F|#REJ1rvm1{_yX(J=!nf((Kkg45u!>90a;f8XVXe8-j2kza0IEwPtn?M zYAsYM(K0#YW;AC6*JxYl-adiv(iQ*u@nj(SUgMA}U_n<@B=Xb~A{Xz*|8&zg6PPLa zRf_SjTwl4^Z}*evbxn%v#e&K91ecBL<`0j&Pw$Ro{!hU`7)bJC^?Qh*3~t|~1Q*U$ z$d=)FdVAk?7xav?gF3J~&CTfh9+&n4W33;^b+&^-e8p(gtIkPB1WJ!|n6iQZ z*AKu;B2Zq{CoZrKdg)8$oY|ZgCJJ@iR2ZF%8XJE5Zagyqk39|mPRJni8~JPuHBXDm zmZ@zUY`v(GjO>IXPaU=GCGWKD(P1JjGylc>Z7&D;3SE z{=u>yvHq^8y!{~PxHXC_j*^TYN=5MS$5;WPu}BdDz%kVZ$^M@ghG&90FWDAc4yPAm zfQ*!M2a`brVT8hu;ozje@R?z6onk&p=3-{}-44XlX*TUQ1dMyk@(T=Hv5*Wpz#ExD>8 zr$j2E&z^>S7^9?2#26%JJ>$?RV$T?gCV^p9>^-4}3c`cb0!&G37uWM8>k2HzrS0u` z$ZTyegB;;QU1NWK=r$JO=djYP6-e-T=12cd$G0Lmq0H>#P;OciYP&flwsj(%1D$}K z!!;z}<7Q}j&NNw;J$>-q97}Z9E2~%~gfY?F`L{;A;FXYYI(xFqbtiPbA|e5ZAOtW6 zCNxhM4>8wwN$?9N>axi577THC0za4Ex$9cLX~kH0`e;fBB(0DH@L{K#UYSA2OTuj% z;JPE7HQS}D)=;0NF}1-hm`Ic#s;`Uu%GeTT^P2{JKC)Xlzk}XYO2{-}^&!4Pd%h%j zzZ6$r1pLOuXn*NOfid^QTO0v`0{~%69tSI?(I*>Sb6=SnNW>Ci7*f%n zYde8WkI(O6o+0ECC6C=l&+nbPNQZ$k}0HT{EbPVaLLN---F$F5B_dYjkzB z4?^Gf9-~Z6lU1nFEcdFF17FuncA{i%W2MVIAMaeBW!d(^(R*SZLtX}#tztT)^KJP> z`a;NIpon9Bd@B`>x`EX|tgJQ*;LZC3}#E(>Ty+7a?2VQ^Sb-DcZ@_hE|HxH-X+-xEt7Zjyui}S`9 z`NtLD`1w9!$>pbU4U>Gspn$CCbFGd*dqpbKuDlR>giR?LHDGYkn5*S3Qq zqtWjqM#T0)v{?R2J70q}A;Lsu-A>Ak?}?4y+?leWB4{g)5mqDS8l+kgv+w+I7=$QI z^Al6vL5LVHu2hEA5YsWF=FeFQjvO9#=D1be>wuX1rU3qRQau=7S$T5bedR-fGX`p; zv8L9cRF~yyt2HF!|xo3K1T2hCl2+_~WG8?4^EO z8TIO~iRC^bK!xx-rjO(5wVZ#+W;cxM@2fdd$8q{ zw_n3!Yp63RuogcJtnN&4**^)1|99N%aOz&HS^44y46d6@8Md{u_^T@6v&43f8iKKLVo4ip|8y{V(Mta~)yn5)1`c7b<1Mq;#ER zW(t$vhyrk**SAk>$ZUqj$DjIM+4ts4UPx-R@;5h&jY#evlKQl@=N10AESM8XN-J(j~R&X_e&cM&eLNwuZUa*LBgZ&E!~ zX?IKu8YKzR^>oQA7P-(75>W;#F#Q@Xz1PBlp{t%nT*N}HEahRcC)00UF7ngPi3HiLgEWJJO^_uMsE7R;E<`d;#nUlFkQe~rI-g;*S zREBHx?`0|y3*2`rXS$Q!gu07C_E3=^7Yo}-T5t$nHTXcngcEQveQF9HXOlDcCY%U% zMYd+~%-yPu29E<}1^W7NBAK+W{k11N)^cH&Oq=y==X>*KDA(ztGxQ%Y6c9MGd=+hH z0qu8#po2BA+b!BiXBf17V2K>fSd*2a?!z3Gc_TwzC$%XMgfv)YD@|1_erBK2@m}&%o(OfFp;|Yz!VuLJB#GNG7S^`u`eav#m&{z zrLBAc;*c#aOC}8a?a!}U2bWuKU1Ky1))To?JWGaycPBR6ucA?skjnEwLuuX^suABj zJh`1&U#w80Wxm49{s|QIEM1PtvNrq(jo;6_3C1knK}cd%=FgT9EfHZkh>sW+Dt$&j zb<(=Bt|t7&-ShGCxj4w1uu22A3a6uv%Tf+nvzlZiO*Xl-xw&Y~rMGAcpqm}n8`3O= z{}dMWd4-H|0Rp@m4L>*#0U~9i+pFG# zc@wdc?uv^oLrj09o!oK1M$D`6c*ogN5@L%JPjw>lec};6ki8 z!YR*t2PCILt+n_)rHSozOgV!-am4w$jbc&7^@ZcTbfATkJw_oPHTmBw)V=N7JOj~R zQBxD8QKK8QIaS}jRtL5LPlm&KU`STfu?^XX-s;tLUfxPmeTpA?BZJ30=}5j zoW*Fip0Hd@%;jFwV0{;Ooh{&u7Vd_H&J0JS5r z=uZ}(A+G=&86Xux@{*I$b{qL8CnvQUPH<&NSYz)7@Fcp)G0>K4#IHeg-(B=?8nRlC zpjWZEA@$(b(1O2adO@X~?HnHRK2?1<6`d!C4YY`YO71wV$7?3ImR%wJuQntz}hneLPLbemZ=VPS(nPY&c!v4p`V<213OmFfvREp=WfR$d+t~(sZtsCDAu(QrBjc*~m@eF^ zuDX~!e4{=mVD?+`ax?Pj>&q4a`(xNX$hLyk;_5oTI+Roa62qD`DXg;0-2{_2d^#22 zjp@e`J&RFCtRwFrey=BP^OR@^Uz(|h2iNVP$cSp~?+=lS7ms$7XtQ&?x2RNt;i=m* z(veH@g#ZTcp%`oh*nA|T42IIwS~Zr{Oa-)joS3A;t?S^<#b*<%`_oniym16dIT|XG zkT-^EWg$$UOYH+U3*`#gu#M@^V9N&vayH57`N%meglR9}Y3y7gym?26M1cB?_tO0r-zmq_{hG^2=ETp_lx?&pAN6RlaJZb zj$1uN8LFaLnyMlZBPG7MA>hXl>YVYLiF110=P|`D&>Z@8N=XkM;DotSB)0od@&-gx z!;%rW2g=Xn>QNZffOaWhdDnRf8?LnWa6E~}i0kCIMw^Dh<>+f4DgzR#c#i19JAXoz z+L9^~^W9LdSOqBh`8erv;n#D=;G2vRPMfJhiYxjIhBAhDh2K@^o>JzYy%g3QE1{~w z7FZgHYvIJmgp`8O1`jTolTdg+R!NHiy<)|GdPU-WHs*2TlY5aw>I-llR28HC7J{b# z&zNR-#wT*NbJiK6Xo)h6f2Y%VUXb*vB3UkhwiGAz^`@BQ%ypjO{9CN-LRAf6*=_Qx0 zCO3HN-Eu6F2|<*&lVzJPy~M+WTkz9BNUtYQw#a0j#>pwE(0$DJb0UF)sw$t3krxlT z*c*q2LVBDLR4;=6a}?Ah4g({@5y|Qfc38s2zRT@z|4x84K`S&;pv@GK% z|9*vvlPNG0ubI71iR3Cprw*g=P_Fve%ObFU_kZS zyh`f>kH-uXO9Degq<{Ba+;B+w+1Ky2$^7nK;GQhHr0jj^uKNV$LHV<_s9-o)D#3^l zg>tjT_4cqsOJj}+I1S*n@24x;lFcdj65F;!qs)pWb61_A2#LaIH(=ihlKf(*jHkQK zF*2{=-+G@yFZ=!tY=Ha$jhUF_#gL;|=r^qQwol)?e_C5dou`x`N8@JnpTMUUK)#BU zs%`k9z+v0PEV+n2)CO2)`Ud0hpvb9-E=Oiwjy6MOM7q%L#V-Wk<@~GQr+q0XU&~Du48` z=TQWRyK7&P>Bo~#NSUbg6qK0=3K+px4OnWT3LIzT`7=t8-dl*|i?wagU*P%(ClK?< zfKD=T@3VSI0-%ERxDH^i{`os8-U<_u(6J`CK2GMUE8^Jk+YXr99tB|8%TgdQ;QJu% z?n!cxM1AA64EMUmPZ?dJaa;GVBe#XN+M|3~Bx>$1Z>z*`?k=V}J30Wv&g%B6ETw9E z<$2$&S2nBFUv@Z1dXi;6t(40Nr-^NNc}ijOMn z!hMAmf`Y-%vs< z!`t6x6S;ZT7YSA$cl8^#Ez>^Eoe>G_U6D>}t6N^!C!2_w8h^|`2@0*X?U|ECr7sQ&Jp+^PBIqRFDoki(3CsrF_u{A+e`vF~_R%Ff%X~C_GZIN3V&WysbU*`@=-Mv&msi!Pg=)0qC778DjjP)#VoShCVwveUBWe3WNnjg3SoU7=2=oIhZd6BG{!w+_U> zwdf2_dh$>>_ zbZD*)+0B?g8APxI;=@)fMCcP5rI#W^e$rL5t_jFtL#48*n>^hjD;eV-mn{ zft_U(7~+7iN%QUPNX!Occa~cs?Ch2D+?jHWylFG&OTsh5iCx}UrbQlMCQ(^4qm(~g zn)BH%D=+kI(Z^!l0eZ(6M?nH&gU+gkRiEs0x)o8`bXV8B-0ZfeyP{O(WYw~vX(Zae_A0ZC5qdpR*^q+`!Vy*Vktcbd7?@+^2qK!BJ(oR1L9 z@g|n*RAV%`VTT>F|57gFb|sPy5eBxwrr4s86YebeIKz3ko`Dg*X$dQ7qUCdyWJ2|x zyRXBib4M!``+mdzIxeAj!k}tuO`(xvezQNS#gz5kn)XQr^fOauaEtwaG}l!i`7UPg z>y?J{)3P4To|yt}LUc47T?sdU>Wj+!N-bTdYTw;ccD!)UeGd%#4Nf<+RTLqWC6TYn zrN>JOJGxF!B@w#dHmsei7tVIK*?R4z^(~eS3W64U+Ia+;Dc(liLPfUrR819uEc3>z zI)o1(8~E_seuUxlW~RHh4=nyPVljANDk|#6L9#MjqQ*j0H!0cvOC7^$|4;363K^uh zXvx7SeF=b7<@jFw_L?XWE18;7F_S9<@o`n?1jIs^=#$`(T6cW zY`v(>L%@Bz#CyR*q=YFxGSkEBsF}_464;x!Qz0Wh8ZO{d^V2swqOe|lGoNJIoPo{A zu#2xkq6S7Hl@d>^Ecd*{MM~ddV4o6NxZi^UV`ZisBl!Cv-)n?Myeq$wjSYOr%RES) zCjH;i()Bwigxre*+5+u0tiNArR|qFR#03X@I7teCRoYD}R4o^G0k^Hce}8gXMMNPd zQyOBDC zgo{lt*H`|dGsTez3ApmINIL@&$0BcBBH z!;Amo`IBp5@phMeAF&HbA?;PC*8f%QCN!DGx0dMd%kx1uXpnk(theM8v1}Ho>;35H?YL4sh3AVy=Pz9g0FKhYrF-gdvgn6N zFY0*HHL!=v{@)Tkp;#~qeTgvHme29|`TmI52j+@nGCY}Ys?%D_-28k*wY)|RH+>;T z@yYx&Em0CsvYxqlc`*}cf#PxZ@Bk67%c4@FwF{InzDNkbvirn}Wb%yfMMAmWPcNzgo7Zjjh} zmR0b4aD*q+I+l zA!U1Y3YLHm-EA91Y;msJKI|UUcE)Hrwbs4K^R*6V541zbXM`Mr8?kz(7Ranu%bs?_ zws`9eaW20dcGm9LI@o_(inVp~ZxT3U4MCPX+@_P@d7CWzZ$`pKkxZ#| zC28;F+b#O+1e>DTry+q&JsHtLz*;VCkt5jL9fmD6ok-gmPzg7sKY@aF$GJE!+L z+bGO8YHZtfW7`cHr?HbZwr#U98#GDdG`7vgwr%Y_Z@-y2m}{;%nSWp(?DxTX*1GTC z{Y=#LG@$%JmL_@4V>gxxtpSnw>r%Z=zvbfBRASQ6F3>zjeFJO1aGVcWAK3x zR5jV+Ss+rqSd}Jg;sXLbR|s5sY3D9b#oPOy=4Egk(x1%5rquj8x`^Al3{Yzd-%=I@ zdjs~g4a1?VYV0rgxXhKPU%_1|kkx1GFGqC5tIXNIgBR{5$B@M#?Z_e8xIiKA6g+-SjbkSr7SUCHWn)}=Jv$l77veijd$IT0zkk|DQvbf9a=*nf@*KRZU>ElOl z{j~Rvr&f|0m;n>A4e#fDo~63t)rUmTK2(}KNZiL;EpWd zSc%x!K+l|YmWS!&K5eSoF}HHh8QWCL8178$NA3O&Di$(~t0UbtGatJ4JZq)c0a6YD%gS#F2j?ms(m} z204XQ$;2O=Sc_~MpL*rS>yJGRPe{s|MzefV@B?%nZG_*Jh&5)WyEVI8TltmvkE!HC z&1F@^($v)JPL3f<^)6H$w~HthLCwZY`A;@^~ zW=2~wp2)~VqQ=g4Qpxa|VJ!Aqs%vk9m>!T)7JZsn0gRzg|_v;-der1YWA4#1n8MN~Xyfw=T_*0=`16 z_B76MD+{n;-ba=?moOGxt*xvM%1TMLJ74`el6U-#uG}$I_?=kAGz07zO=4*#n8^+F zb@2Xz{NXTAD9h&ln%tb`+49>!idLUF_cet%4i-^?UoHu?-^ED^;7i(h2~Pl@*@mw2p0=q$EkF!IX&+`#D1}H1$PXRE1s(|ATS?e4rg%D+2ZoyBK=9uyDWU zZl6bYI4csS_{~Y{AUJzCq@73#5cd|z95IcfD?Sw6g#D#Ef^ zs)>z@LsCUp_^lIv$!N1$Qc4?r+WL3CSe9lNxHB>0vyNJ)fHCgyU~G^G=z0qH5P_4E zc1RLQ^7D?p@U%|s>U^qYu2_HH8?{%)fZzG8dqZs&@vmA&V7k?eJf=4=Bm! z7xFrK1=TCb-=tpJncc4mT2usftoQu!aVaY}hE#lllgM8sSmBl{q#uyOELEvP$cHa^ z@Jah)%i}bH3|yEyyiA67r!wDu0oTEu1R9de?=mxV$RV{532A@PyHw@Di|yEF>=;)0 zxGXf|`$9-RomxNh#GgvPE%(RlYrp9R!rQ{P3Wa}mrIY6`N0-{&j}^LWOr<~kEQy(7 zn~=FzH%74h)H<=iL#CcYSABAB;L7J*6wSQe4Z&P8!z(PkI3^_y+l}*geqN1^L{QgA z2L~8G4Uzb#;~MIPsQ&Zqrbe@Pq3%0fSL3_|8*Qf5KtEdZ5@joFPWsK2xHZ~e4nF!C zc-sPkQ2jZVHs4!*{XZMx;y#n^f49%Wz%w1eu5=YF~kYdBa zXq0%3eYzs-fsIo%=Q{sgqvz4LwH1Zs=&|Qk4<9DCW~UQzn4QtdN9?|VB$8j> zj2?q?y3&kj2mD1O6S`02axiJApRXrQuNC=z%_t>9vR*o!ynbD3=!}^+{yC2y{+kC) z16INquJcM+Li^=gqE_zIPp%_gY*Ha|d@g3Cp&vvOnmI2@rvQ28m z_4N_Ps;AMEXIk!v1{E`=#u>dmpGs)PabTz31q^rp5eb3!VnB)9Z@tLp_nZ$bnjQi_F<@NMh;#jZX2}@T zc-U43l369ILXJ1@L4m7t+rVpb#Y)>G1u)U2ko5u{xtdrZU(c9Gl<4q2o8Wn5K z_tZHRglU+ouk z*wRnIURM`VM#!0vA0kz&UhwIw#Joby!=X zM-3icHn7oYkNFt{kbyKVQGQ{U{`MTS{AFOh>qB<+?NQR`7{TaIq+hvKGo*3A(hj?wd`i@A z{mF(Mg`7}2dl#ebhv9?}hbxS2m7{>=ph!&RorXCjW6)cuI)k}7)K{L#UAhCcxB}X>6l9 z;?f9Bn^B?Y@6)JOmFe=0)L-foI(kH1_gXz%i8)&bIrRJUaDsvB6h0BaKtTPDBt$XZ`e(o$*kh12*vTdRHADla-^YH{kPVwa%T4s; z%}u6(H_;mgdQ+~hzQo{TY=@A`T)+O+eVa;Ry;ima6BK*zAyDHm>nMNog8~flm6BP+ z2e1?PWJTwjYti5^5Q6PdVqEG zqC%|3B3JX)!xS%kdOP}^TCh5x3f>7uPNsC3b>Ig^dsMt8ZOh&)KTel=_bAX{>F&lT z*M0B$P^_g7f10me%DaE(rTKdzX%R*~a(xN1;UsPZIX$dUbGiDztwv9Mdnh~wbYGM> z2?p4ZGPAOp-)_b#gus_?jJHZbzCagw)osQ#R+1tr#o?l5?#efhGR_L90yKfnjWOsr zuj;>%c{085RUj(6>j{?d%S=3ma({5ABQ}!j*9I&0+rz0t(Cek;>4Gh%qEzegwBnB;KK^9t1XWp!)=?E)1uGHAFgk>Z!l8^ex~L^Q zI*T07em?v-{beN4CTSe(92M{DDPU>1&t#-}UxkMLaWH7N<9S2-=<#pWj1$-t5|%&r*p0jMdSHU|*6|w`oo}0NU(| zO`Ge%Sy_n;l;@GOB*>z|o6*LAAE-SY{G69}4V?r#XQM`F7JJM}U77I)im?qcr z;LE|JZ)RAlG{fjh**Yp}c1kx1v-PH4k*`|h_7Dy5pyXKH7_N7fK;LJS{FRvk2MD;i zKD~}qeZyh&7<%`34L~E)=LPjcXYr)e*0X#KzMjN~g&(&=SnJUnj^$9cD**6z1VfKiQPxTIJRx~4#tJ+lAfKk>y35B|RX zi3}K5stZk}x_mD<<3r>A>@>#Ch(LW2&Fk77DP_w=wEgwkrPtF{Y9*1oX3YNM9mVNg zj+L*K5uc7PE)KGtEgZK)!)2am0U);!4)a%E z(H_6ICw3(KSy@hk-6c~QRVExdEGNK!0<=cQ-8*lG%1gH0c^efvRr1@~q5;wfP@0qf zQ>J&qKL74ZRu&ooG&JdHn(dOjSUvZGpZm6=#zZEEMBJ!Nv`CS_T5; zBv+c9{cE_JJ3IApLr#KG0~BeUkE(v&kM_fExGm48x@en0S^jKE%Z#@k;^aFRUB9m| z11j7+7H|aFV1|?;oStcQc|qxP;0NIOAS4q1`4qNYn-Qk-<9AJ*bT?^Y2C6TeE3wQU zf}F%%mEs9%(l26}r=!SH$U3+j`V>l%!Zn^~CAXN_>^BgcS}4NMJ&uBn-kyHqeJUyw zS;9r|WJvwg%JTev3GU`l_GZ#)4S_+#!HASRK0l|PTaC8H>&I|RfmY+O`ew5;nFmHa z%;t#By};01-Y=hehl&?|KvR{cNTlNvh(=RkqVIH{^S=R94v;&p!!MDavusk^V>3*exsg1?Tif+RO>cWZ}FP0!7k1 zqm$1QrUae<^+1Kfr{N`oq=?RY$E|p`8JzrXMYy$(QZKepbBjmAu7GmS|2-kZAL?8) z*jTW~PjN1Ydk*L$m>f;x0GThQgGi>UjkY1;G^)Kqk85L?%FRrMoiTtV8UrEJ^LB!# z);0_1@lzzi{g{uoCO{(O%1+WPh>69*&~dP~`DXIgoP2aamo$al@(@UQ3oKJGF-n_zZ9NEX z^5m{P{|j+x03a^?E$_Ni$+!a39z8v6BjGVk1xe1~-CptIcSZinzQYU03oiCN#m5Xv zZL420LvxO@MK`(KEG*D1D!<|ln8Zm{a0ij@ELrnG*L)Kr>g9qkLWcOS+z&aVj|kK5 zwBT45g83}bS7)24o7wUtbh%wB@&-S${Y8FuTe+#}_ThI%Ga{uQ;}q zwmwgNq=R*%-dLb>=3%H1aj{rKdeS+h%eydQ;#I!=6vy9R|0G%F>O>vV19LX_lrd}{ z!&=wX1+p20@W{bJvwGree~?s+h%w|NXxq+aY>*A9HxUiSI1ybc1dHk&Za_Rv*=J`i zWc>d!vORd5#qFY@$k3&Y`5ccea$G)39kl}G!Q}R&ans!D>KL+NSCl}fH?G>C@=q0p z{E=Ww@rSY}Qr@khpi#C!UDj@sYM06z>?6o+MlXS}&jh$T+u>fk*S~T2c~X~NG|4@L zevYCME5QM>*E%jqUM3yRrpKBYusEg%emr&btp-VAZpz1?U|_#0Nxx$P$l@}d4yoAOb@33l)(ds_C%qdPn)Yyomd}gV1vGCkm;q+ zZT7Jt0|qEGx&xu9Q~&a+Q@p{r9)=Qp6QiP&i;MnSLBK--5HNJ=%;16f7SK`ec-)X^ z(IZbD0g!VjqPnXIAiIEr!4gr{?bj{F!bCdzj(dLn9O7mrjhbI_HWQTgY12|@TOp)p zHFIU0CDs(sX3one=;yD6Pn|M!SiN-&+CQWyAdX#xROLU<^L4|X z4ETcs^1K4qnYt~id%93FX|7s{SXvL@HvH=Q38$JciSf;!j;JtY`n4ZTc#30?TP2Ue z?FsT}VEktGQy%B9Un-;!bQ!Gf!|gyEXr0w$EIMqovL7bfn&V*o76Ppn@cCIn7`L}e zjr4s{qc`c;&YO8_6DBhibqqWu9OuhK_V*}R#7?*w4c6ryy%YZ)LDvgUPjG-&1BR`S zV(luS@<09uwAX@jQKVoBmty2`*v20+=3@y}4SbyRLhb6j$8GLl`I^;_E&Qph-rN)a zR6NgM>aaG?J&4aJF;WgruHjd=^Sr?KDOEC8vEo(oG*>)lz3e~H9K+3i!$M2Fu-HL` z7pm2ty}Z1&8?4alEhZpGL&PINhbwNO8yoqg8*HEdF-mp@q9X@(0QZ&mMN67VZGO{*z9rSwcr$EJ+9p<2u?|8N(Buhgi=`r&!tKO{&He{;*fE+ z&JwoIIV9B)tXQqI4tL~wj-6gr(Bi^CUcKO;4OHW^OC*O?K7&&emeO@ zcbj(^=xzn7pZm^;)|$VzTX$3pnWm>Y_3rNeMP!z0$NIPK7l34Vu>XLj>n(^gMX$E3 zzIVr=v|Fn64!N$NQseD#OT)Oi1pUlw>Hjv6J8B{JqnDdE&4oFy8Ql`7k;|+Zc?$JbB&1a=z0^SJ4;rb z-Aah^GH|1##ax6IBT2Y)sS2`X?B5Ss-d@rkZ?2X7LR8CSKV@8461*6#a%YTlv$P(m z`Z*rzr^uUUW}Rxc@4+}_FpU)4)4~7HIM~-R+k0e_rSe89dxaVX zNzWymxsD;yny55v-fens81)f>ar7kGo2GN)|e%N|O$z7>_%|MMCQ zJ$z1xxj9^}zN*g4l@cT}(*_ z8IWRe;26?J$S+imIxnY6;0w5lm~;yP%|dt4R6UA&@;Kg-Kr8jq@5Vn4TqymYc1fS- z@<1Vn&%l&=l{XFw+TcZoh#g}y+^JW-s}b{?2ii#$hKinLZ859#m4Y&|Res z2lP}jY3OmHeJ-3yO&{u&r)Q_db(T`ZxrOhdx6QcNb{JABrl%t_$-S}##RID)o+HTk zuDJ4?2qPA4I$vV_cOG>8<91sC=1BDBrngAbI!FRI7lO@GmkZ)Bkx03Nru2Q8wR{f< zd<@ymWH}y1p4j}~Hobp+|3xVSQ@|-|L~tNBku0J<00u2s(04O>>b;(`x4(Nu{<-y< z$(#V~sXikZf8_qFyE$C%`#t05;3E4ra4&LWEwy&y`GCR;QGZ2&|0OQ4vW}4xk&^%E zJK_HI)}7YN{QS1)Z+EZ>a>bM3`?68Pyii>Z{ZUrjNIo)!n^}h2dFQX`2rdU*fh@JD z&udqjQ-4F{+RfO+c!uH7Zqpy52L30mlddp`e3v=PAB$ z!?(Lbvz6NjY53OO^9OCPYUDL02Ea)&->P1b&?{7DsfOhe-+>Qz7uQUl>x^6oZ{7TY%Cx ze?A#dYML?RUl;e+F)>vDZDMiyVKXlkc>tI*F;NMC*wg^i4p_ccy{Nc0^^?HS6$r-` zHk)6}JiYq};eaeAu6Vdpqoim#{YTLnlgh_HRRj1>l_(bU{bw?yyO^Q>zgERL37k3|`)GJ2xu z_nVbMrQUmTY4vv~6gg5AZ16yqVxeQ~z^&Jp+P=kC5#Y*9U>_N!b$&DXOuOjw3#J3o zntthmZp|S4MLtQ@J2IN3E2PzovL*KuJAOgwwA3o!)XlnmXU`jqtq*vVQcO!$;@qY| zqi<8_zfv?*744HN!Z|)j(3=|k5Pw)x$q`);h#xQdGqTnIjs65HnY*9Uz`Nk{gM3;d zCS^z#l6(#e9+JF(W***Eh7AAnTI|mVWMs8*{`^aQB)TF|9TM4|gr67<#HsnF&XJ1- zXDDut#&Wgu)H*0LuMcj*?(b>O{X-(bhb@2Sxd79HJbl!F3Ajjd%DE!>p`Szs@ev>H z&!5;mpm}n@XxKs$LPijGf%WzpKZ6|PZ(SrR8#uo=C&=GZQ)X=d_Qg>?UNR5G#Sl18 zPYrqa$QZx_wi;LAxk$I~|aM1zYfR8T=RW#rLiVE6x8Ko?)9GbKEIx3dlhCQdmM1 zeZCBfXo2~R-^@3F2F75-`~blCYG)SL{JDvv0iWXvTd~U-Fc^G6nIP|Z1e;<-FYbAG z>ICv!1lhF4SV58NHHPEN;QJ+39nEp(X>Ng5Wt_pp6Z!uxLT~AR{Fgix`2wVz~II7UAa5AzRLR^)Py zSp%(HFq576iQyp2TM}Gza+uNkFVyh|Gmc?#N-9jezYS(PC_ki&eX#dtl;8hDVxjMV zp5}i?S{|4Ka%}zJB#O4S`m`#{)n$y=Ts2nN1j2pXcx5b_W>ZYgHdvW~)Dj{M*h!ox zu7w@_a#S)HQl{A6UIVpw+nvxHDfD*?n+$qY=7%-?;1vT&(DoHLgE3;)QNP!LM zr$}U^B*p*sXJ(D$pYkjAeGL|64&MEQ6l|jfoApw9zhV~mrZ$2Kh#yu%76==BV@ zzM|0Pc_BQm-+PJ;ztt1TI|1wU3 zQJC)fsuK|C3Ucs`Ku^Yy#2lQ&a-jQ#%UJx+Ei?MPBir$Usq;05^k+)A?W!z2s@GcO zX={2(WD3FN+X1e}PGq>1wH;zmxxtDxPYmiWqYYnDViwN8^5&S_zmme==RjU0=bOyg^4})O2EGO)amdf7@h;+#phIu%Ya7(M z9^RvVr>U0!PE5-N=*C`q95N>Km&un8iU{q6W6Px0rsw6o`In$jxb*S@TIsTALZEWo zyDzw^x=OGzA|KcDy3u;w# z?=jvBp|j|SbAo-!Ah82jz;cci11lQ;HVk|eNhS_7p~gc(=GKw5VoZ*@a_8z!@!={x zww|OUZF&Pn`*Z@2J2d#x_mEp~YM?PkA`@cElV!vVqmS)r(f=6$`ae=hgd+{1+i5`a z1Ry*@zW5nk$pkq0nyFj%FHxOp-a!wwiokV4u`<&U!F$T@H6WxmD;H7A{bnW>{HjJ3 zwvd>cS(xrJJc`likSJ~<3$^)pw9*->W2x7T+UX|HO2P*FdINFg8$UQ`0m$so0V2dA zC)Xb%K5pu{4f?0H$Su9sq+H+JIB3DpI^U}ImoEWZ#fPmkDCAF%Vj9VDe!ks1EDOx1 z7Dr#;NO>DQam^!4C?W;=&i*fW|Ue}D$ zVej?l8j*pgwfmSWyN*HQm-2Yh+G?Tzm_PtLW;G- z=~Ci01V(^Fi{z=Y*W1w|0cv%!DW4Mp`J(e&bzb!XQ%c$WG>MF#hsB5lKPABMy6I&v zC9oN6NO?q&%TT8SZSDP_zNo|1Xa)! z(eCttUo`Nhc0LqQFxAJDs{Smjeq6eU4z2E?s=}+ZLnGyXg)1IVn$Fpgk^AsTC`;bx z8*E80ZUB^>yb4L>HcdA+iKh;YOk_Kq+JfGwF{}=0^R0De*yS^Cm4tFhmZadoA^6(x zX+s2zwhs#_P53<#Hr;%?TQm9Ous{UH_|r$fVt5f0{|@`D8PXTK85I_LLn-aNnY z4CZ6K-3i!Jn7$apcfP*_45R37`!o$K$=wqPRl=9St1lzIJwyvz8cz2ED=|u!nbY~Q zHP{^qqO&prg@+Gx2HnBi-q{=yWyRYl?o3sXJq1r2e^7^ND63qCsBqa6u`;d;qUkvI zPg5X8OOcAH-EQQSz22?P|VvJK>74Qlzi1f42$ ziZzbrp-~4M+dF$Gi(Nf0I~qCxv)ox+)q5G9eo(H8#z3wP^#-2FeUcq_<;cf{THhdc zDYQ3aDM8#`T|={-GFs=kM>~Ip@A zKw;36dx7y4hf^Q;>8G9Y@&j({&}CW#^FfsS1MV6g)=-fAX$Uj1#N0Je+QtQnmv`Io zgxlQus+@gexD}PWZ+YN%k!R|Q_nG&#D^zd@K;&5GLEL#I*>*@*EgN?4dbNjxXth@1 zCZe#gD&77J&g-~ENv>dey?XB~{hW7BEkq6vp$Z2N-|oB7jDh?WHz7WgW&t) z-UB8t`{mNc`D;z_HEi>3n7Kh-m{}>oCW($QkZ;oTsr}|n`UXE*BF?t(@`~4PhJ4n> zVLBaeN_f6@?596Hj2ZER2*0@VxY>CUWGFXb8IJ^;CK(=M^k=DXRgE$>1ecC>6cW5 z>E#4K4z4*he)GbpgMx=yVBI_tmUg@0l&@bC+P_*?DjIIB*7kg+70y-!^<&b8Hm|W` zpB=(J$EFzCfE$!(7o1s)F!uLpr&ufBn!iQQt>OiI=@-|Id$HOi0)E}Z{G9269cF=s zA}w1+R2a!5J^aDm`Wm}j#SXn7(2J*T+d?E@@Kivk}=_!yyLK-WW z*b?;b68ZISW64XQ1?89B9+bP0WYnRdqk0mM2n$~ZUVeD8!K^ynfp!5LDlI;@&O;_A z1X5##oh5O#v`SmYBg&X#3)4DzGFAb_+FT-2OSSAMU^A}x&g{)&`Z?yq=SPup2( znSmpyASREx5KZ%~=8mR3jTryle7DGMH(NWX~QR2<82}E&Wh>!E2trDPCxZj;k4Jq80%j>wfC+DO%)2vM3QxRx0=1m3B=pm z$rPInBlIlMAv1Y0YU;b@GDVAtUKEj>x0dK~$}kAiQpxDPh@(#uCb&i*RqZE4?$Yle z(!tDMqjmXiQLkwJ!L*9-Y-9KF*?5JM^46)FlRl-g_{3p(q(pLT}i7DYOK+L2=-j45JY0L`VYPcOZtYWRw5|p ztG`R557n;TnCd<)EuL5ZoeX@jX!s41$29oo(@jwUov!0yeA*@VZWo`tr$(Al?1;7H zJcs{RMt#B?BHqp_E&l+my5&gwvj8MG6tD-^$DmNK+-?a`5lSyMr(4K~g|pAj*=<>* z=9fBVBt^=MNe3L6_u{j6AT%sx7N%s>}HPb zo3XgR+UO-vXxp+~W8SBrOxFal%wpTO$skTdgTmv=$+H@dzGmGPf{EcdV1_aNR04bsJ?O^ z6d?VA6788+yLUk}q#00$ZBaQHkSMk?ON}F(Dh@-%lD~|>ygltdEXwk>R7$sp2uIJ3 z9J>(5$;zS)L+;E$e@Jkkz?Vh>GAogG0PcayK|x>vi4NKT*K?8vj|8wL?gUZq2GXd21S>9(40`-x=N-e&Q7sZq+- zmYBoh^I;I8lKJ5H@!$EsU6pf&>5w;35BGf1e&u0PhCJytW!nctMV-fzcbuSkq&PM! z$?U}g*Rv~Mc{)+8e(rD3dO7MW1EIJEqlq%P01E4b+N6Q9y<>Ot^k^)7Kv5&NPCam5 zSyfiMy*59ZU4|!Ubrn7(^Xh@1$QDJo>c^C?DH^Nr+{oJq@o;k-hJeTf$UyekoC1if zIXK$=)_j^)fhHCSXO)k*z@k`ZrbIjQ@&Q<2lE6A+Fzq_8KOcTga>sLaO8MsU)+GSm~{A2!H1}9UhiRDKpMiE-;3E*i`Orvc*O<_LN|1EO12x zO;a=ln?O2M#oY#>+C zm3`x3>w^INFS2FYkmPV5U4B#_?^T6cZbJ)Iek9Ga9dQ5P(}=j}NN(aZwR?N~*$X{< zw-p*n3`ihRwV5a`?~`Qw24oClVb_B)@&m@mEr;N_?Y(h~zPp0lGY>CAA*o@Cv-|u> zmxr%Q=P`j)b{|SfV;x%Bymxe#m%jrIfBx8|UAyZ8ooiqmHj z@L{o44@&Vr9aiLHa#aTQH;G51%=s=}1{iLhZPOmtu>m9u6|*#{ngq*f%~p$&S+hH4 ziK<63b=E1Y3l^TIHWU;}`OPS#lzUsHATLMeR;$xg~X zbQ$8FNZM>bqz6I$D+=cMa4*!Q@|*&V^X+KUvh9laL*BVK{WNl{x_6Xk^rCtugjyMv z42dHZZH@;<@g&iF*#~)#dbm3ktx#;SmPutQ`;@_ekcoSn(YxsPx zZ@;0ZN!b1%AJyhpix4nYh2NV_S_6CTgxVd|q}yZ}+I*(f40o7mkWaYXm38=6Eoo2x5df zBReI28Zp+)dq2Y3;JlMMxn)DLIFl%OU6Nzk><*U+`$h*x0!t+W%9D6$5IVIYt{*Wp8Dgo1Rv{j?k(XM2xM4MM;}m4 z6HFNJBexMl^gc*aC<|8v!d~dh(4UjVJgU5{s%m;@3RJTmQE1|BCG2Lw$+)U-WZ8I> zp0@ls@?U?`qkci%cNymG|2Xe7z4QezCSw`gfyZOaKl|FzdvVsBHe$S-)jy$#vOc(2 zp1^Kz&oAA3M5I};n2wI~l*NUM%FZ5hTIM)?M5cT(Ze-}ihtg^ut{H4~AAvlR%>fHl z7eSgc>{QZRL=g?;I%4o_Tq(#GLk^e}=#4dP-WspEwakeO70GE`uQ?}M|F$j4XG#hr z`r)#vw&1R?R>u;!UU$r9X=ms7?7J*#g|9FC$0W)8ey?{tGCU{ z%=9Wz%u?OB&{7t|-fY||Exg`z{;cXze}hk$>dO1{i=fl(9PNdR@a=R41@xXZPe-1> z4rPgpaB7378j$S#v~n+@)799`sO+9E^=E?rWHYC-lGvb2a3bQ`^~_&es3*Pl9u(jn z1)49R<#Y=h-gENV+dWjpt-Mxe7%MBu+vMr+dGmhhyb|+%3Sfoas}GiihzrVF7l_@Z zMUqNR5-%IBIe2g0QX@S?<$22-oaC)2{PBpm&(wXzj*h}7FxgwGiltgbd;Zly6alD2 zW-PU18eRD|vKQg2ZrnQh+z_|v)X*=c;VYf22)GjrH{5s%j3NN2P>F38yNiCB5nI2S z@_RI)zZ3DY&EV zJDk8XRjH&Hj=cI+Prgl@^{e*L~SJflR1 z48drYFR0sa=}rfdlO7tp(AdsJ&Y5(7SneGA>df)T(O+&|P}xQhOMTmb+X3!+psxmc zoYHLg=p0UQ@~9{9<~8cA^z6-C+&!^O^fvO1z?3H1P*JPUU#mHUgT^9@qRyWqPv}ux z`3Y7`gR^^gig~{{V{F<~OyuQpnf%|*eMQfDfEqV!{qf@g%lBj#OU3LHzVQ2u^7WMn zDDn@BMDrvWF0<_@B-7|83zuvlA3o#uP$>l}Hn{MPkbp9)R{K+FvUnkM$({7B+g>LP z*;>g=b1&899-vm*VSRiDh&b^yobB1R&ykl`9}!r~>xjesLATXdH=#|gFIpRuA1g|- zUp7=19&=E>z^RWEl=!Ew9FVDzevM6b_k7EB6wn*Sbt^-_p5mwQaMY`p!0 z2+n%=MzcGLLj~oV7XcU{iwk64e@q+)A|9f_sW1V(>3n|assI43^xmT+1_u&%oB}9m zOYCITD%9addX`Ti-{J&*k^~$pyI-ATn@Jg4E?2C_@E0aNPuX1Ep*|$MpOn3#5^D{V zvYt;pc7X_foO^wI@#Xw$?|bfmY#MK0XzLn=%vet*#;0EBkN9W)NF-I+@i`QiqsZ|C z@p?`^RZqa=?X9Nhh-y55D1n7#Oxa(^hnUWB4il0DB9*(#oe*&% z9f6Eh>+w}A(YSdRM$4!827RzwnpA{dwdBQS;jD%mC)k<4eZ-%hue%F5A^L z?@N0}B0@?m@-lNqAyie&<~WLV(iBq(v7hBVTj|Lsd>(q)|9&y|!e~3Yh=-DtInSrq z%9CSY3*C|6qm;E_h8VQlL~ew;gsjSsXbag%-s(hHPy-5M{cQ;vLtSsyJuLKhD5MpU zLGs|A?axlQ%dRkk2HMJ|<7S{UtW%u5jw8d?kU5$jw}`XNaAp6yWV25?MStOr2<$7* zced%P#hH$dL9dU$ZHGj(u>Wm@a7TSyS}TXezWS%xXUww5@ERg9n&kcZL;c~+ORzxU zAK3x7ooQ-x?fqc>9gbLT%V52M+ z3}VHFd}!!Z?9m{VpMk1TZ_>(E`|BI^TT9xr$Ma{4^<$m0XOAQVj~#R};MhKs{&K|w z;W@}aMQNEM$Sd_O(eg928ihYIb)g_$UPQMK_xZ-!W5+0OsKZ0W&1;nRCR2Tb z+}8cJSfQ)u-&4-pd(5qZP;;`t2|jd3&wYI{gWDIuRpZ_)%JY*2x}sbN3!4N#Y@Ytm zuiJ{UGA`{-rlE0bfT@sDkY3jT zLEr63b>0LU^EU46AM($f#OQxjsJ?^kcUjRix7N+rr`$YME*LPnj)qt7k;22!a<;aK z-TFP^+&e<+uwTkboA{Y5RGKWmzE)^}lr%Rs;^Wxl=t5_M@Fh?r`M~A}ZBn;V^2Ui* zqc|T5&G8;2^knlo;*Gcjex~VLF3le3lL04ZOm#@=yGJyxAc-e4Wo!VkSEJM9u|&7a zUqK!1^Safon2+s@5ZZ;m!Keoxr96t=p%$RA7MF|U`M$|WYS#+~(!*q4lVsjPI&_y~ z?!h8dXV-KL8e;xR8JPY_I6}q5&7w>hq?@<>FiK|76%^wY#yMlKGxEA1Az4};-*atx z`Xw4$DoUXEdaBX(|PMydch7oDbh@JnP;MbK|gn0;~IP|e4Yb9^K zl^Fw$JxllbnbbutzP(>?l<^1&le%W4ns-8ElPil!N14*DrE(j?j?1{LKlxRqvl_Uke(7lks+(06K#mNiHO7}oJH7;S4EZQ}||zqQ*Yu2gZEWwO)=Fb(D`i`sUKR972b zC>EYc9^UGs2O#$l#Bx;Ib!!BHLFGA%1~xy<%|D69TeJmRwD zCSoO%UkBBcyP`;t&)9pY@_b=8A+9_(J#+%lI4qbgZ(?{NWuOA6l1CiIzsPW0H&e>G zQXO}ZBa}#HVlbZmpbjD)%t0UeHUCARneIs6v4^W*dP;4d@qt++6K27WKwl{`Rw**t zj~}iyuSf-T0F-2sH<8;m@bl2s{YV>|$ivE4>M}22t?GcMxc#GaF=P2E(#v<_DCxvx zCE;Y#c!3N(mbQslf1%6MR+eJbTCJfj8ZOSVL~cZ?ueVei!-*cu3Z0dbRU-MRv3}|m zc<;738P)AwKo=%<|5hMUBa0I$y5MH=HHp!Whf{yc@EOZND>wos!)){YTl|J!ag}=F^ua4XKEU)HAmaK%&=+aBF<7ek`E4R@G0Wav zdu~3V1WYN3L5{k%+;`$m7hN@87NE&HTrYOYHgn4tNl<1l2s!4b55B;7;!KUGVDj*u zpM12hJYkVFXCPKi-Z*(zkqSlnHtty%3^RwR=d@4eLO9$4_jo>4E$9}Id(`D7nl3xO zRXHF~^;k_cTu8QHoFI1yZxQTs9mJR@zS9{@eXDx2K|!g!H!Qa3T9g6+>N7L{Y49HJ zT;2$2tSOb{c;R5aic$n8y*VJa4Q6><#em{+;wO}l+yiLL}^y|*!CL@ zV!|&>jZ;t%u&~U8$mQ#*ES3i9cKTA5ALXmyWm09(JB;P!!v1S{9B%VKyqr;u7P7St zYT5b3P!6FK(%?WA%%vXfyeS)WlahisR>Cm;^q>(>@D-8QeqsT)bmS=eHD%Oy{tvdk zF}m(2T06GUxUp?ER-*=u(WG&cG`4Nqw$a#ZY};;ZocqiFUF%)*U*bpb-VSG(qB+8J!fzKa$(!tL!yc%!pOH)X zK<=5dw*M(fCnYaG)=KVM#!CY;295uwWqXf+89W!+Wp?yk{cU?>d`BoiH`qI1uIEML zTXCoMOIDk$q%aJ5_!Cq6i9H7w$4u&_xc5n!n8$}KY7bDL?W1W(7Hx0Gt{bGl!AWDfH4l=Q`> z8XiA`STPMV?#E%WUJdAHrfi(^S>y)bQ&vJx={oJ!6{!IB!*s-1Gu7u8nHIWLi6BRq z=n(dc7B!vGm$g+!7ZPDUzY{g0CVeG)4@P|aC(A5h7HR#TKG01QCTq=o$Nx^Yasgq@ zaeQL-N*$=~j4+2Wv#{uK)B%no8G3b6wYm7q!VVvkxl;Fr&PDgK=#C4HPFxm)@XIyF z-CHk`P(#$Bo|%~V?YUE&+oiY{76Q*hIb>-ScgsVvJI(bX)bEkp3v~1-p0>2Aih(h2 z2Sa0BqwiwJVL=lt!}q_V_@7)lpO=~A<*4Zmy&2DG|9Lumt}8M<*z6K|IwSn>q>FcW zn6w1?t^cJC)&?U1)v01%jS=?Pcqe%F9X`Jt4Uc);x;|G%*EuO7=%5wt9sg)xe`F>d zl#8f+OhGEonj|T6isI_#B6eSfciC@YO7N?e!yj4i(ix7!gTLj2TwOso7X^Z<>8nPa>#X2zB^sN3{e`Kuf8mAqJmpMlu1)^2ivD76_%+;alMX#NsQA z_Qgz@0XuX~&A>u0TI_36Xe7#X2SvCQ|9-_NRR^Swb%%}DR2BRC7n&h^hz+f|af9Of zfeNmg>j{+oHo$HtAvW%W5hIClLv^)!;mKgOtv`|rFCiGfMYY!i1(gi%qFNgDjS*`3 zN6pSYHudyZO}Ct#{>bIS&F7C7-imzFb=vJZvixSndVjck^Zt>YcB0$R$f<~cK1mZs z@Ws&I4_|v;&&DW?L|-cjp@iIE;}z34)p@tKAZV%R8>%wTyLd#S>o^_iZ7djq*Ld`x z_I@0Y5xm*=jSwt?Y5Q};*t$GXD2l1bTL5gaFyO;_BNZ!VV)}lEbtG(gMhf zu~J2gBp-7Z_*79pvEcXWqz= z=vGINTUxiEkFdYX?0O#WShKelB-9+44YNBqL@pxMWd4_k+pXMu`+teJ7f=U$n(*1+ zZ_vmUoNu}_@6C%mAq!paSqr?L7f)!#w2jrbt7>bhh=~Q1PM52~4BN+H2Z}b~ufNJg z@Kc)725}eXvBxkxT_>X!+*7V|)!>5SKYmeiLc+N)1hhB~`IOxf1 zBWzh#y{Zwo+M_3nD$TqExfe^>8DJdR`hnP5N;#`p2AZ#h5@P~(RI>^x6D!5s`l|GG zBH@-xWTpFG!v%ONedw{GE++~P5DGBh2<&JHl=SAePB!|*bE9*n7`TQBt&2B$qVjZ@ z5o;_rP$Hniu1z`u2EYw>JnmX^$2@ZZg18z&^f`ec3vL2XRu!mcND_~oR5DNhX3pwd zLn06(2PqjidIR(3QG9?1I`))T_*PgQh-gV;nQTVCOpw?>ld^m373jonN-WVDkv1;BS5=i3PAZmSL40BMJ}k=DFLdSmO*sI?fK zSjD|rw!&&SMAT_|r$|`v$Wy80Xza!<%JOLAx^E){K+as}xvSG(FqXv=+Uk)jcz^vJ zLt>vpQSYq@ncLMJ6`r|r)g^z{t&ua=J{FkX$otr=CHN32(*7t%eM9X`vfFBE>HJUz zE}t`l;)#lURcn#<*O=(tUYkH+Py&WhM!11r*sA<%4b@n3=ezMvEbfS7tz~l1Gp^9f zsDp`|c9;_O^>>5^zphiygKbD4`idv?r?K7^`v^SKl5R5D>lHWGC#stsdPy@}n`%Ae zjF_xuA-9n{fK3Mrp}fT9q|pfjI-M2sCz2pnSo+#qAsE==6~}2J)#Lm_GVAFRQzxh# zlJ~LX*V+Red^18v#REttdIR(Vx9e6AS?|cCD`tfOX?5+$#Fo#ZOacjE?&|H|g3M00yHhg45ak&5m&!vefcN{2pIxR!eid`g3N&)KweAA+E#1^r(cslsvRhwLUW z19!u0DZTGve@fYRLw~C&D3JHgjJoi$*m!2#5okZ2EixU9g%(ex9zjqbbE3cVpL2RS zZzAH}*>+t`nkH}agJIt{$hKa5(UHmxgb=tJ`}zJf_LGdXj~-e>0-)JxdcXX1oAPyi z5N!H)HL)-ZrNZF8P?OaHs?AZ>F)SD}VLG_5Y5d$F9?>-^q=f?Li`dc+O+6nf)f&z6m+*zdWIe0Z$eXa3wI zY6mQ4GPCOsK|O){t!<4fKc){8(XYERAxuuK-kuyKr!AfS3r>%QF2bY?BGx)I1|K<8 znuVr2+%mBo{H#8DScTtTajYxw{=%7M7EAk(akU8jyJ>vOFh63W?q9Sh9@8HpQV0uO zqfIoSjwdQIw`PX50yDFUoun=~(}UYZ_&ISKLht$N$*R5&Kbf`)F|9OK_ONB|S?VuN zy98%i(e%c`#6FJhNXucCtYEBhx7suK!GtWUokK#j&Sr!SwjDQTfz@3-4+7qNPr{nl zdit1GZ9085@t|h*IjqdKi6w`aUp~)X^Yzl^3Sr8s(EY;(EaY#S*(gZtR z-_~xP$CKBUL-i`IaCGY0bDwsI)XzNx-UN((GVsrjlMr6cpm5wfCBjvl z*Q@0}|EYAy5lfPyd-fZ{)RDljaPd&XOQ;wdc3t7MBow(X=WFD=?4S}8t7#$93(P2 z#Y!mScbwi`IxX*_vZY5tN8zf6uc|>ond+@Yhj;SDBxhah{L8K+QMZXTu&((1P09S3 zfOzNif-9fEPwMyT-;qQ1keq(i^pkf+;Hd6lXYa4EPm-n&lLb&i6D0opasM@K@i0lMWNdDL$WUKR!E2?#3ZYs=qg*J|j$uozkb|!E=K3(|I%QqMl9ZP z`2*5*C4BMA^`=e`4L@oZEROdOvF(3)Yu;J)$7}TtNU!$vf12eZ>hybjRGD5SQ*& zhFiCI4ky5uJuuSX{Ni7+TwubZuNxssHUw;?QD95SxNGyL6_Eyz{HST(1J+}TkV0x0 z?e#eu6#&BCs@GOTK=YI9*$H115@o9|B_?Up6zX27`V>@EN}94@Ya5FmiF|V-;AT%B zRoT3?LIp#FGjP5Vq|~k(aY{D@-S2Q9v^g-o=?Pg+)!&0zW>#_M_Gv94Fy`zPTIz*G zG-3YLGBCaYUWy`^5Mw(A6W`_i80BBH7w=QvqG@e8Hp1qO2BqGoK_!np*zt(Z*oHmr z9H6&hNh9f`bZKnJg+aK6=H@p@Kt&0s@5r{l-%i5?-ug#zW3%LeI*9?(#a(`|j-}bm z(wF-_#~vi;zoub2c5nICr?8JRrp)_eh!aJgh6Lm1vDX(gMu~%E$C~f1D)exVj|C<$ zLs4_ez*vSZ!_y_o>DdZzDdSl?cou_-$aWD4nj9)tC8Nw99& zjmmSYV7s}mgPI-8&)W|?1iM8EFGv_$O&Y}fY%>acFgA*=ZQx>mO};-YUqk`lY7)}!@&2bf zIm1g7!QbdBEH1X}-pKDY`q%q4fahjpkeF5&Qe9m~VsPe@ey^m1mT!i1E91-y{PZ z9HJ5ha-m-!kz0z?f>Z6==;h@kciySrP3P*^*6w`;CP{!#p6vJ*oWEqhra(Cn-ZUC| zq`E0(^UaVo>)SEPB>H2IqU5)d!2}3y<9y4&IdNkENkIHt12a@s%(v;nvWcw>Szv`i zKZbX`wWO#F@;Os9Xv33KHG?85eB;`N>S(p`L1HM8wPvtcTSORv5_)BB&d7UD3@^rAO z{T*^&%XQn!Hr=1$OKK~lNZ%>wsC_?L&DsJ0TiGBYW!vg?b=>mz>tsu3s#37z*JUpD z_lHpGbl;z6aHI&Mf-*fV(uWI%yL*@&#iE(HT zsSydH0JYeXU&H#v?&fDatW$k9Brh*Aj{VbSOIT6yu*tz7*|4HN!A^i?&{5ahT>PRf z{$;r%kiAWlhrdSzvkcc!I)d5LkmYpolSV7c00H8x1}%XfhQs!JukM}iH+V#@yD!aA z#fd&tCBIN?Zd*8!2tUD)x>$LI;piQawdKO0BWoJw=*(+RNns|;a9MZGjHl$|r-H^{ z`hOE9ug*M16B1Ke^9wl5N^*@&lJBPB3?Sk*QJjgAVR|-~ju&$qoCGeiFmNYhrHp4mbrZD^O0-omdjkrB^qiaP*OREK8KZ(dU z#^`tr3U$3Ut(%PpS1hv=ydrM*8-w0a)7>0_+|DHy$J#p@SkRwe%K-sz(_)VN$_Y4?eEPIrV` z3%}lJhpKSBD%evQ$`~oKdRH*Hn`*BNB~U=(oY~D)slg)(K5E6=8g0^n*6bZ1*U6^e$s67S ze~%$FPdU9ixTt$9*jwSh6Ce>2?dSOKdOZEA#``@VMkxE^>(#;xk_={+7+4k@iVxKk zhZ3v*h-$~2xAT(7(ijy$hvp_9jnMuEw||U`fIxjHtV69+n1AYLIBAjRsu0hC# zlH=%@wYkw4C+-ekhtkhsRH?aKUsJjACgVzgzp8GE%OjwW{kGfCo?6Bu#ZOQQpHN7b z@3o5>S#M^L#*6AyZ{qcN+3+>+XZHzD4|3RyaD4jj7Cf-kMjKrbd4Ya*`;DEvau7mL z)ZD`>Zhmz1ht#l_lEO7{_K!#s7I8HX1Nra_IXMD{ZM*tt157<`K^nJZ`hW4ovMc4RrMi7qgkIHeLh4d0njX=bG1CWqw3?wAu8ZYSeU}-Vg|rnE)u`_PTJtrzrPdut3sB; z7XR&+g_Fv;oBmQuqV?48IG({@8mid`G3H7UTBjR8s>r{cML!bh{Rgsljw{gRAa@>M zF?pw-&Y|Ilgh1d87G2o>$POloP|zF;35=DnvO1_-Ct3udAxJM&Gf%a2!WDJXwa9rF zVXoSVz!d~omYtE9{fzghsr<{M*GMvJRtIF= z_zds6AE~^i&?b&c-0ykbr+YVUU#@3(2<=I?EOyr=@- zx|+x=ajB$-!g(kKGJTFUKj$Sz>n@I&<1EZ_jO|?!TZ?0hK#813KwAKn97|eiU0J>3 z%lz|~-6j*lt_+HEsXzfny0eR+UKqFD8H_yI?`yKl-26Q3K1&#iA5RNt%sbB5L8MDH zozjQTWFs{EbPzTo+?=B5nbDqA#7@IkT7K>c$c{aikonr4MB`WqVN6|ZR>qW&A~W}d zAvFiQteh|<^7|o~9a-uvWo(~Z`tjaeEMk3CZ3L(f-$(?gt4#|poCM(ayKOGdDZ?J8r<(;&<6u9VNwDd+R!A&3)V@t# zmYD5Fl;h*FlSVy*3wT=a4@87V{3WtRVff!A7vNUK_#j55un~>i7>Hg7ylF)QJ97dk zhOFiBox?V|(x)bgfB8QnaIp)&J2WxMGL6E#FCiwF6(&{*VLg8l}@&4v? z4aBm5rje42KCdAOUTbCcRM(@ z5unW!Hb+|DXWYj5`q7o@x0f@bk6J;G%A+seqA_!}$+$+LToin!bZ3S+4l|z6k;b=1 z=&K5zO#0nzxiBI?J)LvdZ%|H`{zO!B1m=X*G}A(1@T&Qy4?~ zm9^OAdWgW)SS`%u`{CLJr|r_dBODYK)=z$}JA_Jsd+ydCx!#|<*9}c4&Zu;EH2do# zI*aVxRrz!T2og`ew`?$4nZ6aAQ@@aJuZ8kCVMGz~I6J(n=JBzi1xHYo7Su}Gzqu-S zPafLw&1wwwWU7Q_u?3S=_bhQ)Kc)123_mzvQQLV>nfI!tUL); zNd>S$#UCHPJ=S{jg!{dbzW%AsR}* zQP)4h(0z#PnuHDRcw{=*t;eR`N*%a8)%I5gI@5_Vi8Ab7hhO(MgxK$w#A?+|dAG*- z$Y>!8U4w+hIn>%?_OlnQ^tVT82jxO;2857}F1HQV)J82D+^a2pfbIas)3@poQQ_a9 zrR+&210Z7bHngBG>DcdnYb>2FuwzO;@g%~Y{o2*pT(vXYWxY47y+UiEYgFP9Icn%N zZk<8{zWLna-27IwYLlSN`p#L47Ls}lLTvFmcVXPVd{VRO9sCQPxL)1w(JW9a_TB|IL$%M`J5B_qc`)U`wf*fZh zO+dMrfyt^iwz0om$Eqci=7_w!RwrBDN4};|h8k;U_5M&zF+Hr@su;a67`dr-U4QSq zdUyf@nqWFE)9vpS+6RT@7r}evo8FQq<({dPN5U{;{!-Lh0_g)=*ddR9-&^fzVcM|` zrdH?@6q`pRBs(Pd6XSfScuw;qC$i_px@}3aVAY(P^ekWurLIT@TcEH!7-nx(@wGwzYl0lynH1d{2hCpEWdvxu}&JthIeH` z^bAALRy{F!@l0u&H89f+g4i zpd}09jl1LF=HTafwx?7|9h>pZY0j@xbLeJEQIRTk%@>1hz*E3EuF$8AYBFYiKA@hj z>hkw{VqA9tGJ{Uc!IrJ<$7E1IKN+`-A!GIjyZriUuJn@hmtPgcZ5E^6p4w3Zx|w(? z+`bG?O>^#7M_o6(X4=gOG4(&ir}5t8QGsPWYF{LDl?$x<1tr0~sY_{ed3}+}wj*SI zebJo2^~N|~C)$wt0sG7$KDzSmEtSIO>jF2lQMbD3eU^zzd^rThz3nX|h(?oR#0!O= zw*irB0h-A6zGW@T6Jcw?sB##ln$2)LNrk$IzIyrb9`rOh@zbU??T`OV!7gRM>2PzE zZj9-Ay2L_u_F)a81rIQ#XCkzp@8s}m9cfaufdI^fhj50gincA|ex(1?A5aHIAr@J| zG{Cgr1*fRzj81Iv5aRY5C0@!xEGrCKyYn5O_NtVvXOTG0`9pw8eQX* z%+Sxm>(+|t<+f1#mZjx7B^%36gQ43W%4obU%z6i9Cr!GRFU?d zynnU+&T=pwKH1t9jvS6C*PIi?y89D}7{_F|0%>w%dcs$Vb9z}hr=0Ub0@Qi6IeN7~ zRjrYxKlN^lVPSX6&(WW%&ZSJuE=`jTdiNx+Czj7+0{~Z}Ea;hmMiKq3XP!VKlqT<( zY#=4^5t#>$=y02>Fb2{Q4K$9<4fp%aneuJTajE*VCTTV*3E(Q+_zpN?neYgcsqfTp zx`ORDXSmNu*R_zL#2N7g7MZU(u3oqtBn*4JrCH}J@E|$G|0d~a@*T&0IEv+(ygdnUaV z(jbjx$VxZ(*VU@YJ{$gQEZ3)`H_}oo+Dcc?k@csxKO1<=x`Z zKkoU;kG)Fy%_G`x`GvStvUif#B$Eis_-fnP+K1`KPb_`ovipmtw1R^$v(BXQJ~g5} z%a+BW?EmkWP&!z8rJ#je#?}$0SnV*4*fV%k&@(jodh#G94F>L+L;Y&Y`^UkkkVk}g zk&h^qt=rp7`rq>V=*cSur73!i0F0G6s+B*mT6p zIj+}3lhAcE|3C7YhQCuioDB5S3c_DGn~j8%T!HD7!%j5gBO4Q{Q?S(&LSR zzDl)@9exOR=nkYV*&5Bmt#5<8d*rP6`QThdh!lK??Ox8IOzIve{v9^d(YMKJ1I)RH|d*i zNr%~tIbNI?#q_+<5_a#u@-d z+QV475d=EJjjRQu#A2S5yS_a?*J#x5zQlD~>mIb238$2UY4{%d>zj)bsKBD-c1Jc; z!qC#pqG#$(j}|2B^@tmv?E&3E8}*rEG!}G_`7S6(EcX!{&F-z$9n*l@Z}vDz%Zlr! z4h`bui{~vs0a6bUZ!!E9QOJj2|oOrJv&OfuZVg0^d?3v zFOd+2la~==e?wV=eh;9N(8RVeg_ENfO>XgS%EB5IG&H@XjW(3ALLmWca3^mIasUP z1wRMO7qCV5yo5s%aK7k>*PFEAyws{&{K-UIMTOC-X7KJpX?6uMHp8}=O^ti;5dvqhT4zevaSIwbg-KJ%7n-sV ztDgmayq)cThuv+kv=m{MdPC+UjY}2f-51J_yME~R^zgW6{7>TIw1IZr6`?Fv|Fqki z9lmV7pDF3Qwd9vnBFt=LO30X*TW>#3OWDq>4_)`~QKvf0qS90z6}6B@=o0632ugA3 zK~U7mCXl5^ihi+DQL7`cX1$s;`63{`O=b5e1SZm69PK$;NV5!n8&jnyRncy z6PvuY%p>6v74YT64;c@yaom8`S1-wh;c*B>3@rl66ylYoq5_n*_M)=~88+Oj_#ChbCjwc0FTxE!($bUGz8+1ELG*r$M?ml zE&AA-?=x2!wqtOun3@SQUk_*CpiDFD_;v>)ceA~{LxSI*&=~0#XPGr6^0L30I({B< z=s`;-^mT7_xjW_{k49$S+F~Iel;V9;xg)%e#g%=JH$Jy;RU4n!(GnK-VTwt+Y`lD$ z=w2zlck)21v>Dn!o#9mD9AM7GDh`G>-Y zrM~ku`U4^ma)+M9sXpZY!4o7qNg%cPjC*W}UWm0Um$V|y37`mZKlM`!_Vh&yjOjkS zqT7FsH9($s;KVwv7~Z|-f#Ae{3g~P1rbvB|4(kaHphG|Tnq5-pvorpLr`DCR`zP6M zua$5u0C_(X3fmM+umMGcIX~M`2?f{oYqnS)5!ZtcI{>}RUZ2w>zfT{mUV1S%m{}H`7>dM zik9XjR8_GTy>7H5iCL32*I!@{1o^`+Pvcfr=vwh*9n^7Z9C73VIXDv#%MT7U{_tGP zmwbx`ZVlUeV&d(sE8D22jDa%sn+ole-9I??M)VUtI4v?_XD?qM_l4+7U15lEzI(+_ zU$|=o_`(MAT<)>_;iMwvXbt-meqfyPqVZ7lIowCQe8F}!=!ZQ;PrHJcJ8r&i>_lmn$KG+Za8**@s-WA+Df`Uanmw zI6{mon~beJb(Fb11?Xr|K{6+lW=jOR@!=7G8b*p)=&Ck*1m`b}KL4UP+ynvw?B*_Z zZ?^w)>~!EJle8Mcf1Bz55@0vPo9t)}vi9D_WqLc}3A(MMN@P^7BT@Z_%47U`m0@#K zE5Pl|=lu5cJ89A@@^uAkoJb@ih=mB*wayo#s!HGwuZsS1jmhsQPG;lOhfNCdX!u#s z7K{H-0PYvT5z^gV!n-Goz>LwEV)hEnIMZDVi7+6cR6|PBAt?%2-Uu^F*&1$M=%2Gf z0azrLWUqGB{^@rI7m<9(Uubxb&Tt_I1MwX6V}zwKhDdxR%2t0aBv71=bYLd9QwK1S zkSNmVsOPN4wHk$#art|g!eC>4^juC4F(0rW>h{M3`2rnme69TLd|e6ss>tRvpdu|!RphZVf59MKWeSlfL0lI3WvISY)KPWA}mti z6eSzONCyP`!Ivy5oqXG=P^Gb$t*u$Z{&EKekT@hQLm2eH$>MbbBSVdsd}xw{E1a~9 z6<0F?1jN|2a645@YYA?p-bBwqJ8?eM#(TEt{d=xOsr*H@{g*!CWGGSm-hkM{0k{BY z*lhG6IJgreOoHTw{mTPCLaXXeOEr!C&+0cCv^X4Sq{!$41RzX=W9i;~jxM?8y;gRt zUhpV^ZL?07VH{qwGwG9`oInp=-F7k!B|H>|gFMiNy1!-%LMj?_L-f(N$8J2|x;=V) z!2_Y9zH?T6U@;K839N&`%}E~19JK5=sXXn9**EXH19crLlDP?FiL^V-VO0(gx-$5u z1kKL`>h|xhhc{itprH(2d)MD5^#T0QswLK1gDCGg$2|f@`eh}z8yoSykvyP6@|zw6f3&o=Qw)Pz`&FP&52+R%f0Qx z5L|U&GSOpV(8A%ic@=P(MaFq?sCLXAH3LiQBYM2*C`J_=+i1sZj> zvXlVFfTN?M$I~_QO(3&}Zz}V|)&%UoopD#$;c5lNKO*@pMPYK4Vsttb#I?4Z`x4C} zp^6Zr$`xsehVwUgE;{5n@M)5;$3j!~a4^JJ5W2R5)C5y#1+`xfE#-9U+|0A?s`q-Z zj-(eDM`v4`!9*(6)w+Kg88XQiLAzt67FL01T%9 zo_sPommr653c|0}ba2`MV4|>2N!%U#WJySn_3q3+knwZa-aI3(_r#(70p9)CQ>ofL zDp0W*;-8yCmil3IU`%g1oKj-^*5Qk%;Mzw_^cBB5n5eM*9c+B6CxDiH^XJG| z6VHA#IwALOG-4rRiawaRxDhN`EGrqx@Te%1f&@bQvsyy8IdQHkYvYr-(y=VgbkpK5 zu$5e%KheMQh<7T)hJ6}_WhBh){thQblE*iqjKw&Rw#>UAH`?9B2|*glqCZCqJlV;` z5-gM7h9q%?8WC^;83@+pHYClmNO2&5bYLJz*4^AK)bwVAKGMHPl7x)+Iqw$&C9Kjr z2q=&5DV#h)6O#~sIhnqfDav!SHBfmH1vfZ0rYPe~ zP{ht>X7D|b`86xjOH1?x+^I-<@Ytk_RIK@O7RR>VAlUwI|J7W7Sv!ZfR4}(-2~=7_ ze?B7&%B9}J zs1z}5<9MeJCr=Pee*Ad7Sn+AMNdkQip?=Q zoiu2h)OuL{>$G)6vQv}Jq&~eAdiZI^U8v;Tr|BvP4k$@2yOp6++x9(IXmAahRtCiF zq)4HxSkPwIiftG|uCG;3T&cMZV!{%`DjE$pOVXMi3^9BabQ%VfJMH9V zK=***0wa{b8j>Uj!He9nDzOwJU!XLv1fYuY+|--?jfq_x*=5 zTz4rltT_sZqqLwbfRzWWiX{85@=R_~E&4O`q*QB+v6yPln?d97K^Mn|6PlPFPZ)u{Oo*SERn2meSDC zu2*9wX>SO603qrX`h&TJQZ|{*dqTj^7pziNt2&Qnq@2<>CU2+3k;HCO5q&X_&mvwmzy^Hp-zCAfANdZ{~d+33jj;;YkkF?Je z1)VBc`XpLaIjI)5*evHn=i^O(9;=|;!g9(qm?wT(t;{C?SxTHt$%(3c5d{|}H%Eje zr{2<$y6f$bFe|++j+eQbG;>63ib8{UfRW!cYIE*zw_f+Z<)h>z&{T(D1LY}InKz8Qq$u znGyiCaH#|SYNP9QD7EySioku>&@={$jIiyoWWp{PB1??<|O|f%I<}8QI7W55z45Aey0mG!2Le33#MZ` zfZa^fdD$|V&+C_Ge04DdinP+yXdK4`xn(HVhRkv34COX7An&&(im6oP@nPhUVu)B- zYqbl|DxOVPE#Q*a5CtpBV_&7wB`9MdKt~C@!%@j)2m@5&m{f9GQ&+)p!zLwV<+*}- zvRui98Vne4Pyl-*1K=FnVh2?j;>MMQ6#rdJ9lOcKNxIruOB8r~J#A_h!OTg z+NaZ59PPFALiX_RXe9pc^nax(tT~sL_ZNkmY3!?KX4qXm+}t{7E3)l>>>>0LW+z8I z>bu&7Rrx_A8SiH_s6xn~g_5*SQkavU59w2;NC?#*uvJE1B`yQyRg{$LXq23ol#B>X4kkh>g^H`z zD*M`dlO_eb#OIXul!f~S)7yLz2QjhoXg7IJuLj_3t6UL*5ohcAaDT~}3KYKQflTV# z1C;u7Jb;Eey@s~0QXED08QEs~I3FGs`FTNV+Tm-bemt`l94QT!ESNO#8$r)I+sBMU z%e5;d#C9KB-HqJNxFCTd{wqc(R9aC-M;0i`McG$b2H>}gRZbdkYUl8bjzvu=QirHv z;QGA=CrT11OzT^Y6~qJ&0|`g+8J>jmt0|dOsTqJphw!Oup|@gDJC)ZP``BnBogoCu z4bQXi61gjSlIbIG=HWydHl6`ai-wNL_^IECkomg90w3;i|BW3U23gQ~q35V-^pO>k z$K*`-nljyY+?K;CUS$hUlP(I}@_;Y_v}$p!a@49IFE2mfW6hkInc1-pvv2iqT1rC$ z4NM3cGLfqHv*BjuSiB524KGU5yCY0mLi_Cr{wD? z>4&T3`9~Bm%U|L5+CT|9=@)YQs@>zM(;{(1Nib;~hM5+Ornhb08r>2UB}~LT^SH@u zPN#Sko4>+!u86wvx7K0q7GME6ifem>x9!Pb3;^c{GnvyRKM_Zyo@U^9WP9-t`LV+O zk-`C>iCiQ5)3>bJ>{=T}dz>nf6u!`f0%{|yIntc`uU~6u0mcCubpva?tV__lhZE)d zL-|L+)Z-bc+dZm}@FIm-&b)YgL+klWCLKiB>icDT@dzfWk~Vg4qb@|zpy?!`7>&N- zNMef1U$Cgp{4qKP?9|<=-_--nN+Ne!|2eHc1fcO${ahbRpk@%C{6{P@UDtAMT~C9> zm}d}=qo>!mroNCDjPwoCz;J|rBL^IuC=A8-`p`~y-|A5%%YJ7w($nLf@FU_Z1ie*n zdNe%czJ9)63ZV-rT+TY8;47xih6?wW&dYX@0CY@G}6ecjMV1xJdO%)GjFKj`81_ zmOUFtzbrh9J1DxY=h_Ah>QU5>!)pfDb0q!6>Aq69rdAf+P)=vMU zk8h&xSXE;&xYq}Y=7uN}|FgUZUI7Oy36uItg-vP!DF#XWkJm9xs* z2df)jAbQXcfssN198U;=&8JmDe#$hYN+ZNzx4;UP)s7fu79a-h$9rz-P%-x@- z?%{}KU~^zep{C6oz7Yrgx9HCRuelK9rNLn1`4>+(!H?nYgZlFL5WE5YSmO;2tklCp zFyj%@`oGTviA6tNoFC&*>~C-h>iuK%RKy~8t+ zB^ZDT?7Esvz=S2rB*;)Y=st8Pe5l|{h}9|_09xn&{^r7eMdWkdZA%C=HUqRFpugGg zx70{|B*~-a$9>lyI#J9!va<4c-6b|1 zOJSucd}Yq~kl1gkOa*(;+e5re;r(r{2g%33D3FqD?(EEJ``0>p0sW!wWwAAzK4cCK z4uEy{mBbPj=*%S&rVUK^;P$q#Fq|(_C4Mf%_*i`#A}uArvVlzxU@@#e0NAr#5+1Bij14yrOUgYh1j+jE>b!htB_P5vl;Rl%kem)LqC(;LA_}Xl)#Cd#y~$Za?m& z8T_#F+UI2yX|QPb5HynhsG9b_=!O=VL-~RG<${fW}2QBmihg6Qol5m&mvm6gTnZBfSp|aPv|2A1L6cDnKRgxhM zEU@kpl=HgQe76H-Yp%9L6p`z&=q4a)agM!B#;?7nqfrxi@+Irq!q3mE0(9&NW7`gnPWh+ri@hH! z`!UotdjTL@(X2rKZrR2Wco^&>ylo+olEW3Q=n+4uTMME2>!@A8^(p0P5w_(yJ-m7E zCYjA?4VP@1CLY9}cmdj5C3NtLKop!$Hp>?&80>e%QpPlDlQmjlI1s9dEAMiL7V7+G zn&EXn?9kx+tl;ypIRvA;lQ$6oMm#~!^ydAbAJ^RxKkNr~rSgvzrL~Rt7!?tqa)eL( zGz@(Zy|~iw9x8WE%DaZ`XR{1OFehyf;}`9(Fv&~)Vdllu+E_`{71j(~;Ac3kE24C9 zOj>uoh-KvMMBIGKYh&L|hWzh*7yx^fxzACj%%VKyb?@e5nL1C8N*WUBq9YO~5T(AR zJzs>n2@n)177lo>XCXs}R$H#a)m6^gd~g2Y3iA+>EUJp1K#+nRzp21oJXpyZ{K1AF zke}!j-l`i36zV`^j4 zaIS(y{d5#!$K18R2(*ZF3en&al#hyXsKCbWly~d6rAd!g&k7&N zNx$+i(2xyN$wUa2$4Y(H6B!z0`gQuNhQT5_6Y)RWtqU|RoEg&;0;IyZ1WVAc>;<_2 zy^h=Sg_MMg;eVSrc4A||`?t3uvK2Q@AE0bjWYiZSpoY((va{;_pKNft0L_cS ziIi&OeFIS`q`1H^zqw+oj*}9OLPO6heI+5G)k0W>9tu((9z}s8Q7*(pl9|!vqBlLH z*&{@fN2^>wcR}_~LRM3Xooq2;V@kuC>!*w=44H@3e7x0C`0|h8`PQoFJKfVS?GHQk zLIYUaWYR*4L^=B>)nqg+t~g-(7LIqt97MSRXcIaIwRa&uE^WM1fHnXJE{Cy<{(r2Tqq5M zH(`JOE{)N5Sc&GBR!$_(wH*xXy$nV2LAP`Prf*hb?B^{`CY}xHlX53gMMu|XZ}5cL z2K&1A1jHtfJ+@h|8w3GrkvoUn>wYZVbXsu7QlQm7etEe^O|0z7yro~+ks!~jW#A3j ztrt>c4p^o^dEC*tQkBP(rYeJ#hr{dP2`$0OJLn-YpRM^wN-yrFOwjzF%Ro+ps)R@+ zArB;uMMbk?qqnmG9SQ6oBojm+8Jm~({aa^8g*B3?X}H`QH;x{nTva4umMC|S6ZNqN zOmVZtCrGPF>Hlf&E4-@uqHZba5)hFFY3Xi|kVYh=yGvTS1*D}!K)OWWA|TyT(j{EF zyDr^uzs>J^K;-r`HdFWv(@<-m~QvBjk2#LKk}kMCrkv*`RHAQq#Ik`d zv9zt;JYxS5hKHC{C-*hvk1}pI&9MbUl5kcFSkJuC#8&O50YML}(EcX^-i5vAgH& z{ikEbJPoX2X(>b?h_i`Gl+k8a_ytO)aTKmr~)F^h$bh23?a zAN!vF@MER?52u%Sa!O}4bm!aanFKTE6f$UhuRB7%1pAdHEe)v7V%O6V(u(D!6?F{N z_lY)^aGCshUFK&;Oz|<&=f(O!gP`_;*UMh`9tN+ z#o4R0CwI%L*p~G8r=WlO?JxMlt=rj{oZEJ8#OmV#LbesdsMEEvj&nL+!`1}rAxcVn zsE6=5f4@EbrIRWIs-x|zOh_?)h*WO-W$UHbW7BeQod4yneT~2}6WT!4s7K4m0>1iD zyENS7>X#`mFCPFU2>~2&AmW2#Eevc&K0s^gxNgT7ubb`i=KA01fK%<$5o}%))0&W!IeXXe z2{|{@t_&Ot4ZxH#gS2pFz+C>;R-{ab)+_Df)o2da5wT0>nT^!r11JBC;bC^E+)*P6 zT}&Dl`sgeNR4=G|8|WriT#!=tQ7pQf7Ej`iQz@0*UruhsnlPj;(6}JE9@5#~5!#=I z2q(YU7rw)8H;US8tgj7IK;QUtGo!SP_vvOT$*ATj-zARbkLG`9_#01x$*kC3e`C<= z%ag7z<0bF0!ikbUaVmdlK*q>jfX8B7V0mZ{23cm6MOJfnKb3`ZYcf>`zOJEQH7;^+ zD$o2>DrfJ8-}0GHOvzs3ozn?ir^f18+s$N!jh)?}s@=#yQ#Spp2fR z=yi!^9%5$w=(qCc@|e#{BvW4c)oDse=h2KlBYG!;IPg(N!VSZtk2UN9W#{4}ud)vv zoCp)^bvyQcV#dYPhmT_K%;JOh708?@#opwO6P4GHDaSh;=ifjl+IO4 z4>u)gqPNpfd>Y-2FJ+=jtjO%zKn~d>KzDGJa+qTv!sJ>jd@-0I5N{qY_7$A4s8D%1 zsv&ovP;wztBIbkIzW|QEYW%PPcfu0$_+SW4NKftebg+(STJ&Y0@KJA1FG_(MQh$`Zu!t zdv!C#lx5H2Oau%mP?wlPFUB^#B_{GVuVS7U$STC1BMH9 zEsGw8$`f?txJi8$&2qv@B|5a^xP)q^XS)lO*;13unrRf9EvE;^vHV1*qS)ze4OH2}t`yl-lg8_Rk!)0Xp~;R7`?1B- zKY;|bf_)hC9r!(Sj!hziglFo6-?Yrlq=4FQPshxbt)6W`-0a)=Ey1%9ut4`g`S=MRq<^dizjdr?r~a~9u$zMDE6MqyfnZ*A z2qFF7kDrk|?%SMkg8S&IVh8TKyY?U-Y2&&#R-hgwFZgFLt@^50;$e7IHo9-))F%DS zQmen8NH(V(jwB*AyTrcBfWsjcaHYkK4N#bLee`TW(~ z?5s|u*^^+&AW7=>qm@qGYAY3vU}_q=uZ~G0TNtRJfblL!2EgJgn|@DS>p2_fmU!Ke zm$-Rgo2;prpjfO^+2%(XDK7!2R631x0h42 zjljWWl!)xjGt+LcM7j~aC6-`M{?V*qjFphq6zWjUw@ANeWI0BBb01%R`9R27( z8F=S{E4)n|Cwc<9*bY)E>0>=oEO!S^fol+nMNl!#ALNQ*GQm|i@#1~C9yk*1t<~A~ znBSJjk}2T43)D->zkUkopk7#5m=Cx;xVvnFvjs|^gjbfleVq%4f-=2^sJZ1+q zw6nk@bd& zkc=c3aU&6Q?<;i4G2tx_RU7-Q5Ow6YUtQ-(b{Ka5B=uRnQ6WLTw`X?PwpiHj{;r4V zs>j@A-a#%$Ht@pZ&(nFIy>h0x?%D9)SHl(qZ@34lYDrbVyP_ZmS(ET{;GL0lWTEmx zJ>Efn{($vmX_mF_)Bv0Ap41KuHNHD}P98Y#Vo{aRPYLR0o>i=lfu^Iib01!kV82&y z7d!ix_`J38OGV)Q-oL4-3s;>*ER~7RZ}L+fB8CDhdh5>w!A5m5DnXT(U!9ZC6R}RA3{2oKfq?S6`x{0 zX#hy3;r6hJ3p-SvZhTJ!QA{;cN|B?p(q@dd^=^a1?Q}@MZCrsdNzri^Ylmx|jNf5- zx3prj25R*9phk6D^IAswm$d%9AHVTAF;rWRtiPlZiWnXq?sqx-Z&C!7JxlhVOvg$4 ztKeLUJun%y24$VdRqFWZuhDwN#uuuWxRxn0(~hB!h>N5EiqF2(?Lus%T+{$EwUErRca|Z>3V;sx=@HQ1!QpBo#6XXoa8 zU;N7YQ3gm*XF+8qg1lBpoV;KZWDoS!0~=Q~F&k*A4V(Rn#qiJu|BJr^!_ z_V>@Yae@)zMNc>>C@28#aF~M_a4^#YyuuM(TkkOaEB8cij#TVgxv zTZQJ+5h>lkQ1BcNP9@JfMN?9SJ%O?A9yn`@Ay z1z1!=Y||~Obpe*;e{jDPvuO;s)Ya71a)Y%5nt~Q_8++DT!;y}2|Ni~MkMBi9M?nJ4 zT~AN%?}qEQ+&T`ASqkVtueB%OuYD22i^j5)t2R?)$@6ymgmHIfl)iZVk!au}v(0Y# z#2VEXEGjYl@5`GUy+*Z8RBGQ3-(|^43!`zEjJQwclS&z1KQ;HamZjA}QK>2wFcTpr zc>S&cJH-@Nzb+UJev6XCe#>&OVA#}5Q`Y;d?)UE_;F&Yz>7+oV7@(Ga1uWbcnFoRB zU{hQLn3U_EW5%34A6dIvMpD>Z9Y+#_idj$0ix_gD#Fz1+iBDg?8J(V%r^c5=XCjIc zz1^=i_&8&^?kdEq(&=I7ZfHFb33EX|7=fz8e6<^j&r-PuYItU}D{kSsQC$Rn= z1ivYC7ajtTT;tlw5V}OHAi&QzK0hC^7AF?xChmjF#>Up7KAlx*vkp-G<`-$)l|h~n z6zc4Ov9U=7eSLlU@k~J%S~LoGa6IuKH94+!CAr%m7ocEH!PNXR?F^4X z2ErlI3{qP=J3vNPY+kL!GiIu$X0ILXybZL<;6_kn?uny_woNAwxLUy`;Y0`m3bk30 zSTA6f4gDh#D_`qEi8#vlK#0ggFLg zv{J`n`j;s<;~(R@_onVMImlN1$F2W6VIf3F3%o9}@nsdBYhb2C30o9K<(3QoVLszNTR?kx0-@e~fIs(TM4$REz zjHK1$fKM>4^X7cdS78v7=I@rN>l%^am zu;`UfP=ZC{Op&TaCu3+xVSF>5`pYrH`*d?f5cgn=A5^krwYLNt4aGDTRr?Ity)V=0 zFeSt@2UA?hiZ#LO%lBalIGbfew38vHfFvoJk?%s$EEW05burdpZo1aE8k?G4_11_$ zz}9xy11K?00Q3q8kkfCSM-_TqM;78wG#mxXRS`S&pNB*y< z9fSxOmDlA2?mla>blX?7T+~8AP-8>a^IfRA;k3@P>S!ZudRRnGH{3KYW%7>S!&(}& zpr3Gemo6?JB9oqL9x#%B%|x{N`DI*=Cd=5=)ccZ4yYx400ry@2RV|&LUKFfhT@y&a zuSdLrn$OoG-AQ4@&zl29hd$bYL5`J@K25oG4Q8MIhLdFdYAwzh%t7=q+*L$ z#!#Yau`l2619o1OmkIKkA5qV8)V9NiA3EhYZAPgVz1Ct~3G*?~QO~Gk1c?}uhBU<^ z{uK!H*V#RL6!-2y%VFn6VwgeUrl5_OwK)lDMe_-!dVjzDnJ7p0h_<3k)=mEF%3r?! zjW_6NaDfCOO+{H%@jE6+;Ie7!*S>eJloR{k&~gS*hkzZ4hW^T>K6)u%13xMNgtyUL zs_fw03hw%OLIpzSl`0*wqESwwm`Y_;jxfOm%!#fJ^ZLW9*K;=MIXjp0(2l1xOj z)W}&bp3fk=ElwtTFT)e1xFU)$oO8dtdLQTFwmRtoR46-#hli6Cl$c>ZAdtgzaVK~) zbs_ZERSV2Nbt@~dHqVDK?5yCM7K~m>Kk4!rx3F#%O3wwqD8_WQ5bY&u;7Na zs(5O9Xte~MX<9PyC|FUaQl9vUx`ps8fP||5jdwuZRi$Zw03pJjPl6G(ZN{`;tHdc&yJdv;Z*$oR=DdlF?l>W~b{}fwpUvBGruk z=7BAoba_h>)J%$ndACa_7u!U3C2aB|G`4>c6(P=itudnYM?}_0E@oKg6PM?yL8jP0 z#XYa|&hy)hGjv#oFDY+4vjSIy0##bq1gAe(vWk#k<}nZ95j@fs7f<7boawuq$$M#x z2#dYVcz{H-lfjcwKFd7)Q@e=j#~_js`H?MlyD zQRL|eEV$FmKaA`P;?_j!Jvc5%GadwBxNs{VsR4OGadlJ1UPUA6VOY2EorE7m7bOG^lQHj4S|VFh3wx`ZO<(RHn{5+eO|e3 z4$`C!9AC^ixvj+tRQca#qoYbcDBBHGT^-KCTzBYGZ;a>T)_~Mty55Db+|jYi>|I-U z6M&_YP%hhXy4}59TN|64)>g`(uh~v{9>y8jB-rbXDTnJeqWjs!mlck4-{=R7_r#7` zbiT?uIXS_(!tq!djY_23Y$x6XI$W#u8FjDsS*sgo7gSazSa2(dQd&a~+m52G1Fwf+ z(IL)sGJ*sbN^@ELL9p!ia01y1KC!F#Gc-MD+Z*KURFGpy37;w*<;79aBIuE6w)(r5 zGGIAqW{Df4jl68r?2oLc$Di4JOW&nHhave4gssC6c1Y6+3+?67Ky=$J8&VkxTrZiZCYsQGW+w% zY7zdRTc%SPA{$L?P9of4@Sd)3_MDLGz{xh$YrA%UF)EcDj2V3CWzCf1 z9Du)BHx^=!<&F>24Mn!=ZvGZLLi<%>>#e{)-3&;IrHsgbPWNI%C~@gC9VySR4g~}O zZNlF#r@}<@HLojb>O5cyEyhycSrd!izv$%L-rccU**Lu(hqq=Pv$QitzY|6x^%!Di zN=FEIon22{@GRO9G3jmkQ`e+jPANpqnI5*(cex0W7_r+B6+O2!nJ@91NTM!%C=a{2 z@ZR*MHjG-8KHj%JN0-ybzIXw>zh9%&4uggX2B--Ie5%H$FUyVK&?d+q&F)oH*0rTCJDWEfne=T|N%Kb>`$$6?Hc3C!ub^_L@j5jhqxxR%TTb+- z+~Wz0L$76cutR|%YiJPmSrmGR9u^b2oE+0u4`4zkTGuxF3G8_=I%Jtx1cC=GjDeS5K0xJc{9(fnDxM5X~gaGBh;^?(3kC!N;2 z&gPT;R}V{uPPrEkb2zJ5&S~x+Ly8C9pA1a@9UVjhFgk z1p;D9A&pU+n^p$UjrL$$6SM=haI<)kxeZ%sX|U#*Dk3Jdkpata>9N z(x`|vZ+7>|g|+1)GvKPv^)-z++ObC3+B2M*`(7k1$%$v1FK(Rb+%C_)eqzW{iY$EH zrIJnkG(HJ7V4lvf;!I))z3&T=6OI5mYaD_3_CT>~V{%b1XSGsxeDq%>mM=5(_>odR zz~t$;_bXAWSfj(k=~4|pzSx6SFp}fq?al^V-NHM<&n4bW5T!YwN(-Qe$<;Qf)qvBG zOgO!|vhZP-U{;zRcHcvEoS*n7h#%Ik;T|@hs%fa;aKx7w(`7L7Gue;nhX$H!+KkNnxlRhD5ul{odeDrZcPSKBUizYMq|qyl8?O}BnC*OFvAwegR#mygR+Kmbp#LSnwb zs}tcd#2OZXiT*D5)h04WRs_U?U284~q@+nPWD>)8CUU|M%l~%0@E%mmus=EMC-QV5 zTKrt){XIO#GT(WI1(e%IZ$jXKz7_4%O~J2U!MkLi z8_KY!N<%&1mmMaf5=EXI`C~Tl%G}D_VDJ#S+`1rl6Kj4KfWbwsfbjE6k*&q4H>7Qq zW!!C~uv(ZD=Nn|gSX%A6W2vz1yaMe?+mmX` zKs4hfowPqf#aZ}ibD=&ma{Cwyf)ClIat43w6D(qo5XBo}uN$yQAAVeS_Iu)X_IrRi zENgUp7X6$9(mWiLg#h))4J5wniX=?)+q9@^C~GS(^`ta{Lgb(xRWqzWqObvbID|2! z4uo1|&DF-*ri0TTe=>KUy_ne98^9BS)WwW7;dYxPFl!VYO;-4&0CrY9n@T1sV z&|bYL5v?XD1Fkd=!8oBqA{Q(1)f97h+>C1hac8|v0*jP5pw>p;spXOQ#_Hs}yWAJ+ z(SNr*9k=8=!3&8j(J1D&>?e9Srh+Gc%;RE<@BN;mE(0GQ-@NCN|6`SqpZMEcH4@jw z#rLgNffah3_$PbkfXgjX&Ft6iIl3oUmA638QPe_89k6~6S1h!&#Iuga&85 z8D}-_J2mc<`(|4Zicl*j@LhraH!CANDoG&Ynb>FHbx;Gn+p*l^ z1rJC$wqDd!a9t1f-K{f9xhEAZbZLO&pz|%wTKdu-^X!tKq!5uIi#`Z@Sj8v<)M6 zO)y}=zr7-`&3Q$NQs)!_kXW0sj!vt>xQ(Vjb1hG|`VYzodh(G91nj@j#WsD75hguy1QJVCB`av`%Yl0XThOWbJ=8+W&GZ6>0t zf5qb6-dmZyfYSXlkRgyXWO3)aio?;h$_0u#Kt0iNDAgTx-NHvQ0DT?iYKLHAN8*ft zBL-?{G0&yW6m8b^KE}X7eUZgHj-{<^rFL|D>?e^jpj9VV-WW+Z<&pmOjKjylMGl&{ zH{zyRiW9u!4Xn}Z*VJK7{+Vz6R@gu6ME}w${LD;&_8docu|^lRZ*8t)J-qe7YQtQ@ zQZ{~AN=we*h2|_1d(#2|e7Cv#5YO;WUE8q=FSJ_}qY2KeHPh>VyxOfyA`lG8!cFW$ zg=3BIsuaD=7PnAd#Nq{DaShURXx1B7XJcbS{+oD?6FYE%xPtz=o5L?*ufnirlZ~U= zZOfR67z@NgJpQx1kmeIb_NM)+e*1SjG)Ij`N`(Z3jH=|kt@{fRfQU88s!A6tj~T)~-{!*4Knn2=GSlffdC<0_#i9%pK@AS?msPoiOg4H<+MD}ynFKW=XiBWpOql2`Sj|-f5~bqj>5s;k<9nv zpfG=p`m5zr+z8tbAFOW9b_{%W3Jttg!axSX$oGIRs(bYdPAsp=ss1U|^ac~Vlr&oISXy_n%H7c=wM=M_9nO_{d- zPX_z{Nd_eRBN4bHmK?=Bpf#@pYH(kpz zpsfeS3zbSLBsAx{vG~&-cEgP9MN)^j%{O_ijQyU1oVq-nGBrLmd7Mc)gNWy0L4JNH zp5HPu*nDogt(yz}%%RwfUSD3KfIQM8^8e7d!vNv~`0=YJmKXaoox#Xxph3640Y5Ah zxhLrr$YS~4=1`aH3H$r|lOSe-ipHZcGI2#ga$0S1Qia&kL07{O( zthN=U0U*W`uq`cjl<>VgBs&wRh`vzE^a>mIIJp+DnjsIC1l@mK44LLE``;I)(%_?m zt!t*$|2D_%IOMPMf5p7$+mm&jI zch|__rlX6Cs`~nKU))Y0bM2TP0pkpUInOTWRi@zVJvnnBFSaz5YfHEs2|Eiw8eSet%%q4u2r9bo@T`0oskugID5Ph;a*~@=rmnB3bdc_rO;hS6Hz45X+81*B2LA_y*oqVU!U^Q< zlLst!9-f0wc6k_r1V)F6T4K<PC$I(76NT$sgGD~LwT#pPb*En7K6Cfv13O5x+`vshg#v-8_4h90q zdro=oPrq|DyiC1c*n6pn0FvLwUgYiB2#<42?gZJ(vn6dXzy+%cb(@KSa#!-$cjj5fCk3;waJL!`ooaR z_h!dA#5dp2y?9ReR9PiAl9Pam`f0|@$A?Ab9eD0CDc z_W^oh_S93SxJPSkW-0{vU_d<55#&}@KAo%Wb#E^DiqhV)@l_v5Qk)!DVm4bhCH|bw z37a8B5!fLpJ{ulZ#qRuq5ex=24oGM~1=!iy8NwH31`tA<2Q2E=&>^tu{r-zMUsO~S z8*ZA6pu+4i$RzH}7vwlca1{oO55Lwi-n5(f%WFl`Dw zVefkEkn%Uql}}mOk834W;JCTA7U)I22M^(uoV;p$7(v!xBjqyb(*Cfl0_dwR3PF#L zBLejp^T_-!92T>~3sR2)5~_1)6s=SQkcLcyZASs792}hp%7tN(kQZR6COfdU0R$-k zX^bCp?Q^v%qLf>aj9CB*WP-3VapdFrPj*DXM01Z~prqs^p-WM`HsnbJClr42ssjs< z2s1&kFpl)@Kk^4K?)_`=5~{qU<-0~ZT<`dLUC2RH*$AQH`Qa<@h8Yxa2gD*MpaK($ z`RCl!N?A%{H^+Z|eqLtS^c66Z0G0dDzCAW9-9-T_4=f?@5P*P*`d{Q6*8reE`I)b)@1k%2d?KMDPL&JzngB z1cbNwMMbC+yzx3=eJx8s{fqr+&a2s2&YusSKkfwYxDvbwT zNs%R`$`Cq9(p_+ohZr^5coko>TD>m zI7ERp!1uUTB#azLAQ^$n`~E5u(`|tgV>V}>WBXhiltD(5qxFh*Z>l`MwwCx!ee%5~ zDIo?hkq@lIZlI|72mEeJ!g^=C(B0D$Z|16ZF9dW)E!1R57}*MzmPU$OyBax8d;(Yn zBq=#1;>R&HL=LS}$25cjbxC^B627}(D)<^EBGR*I8(u{fm7%9(iQ%R|lMFyVL+XG~ zO-)U|$Aa-*V*sTZtPxWBlk=D65XQMN71U#a)PzcHO)#$1HobqtmDQmB3!rcT!?F@V zWpy~;P%yFcS|P}jN2zc;r%ZK%_vBg>?4)23T)82w9t(mSgXA-i+T2ry+GW)+f5JCA zLsdlwloL2;iaQNkOiXOLR;9t9hZCDY^}GBdZ{|I(g#Snp)3w(+f^y0FgW5UJy4w1? zCQD&jQ5vYG-94L~opqG#cOjRX-~~%xnUlnCDL-C3J(nQx?ar0E)+K^X`X&+!W&EX0 z`h^cQ{dfT#;7PD@Lp zfpDKT0eBkZ6h}(SjUarfW&tmeYs+fgWOa8B57Tspua>#CqyR+x`_~0x;*yGrVgt&6 zSLvN(5kQFoF1`)C(E$3J`I{S`xvH`d$2qEOF7r2=fR`GxTjcxo(-#3DLa{s~E|yFn z%MI`cFrdEUGc+_DUhR&qc@&TUoih{0w#3x0iWN2-Rw7I=^+0dDeQ-eGUY(*2*xnbY zz)COCok*suSlddM?8g|B6u@}>sHi{_+!clgx7D#mgVZwMGOvL3#6$K9O*l!oRZg>) zfU+>~W;8-Pxvac=q0m+@_6#8=ZW6wRpa=XoyI~`*x$ac2<6J;vZtm-v-@gSxWR`KU z9Eyj8t%wvy+zgm*5^SIV83Zp5lAlEt74aap=FgCw;En3e`~47xzbf`;j+dP@HZM6Z zHy06b>JAQP+ELza9dE|XE<*y9l(6cS0zi8!-3}8@3*9N6V98};M6ndb6qO0qCWt+v zDm)5dPo@nz_M-k^-gfO_~XJ8pscg!4yD79e8N+-UK5A;HB`K$-##Hnl|C6^yYP;(oz)*mo773 z9_%i-BM=nA+N4{Bb*=WKt7*#sT2}^%Fs4*Yjj`n#)lVPv(rF z#U|T{q7`UWwgvFq7;LgC}wsvZpe?Hg{x%3tjJAkH+bzl{g8RZlfhJj-lPI~U*iSL{mHonqSIxIALXz}3X zun-0%2(n^am6(#~v8TS0qkU=)1SEcdd8bd1ADx@SlCNt8wwiFv@Wdx}+q3LRxR^KD3;_XK%Z6 z4a8xh-n#|+CiaR7{v`uOj~SPqzW&TFQ)J*gU#1Ss^jWA2s7$<9ykGJXec%8i#jFvT zZ_a+zN%9r}R{-EO#uRm`DUVEd;qqj4yTxYjGJ}T1>(edd6orsPlt-}oT|EknoW4F; zyu^bbpj?Y+&Qx*xpkHnAoAG&>a8y1pQe1ZkO!QXoi&Ng7y8IJSFvj48FC5Z0@ z^$E3mjg4!998>@P&EFMr_}jvz@x+MU7OGnYK_C$In!#PF^2%=rOznmZu9mc^11%VI z2z70Lks2XeYy)=cinhp%h(!~&pgIg}qw0Ic0OC>qhp52T30{ba=p+icL6I4(_X>63 zI~h@?6-!*1h`5y}?rwlq2-f-tb0&E^oala5;*Wj?mFydhA6g)LW1Y2UD&(z7)Swq2 za;+n9LIv&dU^-0;)j{*=7xhttSR@|KHn%3dF3mOf2^y|>y&YgKZ_?t{K9!syV8`rA ze>6H{fyV;SV}UM(e!S>5*k^1cJKbq64;mc=j{xw1!Bp7ekb0u?79k|P$hLE#tTVQ1 z(s+}|X&l52tM!O2%!CnU>z*HFwRQZtiGV}aKTc*%Z zw3Rdn#{k>R{we8a0Iibyz2=4~BcxLep?t~eVQbE18fL6=LN(x&I4{}+K?sZ{Qx(k< zwss7zcPA1-dCY2{s>k%$W;XNNvhF#k3UQG0exYv}n&q3<21ZiBk~%a_k! zVcX!od?SMu+MyOlj@G3fgQnN*SKi;QCG=CpMzd0pR|pKTVUX8t%(Go)G)yj9mY@kE zlLuh_|6l%Ju0cps@az~8S#@s;uWNBt9>%}bHxy&gsUL^$&k#T_dm{mJK{BZzM$EBy zS!Omu;VVZR{LI35+&*B9-uh$R&GAB%j{uDQJYMX~{RFl^gf> z2d1q@we_6lZff)G!r|goC$=1SqMpz72iopqJ|)?*uS@BnJG;9LEXZF{ z{d|_|_#J*4#ZkeevUICU=C|UX;x041>T?pcrY4K+1bd5Wbt1n8&BI`TpM$f`qakx@v+*G(n1+;16 zp4S7x*iZZK#-J4L@cR>aS!s-9*vlP$Z9(efWf z%-z#|@JYcW9)Emp=avMLpc{K482o2JWXOZaU&vsria3NYhet-*zC3%uee#F0ZvDFy zK0bbH`R9`l{}#cN7V>Aq!D~lKZ?$eKV{Ic*&t$bT^i?}Eb2mbQvBrqmnbHv7X+MU} zluA)i(ed$GPw=bN`Np%yrSDWQCDO1aeQ~sTypfJ+#u{608F-or5ZKWjb_NE9G^bIC zG>^ae(#foW85ty%34iIH)+$5?2LToh4UG>BX5RC#Y2E?Kpq>zDJ+~pF60b-DY3AYP zzUqk}X`LGs2PeTy+QY z9!EFPnU~W0V`!lmcrc$|R1pQs2)>MAai|Yhq9Xteo+i;d@YhD-~9UZUB zhNX@BLtjB5%;*6Vdm_`Y6!w2-plnytSa8Jbm0yY1#=CjD4zzGWF7%;OWX2mXjov-w|4P+8y_{IKYHbHIF2a(oldgyB+qMtcAUk|+x zJ=2^gHP%nvy_Vi$g^C|BJx%GDu8jT#v|O@HVCkxx>uNYyp!4rU;juR%6@fv+Ke9$l~Wc4%^H~^#~T+IkUC=I0vrB23n=u&dJ{zv8mw6XVunv zgh2+2_}HNzDGI8p;!lSJGsk3kBW5a0V|zb;&Mx_PE^SQ0+sf(NnLp2z8+)CmF0C&; zK5&7JtSu(AD5_E{=s9g%Q~j-e%-+=(S;W5x=2=-pMLs=c^73K_LH}*I@`cg+$eh`^ zx%XRXj#ra4&4GuvqZ?xX4j~3zm3B#fes)7cYQ>O1>f_y(;P}MEio5Qw7sMJriOdjg zKf~#Vm&GaivurZ7YSH|LTjJBa^s}Xf@X^HG(`#1#$$am)8BE+$*Q|b#V?CGK)RgWx z#Gh#Ey{mP0er^!%K2d*%x*(WU`{Q24o#fv+R8z_qk?SqQ8M|th<0E;SIpo;=+O*W| z*zoV}uDuQy%^<=Vl91gUl&R&ebH2`zQYw*=SQXZx?HL~T{r!C=Qrha5)$e4uVH(A| z0#0+*HT;!KZ!m8y8VFK_hkYrIW~}EAZvD87`{Jg5dr`z@BIoO&)?s3ASK2{3 z1{4z7=f6ryroj5CvlDo`fe`3vx;uf&#r3s>VZ1bes+XNz-p>CR^5%z~rkirkIdmWL zELX~vem_zEd-p5Zw8_j+G2){EKDwozu?Frtwc?*8B~ea1XnvC^ZhX2ArQ*+{pT?kD z$jJn&Sz|*iAL3fy&|q$3lbfF(N``DlgtT<&`u-(;3W61c=vQC)?^~0>G

s)2(_P zpO_K_BTm?mj}+J9RI73+>^te*NzAAs)*1;G*47*Ijzh!~<)lWaW$NKpoY3WEvO?7& z0^IpT&PwEtXl=$|#R6?tRTY&tZ2!uWn~Z{Fj3nfUuY^b}ewEk=b;s!`EtHxJ5Pa{Y zihV0b9V5QXJy?3X7d`;>ALKig&hWmNQG6f0#VwmYd2V4*l5vxngF-ZKmWk z7#hr%>(i|zkf7ZP4sZRf=LW$bwlaMM)O4ID-X+}Q8zFZb;VflA5DXXUot<1=$L8jw zs93#%dYut*_^?u(UMB{a1ZTXcLUf?AJugXRPY<9)r*b`*2>0NTn&| zzZw#_r5_j=0Ec~Kc$nF$?Wj6@JjwXfAuH9UKJ;{uH>xWPFIJo?&2Zjz03=UGXd=_2 zv8`^=^FDWYoM&A5ey^D<<+-5a+6c<9DrO zX+L2i&_L9iJUBpkuXR0!9E2A1)UgKOXY`qP$d|%aC3`G zNxgWR;YNYMcLXz*C-)W^jyT9b04r2m(EH|0+Sm8-@W+Um6MdB~X~lCG{V!z5m6I;` zK_G+KpHHZ{2OD_DzgRAo!Dt^tD)@d?3f5bb?Fl(a`L+S z0^iAy`)vQ}=$!padu3dNvoDcpTzThbt!q@__PJ%%G

tAwGP?944XFzS#-!P;4zVkWfb7nj2h99M07ZAd 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 some View { - background(ACARSPanelBackground(cornerRadius: cornerRadius, highlight: highlight)) +extension View { + fileprivate func acarsPanel(cornerRadius: CGFloat = 20, highlight: Color = ACARSTheme.violet) + -> some View + { + mac9Panel() } } @@ -107,7 +81,9 @@ private struct ACARSToolbarTitle: View { Circle() .fill( LinearGradient( - colors: [ACARSTheme.violet.opacity(0.18), ACARSTheme.blue.opacity(0.12)], + colors: [ + ACARSTheme.violet.opacity(0.18), ACARSTheme.blue.opacity(0.12), + ], startPoint: .topLeading, endPoint: .bottomTrailing ) @@ -210,34 +186,7 @@ struct ACARSView: View { .padding() .padding(.bottom, 44) } - .background { - ZStack { - LinearGradient( - colors: [ACARSTheme.canvasMid, ACARSTheme.canvasEnd], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - Circle() - .fill(ACARSTheme.violet.opacity(0.10)) - .frame(width: isWide ? 520 : 320) - .blur(radius: 40) - .offset(x: isWide ? -260 : -120, y: -260) - - Circle() - .fill(ACARSTheme.blue.opacity(0.08)) - .frame(width: isWide ? 420 : 260) - .blur(radius: 34) - .offset(x: isWide ? 260 : 120, y: -120) - - Circle() - .fill(ACARSTheme.green.opacity(0.08)) - .frame(width: isWide ? 420 : 260) - .blur(radius: 40) - .offset(x: isWide ? 220 : 120, y: 280) - } - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .principal) { @@ -344,9 +293,11 @@ struct ACARSView: View { .background(ACARSTheme.green.opacity(0.14), in: Capsule()) } - Text("Mensageria aeronáutica, fila recente e leitura de volume na mesma janela.") - .font(.caption) - .foregroundStyle(ACARSTheme.ink.opacity(0.56)) + Text( + "Mensageria aeronáutica, fila recente e leitura de volume na mesma janela." + ) + .font(.caption) + .foregroundStyle(ACARSTheme.ink.opacity(0.56)) } Spacer(minLength: 12) @@ -561,7 +512,9 @@ struct ACARSView: View { .monospacedDigit() .padding(.horizontal, 6) .padding(.vertical, 2) - .background(ACARSTheme.violet.opacity(0.18), in: RoundedRectangle(cornerRadius: 6, style: .continuous)) + .background( + ACARSTheme.violet.opacity(0.18), + in: RoundedRectangle(cornerRadius: 6, style: .continuous)) if let desc = label.description { Text(desc) diff --git a/MeuLabApp/Views/Tabs/ADSBView.swift b/MeuLabApp/Views/Tabs/ADSBView.swift index 25da48d..37c196c 100644 --- a/MeuLabApp/Views/Tabs/ADSBView.swift +++ b/MeuLabApp/Views/Tabs/ADSBView.swift @@ -80,37 +80,9 @@ private struct ADSBPanelBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [ADSBTheme.surfaceTop, ADSBTheme.mist], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.12), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder( - LinearGradient( - colors: [highlight.opacity(0.28), ADSBTheme.surfaceStroke], - startPoint: .topLeading, - endPoint: .bottomTrailing - ), - lineWidth: 1.1 - ) - } - .shadow(color: ADSBTheme.shadow.opacity(0.10), radius: 22, x: 0, y: 12) - .shadow(color: highlight.opacity(0.08), radius: 14, x: 0, y: 6) + MacOS9Colors.panelBackground + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -118,7 +90,7 @@ extension View { fileprivate func adsbPanel(cornerRadius: CGFloat = 18, highlight: Color = ADSBTheme.radarBlue) -> some View { - background(ADSBPanelBackground(cornerRadius: cornerRadius, highlight: highlight)) + mac9Panel() } } @@ -263,30 +235,7 @@ struct ADSBView: View { .padding(.horizontal) .padding(.bottom, 20) } - .background { - ZStack { - LinearGradient( - colors: [ADSBTheme.cloud, ADSBTheme.canvasMid, ADSBTheme.canvasEnd], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - RadialGradient( - colors: [ADSBTheme.radarBlue.opacity(0.12), .clear], - center: .topLeading, - startRadius: 20, - endRadius: 420 - ) - - RadialGradient( - colors: [ADSBTheme.radarGreen.opacity(0.10), .clear], - center: .topTrailing, - startRadius: 30, - endRadius: 360 - ) - } - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle("ADS-B") .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -1864,30 +1813,7 @@ struct ADSBAirlineFullscreenView: View { .padding(.horizontal) .padding(.bottom, 24) } - .background { - ZStack { - LinearGradient( - colors: [ADSBTheme.cloud, ADSBTheme.canvasMid, ADSBTheme.canvasEnd], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - RadialGradient( - colors: [ADSBTheme.radarBlue.opacity(0.12), .clear], - center: .topLeading, - startRadius: 20, - endRadius: 420 - ) - - RadialGradient( - colors: [ADSBTheme.radarGreen.opacity(0.10), .clear], - center: .topTrailing, - startRadius: 30, - endRadius: 360 - ) - } - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle(airline.name) .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -2711,18 +2637,7 @@ struct AircraftDetailView: View { .frame(maxWidth: .infinity) .padding(isWide ? 20 : 16) } - .background { - LinearGradient( - colors: [ - Color.cyan.opacity(0.08), - Color.blue.opacity(0.05), - Color(.systemBackground), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle("Detalhes do Voo") .sheet(isPresented: $showClassificationSheet) { AirlineClassificationSheet( diff --git a/MeuLabApp/Views/Tabs/AnalyticsView.swift b/MeuLabApp/Views/Tabs/AnalyticsView.swift index 417324c..9071e14 100644 --- a/MeuLabApp/Views/Tabs/AnalyticsView.swift +++ b/MeuLabApp/Views/Tabs/AnalyticsView.swift @@ -74,37 +74,9 @@ private struct AnalyticsPanelBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [AnalyticsTheme.surfaceTop, AnalyticsTheme.mist], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.12), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder( - LinearGradient( - colors: [highlight.opacity(0.26), AnalyticsTheme.surfaceStroke], - startPoint: .topLeading, - endPoint: .bottomTrailing - ), - lineWidth: 1.1 - ) - } - .shadow(color: AnalyticsTheme.shadow.opacity(0.08), radius: 22, x: 0, y: 12) - .shadow(color: highlight.opacity(0.06), radius: 16, x: 0, y: 6) + MacOS9Colors.panelBackground + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -113,23 +85,9 @@ private struct AnalyticsInsetBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill(AnalyticsTheme.insetSurface) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.08), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder(highlight.opacity(0.16), lineWidth: 1) - } - .shadow(color: AnalyticsTheme.shadow.opacity(0.05), radius: 14, x: 0, y: 8) + MacOS9Colors.contentPanel + .overlay(Mac9BevelBorder(isRaised: false)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -139,7 +97,7 @@ extension View { ) -> some View { - background(AnalyticsPanelBackground(cornerRadius: cornerRadius, highlight: highlight)) + mac9Panel() } fileprivate func analyticsInsetPanel( @@ -147,7 +105,7 @@ extension View { ) -> some View { - background(AnalyticsInsetBackground(cornerRadius: cornerRadius, highlight: highlight)) + mac9Sunken() } } @@ -490,33 +448,7 @@ struct AnalyticsView: View { .padding(.horizontal) .padding(.bottom, 20) } - .background { - ZStack { - LinearGradient( - colors: [ - AnalyticsTheme.cloud, AnalyticsTheme.canvasMid, - AnalyticsTheme.canvasEnd, - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - RadialGradient( - colors: [AnalyticsTheme.green.opacity(0.10), .clear], - center: .topLeading, - startRadius: 20, - endRadius: 420 - ) - - RadialGradient( - colors: [AnalyticsTheme.blue.opacity(0.08), .clear], - center: .topTrailing, - startRadius: 30, - endRadius: 380 - ) - } - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle(focus.title) .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/MeuLabApp/Views/Tabs/BibleView.swift b/MeuLabApp/Views/Tabs/BibleView.swift index 473a914..736d94c 100644 --- a/MeuLabApp/Views/Tabs/BibleView.swift +++ b/MeuLabApp/Views/Tabs/BibleView.swift @@ -7,14 +7,14 @@ struct BibleView: View { @State private var selectedChapter: BibleChapter? = nil enum BibleTab: String, CaseIterable { - case navegar = "Navegar" - case buscar = "Buscar" + case navegar = "Navegar" + case buscar = "Buscar" case aleatorio = "Aleatório" var icon: String { switch self { - case .navegar: return "books.vertical" - case .buscar: return "magnifyingglass" + case .navegar: return "books.vertical" + case .buscar: return "magnifyingglass" case .aleatorio: return "dice" } } @@ -23,17 +23,9 @@ struct BibleView: View { var body: some View { NavigationStack { ZStack { - // Background gradient — parchment/mahogany feel matching the HTML design - LinearGradient( - colors: [ - Color(red: 0.24, green: 0.15, blue: 0.13).opacity(0.18), - Color(red: 0.96, green: 0.90, blue: 0.83).opacity(0.06), - Color(.systemBackground), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - .ignoresSafeArea() + // Mac OS 9 window background + MacOS9Colors.windowBackground + .ignoresSafeArea() VStack(spacing: 0) { // Custom tab picker @@ -106,7 +98,13 @@ struct BibleView: View { } } .padding(4) - .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 14, style: .continuous)) + .background( + MacOS9Colors.panelBackground, in: RoundedRectangle(cornerRadius: 14, style: .continuous) + ) + .overlay( + RoundedRectangle(cornerRadius: 14, style: .continuous) + .strokeBorder(MacOS9Colors.border, lineWidth: 1) + ) } } diff --git a/MeuLabApp/Views/Tabs/IntelligenceView.swift b/MeuLabApp/Views/Tabs/IntelligenceView.swift index a8bd179..0508d81 100644 --- a/MeuLabApp/Views/Tabs/IntelligenceView.swift +++ b/MeuLabApp/Views/Tabs/IntelligenceView.swift @@ -238,11 +238,11 @@ private struct IntelligenceWorkflowCard: View { .padding(16) .background( RoundedRectangle(cornerRadius: 20, style: .continuous) - .fill(.ultraThinMaterial) + .fill(MacOS9Colors.panelBackground) ) .overlay( RoundedRectangle(cornerRadius: 20, style: .continuous) - .stroke(tint.opacity(0.18), lineWidth: 1) + .stroke(MacOS9Colors.border.opacity(0.6), lineWidth: 1) ) } .buttonStyle(.plain) @@ -296,17 +296,21 @@ struct IntelligenceViewModern: View { .init( icon: "airplane.departure", title: "Briefing Agora", - subtitle: "Monte a leitura inicial do laboratório com risco, contexto e próxima ação.", + subtitle: + "Monte a leitura inicial do laboratório com risco, contexto e próxima ação.", tint: IntelligenceTheme.mint, - prompt: "Monte um briefing operacional agora com radar, sistema, clima, alertas e próxima ação.", + prompt: + "Monte um briefing operacional agora com radar, sistema, clima, alertas e próxima ação.", priority: 0 ), .init( icon: "bell.badge", title: "Triar Alertas", - subtitle: "Ordene ADS-B e ACARS por impacto, urgência e o que merece atenção primeiro.", + subtitle: + "Ordene ADS-B e ACARS por impacto, urgência e o que merece atenção primeiro.", tint: .orange, - prompt: "Explique os alertas ativos de ADS-B e ACARS. Ordene por prioridade, impacto e próxima ação.", + prompt: + "Explique os alertas ativos de ADS-B e ACARS. Ordene por prioridade, impacto e próxima ação.", priority: totalAlerts > 0 ? 10 : 2 ), .init( @@ -314,7 +318,8 @@ struct IntelligenceViewModern: View { title: "Revisar Sistema", subtitle: "Cheque CPU, RAM, disco, Wi-Fi e sinais de degradação operacional.", tint: IntelligenceTheme.accent, - prompt: "Faça um diagnóstico operacional do sistema e da infraestrutura. Aponte risco, evidência e próxima ação.", + prompt: + "Faça um diagnóstico operacional do sistema e da infraestrutura. Aponte risco, evidência e próxima ação.", priority: cpu >= 75 ? 9 : 3 ), .init( @@ -322,7 +327,8 @@ struct IntelligenceViewModern: View { title: "Ler ACARS", subtitle: "Resuma mensagens recentes, voos quentes e qualquer mudança de padrão.", tint: IntelligenceTheme.amber, - prompt: "Resuma as mensagens ACARS recentes, destaque anomalias, voos relevantes e o que mudou agora.", + prompt: + "Resuma as mensagens ACARS recentes, destaque anomalias, voos relevantes e o que mudou agora.", priority: appState.acarsMessages.isEmpty ? 1 : 5 ), .init( @@ -338,7 +344,8 @@ struct IntelligenceViewModern: View { title: "Risco Climático", subtitle: "Leia chuva, vento e previsão com foco no impacto operacional.", tint: .cyan, - prompt: "Leia o clima atual e a previsão com foco operacional, chuva, vento e impacto no laboratório.", + prompt: + "Leia o clima atual e a previsão com foco operacional, chuva, vento e impacto no laboratório.", priority: 2 ), .init( @@ -346,7 +353,8 @@ struct IntelligenceViewModern: View { title: "Próxima Ação", subtitle: "Diga qual tela abrir agora e qual pergunta rende mais valor.", tint: .pink, - prompt: "Com base no estado atual do laboratório, qual é a próxima ação mais útil agora?", + prompt: + "Com base no estado atual do laboratório, qual é a próxima ação mais útil agora?", priority: 6 ), ] @@ -365,17 +373,8 @@ struct IntelligenceViewModern: View { var body: some View { NavigationStack { ZStack { - LinearGradient( - colors: [ - Color.blue.opacity(0.10), - Color.mint.opacity(0.08), - Color.orange.opacity(0.07), - Color.clear, - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - .ignoresSafeArea() + MacOS9Colors.windowBackground + .ignoresSafeArea() VStack(spacing: 0) { ScrollViewReader { proxy in @@ -418,7 +417,9 @@ struct IntelligenceViewModern: View { Button { incidentMode.toggle() } label: { - Label(incidentMode ? "Sair Modo Incidente" : "Modo Incidente", systemImage: "exclamationmark.shield") + Label( + incidentMode ? "Sair Modo Incidente" : "Modo Incidente", + systemImage: "exclamationmark.shield") } Button(role: .destructive) { @@ -475,9 +476,11 @@ struct IntelligenceViewModern: View { VStack(alignment: .leading, spacing: 8) { Text("Copiloto Operacional") .font(.title2.bold()) - Text("Uma mesa única para entender o estado do radar, do sistema e dos eventos que pedem decisão.") - .font(.subheadline) - .foregroundStyle(.secondary) + Text( + "Uma mesa única para entender o estado do radar, do sistema e dos eventos que pedem decisão." + ) + .font(.subheadline) + .foregroundStyle(.secondary) } Spacer() VStack(alignment: .trailing, spacing: 8) { @@ -489,14 +492,20 @@ struct IntelligenceViewModern: View { statusPill( title: "Alertas", value: "\(appState.adsbAlerts.count + appState.acarsAlerts.count) ativos", - tint: appState.adsbAlerts.isEmpty && appState.acarsAlerts.isEmpty ? IntelligenceTheme.accent : .orange + tint: appState.adsbAlerts.isEmpty && appState.acarsAlerts.isEmpty + ? IntelligenceTheme.accent : .orange ) } } HStack(spacing: 12) { - quickMetric(title: "Radar", value: "\(appState.adsbSummary?.totalNow ?? appState.aircraftList.count)", tint: IntelligenceTheme.mint) - quickMetric(title: "CPU", value: "\(Int(appState.systemStatus?.cpu?.usagePercent ?? 0))%", tint: IntelligenceTheme.accent) + quickMetric( + title: "Radar", + value: "\(appState.adsbSummary?.totalNow ?? appState.aircraftList.count)", + tint: IntelligenceTheme.mint) + quickMetric( + title: "CPU", value: "\(Int(appState.systemStatus?.cpu?.usagePercent ?? 0))%", + tint: IntelligenceTheme.accent) quickMetric( title: "ACARS", value: appState.acarsSummary == nil && appState.acarsMessages.isEmpty @@ -514,11 +523,11 @@ struct IntelligenceViewModern: View { .padding(20) .background( RoundedRectangle(cornerRadius: 26, style: .continuous) - .fill(.ultraThinMaterial) + .fill(MacOS9Colors.panelBackground) ) .overlay( RoundedRectangle(cornerRadius: 26, style: .continuous) - .stroke(Color.white.opacity(0.18), lineWidth: 1) + .stroke(MacOS9Colors.border, lineWidth: 1) ) } @@ -529,7 +538,8 @@ struct IntelligenceViewModern: View { Text("Comece pelos blocos que reduzem incerteza mais rápido.") .font(.caption) .foregroundStyle(.secondary) - let columns = isWide + let columns = + isWide ? [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())] : [GridItem(.flexible()), GridItem(.flexible())] LazyVGrid(columns: columns, spacing: 12) { @@ -572,7 +582,9 @@ struct IntelligenceViewModern: View { } .frame(width: isWide ? 240 : 210, alignment: .leading) .padding(14) - .background(RoundedRectangle(cornerRadius: 18).fill(.thinMaterial)) + .background( + RoundedRectangle(cornerRadius: 18).fill( + MacOS9Colors.panelBackground)) } .buttonStyle(.plain) } @@ -600,7 +612,8 @@ struct IntelligenceViewModern: View { .foregroundStyle(item.delta.hasPrefix("+") ? .green : .orange) } .padding(12) - .background(RoundedRectangle(cornerRadius: 16).fill(.thinMaterial)) + .background( + RoundedRectangle(cornerRadius: 16).fill(MacOS9Colors.panelBackground)) } } } @@ -622,7 +635,7 @@ struct IntelligenceViewModern: View { } .padding(.horizontal, 10) .padding(.vertical, 8) - .background(Capsule().fill(.thinMaterial)) + .background(Capsule().fill(MacOS9Colors.panelBackground)) } } } @@ -647,7 +660,8 @@ struct IntelligenceViewModern: View { Spacer() } .padding(10) - .background(RoundedRectangle(cornerRadius: 14).fill(.thinMaterial)) + .background( + RoundedRectangle(cornerRadius: 14).fill(MacOS9Colors.panelBackground)) } } } @@ -680,9 +694,11 @@ struct IntelligenceViewModern: View { .font(.caption.bold()) .foregroundStyle(.red) if let sys = appState.systemStatus { - Text("CPU \(Int(sys.cpu?.usagePercent ?? 0))% · RAM \(Int(sys.memory?.usedPercent ?? 0))%") - .font(.caption2) - .foregroundStyle(.secondary) + Text( + "CPU \(Int(sys.cpu?.usagePercent ?? 0))% · RAM \(Int(sys.memory?.usedPercent ?? 0))%" + ) + .font(.caption2) + .foregroundStyle(.secondary) } } @@ -693,7 +709,7 @@ struct IntelligenceViewModern: View { .foregroundStyle(.secondary) } .padding(12) - .background(RoundedRectangle(cornerRadius: 18).fill(.ultraThinMaterial)) + .background(RoundedRectangle(cornerRadius: 18).fill(MacOS9Colors.panelBackground)) .overlay( RoundedRectangle(cornerRadius: 18) .stroke(Color.red.opacity(0.25), lineWidth: 1) @@ -735,7 +751,7 @@ struct IntelligenceViewModern: View { } .padding(.horizontal, 14) .padding(.vertical, 12) - .background(RoundedRectangle(cornerRadius: 20).fill(.ultraThinMaterial)) + .background(RoundedRectangle(cornerRadius: 20).fill(MacOS9Colors.panelBackground)) .overlay( RoundedRectangle(cornerRadius: 20) .stroke(Color.white.opacity(0.14), lineWidth: 1) @@ -854,7 +870,7 @@ struct IntelligenceViewModern: View { } .padding(.horizontal, 14) .padding(.vertical, 12) - .background(RoundedRectangle(cornerRadius: 20).fill(.thinMaterial)) + .background(RoundedRectangle(cornerRadius: 20).fill(MacOS9Colors.panelBackground)) Spacer(minLength: 40) } @@ -868,7 +884,7 @@ struct IntelligenceViewModern: View { .focused($isInputFocused) .padding(.horizontal, 14) .padding(.vertical, 12) - .background(RoundedRectangle(cornerRadius: 22).fill(.ultraThinMaterial)) + .background(RoundedRectangle(cornerRadius: 22).fill(MacOS9Colors.panelBackground)) .onSubmit { Task { await sendUserMessage() } } Button { @@ -906,10 +922,14 @@ struct IntelligenceViewModern: View { .font(.subheadline.weight(.medium)) .foregroundStyle(.primary) .lineLimit(1) - Text(session.updatedAt.formatted(.relative(presentation: .named))) - .font(.caption2) - .foregroundStyle(.secondary) - if let lastMessage = session.messages.last(where: { $0.role != .system }) { + Text( + session.updatedAt.formatted(.relative(presentation: .named)) + ) + .font(.caption2) + .foregroundStyle(.secondary) + if let lastMessage = session.messages.last(where: { + $0.role != .system + }) { Text(lastMessage.text) .font(.caption) .foregroundStyle(.tertiary) @@ -970,7 +990,7 @@ struct IntelligenceViewModern: View { } .frame(maxWidth: .infinity, alignment: .leading) .padding(12) - .background(RoundedRectangle(cornerRadius: 18).fill(.thinMaterial)) + .background(RoundedRectangle(cornerRadius: 18).fill(MacOS9Colors.panelBackground)) } private func bootstrapIfNeeded() { @@ -1168,22 +1188,23 @@ struct IntelligenceViewModern: View { if let tab = action.tab, !tab.isEmpty, let contextIdentifier = action.contextIdentifier, !contextIdentifier.isEmpty { - let kind: String? = switch tab { - case ContentView.Tab.map.rawValue, ContentView.Tab.adsb.rawValue: - "aircraft" - case ContentView.Tab.satellite.rawValue: - "satellite_pass" - case ContentView.Tab.acars.rawValue: - "acars" - case ContentView.Tab.weather.rawValue: - "weather_day" - case ContentView.Tab.alerts.rawValue: - "alert" - case ContentView.Tab.system.rawValue: - "system" - default: - nil - } + let kind: String? = + switch tab { + case ContentView.Tab.map.rawValue, ContentView.Tab.adsb.rawValue: + "aircraft" + case ContentView.Tab.satellite.rawValue: + "satellite_pass" + case ContentView.Tab.acars.rawValue: + "acars" + case ContentView.Tab.weather.rawValue: + "weather_day" + case ContentView.Tab.alerts.rawValue: + "alert" + case ContentView.Tab.system.rawValue: + "system" + default: + nil + } var userInfo: [String: String] = [ "tab": tab, "identifier": contextIdentifier, @@ -1203,7 +1224,9 @@ struct IntelligenceViewModern: View { let contextIdentifier = action.contextIdentifier { if let focused = appState.aircraftList.first(where: { - let values = [$0.callsign, $0.registration, $0.hex].compactMap { $0?.lowercased() } + let values = [$0.callsign, $0.registration, $0.hex].compactMap { + $0?.lowercased() + } return values.contains(contextIdentifier.lowercased()) }) { appState.mapFocusAircraft = focused @@ -1238,7 +1261,8 @@ struct IntelligenceViewModern: View { } } -private struct FlexibleChipStack: View where Data.Element: Identifiable { +private struct FlexibleChipStack: View +where Data.Element: Identifiable { let data: Data let content: (Data.Element) -> Content diff --git a/MeuLabApp/Views/Tabs/RadioView.swift b/MeuLabApp/Views/Tabs/RadioView.swift index c25b7c3..c291bc6 100644 --- a/MeuLabApp/Views/Tabs/RadioView.swift +++ b/MeuLabApp/Views/Tabs/RadioView.swift @@ -61,43 +61,17 @@ private struct RadioPanelBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [RadioTheme.surfaceTop, RadioTheme.mist], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.12), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder( - LinearGradient( - colors: [highlight.opacity(0.28), RadioTheme.surfaceStroke], - startPoint: .topLeading, - endPoint: .bottomTrailing - ), - lineWidth: 1.1 - ) - } - .shadow(color: RadioTheme.shadow.opacity(0.08), radius: 22, x: 0, y: 12) - .shadow(color: highlight.opacity(0.07), radius: 14, x: 0, y: 6) + MacOS9Colors.panelBackground + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } -private extension View { - func radioPanel(cornerRadius: CGFloat = 20, highlight: Color = RadioTheme.blue) -> some View { - background(RadioPanelBackground(cornerRadius: cornerRadius, highlight: highlight)) +extension View { + fileprivate func radioPanel(cornerRadius: CGFloat = 20, highlight: Color = RadioTheme.blue) + -> some View + { + mac9Panel() } } @@ -108,7 +82,9 @@ private struct RadioToolbarTitle: View { Circle() .fill( LinearGradient( - colors: [RadioTheme.green.opacity(0.18), RadioTheme.blue.opacity(0.12)], + colors: [ + RadioTheme.green.opacity(0.18), RadioTheme.blue.opacity(0.12), + ], startPoint: .topLeading, endPoint: .bottomTrailing ) @@ -197,8 +173,10 @@ struct RadioView: View { let safeInsets = proxy.safeAreaInsets let horizontalInset = isWide ? 24.0 : 16.0 let availableWidth = proxy.size.width - safeInsets.leading - safeInsets.trailing - let contentWidth = min(contentMaxWidth, max(availableWidth - (horizontalInset * 2), 280)) - let artworkSize = isWide ? min(contentWidth * 0.56, 420) : min(contentWidth * 0.74, 248) + let contentWidth = min( + contentMaxWidth, max(availableWidth - (horizontalInset * 2), 280)) + let artworkSize = + isWide ? min(contentWidth * 0.56, 420) : min(contentWidth * 0.74, 248) ZStack { immersiveBackground @@ -209,7 +187,7 @@ struct RadioView: View { compactLayout(contentWidth: contentWidth, artworkSize: artworkSize) } } - .frame(width: proxy.size.width) // Garantia extra para o ZStack não escapar horizontalmente + .frame(width: proxy.size.width) // Garantia extra para o ZStack não escapar horizontalmente } .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -311,40 +289,14 @@ struct RadioView: View { } } - @ViewBuilder private var immersiveBackground: some View { - ZStack { - if let artworkURL = effectiveArtworkURL { - AsyncImage(url: artworkURL) { phase in - switch phase { - case .success(let image): - image - .resizable() - .aspectRatio(contentMode: .fill) - default: - placeholderArtwork - } - } - } else { - placeholderArtwork - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity) // Limita a expansão ao tamanho proposto - .clipped() // Corta a sobra da imagem gerada pelo aspecto ratio - .blur(radius: 40) - .overlay(Color.black.opacity(0.48)) - .overlay( - LinearGradient( - colors: [Color.black.opacity(0.28), Color.clear, Color.black.opacity(0.34)], - startPoint: .top, - endPoint: .bottom - ) - ) - .ignoresSafeArea() + MacOS9Colors.windowBackground.ignoresSafeArea() } @ViewBuilder - private func stationHeroSection(size: CGFloat, contentWidth: CGFloat, compact: Bool) -> some View { + private func stationHeroSection(size: CGFloat, contentWidth: CGFloat, compact: Bool) + -> some View + { if compact { let compactWidth = contentWidth let compactArtworkSize = min(size, 220) @@ -551,15 +503,19 @@ struct RadioView: View { guard let np = appState.nowPlaying else { return false } // Hide when it's a station promo with unknown artist if isStationPromo(np) - && np.artist.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "desconhecido" { + && np.artist.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() + == "desconhecido" + { return true } // Also hide when the title already includes the artist to avoid duplication let artist = effectiveArtist.trimmingCharacters(in: .whitespacesAndNewlines) guard !artist.isEmpty else { return false } let title = effectiveTitle.trimmingCharacters(in: .whitespacesAndNewlines) - let normalizedTitle = title.folding(options: .diacriticInsensitive, locale: .current).lowercased() - let normalizedArtist = artist.folding(options: .diacriticInsensitive, locale: .current).lowercased() + let normalizedTitle = title.folding(options: .diacriticInsensitive, locale: .current) + .lowercased() + let normalizedArtist = artist.folding(options: .diacriticInsensitive, locale: .current) + .lowercased() return normalizedTitle.contains(normalizedArtist) } @@ -612,7 +568,9 @@ struct RadioView: View { .frame(width: contentWidth, alignment: .center) } - private func factSection(title: String, systemImage: String, tint: Color, isLoading: Bool, text: String) + private func factSection( + title: String, systemImage: String, tint: Color, isLoading: Bool, text: String + ) -> some View { VStack(alignment: .leading, spacing: 10) { @@ -866,7 +824,9 @@ struct RadioView: View { .buttonStyle(.plain) } - private func immersiveInfoPill(title: String, value: String, icon: String, tint: Color) -> some View { + private func immersiveInfoPill(title: String, value: String, icon: String, tint: Color) + -> some View + { HStack(spacing: 8) { Image(systemName: icon) .font(.caption.weight(.bold)) diff --git a/MeuLabApp/Views/Tabs/RemoteRadioView.swift b/MeuLabApp/Views/Tabs/RemoteRadioView.swift index 6b52336..359aa7c 100644 --- a/MeuLabApp/Views/Tabs/RemoteRadioView.swift +++ b/MeuLabApp/Views/Tabs/RemoteRadioView.swift @@ -22,8 +22,8 @@ struct RemoteRadioView: View { var body: some View { NavigationStack { ZStack { - // Wood cabinet background - woodBackground + // Mac OS 9 window background + MacOS9Colors.windowBackground.ignoresSafeArea() ScrollView { VStack(spacing: 0) { @@ -303,19 +303,16 @@ struct RemoteRadioView: View { .font(.system(size: 14, weight: .bold, design: .monospaced)) .foregroundStyle(vm.mode == radioMode ? woodDark : cream.opacity(0.7)) .frame(width: 60, height: 36) - .background { - if vm.mode == radioMode { - Capsule() - .fill(amber) - .shadow(color: amberGlow.opacity(0.4), radius: 6) - } else { - Capsule() - .fill(woodLight.opacity(0.3)) - .overlay( - Capsule().stroke(brass.opacity(0.4), lineWidth: 1) - ) - } - } + .background( + Capsule() + .fill( + vm.mode == radioMode + ? MacOS9Colors.contentPanel : MacOS9Colors.panelBackground + ) + .overlay( + Capsule().stroke(MacOS9Colors.border, lineWidth: 1) + ) + ) } } } diff --git a/MeuLabApp/Views/Tabs/SatelliteView.swift b/MeuLabApp/Views/Tabs/SatelliteView.swift index 50abcca..b63d805 100644 --- a/MeuLabApp/Views/Tabs/SatelliteView.swift +++ b/MeuLabApp/Views/Tabs/SatelliteView.swift @@ -319,11 +319,7 @@ struct SatelliteView: View { .foregroundStyle(.secondary) } .padding() - .background( - RoundedRectangle(cornerRadius: 16) - .fill(Color(.systemBackground)) - .shadow(color: .black.opacity(0.08), radius: 8, x: 0, y: 2) - ) + .mac9Panel() } @ViewBuilder @@ -395,11 +391,7 @@ struct SatelliteView: View { .cornerRadius(16) } .padding() - .background( - RoundedRectangle(cornerRadius: 16) - .fill(Color(.systemBackground)) - .shadow(color: .black.opacity(0.08), radius: 8, x: 0, y: 2) - ) + .mac9Panel() .onAppear { // Select first page once to trigger exactly one initial image load. if lastPassCarouselSelection == nil { @@ -652,10 +644,10 @@ struct SatelliteImageCarouselCard: View { .foregroundStyle(.secondary) } .padding(12) - .background(Color(.systemBackground)) + .background(MacOS9Colors.panelBackground) } - .cornerRadius(12) - .shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 2, y: 2) .padding(.horizontal, 4) .onTapGesture { onTap() diff --git a/MeuLabApp/Views/Tabs/SystemView.swift b/MeuLabApp/Views/Tabs/SystemView.swift index 4242ba8..8abe53c 100644 --- a/MeuLabApp/Views/Tabs/SystemView.swift +++ b/MeuLabApp/Views/Tabs/SystemView.swift @@ -91,37 +91,9 @@ private struct SystemPanelBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [SystemTheme.surfaceTop, SystemTheme.mist], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.12), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder( - LinearGradient( - colors: [highlight.opacity(0.28), SystemTheme.surfaceStroke], - startPoint: .topLeading, - endPoint: .bottomTrailing - ), - lineWidth: 1.1 - ) - } - .shadow(color: SystemTheme.shadow.opacity(0.08), radius: 22, x: 0, y: 12) - .shadow(color: highlight.opacity(0.07), radius: 14, x: 0, y: 6) + MacOS9Colors.panelBackground + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -129,7 +101,7 @@ extension View { fileprivate func systemPanel(cornerRadius: CGFloat = 18, highlight: Color = SystemTheme.piBlue) -> some View { - background(SystemPanelBackground(cornerRadius: cornerRadius, highlight: highlight)) + mac9Panel() } } @@ -477,30 +449,7 @@ struct SystemView: View { .padding(.top, isCompactLayout ? 8 : 4) .padding(.bottom, 20) } - .background { - ZStack { - LinearGradient( - colors: [SystemTheme.cloud, SystemTheme.canvasMid, SystemTheme.canvasEnd], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - RadialGradient( - colors: [SystemTheme.piGreen.opacity(0.10), .clear], - center: .topLeading, - startRadius: 20, - endRadius: 420 - ) - - RadialGradient( - colors: [SystemTheme.piRed.opacity(0.08), .clear], - center: .topTrailing, - startRadius: 30, - endRadius: 360 - ) - } - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle("Sistema") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/MeuLabApp/Views/Tabs/WeatherView.swift b/MeuLabApp/Views/Tabs/WeatherView.swift index ecb340c..c352e83 100644 --- a/MeuLabApp/Views/Tabs/WeatherView.swift +++ b/MeuLabApp/Views/Tabs/WeatherView.swift @@ -62,37 +62,9 @@ private struct WeatherPanelBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [WeatherTheme.surfaceTop, WeatherTheme.mist], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.12), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder( - LinearGradient( - colors: [highlight.opacity(0.28), WeatherTheme.surfaceStroke], - startPoint: .topLeading, - endPoint: .bottomTrailing - ), - lineWidth: 1.1 - ) - } - .shadow(color: WeatherTheme.shadow.opacity(0.08), radius: 24, x: 0, y: 12) - .shadow(color: highlight.opacity(0.07), radius: 16, x: 0, y: 6) + MacOS9Colors.panelBackground + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -101,36 +73,27 @@ private struct WeatherInsetBackground: View { let highlight: Color var body: some View { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill(WeatherTheme.insetSurface) - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .fill( - LinearGradient( - colors: [highlight.opacity(0.10), .clear], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - } - .overlay { - RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) - .strokeBorder(highlight.opacity(0.16), lineWidth: 1) - } + MacOS9Colors.contentPanel + .overlay(Mac9BevelBorder(isRaised: false)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } -private extension View { - func weatherPanel(cornerRadius: CGFloat = 22, highlight: Color = WeatherTheme.skyBlue) +extension View { + fileprivate func weatherPanel( + cornerRadius: CGFloat = 22, highlight: Color = WeatherTheme.skyBlue + ) -> some View { - background(WeatherPanelBackground(cornerRadius: cornerRadius, highlight: highlight)) + mac9Panel() } - func weatherInsetPanel(cornerRadius: CGFloat = 18, highlight: Color = WeatherTheme.skyBlue) + fileprivate func weatherInsetPanel( + cornerRadius: CGFloat = 18, highlight: Color = WeatherTheme.skyBlue + ) -> some View { - background(WeatherInsetBackground(cornerRadius: cornerRadius, highlight: highlight)) + mac9Sunken() } } @@ -246,78 +209,7 @@ private struct WeatherAtmosphereBackground: View { @State private var animate = false var body: some View { - GeometryReader { geometry in - ZStack { - LinearGradient( - colors: style.gradients, - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - RadialGradient( - colors: [style.accent.opacity(0.18), .clear], - center: .topTrailing, - startRadius: 30, - endRadius: 360 - ) - - if style.showsSun { - Circle() - .fill( - RadialGradient( - colors: [WeatherTheme.sunAmber.opacity(0.75), .clear], - center: .center, - startRadius: 12, - endRadius: 140 - ) - ) - .frame(width: 220, height: 220) - .offset(x: geometry.size.width * 0.24, y: -geometry.size.height * 0.26) - } - - if style.showsStars { - ForEach(0..<18, id: \.self) { index in - Circle() - .fill(Color.white.opacity(index.isMultiple(of: 3) ? 0.80 : 0.45)) - .frame(width: index.isMultiple(of: 4) ? 4 : 2, height: index.isMultiple(of: 4) ? 4 : 2) - .offset( - x: starX(index: index, size: geometry.size), - y: starY(index: index, size: geometry.size) - ) - } - } - - if style.showsClouds { - ForEach(0..<4, id: \.self) { index in - cloudBlob(index: index, size: geometry.size) - } - } - - if style.showsRain { - ForEach(0..<18, id: \.self) { index in - Capsule(style: .continuous) - .fill(Color.white.opacity(style == .stormDay ? 0.28 : 0.18)) - .frame(width: 2, height: CGFloat(26 + (index % 3) * 14)) - .rotationEffect(.degrees(12)) - .offset( - x: rainX(index: index, size: geometry.size), - y: animate ? geometry.size.height / 2 + 220 : -geometry.size.height / 2 - 120 - ) - .animation( - .linear(duration: 1.3 + Double(index) * 0.05) - .repeatForever(autoreverses: false) - .delay(Double(index) * 0.06), - value: animate - ) - } - } - } - .ignoresSafeArea() - .onAppear { - animate = true - } - } - .allowsHitTesting(false) + MacOS9Colors.windowBackground.ignoresSafeArea() } private func cloudBlob(index: Int, size: CGSize) -> some View { @@ -365,7 +257,10 @@ private struct WeatherToolbarTitle: View { Circle() .fill( LinearGradient( - colors: [WeatherTheme.sunAmber.opacity(0.18), WeatherTheme.skyBlue.opacity(0.12)], + colors: [ + WeatherTheme.sunAmber.opacity(0.18), + WeatherTheme.skyBlue.opacity(0.12), + ], startPoint: .topLeading, endPoint: .bottomTrailing ) @@ -435,13 +330,17 @@ private struct WeatherDayChip: View { HStack { Text(day.title) .font(.caption.weight(.semibold)) - .foregroundStyle(isSelected ? Color.white.opacity(0.88) : WeatherTheme.ink.opacity(0.62)) + .foregroundStyle( + isSelected ? Color.white.opacity(0.88) : WeatherTheme.ink.opacity(0.62)) Spacer() Image(systemName: day.icon) .font(.subheadline.weight(.bold)) - .foregroundStyle(isSelected ? .white : day.rainChance >= 45 ? WeatherTheme.rainBlue : WeatherTheme.sunAmber) + .foregroundStyle( + isSelected + ? .white + : day.rainChance >= 45 ? WeatherTheme.rainBlue : WeatherTheme.sunAmber) } Text(day.maxTempLabel) @@ -452,11 +351,13 @@ private struct WeatherDayChip: View { HStack(spacing: 8) { Label("\(day.rainChance)%", systemImage: "drop.fill") .font(.caption2.weight(.semibold)) - .foregroundStyle(isSelected ? Color.white.opacity(0.9) : WeatherTheme.ink.opacity(0.56)) + .foregroundStyle( + isSelected ? Color.white.opacity(0.9) : WeatherTheme.ink.opacity(0.56)) Text(day.shortDate) .font(.caption2.weight(.semibold)) - .foregroundStyle(isSelected ? Color.white.opacity(0.74) : WeatherTheme.ink.opacity(0.50)) + .foregroundStyle( + isSelected ? Color.white.opacity(0.74) : WeatherTheme.ink.opacity(0.50)) } } .padding(14) @@ -591,7 +492,9 @@ private struct WeatherForecastRow: View { HStack(spacing: 14) { Image(systemName: day.icon) .font(.title3.weight(.semibold)) - .foregroundStyle(day.rainChance >= 45 ? WeatherTheme.rainBlue : WeatherTheme.sunAmber) + .foregroundStyle( + day.rainChance >= 45 ? WeatherTheme.rainBlue : WeatherTheme.sunAmber + ) .frame(width: 24) VStack(alignment: .leading, spacing: 4) { @@ -661,7 +564,10 @@ private struct TemperatureRail: View { Capsule() .fill( LinearGradient( - colors: [WeatherTheme.skyBlue, WeatherTheme.sunAmber, Color.red.opacity(0.80)], + colors: [ + WeatherTheme.skyBlue, WeatherTheme.sunAmber, + Color.red.opacity(0.80), + ], startPoint: .leading, endPoint: .trailing ) @@ -753,7 +659,8 @@ private enum WeatherClock { } static func parseDateTime(_ raw: String) -> Date? { - if let iso = Formatters.isoDate.date(from: raw) ?? Formatters.isoDateNoFrac.date(from: raw) { + if let iso = Formatters.isoDate.date(from: raw) ?? Formatters.isoDateNoFrac.date(from: raw) + { return iso } return localDateTime.date(from: raw) @@ -785,11 +692,7 @@ struct WeatherView: View { .padding(.horizontal) .padding(.bottom, 24) } - .background { - WeatherAtmosphereBackground( - style: appState.weather.map { WeatherAtmosphere(current: $0.current) } ?? .clearDay - ) - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle("Clima") .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -909,7 +812,8 @@ struct WeatherView: View { await appState.refreshWeather() try? await Task.sleep(nanoseconds: 1_500_000_000) - guard appState.weather == nil, appState.weatherError == nil, !appState.weatherLoading else { + guard appState.weather == nil, appState.weatherError == nil, !appState.weatherLoading + else { return } await appState.refreshWeather() @@ -940,7 +844,9 @@ struct WeatherView: View { } @ViewBuilder - private func currentWeatherSection(_ weather: WeatherData, style: WeatherAtmosphere) -> some View { + private func currentWeatherSection(_ weather: WeatherData, style: WeatherAtmosphere) + -> some View + { VStack(alignment: .leading, spacing: 20) { HStack(alignment: .top, spacing: 16) { VStack(alignment: .leading, spacing: 8) { @@ -1308,12 +1214,14 @@ struct WeatherView: View { ) if insights.hourly.isEmpty { - Text("Esse dia ainda não tem previsão horária detalhada disponível. A leitura acima usa os dados diários consolidados.") - .font(.subheadline) - .foregroundStyle(WeatherTheme.ink.opacity(0.62)) - .padding(18) - .frame(maxWidth: .infinity, alignment: .leading) - .weatherInsetPanel(cornerRadius: 20, highlight: tint) + Text( + "Esse dia ainda não tem previsão horária detalhada disponível. A leitura acima usa os dados diários consolidados." + ) + .font(.subheadline) + .foregroundStyle(WeatherTheme.ink.opacity(0.62)) + .padding(18) + .frame(maxWidth: .infinity, alignment: .leading) + .weatherInsetPanel(cornerRadius: 20, highlight: tint) } else { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 12) { @@ -1414,15 +1322,19 @@ struct WeatherView: View { days.append( contentsOf: weather.forecast.map { day in let date = Formatters.apiDate.date(from: day.date) - let weekday = date.map { WeatherClock.weekdayShort.string(from: $0).capitalized } ?? day.formattedDate + let weekday = + date.map { WeatherClock.weekdayShort.string(from: $0).capitalized } + ?? day.formattedDate let shortDate = date.map { WeatherClock.shortDate.string(from: $0) } ?? day.date return WeatherDayCardModel( id: day.date, title: weekday, shortDate: shortDate, - rowTitle: date.map { WeatherClock.detailDate.string(from: $0).capitalized } ?? day.formattedDate, - description: day.description ?? rainSummary(chance: day.rainChance, mm: day.rainMm), + rowTitle: date.map { WeatherClock.detailDate.string(from: $0).capitalized } + ?? day.formattedDate, + description: day.description + ?? rainSummary(chance: day.rainChance, mm: day.rainMm), icon: day.weatherIcon, maxTempC: day.maxTempC, minTempC: day.minTempC, @@ -1444,22 +1356,28 @@ struct WeatherView: View { return days.first(where: { $0.id == selectedDayID }) ?? days.first } - private func weatherInsights(for day: WeatherDayCardModel, weather: WeatherData) -> WeatherDayInsights { + private func weatherInsights(for day: WeatherDayCardModel, weather: WeatherData) + -> WeatherDayInsights + { let hourly = (weather.hourly ?? []).filter { $0.dayKey == day.id } let rainyHours = hourly.filter { $0.rainChance >= 35 || $0.rainMm >= 0.15 } let peakRain = hourly.max(by: { $0.rainMm < $1.rainMm }) let totalRain = hourly.isEmpty ? day.rainMm : hourly.reduce(0) { $0 + $1.rainMm } let maxChance = max(day.rainChance, hourly.map(\.rainChance).max() ?? 0) - let dryHours = hourly.isEmpty ? max(0, 24 - Int(Double(day.rainChance) / 100 * 24)) : - hourly.filter { $0.rainChance < 20 && $0.rainMm < 0.1 }.count + let dryHours = + hourly.isEmpty + ? max(0, 24 - Int(Double(day.rainChance) / 100 * 24)) + : hourly.filter { $0.rainChance < 20 && $0.rainMm < 0.1 }.count let humidityValues = hourly.compactMap(\.humidity) - let humidityAverage = humidityValues.isEmpty ? nil : - Int(round(Double(humidityValues.reduce(0, +)) / Double(humidityValues.count))) + let humidityAverage = + humidityValues.isEmpty + ? nil : Int(round(Double(humidityValues.reduce(0, +)) / Double(humidityValues.count))) let rainWindow: String if let first = rainyHours.first, let last = rainyHours.last { - rainWindow = first.timeLabel == last.timeLabel ? - first.timeLabel : "\(first.timeLabel) - \(last.timeLabel)" + rainWindow = + first.timeLabel == last.timeLabel + ? first.timeLabel : "\(first.timeLabel) - \(last.timeLabel)" } else if day.rainChance >= 40 { rainWindow = "Chance distribuida ao longo do dia" } else { @@ -1468,7 +1386,8 @@ struct WeatherView: View { let wettestHourText: String if let peakRain, peakRain.rainMm > 0.05 { - wettestHourText = "\(peakRain.timeLabel) • \(peakRain.rainMm.formattedBR(decimals: 1)) mm" + wettestHourText = + "\(peakRain.timeLabel) • \(peakRain.rainMm.formattedBR(decimals: 1)) mm" } else if day.rainMm > 0 { wettestHourText = "Volume leve distribuído" } else { @@ -1533,7 +1452,8 @@ struct WeatherView: View { return "Tempo mais seco" } - private func rainNarrative(for day: WeatherDayCardModel, insights: WeatherDayInsights) -> String { + private func rainNarrative(for day: WeatherDayCardModel, insights: WeatherDayInsights) -> String + { if insights.maxRainChance >= 75 || insights.rainTotal >= 12 { return "Chance alta de chuva consistente" } @@ -1547,15 +1467,19 @@ struct WeatherView: View { } private func heroSummary(for current: CurrentWeather) -> String { - let rainText = current.precipMm > 0 + let rainText = + current.precipMm > 0 ? "\(current.precipMm.formattedBR(decimals: 1)) mm agora" : "sem chuva no momento" return "Sensação de \(current.feelsLikeC)°C, \(rainText) e UV \(current.uvIndex)." } private func updatedWeatherText(_ timestamp: String) -> String { - guard let date = WeatherClock.parseDateTime(timestamp) else { return "Atualização indisponível" } - return "Atualizado \(Formatters.relativeDate.localizedString(for: date, relativeTo: Date()))" + guard let date = WeatherClock.parseDateTime(timestamp) else { + return "Atualização indisponível" + } + return + "Atualizado \(Formatters.relativeDate.localizedString(for: date, relativeTo: Date()))" } private func formattedClock(_ raw: String?) -> String { @@ -1586,8 +1510,8 @@ struct WeatherView: View { } } -private extension WeatherDayCardModel { - var detailTemperatureRange: String { +extension WeatherDayCardModel { + fileprivate var detailTemperatureRange: String { "\(minTempLabel) - \(maxTempLabel)" } } diff --git a/add_ds_to_project.py b/add_ds_to_project.py new file mode 100644 index 0000000..0394445 --- /dev/null +++ b/add_ds_to_project.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +"""Add MacOS9 DesignSystem files to the Xcode project.pbxproj.""" + +import re +import sys +import shutil + +PROJECT = "MeuLabApp.xcodeproj/project.pbxproj" + +# 14 DesignSystem files to add +# Each entry: (id_prefix, filename, relative_path_from_root) +DS_FILES = [ + ("DS001", "MacOS9Colors.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift"), + ("DS002", "MacOS9Typography.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift"), + ("DS003", "MacOS9Metrics.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Metrics.swift"), + ("DS004", "MacOS9Modifiers.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift"), + ("DS005", "MacOS9TitleBar.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift"), + ("DS006", "MacOS9Window.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift"), + ("DS007", "MacOS9Button.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Button.swift"), + ("DS008", "MacOS9Panel.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift"), + ("DS009", "MacOS9Label.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Label.swift"), + ("DS010", "MacOS9TextField.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9TextField.swift"), + ("DS011", "MacOS9ListRow.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9ListRow.swift"), + ("DS012", "MacOS9Divider.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift"), + ("DS013", "MacOS9Screen.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift"), + ("DS014", "MacOS9Theme.swift", "MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift"), +] + +def main(): + # Read current content + with open(PROJECT, 'r', encoding='utf-8') as f: + content = f.read() + + # Backup + shutil.copy2(PROJECT, PROJECT + ".backup_ds") + print("Backed up to project.pbxproj.backup_ds") + + # ── 1. Add PBXFileReference entries ────────────────────────────────────── + # Insert before the end marker, after WN15 + ref_entries = [] + for (prefix, filename, path) in DS_FILES: + ref_id = prefix + "01" + ref_entries.append( + f'\t\t{ref_id} /* {filename} */ = {{isa = PBXFileReference; ' + f'lastKnownFileType = sourcecode.swift; ' + f'path = "{path}"; sourceTree = SOURCE_ROOT; }};' + ) + ref_block = "\n".join(ref_entries) + + END_REF_MARKER = "/* End PBXFileReference section */" + if END_REF_MARKER not in content: + print("ERROR: PBXFileReference end marker not found", file=sys.stderr) + sys.exit(1) + content = content.replace( + END_REF_MARKER, + ref_block + "\n" + END_REF_MARKER + ) + print(f"Added {len(DS_FILES)} PBXFileReference entries") + + # ── 2. Add PBXBuildFile entries ─────────────────────────────────────────── + build_entries = [] + for (prefix, filename, path) in DS_FILES: + ref_id = prefix + "01" + build_id = prefix + "02" + build_entries.append( + f'\t\t{build_id} /* {filename} in Sources */ = ' + f'{{isa = PBXBuildFile; fileRef = {ref_id} /* {filename} */; }};' + ) + build_block = "\n".join(build_entries) + + END_BF_MARKER = "/* End PBXBuildFile section */" + if END_BF_MARKER not in content: + print("ERROR: PBXBuildFile end marker not found", file=sys.stderr) + sys.exit(1) + content = content.replace( + END_BF_MARKER, + build_block + "\n" + END_BF_MARKER + ) + print(f"Added {len(DS_FILES)} PBXBuildFile entries") + + # ── 3. Add to Sources build phase (before the closing ); ) ─────────────── + # Anchor: LGM02 is the last entry in Sources + ANCHOR = "\t\t\t\tLGM02 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift in Sources */," + if ANCHOR not in content: + print("ERROR: Sources build phase anchor (LGM02) not found", file=sys.stderr) + sys.exit(1) + + sources_entries = [] + for (prefix, filename, path) in DS_FILES: + build_id = prefix + "02" + sources_entries.append( + f'\t\t\t\t{build_id} /* {filename} in Sources */,' + ) + sources_block = "\n".join(sources_entries) + + content = content.replace( + ANCHOR, + ANCHOR + "\n" + sources_block + ) + print(f"Added {len(DS_FILES)} Sources build phase entries") + + # ── 4. Add to PBXGroup (Recovered References) ──────────────────────────── + # Anchor: LGM01 line inside the Recovered References group + GRP_ANCHOR = "\t\t\t\tLGM01 /* MeuLabApp/Extensions/LiquidGlass+Modifiers.swift */," + if GRP_ANCHOR not in content: + print("ERROR: Group anchor (LGM01) not found", file=sys.stderr) + sys.exit(1) + + group_entries = [] + for (prefix, filename, path) in DS_FILES: + ref_id = prefix + "01" + group_entries.append( + f'\t\t\t\t{ref_id} /* {filename} */,' + ) + group_block = "\n".join(group_entries) + + content = content.replace( + GRP_ANCHOR, + GRP_ANCHOR + "\n" + group_block + ) + print(f"Added {len(DS_FILES)} PBXGroup entries") + + # ── Write ───────────────────────────────────────────────────────────────── + with open(PROJECT, 'w', encoding='utf-8') as f: + f.write(content) + print("project.pbxproj updated successfully") + +if __name__ == "__main__": + main() From ccb780e04bef035727c76a61ba6f503c524ec48a Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sat, 23 May 2026 17:47:39 -0300 Subject: [PATCH 04/10] Apply Mac OS 9 UI kit theme --- MeuLabApp.xcodeproj/project.pbxproj | 32 ++++++++ MeuLabApp/ContentView.swift | 3 +- .../DesignSystem/MacOS9/MacOS9Colors.swift | 6 +- .../DesignSystem/MacOS9/MacOS9Modifiers.swift | 49 +++++++------ .../DesignSystem/MacOS9/MacOS9Panel.swift | 16 ++-- .../DesignSystem/MacOS9/MacOS9Theme.swift | 22 ++++-- .../DesignSystem/MacOS9/MacOS9TitleBar.swift | 24 ++---- .../MacOS9/MacOS9Typography.swift | 41 +++++++---- .../DesignSystem/MacOS9/MacOS9Window.swift | 16 ++-- MeuLabApp/EnhancedContentView.swift | 64 ++++++++-------- .../Extensions/LiquidGlass+Modifiers.swift | 27 ++++--- .../Resources/Fonts/AppleGaramond-Bold.ttf | Bin 0 -> 47264 bytes .../Resources/Fonts/AppleGaramond-Light.ttf | Bin 0 -> 47824 bytes .../Fonts/AppleGaramond-LightItalic.ttf | Bin 0 -> 46068 bytes MeuLabApp/Resources/Fonts/AppleGaramond.ttf | Bin 0 -> 47476 bytes MeuLabApp/Resources/Fonts/Charcoal.ttf | Bin 0 -> 63412 bytes MeuLabApp/Resources/Fonts/Geneva.ttf | Bin 0 -> 37708 bytes .../Views/Settings/ThemeManagerView.swift | 6 +- MeuLabApp/Views/Tabs/ACARSView.swift | 69 +++++++----------- MeuLabApp/Views/Tabs/ADSBView.swift | 2 + MeuLabApp/Views/Tabs/BibleNavigateView.swift | 8 +- MeuLabApp/Views/Tabs/BibleSearchView.swift | 7 +- MeuLabApp/Views/Tabs/BibleView.swift | 35 ++++----- MeuLabApp/Views/Tabs/IntelligenceView.swift | 8 +- MeuLabApp/Views/Tabs/RemoteRadioView.swift | 28 +++---- MeuLabApp/Views/Tabs/SatelliteView.swift | 6 +- 26 files changed, 255 insertions(+), 214 deletions(-) create mode 100644 MeuLabApp/Resources/Fonts/AppleGaramond-Bold.ttf create mode 100644 MeuLabApp/Resources/Fonts/AppleGaramond-Light.ttf create mode 100644 MeuLabApp/Resources/Fonts/AppleGaramond-LightItalic.ttf create mode 100644 MeuLabApp/Resources/Fonts/AppleGaramond.ttf create mode 100644 MeuLabApp/Resources/Fonts/Charcoal.ttf create mode 100644 MeuLabApp/Resources/Fonts/Geneva.ttf diff --git a/MeuLabApp.xcodeproj/project.pbxproj b/MeuLabApp.xcodeproj/project.pbxproj index 76c76b6..2ce1e19 100644 --- a/MeuLabApp.xcodeproj/project.pbxproj +++ b/MeuLabApp.xcodeproj/project.pbxproj @@ -57,6 +57,12 @@ 053 /* NativeRadarMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 154 /* NativeRadarMapView.swift */; }; 3909786604B94EE5BE1AD25A /* MeuLabWatch/Services/WatchSecrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E181A3D935D7491286930152 /* MeuLabWatch/Services/WatchSecrets.swift */; }; 7F0B7866E4944B48AAFB4F3A /* bible.json in Resources */ = {isa = PBXBuildFile; fileRef = EB2CCDD5B45142E9817882CE /* bible.json */; }; + AA000000000000000000C6FF /* AppleGaramond.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA000000000000000000C7FF /* AppleGaramond.ttf */; }; + AA000000000000000000C8FF /* AppleGaramond-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA000000000000000000C9FF /* AppleGaramond-Light.ttf */; }; + AA000000000000000000CAFF /* AppleGaramond-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA000000000000000000CBFF /* AppleGaramond-LightItalic.ttf */; }; + AA000000000000000000CCFF /* AppleGaramond-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA000000000000000000CDFF /* AppleGaramond-Bold.ttf */; }; + AA000000000000000000C3FF /* Charcoal.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA000000000000000000C1FF /* Charcoal.ttf */; }; + AA000000000000000000C4FF /* Geneva.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA000000000000000000C2FF /* Geneva.ttf */; }; A1B2C3D4E5F6A7B8C9D0E1F2 /* MeuLabApp/Core/Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0C1B2D3E4F5A6B7C8D9E0 /* MeuLabApp/Core/Secrets.swift */; }; AC100 /* MeuLabApp/Core/Utils/AircraftClassification.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC200 /* MeuLabApp/Core/Utils/AircraftClassification.swift */; }; B1C2D3E4F5A6B7C8D9E0F1A2 /* MeuLabApp/Core/NetworkEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D3E4F5A6B7C8D9E0F1A2B3 /* MeuLabApp/Core/NetworkEnvironment.swift */; }; @@ -302,6 +308,12 @@ DS01201 /* MacOS9Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Divider.swift"; sourceTree = SOURCE_ROOT; }; DS01301 /* MacOS9Screen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Screen.swift"; sourceTree = SOURCE_ROOT; }; DS01401 /* MacOS9Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift"; sourceTree = SOURCE_ROOT; }; + AA000000000000000000C7FF /* AppleGaramond.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = AppleGaramond.ttf; path = AppleGaramond.ttf; sourceTree = ""; }; + AA000000000000000000C9FF /* AppleGaramond-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AppleGaramond-Light.ttf"; path = "AppleGaramond-Light.ttf"; sourceTree = ""; }; + AA000000000000000000CBFF /* AppleGaramond-LightItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AppleGaramond-LightItalic.ttf"; path = "AppleGaramond-LightItalic.ttf"; sourceTree = ""; }; + AA000000000000000000CDFF /* AppleGaramond-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AppleGaramond-Bold.ttf"; path = "AppleGaramond-Bold.ttf"; sourceTree = ""; }; + AA000000000000000000C1FF /* Charcoal.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = Charcoal.ttf; path = Charcoal.ttf; sourceTree = ""; }; + AA000000000000000000C2FF /* Geneva.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = Geneva.ttf; path = Geneva.ttf; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -472,10 +484,24 @@ 116 /* Assets.xcassets */, 130 /* LaunchScreen.storyboard */, EB2CCDD5B45142E9817882CE /* bible.json */, + AA000000000000000000C5FF /* Fonts */, ); path = Resources; sourceTree = ""; }; + AA000000000000000000C5FF /* Fonts */ = { + isa = PBXGroup; + children = ( + AA000000000000000000C7FF /* AppleGaramond.ttf */, + AA000000000000000000C9FF /* AppleGaramond-Light.ttf */, + AA000000000000000000CBFF /* AppleGaramond-LightItalic.ttf */, + AA000000000000000000CDFF /* AppleGaramond-Bold.ttf */, + AA000000000000000000C1FF /* Charcoal.ttf */, + AA000000000000000000C2FF /* Geneva.ttf */, + ); + path = Fonts; + sourceTree = ""; + }; 308 /* Tabs */ = { isa = PBXGroup; children = ( @@ -776,6 +802,12 @@ F7803D5F2F4A9A7B001C8722 /* Secrets.plist in Resources */, 029 /* LaunchScreen.storyboard in Resources */, 7F0B7866E4944B48AAFB4F3A /* bible.json in Resources */, + AA000000000000000000C6FF /* AppleGaramond.ttf in Resources */, + AA000000000000000000C8FF /* AppleGaramond-Light.ttf in Resources */, + AA000000000000000000CAFF /* AppleGaramond-LightItalic.ttf in Resources */, + AA000000000000000000CCFF /* AppleGaramond-Bold.ttf in Resources */, + AA000000000000000000C3FF /* Charcoal.ttf in Resources */, + AA000000000000000000C4FF /* Geneva.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MeuLabApp/ContentView.swift b/MeuLabApp/ContentView.swift index 5215bc1..0df0232 100644 --- a/MeuLabApp/ContentView.swift +++ b/MeuLabApp/ContentView.swift @@ -208,7 +208,8 @@ struct ContentView: View { } .tabViewStyle(.sidebarAdaptable) .tabBarMinimizeBehavior(.onScrollDown) - .tint(.blue) + .tint(MacOS9Colors.selection) + .background(MacOS9Colors.windowBackground) .adaptiveTheme() .onAppear { if !didApplyLaunchTab { diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift index 0f80c45..726d25d 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Colors.swift @@ -57,9 +57,9 @@ public enum MacOS9Colors { // MARK: Button public static let buttonFace = windowBackground public static let buttonBorder = border - public static let buttonPressed = Color(red: 0.700, green: 0.700, blue: 0.700) + public static let buttonPressed = Color(red: 0.667, green: 0.667, blue: 0.667) // MARK: Scrollbar - public static let scrollbarTrack = Color(red: 0.800, green: 0.800, blue: 0.800) - public static let scrollbarThumb = Color(red: 0.600, green: 0.600, blue: 0.600) + public static let scrollbarTrack = Color(red: 0.667, green: 0.667, blue: 0.667) + public static let scrollbarThumb = Color(red: 0.600, green: 0.600, blue: 1.000) } diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift index e7186fa..c1dc428 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift @@ -58,18 +58,21 @@ extension View { func mac9Panel(padding: CGFloat = MacOS9Metrics.windowPadding) -> some View { self .padding(padding) - .background(MacOS9Colors.panelBackground) + .background( + // Shadow on background shape only — prevents text ghosting + MacOS9Colors.panelBackground + .shadow( + color: MacOS9Colors.dropShadow, + radius: MacOS9Metrics.dropShadowBlur, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + ) .overlay(Mac9BevelBorder(isRaised: true)) .overlay( Rectangle() .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) ) - .shadow( - color: MacOS9Colors.dropShadow, - radius: MacOS9Metrics.dropShadowBlur, - x: MacOS9Metrics.dropShadowX, - y: MacOS9Metrics.dropShadowY - ) } /// Sunken / inset panel (e.g. scroll area, text field background) @@ -87,18 +90,20 @@ extension View { /// Window-level container: window background + outer bevel + hard shadow func mac9Window() -> some View { self - .background(MacOS9Colors.windowBackground) + .background( + MacOS9Colors.windowBackground + .shadow( + color: MacOS9Colors.dropShadow, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + ) .overlay(Mac9BevelBorder(isRaised: true, width: 2)) .overlay( Rectangle() .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) ) - .shadow( - color: MacOS9Colors.dropShadow, - radius: 0, - x: MacOS9Metrics.dropShadowX, - y: MacOS9Metrics.dropShadowY - ) } /// Flat card: light panel background, 1px border, no bevel, no shadow. @@ -138,18 +143,20 @@ extension View { func glassCard(tint color: Color, cornerRadius: CGFloat = 16) -> some View { self .padding(MacOS9Metrics.windowPadding) - .background(MacOS9Colors.panelBackground) + .background( + MacOS9Colors.panelBackground + .shadow( + color: MacOS9Colors.dropShadow, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + ) .overlay(Mac9BevelBorder(isRaised: true)) .overlay( Rectangle() .strokeBorder(color.opacity(0.8), lineWidth: MacOS9Metrics.borderWidth) ) - .shadow( - color: MacOS9Colors.dropShadow, - radius: 0, - x: MacOS9Metrics.dropShadowX, - y: MacOS9Metrics.dropShadowY - ) } /// Lightweight card — same as mac9FlatCard. diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift index 1b00e83..21e00f6 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Panel.swift @@ -19,15 +19,17 @@ struct MacOS9Panel: View { var body: some View { content .padding(padding) - .background(background) + .background( + background + .shadow( + color: style == .raised ? MacOS9Colors.dropShadow : .clear, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + ) .overlay(bevel) .overlay(border) - .shadow( - color: style == .raised ? MacOS9Colors.dropShadow : .clear, - radius: 0, - x: MacOS9Metrics.dropShadowX, - y: MacOS9Metrics.dropShadowY - ) } @ViewBuilder diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift index 0413342..5261d6b 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift @@ -11,6 +11,8 @@ extension View { self .preferredColorScheme(.light) .tint(MacOS9Colors.selection) + .font(MacOS9Typography.body()) + .foregroundStyle(MacOS9Colors.primaryText) .background(MacOS9Colors.windowBackground) .onAppear { MacOS9Theme.applyAppearance() } } @@ -32,8 +34,11 @@ enum MacOS9Theme { // MARK: Navigation Bar private static func configureNavigationBar() { - let uiTitleFont = - UIFont(name: "Charcoal", size: 14) ?? UIFont.systemFont(ofSize: 14, weight: .medium) + let uiTitleFont = MacOS9Typography.uiFont( + ["Charcoal"], + fallback: .systemFont(ofSize: 12, weight: .bold), + size: 12 + ) let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() @@ -44,8 +49,11 @@ enum MacOS9Theme { .foregroundColor: UIColor(MacOS9Colors.primaryText), ] appearance.largeTitleTextAttributes = [ - .font: UIFont(name: "AppleGaramond-Light", size: 28) - ?? UIFont.systemFont(ofSize: 28, weight: .light), + .font: MacOS9Typography.uiFont( + ["AppleGaramondLight", "AppleGaramond-Light"], + fallback: .systemFont(ofSize: 24, weight: .light), + size: 24 + ), .foregroundColor: UIColor(MacOS9Colors.primaryText), ] @@ -63,7 +71,11 @@ enum MacOS9Theme { appearance.backgroundColor = UIColor(MacOS9Colors.titleBar) appearance.shadowColor = UIColor(MacOS9Colors.border) - let normalFont = UIFont(name: "Geneva", size: 10) ?? UIFont.systemFont(ofSize: 10) + let normalFont = MacOS9Typography.uiFont( + ["GenevaPlain", "Geneva"], + fallback: .systemFont(ofSize: 10), + size: 10 + ) let itemAppearance = UITabBarItemAppearance() itemAppearance.normal.titleTextAttributes = [ .font: normalFont, diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift index 6e782b5..3e1d9c3 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9TitleBar.swift @@ -16,29 +16,14 @@ struct MacOS9TitleBar: View { Rectangle() .fill(isActive ? MacOS9Colors.titleBar : MacOS9Colors.panelBackground) - // Decorative stripes (left side) - GeometryReader { geo in - HStack(spacing: 0) { - // Left stripes — from edge to button cluster - stripeRegion() - .frame(width: 36) - - Spacer() - - // Right stripes — from right button to edge - stripeRegion() - .frame(width: 36) - } - .frame(height: geo.size.height) - } - // Main content: close — title — zoom HStack(spacing: 4) { // Close button Mac9TitleBarButton(symbol: "xmark", action: onClose) .padding(.leading, 4) - Spacer() + stripeRegion() + .frame(maxWidth: .infinity) // Title text Text(title) @@ -48,8 +33,11 @@ struct MacOS9TitleBar: View { ) .lineLimit(1) .minimumScaleFactor(0.7) + .padding(.horizontal, 6) + .background(isActive ? MacOS9Colors.titleBar : MacOS9Colors.panelBackground) - Spacer() + stripeRegion() + .frame(maxWidth: .infinity) // Zoom / collapse button Mac9TitleBarButton(symbol: "plus", action: onZoom) diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift index d713803..fe724ab 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift @@ -1,4 +1,5 @@ import SwiftUI +import UIKit // MARK: - Mac OS 9 Typography System // Font hierarchy from the Figma reference (modelos macos9.html) @@ -17,12 +18,12 @@ public enum MacOS9Typography { // MARK: PostScript font names // These are the PostScript names (not file names) iOS requires. - private static let garamondLight = "AppleGaramond-Light" + private static let garamondLight = "AppleGaramondLight" private static let garamondRegular = "AppleGaramond" private static let garamondBold = "AppleGaramond-Bold" - private static let garamondItalic = "AppleGaramond-LightItalic" + private static let garamondItalic = "AppleGaramondLight-Italic" private static let charcoal = "Charcoal" - private static let geneva = "Geneva" + private static let geneva = "GenevaPlain" // MARK: Fallbacks private static let garamondFallback = "Georgia" @@ -33,17 +34,30 @@ public enum MacOS9Typography { /// Safe font loader — uses PostScript name, falls back gracefully. public static func font(_ postScriptName: String, fallback: String, size: CGFloat) -> Font { - if UIFont(name: postScriptName, size: size) != nil { + font([postScriptName], fallback: fallback, size: size) + } + + public static func font(_ postScriptNames: [String], fallback: String, size: CGFloat) -> Font { + for postScriptName in postScriptNames where UIFont(name: postScriptName, size: size) != nil { return Font.custom(postScriptName, size: size) } - return Font.custom(fallback, size: size) + return .custom(fallback, size: size) + } + + static func uiFont(_ postScriptNames: [String], fallback: UIFont, size: CGFloat) -> UIFont { + for postScriptName in postScriptNames { + if let font = UIFont(name: postScriptName, size: size) { + return font + } + } + return fallback.withSize(size) } // MARK: Apple Garamond (Editorial titles) /// Apple Garamond Light, 24pt — hero editorial title (like HTML reference) public static func editorialTitle(_ size: CGFloat = 24) -> Font { - font(garamondLight, fallback: garamondFallback, size: size) + font([garamondLight, "AppleGaramond-Light"], fallback: garamondFallback, size: size) } /// Apple Garamond, 18pt — section title @@ -58,41 +72,41 @@ public enum MacOS9Typography { /// Apple Garamond Light Italic public static func editorialItalic(_ size: CGFloat = 16) -> Font { - font(garamondItalic, fallback: garamondFallback, size: size) + font([garamondItalic, "AppleGaramond-LightItalic"], fallback: garamondFallback, size: size) } // MARK: Charcoal (Headings, title bars, menus) /// Charcoal 12pt — window / section headline (HTML: "Headlines for titles & sections") public static func windowTitle(_ size: CGFloat = 14) -> Font { - font(charcoal, fallback: charcoalFallback, size: size) + font([charcoal], fallback: charcoalFallback, size: size) } /// Charcoal 10pt — menu label / small heading (HTML: "Small headlines for menus") public static func menuLabel(_ size: CGFloat = 12) -> Font { - font(charcoal, fallback: charcoalFallback, size: size) + font([charcoal], fallback: charcoalFallback, size: size) } // MARK: Geneva (Body, labels, lists) /// Geneva 10pt — primary body text (HTML: "Body text for most content") public static func body(_ size: CGFloat = 13) -> Font { - font(geneva, fallback: genevaFallback, size: size) + font([geneva, "Geneva"], fallback: genevaFallback, size: size) } /// Geneva 10pt bold, letter-spaced — highlighted body text public static func bodyBold(_ size: CGFloat = 13) -> Font { - font(geneva, fallback: genevaFallback, size: size) + font([geneva, "Geneva"], fallback: genevaFallback, size: size) } /// Geneva 9pt — smaller body / list items public static func caption(_ size: CGFloat = 11) -> Font { - font(geneva, fallback: genevaFallback, size: size) + font([geneva, "Geneva"], fallback: genevaFallback, size: size) } /// Geneva 7pt — disclaimer / fine print public static func finePrint(_ size: CGFloat = 9) -> Font { - font(geneva, fallback: genevaFallback, size: size) + font([geneva, "Geneva"], fallback: genevaFallback, size: size) } // MARK: - Debug Helper @@ -101,6 +115,7 @@ public enum MacOS9Typography { public static func debugAvailableFonts() { let targets = [ garamondLight, garamondRegular, garamondBold, garamondItalic, charcoal, geneva, + "Geneva", "AppleGaramond-Light", "AppleGaramond-LightItalic", ] for name in targets { let loaded = UIFont(name: name, size: 12) != nil diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift index fbed990..11d70c0 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Window.swift @@ -18,18 +18,20 @@ struct MacOS9Window: View { content .frame(maxWidth: .infinity) } - .background(MacOS9Colors.windowBackground) + .background( + MacOS9Colors.windowBackground + .shadow( + color: MacOS9Colors.dropShadow, + radius: 0, + x: MacOS9Metrics.dropShadowX, + y: MacOS9Metrics.dropShadowY + ) + ) .overlay(Mac9BevelBorder(isRaised: true, width: 2)) .overlay( Rectangle() .strokeBorder(MacOS9Colors.border, lineWidth: MacOS9Metrics.borderWidth) ) - .shadow( - color: MacOS9Colors.dropShadow, - radius: 0, - x: MacOS9Metrics.dropShadowX, - y: MacOS9Metrics.dropShadowY - ) } } diff --git a/MeuLabApp/EnhancedContentView.swift b/MeuLabApp/EnhancedContentView.swift index 93cdcea..d9a08f9 100644 --- a/MeuLabApp/EnhancedContentView.swift +++ b/MeuLabApp/EnhancedContentView.swift @@ -47,12 +47,12 @@ struct EnhancedContentView: View { VStack(spacing: 8) { HStack { Image(systemName: "cpu") - .font(.title2) - .foregroundStyle(.blue) + .font(.system(size: 18, weight: .bold)) + .foregroundStyle(MacOS9Colors.primaryText) Text("MeuLab") - .font(.title2) - .fontWeight(.bold) + .font(MacOS9Typography.editorialTitle(24)) + .foregroundStyle(MacOS9Colors.primaryText) Spacer() } @@ -63,27 +63,28 @@ struct EnhancedContentView: View { EnhancedQuickMetric( title: "CPU", value: "\(Int(status.cpu?.usagePercent ?? 0))%", - color: .blue + color: MacOS9Colors.statusBlue ) EnhancedQuickMetric( title: "RAM", value: "\(Int(status.memory?.usedPercent ?? 0))%", - color: .purple + color: MacOS9Colors.selection ) EnhancedQuickMetric( title: "Disco", value: "\(Int(status.disk?.usedPercent ?? 0))%", - color: .orange + color: MacOS9Colors.statusOrange ) } } } .padding() - .background(Color(.secondarySystemBackground)) + .background(MacOS9Colors.panelBackground) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - Divider() + MacOS9GroovedDivider() // Navigation List List { @@ -97,7 +98,10 @@ struct EnhancedContentView: View { } } .listStyle(.sidebar) + .scrollContentBackground(.hidden) + .background(MacOS9Colors.contentPanel) } + .background(MacOS9Colors.windowBackground) .navigationSplitViewColumnWidth(300) } @@ -162,14 +166,8 @@ struct EnhancedContentView: View { VStack(spacing: 6) { ZStack { if selectedTab == tab { - Circle() - .fill( - LinearGradient( - colors: [.blue.opacity(0.25), .blue.opacity(0.05)], - startPoint: .top, - endPoint: .bottom - ) - ) + Rectangle() + .fill(MacOS9Colors.selection) .frame(width: 40, height: 40) .transition(.scale.combined(with: .opacity)) } @@ -177,12 +175,16 @@ struct EnhancedContentView: View { Image(systemName: selectedTab == tab ? tab.filledIcon : tab.icon) .font(.system(size: 20, weight: .semibold)) .symbolEffect(.bounce, value: selectedTab == tab) - .foregroundStyle(selectedTab == tab ? .blue : .primary.opacity(0.6)) + .foregroundStyle( + selectedTab == tab + ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) } Text(tab.title) - .font(.system(size: 10, weight: selectedTab == tab ? .bold : .semibold)) - .foregroundStyle(selectedTab == tab ? .blue : .primary.opacity(0.5)) + .font(MacOS9Typography.caption(10)) + .foregroundStyle( + selectedTab == tab + ? MacOS9Colors.selection : MacOS9Colors.secondaryText) } .frame(maxWidth: .infinity) .padding(.vertical, 8) @@ -192,7 +194,7 @@ struct EnhancedContentView: View { } .padding(.horizontal, 10) .padding(.vertical, 8) - .glassCard(cornerRadius: 32) + .glassCard(cornerRadius: 0) .padding(.horizontal, 14) } } @@ -206,13 +208,13 @@ struct EnhancedSidebarRow: View { var body: some View { HStack(spacing: 12) { Image(systemName: tab.icon) - .font(.system(size: 16, weight: .medium)) - .foregroundStyle(isSelected ? .white : .primary) + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(isSelected ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .frame(width: 20) Text(tab.title) - .font(.system(size: 15, weight: .medium)) - .foregroundStyle(isSelected ? .white : .primary) + .font(MacOS9Typography.body()) + .foregroundStyle(isSelected ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) Spacer() @@ -220,14 +222,14 @@ struct EnhancedSidebarRow: View { if hasActiveAlerts(for: tab) { Image(systemName: "bell.badge.fill") .font(.system(size: 10)) - .foregroundStyle(.red) + .foregroundStyle(MacOS9Colors.statusRed) } } .padding(.horizontal, 12) .padding(.vertical, 8) .background( - RoundedRectangle(cornerRadius: 8) - .fill(isSelected ? .blue : Color.clear) + Rectangle() + .fill(isSelected ? MacOS9Colors.selection : Color.clear) ) .contentShape(Rectangle()) } @@ -250,13 +252,13 @@ struct EnhancedQuickMetric: View { var body: some View { VStack(spacing: 2) { Text(value) - .font(.system(size: 14, weight: .bold)) + .font(MacOS9Typography.windowTitle(14)) .monospacedDigit() .foregroundStyle(color) Text(title) - .font(.system(size: 10)) - .foregroundStyle(.secondary) + .font(MacOS9Typography.caption(10)) + .foregroundStyle(MacOS9Colors.secondaryText) } .frame(maxWidth: .infinity) .padding(.vertical, 6) diff --git a/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift b/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift index 76ed5e9..84356c2 100644 --- a/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift +++ b/MeuLabApp/Extensions/LiquidGlass+Modifiers.swift @@ -40,14 +40,15 @@ struct Mac9ButtonStyle: ButtonStyle { .padding(.vertical, MacOS9Metrics.buttonPaddingV) .frame(minHeight: 36) .background( - configuration.isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.windowBackground + (configuration.isPressed + ? MacOS9Colors.buttonPressed : MacOS9Colors.windowBackground) + .shadow( + color: configuration.isPressed ? .clear : MacOS9Colors.dropShadow, + radius: 0, x: 1, y: 1 + ) ) .overlay(Mac9BevelBorder(isRaised: !configuration.isPressed, width: 1)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - .shadow( - color: configuration.isPressed ? .clear : MacOS9Colors.dropShadow, - radius: 0, x: 1, y: 1 - ) .offset(x: configuration.isPressed ? 1 : 0, y: configuration.isPressed ? 1 : 0) } } @@ -61,14 +62,14 @@ struct Mac9ProminentButtonStyle: ButtonStyle { .padding(.vertical, MacOS9Metrics.buttonPaddingV) .frame(minHeight: 36) .background( - configuration.isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.titleBar + (configuration.isPressed ? MacOS9Colors.buttonPressed : MacOS9Colors.titleBar) + .shadow( + color: configuration.isPressed ? .clear : MacOS9Colors.dropShadow, + radius: 0, x: 1, y: 1 + ) ) .overlay(Mac9BevelBorder(isRaised: !configuration.isPressed, width: 2)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - .shadow( - color: configuration.isPressed ? .clear : MacOS9Colors.dropShadow, - radius: 0, x: 1, y: 1 - ) .offset(x: configuration.isPressed ? 1 : 0, y: configuration.isPressed ? 1 : 0) } } @@ -81,10 +82,12 @@ struct FloatingBarGlass: ViewModifier { func body(content: Content) -> some View { content - .background(MacOS9Colors.windowBackground.opacity(0.92)) + .background( + MacOS9Colors.windowBackground.opacity(0.92) + .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 2, y: 2) + ) .overlay(Mac9BevelBorder(isRaised: true, width: 1)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 2, y: 2) } } diff --git a/MeuLabApp/Resources/Fonts/AppleGaramond-Bold.ttf b/MeuLabApp/Resources/Fonts/AppleGaramond-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bf121d73e7c48cc628142cfc43fd7d27a4753524 GIT binary patch literal 47264 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 literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Fonts/AppleGaramond-Light.ttf b/MeuLabApp/Resources/Fonts/AppleGaramond-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a4400267c09199f7d0853a45f85f236df74e4a6e GIT binary patch literal 47824 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 literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Fonts/AppleGaramond-LightItalic.ttf b/MeuLabApp/Resources/Fonts/AppleGaramond-LightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9c27b60990a6ed107a5edb4a43b1231b76ca33cd GIT binary patch literal 46068 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 Zt(3;ce}*(aO}$L#zpoO-ZM<#f{{gy?Axi)N literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Fonts/AppleGaramond.ttf b/MeuLabApp/Resources/Fonts/AppleGaramond.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9681b1f45c2d349ce51305b00e48df8568bd724d GIT binary patch literal 47476 zcmb@v34kM2wKslmRi&zuN>x&+R4V(vFP-jAcc;6jyC*$8Jv+0nzyJd?3q6Gg=h#2rOkK->@)5OBe#PkkyXZcm<~&*iziCv?8wtx9@&hVlP>zV{#KljNpS zsXF(pzjN*lp@fhCh(OXCwr^YW>iMpp5L(CRuQzRL4&SW&`6q;MVZ7eBbLC094_|+o z3$M>1#P#%9hxc6+z2mA236a+j!oTmVBbTPdG+=b@arZg<4`1<}gV%kXkk@^Q5bd#Z4(!|i z)w$nx2)XN496xpr2E=#sr{Oi;C;4*@UwXwm?nyn0*U#Yl-+JDGi!b<6^h@s|ECn-~Wxn`>wc%>vAt9yX~i(vkkjmW(YvUHm3{#6B-0?9~g;wD_r|Z!eyqe>^U$|FnN5CKU86 z`dWgyCSS#WgeDgs&*m`55toQb<%sZ7LP{7|{CCln7hgg;B>gvzd!U;q^Ze@x<2Ft~ z*jH2HC4ZH>L?&`~0kYukK2JQv1F8@O)N50fc)QOLji{hLqJjE}4^$`q?%zm&=%5A( zfCh;HYLXymh?w2~hJ=Mc!#0f&3(un@-2E>SBN5OziGn6b3^YmN-M^9)Nr0wF5;Q|n zpjndc{)Oa71~hNe0?Fcek>o&2B;WlrDU$+dg%m-nqy$1oTx|~dccF3~s@5n5f0$o9-LFdQ}=t{D@`yXVUbU;^;S7m~BPzaSTpgP<=W=YU>J4uM`m&h7r3TuROZy^Nd>dW0MXy_{Uo{TaE!rdN^+ z@%$=s5$KD_i@HB0SCflDUqUVcy@p&0dM&vO^rhrT_b22!ayjVrbYnH<7DBZzeD4{+PUiTmyOwxfb-5ZNeJ!~G z&;N}S9eFwEZR94<*OQw;-#}i`eTv*pZUKEGc_rwZ$gQAnCa>!LfZRb|4f+21oO}}W3Gyk>uh{gf3)U$hyLjFR22Kra>bI|`HzX1JjoBoabTlY)kIr2-;=gBjm3*_HHyX05hFT%ca zu<-0(knrpojp9#aX5aZoc|5YerT_3IfBySlbNZdj?|b_@=H9jQn!7&v^*28J*-I{Z z@Dm4Lwc~-C&b$1*E1z_GylTJ*n$cK1kxZ8>)mptV+!`5euV1}k_R%Bbt2XU9^MXsS zzV?P2U;c_)U;EbgeB|Sw`TUn3d;E#7tzENj1#wA=mdX!K%uG(rceb2$_WlDeec5%_ zzxtnUf8A|w`NAV#{L;y%Zu|888{c->M|XX0*^_BKTzUj?m`i}PS$LW~ ze}4SACkc6a#nYEOJ^SOg{pj%@ed&ik#4yD*{R$87q3@#~z@z;~?_-~!4={T4A4QCX zxjP^F{uOf#MhD=U|C-dD|#z=EqN>K(?`h1VIe*b9e)hE{RH%QEj-;ictoBYhR6Ce z{L)vUq4&cB?ShTG0(STs*rQwEm)=c&4xL*DJN!0Sz^%~BH&d^u+TRZQ{yNy{+u#}RfX(^>Y}l8e`#*tg`X;PM2G;&tuoT~c zCD;y+OmN*N!E=5L_WvRHq;ug9oqr#K?fo#G-UEA#d4&f)1>XEZ_`f*WMjs>r?qU++ zoLM#yrD4KIef@*Py?OUXD1G&w2Wj`l2gwbIPh!US(@$$Wh?F3mo2gOA|wTlU}#=l0HkM|-IGJPvZz*Qf8}i<@_E*?r$jSH|w^tlSgJ zWYY8ZJ-m7MeGjjUW%lgBQR3p2;)-8#DBQbd3D+!E@xJVwWgE_cQ|!6r7Isd&;)+Noz1)1Tb*1c#s+ekTn5*%XC=<4aZWZb^8O*4_dN2AztCTCmqYv8uxX7>d^s8PkO@H`p+Pw$jM6E= zpprmVte|OuF`aSU|6I-g9N0eEXA5{Yz*#fkb#alurXCcJ<2PeyQCj5WG#$A=Se%+! zJ*z6JNI%+YzT}!udu81dqkb!Fcna~tp0VouP;BMTXI89SIn~J1Yu_6)XJ;m6IMEw3 zmJe@Po6=mRg)!N~1udUn^u>ne%ByyJPwK4QR49H;Wqu*q{SEy+cQdSTxTB`XfJt2P zfDolbum#Azk;UmA8y#Viq(PnraIrIxf{>M@OqK=&CJD*<#`BgJmk&gE#jSa*<;}ue zE14W!RVhuz6rUu^o@jYEw*2tcCY@S+)yX4TIHl)nqM3}1wCbA=&#t;;OMReWn1RNq zM^)t3$yZ`_aE(R#8jJ8K1lD;g+#ZK4@Of^GyB_{!8A){leo_?4U{M|vYE%&@T?Q?% zCxhKWTemMZ$(cb7B3mrsL4vSr^r*P^+ZzWPv6HE&dL>Cx zB-5x`(b>}aOEy<(n=e^?@l}dDps4bT>4$x$Ce^@$mFKUo)GWWLLOwZB@=Kn^)+1}z zT)A^F67;$KuoB2W<_67ppaI#>9;(k$5>gh5L zc1fa_cX?q5WREnEYG?wlgo0ZtswRVf+;+jQ34$iOpq>G1VJwm4dDZWdIa&4YgS1MO zc);=sE;V9)U6DMNFJdSGsg_F)8=5y@dN2j*y91Uc7QL~M7GW}CbCYM*6JiZ(y9{|U ztZi?cSz%{<`!VCp3OnO_j~PFDo+E6W%@&m94p@SHq}mDZCen%(qZ`SnP$zjgiMiT3 zG(^qbT*2&~c%~qIp%=~*bO-uW8sNeG6Hg8^zQ@hY9a2y^b?dsdF5R#UDq8_ejM6BU zN4*hAm1Vc)lQ^}SENX696h$v5z$o*gW*LrJoXF>1vR%ns93uGMm>xPP@`-DC~%eEa4TR(RzsR& z?e_HG;L2&TQt*+4ibFy1ey{=ekFgADb)@F76p_%gPv6MUD_9>E2 z8Xl~*Ji4UnO3;0IxSa4;Pda~Y&1KsfyMwX#4zH*x(#WaTu3vRz$Dl7(vfdQc1&%^{ z!B9^Zd&dcq8ewz;b)Y;OgJC`d z-UMc>HQYu#^BKtqM3~&vo3c+r=-B~S!|Y|<&U?Y*}5 zR3mJptYq%M;GyMxjSAzsUW({8o*@;?-Bx*ntw$FN=i7R;s6qBT{;%f}CZ&a#7d8aC zbJS@dYE z2UJ;=Yo%gMR&kJehs2Bjkn}vJiT^HXqT9tZ47wz_5cbLmllleG<+;3AmjoWMFq;RD zi<4AO;9*H)T7xL$4sd>sBs%_CGQbnhfUPrgG-k`h-&Yyi0_!I zaYyd%0(T2{De~WRN6(XVh@>S#(sESZFCeY&OO9;^5H2O{+dweRvls~%yi^z<>=;9s z)HaafSO$}O_RKV#K=SCZxZR%Qu%nr;f@ww4h0m9GIQU^r^5T|ds&j(uS9!Ong_Ts$ z$|(^;5c!0kQk`P*-oUGh>o!c4#N4zms10S34ZlZ`)qvaYqKZp#>zZ4;4z}`Tg1`$m za_~%-s(sx;@U-xO#&l7qKEELNeYDn8;yN8R)P)JJk3Qm27G7-y!amXGmn6677AX~^ zaEv|>4*H;{EUR+M3zsNf`g#!n9!2%#7u*2kV<)L~A_)@FNCbtVh-}CmVG{ft+{hQ) zyd7%y%xj;qV@_16abUzzKK1Mh{JjnZv?w?_#yk`vA3GLh{AP22aTcw!cnKV&;9xSw(V`v*lEPEGx$vJZF!YF~ zQ5Oq1&q!1vir*&)K0kF^g*d%Yq0c|#_j%|a+ruu|$MZf>cIoMuD`GDE7E$iUBxLjs zFL;(ECT;8d5OA!Akcl9N;x;4pF@Ogl6G;*e?6pTGf)92zM_o%Z5xOL-VIm{hx5<(c zCj_G7lLt368XL}@m^^q=9goY4bHj<)U?-2qc&ypsZf@*h!;6jcS6r<%wk1#^j_!i!$XB}i_m7OyG- z=QacDi>g-^CC|d+7oBn_HaJ%qTg`2kHLu_w-gEi^o|yId|&3Gb6#uz;0BJ}7Dt z0||y=;SmW&qf)5K0k2`YCB-Fu$cb-brWVl`?tR7Gx6K_|TkJUbDCXPt(rL#_1Lb46 zhAjs+;^T~OKW3bHX=i-zG2<-PaK?|Yao|YF?gt@H4+C#308@lS4G@2h@P6PtCanlb zDjy?J5)_6_P{@*6ZRm}SBb3?_%+Apq-LY3C`s~omJd?2T$@$vE^g1SF(~~oo{UM=6 z2WIlwv0*F9gl+i<_wZ>&CTZJl7`y(wDwDPCuV`KN>V>I^vs&w4bW$ypl|LNdV|cWJ(^BBf@H06D;a>?&etBgegC> z1$IKf?g*xsr9sR#I3~N7@Gec^`$m`vBaF-a{!}0n@r`7SOeT=j;zPyIy_sR%pDzi9 zta>b^{v9g-T!!gmbzYw)TrFM4tT60kLK=F#7;CL3evKS_`Fr7^R zgkqV!ZALkm(NOf$9ybTwOLa%N)3}$z9?Y}5o+QJ92Y@$8&LJL6!Ybs1NZ%^h?iEoN zJD z+mc;fjAlhmJz4J;Eg#^J441DAwFRqkpYK2HMc_!2WPYuWpo7h&8)$oRT@oBOz4Sns5l2l$8vwl zZCz1a-AaUNGv&cX3nK4_?E?%jTdm9vMCkYHlhw4IUON!2rvu|HEovw!PF1wDUaO_X z*43+>R@ICQmj~O`ax`Y1<#C5110CEC>-hNrcNgj^wN7|5(N>erFzHl@)`0+Mg0H!O zHv8C!<6VyW7iU_FELeh{ck&A#Wl9}lApx=sHoJY)WT~<{0TTE4Y!=JJGcy8zwqW^sGD~v;*sL($iiI%YZJw6DWBau^5?<`aAvp0+vbsT zDbo{w7+Dt^4L9cp;2Z3_x4mV9*vK5JWz1VT<1D9j#D%#nq<0*Px)Hbb9FAFvk#>75=r6|k}pMV{(G%Vb6l4Wp)yI!?q zx8aBUq+{`v%kA}fMe#+vOW;?+FU-h3h4IZVCBvbZs3@AkaV3!#gqX|aRlRN@Y?a4! zBcK@CMqU`?k(Rzp6jYz;<+JI=pk&I5>e2%0-G&F|buUsPeqI)3MWoLb;fP(F;Pwil z3Z?e=0xMFG&|n}RWjDY(yoV}y9JTlTvSXzFIolJT`J54f)?lozW%lf9Di zGLM^Hp@%uI+vRdY+L1J~iK*uo>SJ!tFFc;d&8WfV=Rdk#&cys2Ax6i2D%rQ3%*p%M z+&ECuiNvVSS?!o|8w>FJtOVnkHupVNFL|`5(wWKQlpaRknW)d}fKGIIq)}=IOjvKx zjJ!s0ofEESfhpdT{%D+d=Mt*N8r!w}zh`_RXU8&$rZujfc-l%5t zjiLB*IrU?Y=#oDiNpT#fF;;`GDEU+pr+Pf#BDxUhe}jvskxIu}K{f&8vB)L{&}|ZY zf|Q)3$-axQLn1pgIF7gQdkFn(SKqg7$2kP}J~%)Y{{4UIL+LG&&+vJLVt#1a>sH)g zO(1_QFZ4Y^5AhTgxPXvH;4b%tbxHF`K0cj^7Ce6442bgSEPG*1Z0E>)ePtOO;~nk0P4&17>r@T zfm7{aI0Zv#m~Xi?gs7Y<634}$Ns4A@=Irotm0S2K62(`&rZwhLMFkTodm}riPSQD^ z7Nvx1xXE22sa~HV-x!xge>kChQIzG^V!rbJjMu{GD=J z820MsvW&#L=+^l4Xyw+|e1mXK{2p+HEMg9}QLK;8+h)JAmtW4v-3ASpf@W z?Rjm{&0$?p{K|`>+<`#IZ}_y^j-Kx&i|5;m^C7rE#E}J$Hy|cEk4$!Q`$%S_oG+W^ zvXjU%K_^^U&d3}pgeMDav<~cN+ULX{z0%B6{-+!jbaKm{Ouc~h?IoONAO=3)66^J<1l2BliBr+;eV&=sfk+D@Q3`0OG_rAn&6IBrpm!`rMS7_4o>IO z6Vo{PjXxr7@D+`WltX~2wn z{HBsB7ON{zUi4X|QY}`hrV@!%B%AjtFn#Cm4Z9_`ni{W00-8sZ54kzNk&XJRkxb~K zZOy@AF4HvpuA`hjI-f^uPDi`{!EHh;ucN={m1MY+I)J{6wWK*mnqCrZ%2DA$^9EW) z;_egNG{v~QSkSfMcFL-@j)P`e3f@>O;_Ih=eOF@JK3mq=QMTu{bAAlrwOxTnLI{Hi zUwwi&pce+<{kFvVIqcVX<@h67^}CS9TAG@PCaOVhuo29Uq*9}$knYn2C3SwNG@2e> zU)3NoF3u3Wn%6BVjdZ!Cn*LZZG|r2GWfeC90aZ+e^O&@N83-rg^!amm`IKt~!Kw}n zP9?06AV~CMa3+~x-ON=cT2^HsI$nx4vPP)TN+gD(5m}H#WBJ8}PBYdR@X0)%aEl&z zB}qh#<(FLEczQFCD;Z+O}84Twp_yP0)}QjE%UMvX>3?tn?w2qOX+Cc zcWj$;D*B1rox)jU8|G=RaE$%gP0tX{rW=K$cF0x=rV~%GR+|4GY!Uwg0Fcc&GzXLM zzpzu4epgGs%Y}8fB&*f`q5YzNVjVI#r_t}2vD`#o^ zLYj;VrnyTdyM&Ec0yIJkLTs8>=yu!iGpp3JXTdSijzHRR1S@(lx9iv>#13}ufSD=b zAn*ewg_$6`OU!N!Vv^i8atxMay+Srmxp1zD8hs~S@fZmsR9h>ao}Nv#CPwzXV#od0 zZP~VA-DMBn`#Rq%@4V+l)9veyd}7sA^|Lz5LUqkV7`1Ix)ZCTZm}v~Gn?8kpccNK2 zG_U-;>5sa8I??_}UV@d4;c_jld9sRUi&fzpUToj3wD zWIDndE#Cjv)L*!ppO10BfL8sW8>A8LIp;{8=7v`VAaXY)O z0M`3+Al8{qFp3fbntugC28C)$G*Z-H41*rpEr~Wpg&+>GsF~#PB*`tKqdqkVDhQM+RY6T0j8OTtB01O1B*R9BC2KgZ<^9eX*0Nz@hCl@~@b zI-d~q%y7}Za%Ra+>&D36FgsCVbyR??ULvE`=BENH$vWMIFk8Bfk=d2TVh;vm0(f1- zUE>Uu!qJ?ty& zJ^*GI`{0{h!?O`Nd{HsC-Yxb|FS^fT-^bl7x^epF(f8?dOGb>>V=Q|nH**F(k9!mD zz~}%S=OK)|7qSKsg3WhqOU|+UH|zTbC*+_638_omn{J$2k=C06ZPh zvCqYOn5?o-Lu`(!mB!tUFa_O)CCe&}*pKv5`&AjQM(j~`MPcM0r_m?Sv5k&L;IScA zs^ek|kY7ydkMYsW&iBi6Op}>gf~F5}KdY}BOT~v*mXjj|Q{`1NWh93SrjaZLG+;zP z4ZS`iRi#g4m+u)L+cgb*DB)IBzZz?;YYwbw#ne#7NYsjI$dATG#w$Y4=k9U5Dkeif zJB)p+wpTT*Ry!w^Za!t;6zh~zxO?uo=iosWmxj?D$?m6!etEk)k}cuG`kW#?fY%X{ z?F8M#AHwM(vfmT78&(B4Yp5gc*A}Lh<8N&Uz9g|+%CTh9=x+eFnAV`yjB1&7tWqza znQAY`g@X;hQPhJ20MCQTG#$@kwnka$19sFlizU5R^eBx=I`b_5(pk4*CWP)S#D<(F5b*=- zF)W|gj;#(JP+V_x>|Bha=sMSm|&otbpE;!@TS_?Y7(|Gt&rB zm>eGMUtwVlb3P+}uN$0q1+Ac4N~Xf;NHA8>qi`J_HCa!Yk|!~=qEKxnSf02NRpLKz zcS8s2WIc-%u#iv~K|Y>^!V*jH%Inth^K?Q8#Cd>t&`ihv*pWityW5qAeuUuEvz;Dc zJ2+r(SR&IOHlr-+>V*!Ytp49B(YMZDJ2=#84G+I~e$~~3!>!RXu9;hQ;r4+>y>{Nr z)w^p0jav1hFNzTumAq9!t6yq#P33|Ky}j-FE6>RUDR=kC(D2px?9lLVYp8Yg%K2;0 z7%4TkUpzH+L8D&ZUAtgr`ht3`c_0a|n4Z`)P+dQsKHIzFQxClS&1^oaeqxjK@p(^=cbzM7?XsswliZMUh>;=gs z*9r>Wboo5mcFr3%S8NF88qrwN$0JeF8_;qh#CB+;%QDPARJp&do_Qnk9N zarhgD5(mF{dVY7?t0`eC7=vuu_c(@oyqUa|Om(t@gNF_QOd#YU)QC1*v2XXG@@#tC znw_QN0y(sg9_rmN3#;tVs>!-H{=qv>u(b&`e<0K|h{F1*Pv6P0Hm-J0IC^}M{s+v` zjZi9LseYSHk(j2Qh_&H>&07BnxO$Jn)u_YOXpgJlTGZyMLcQQ>X4{Yt1qbjmig%8k zhulB{)4=8-8nnW23N%nVsa)JMwqydJUorYoEJJw|u|^KDmllTu!!k#~XYm;qi&~iF zGZqaQGr9xl;jz<2Cq@{1cVf5@G7H0rM5_=2su8b_`=WU>n2-4;&42U z1IiN>_Kq)>H>>0L{=FYecdk#67`Y~<51`PP!>hvUIu zA`uM6Kh=N2Z7}0;lMVJBVfU{lE4W9v0KUbC_%GSf{UP3`@$h8s2yaA=3)YvoE|-}Z zbuD>K@3J!Ka5$Y=_!75v;VCPVvG9TmWGwd7%6w&F;tlDr^Bn8xM!I*>%el{@M|TdZ z^)>?!00MjxNub!UY#Ch7RH}f4bhTr39X)3J?j@ZP6ttJHBMM{9E{xdGLaEKd1Sfky zlvK>Mv5>}+ifDsjL4$!Kfi1L|yA-9Ty`9z7fqam)cT==?i-Hyp2O@#6<&Wsu$+FcP zjcW=ziBw)O18PJK0}hrgJsCD>q*n4o%&cm855*(RBKO&i%AWb5m5JZ#r6?=-j?Jis zt}9o)$VJaP>`D!HiW6H3pYvy8dMT~4!r{&>{KgCA&wIW1-kBWCH5PuX_@3rnU$N?` z#xx>uU@MS-nk@moj>Nm2d3WH8CG-3^=9tZMf=#deoP9Qoj^J<6ufeBT9j`&6tm~1h zq6ZY=wo?){`V{~N{{T0RFH$kDeFwre&GbcL2v$W!^tiD?ARi4^eE~`F$!>{0Xu7q4 zThkN|bp>M226eltA?XaFL)}Ag1yI{$-s)NUV#KB@vT4k89c7CUB`qN>hk#bb&>5oG z{*{HHwp2SnF@yLS5bA{4N8<(uy0POzO!Zjnky$S_p zG{Q0u*gn2|lOWRxpt_YYhUunc6&^K`o!QfF@18+Km{)o*ut&6GX@1?}U*qF+m1nBs=$Tn8JYIA-EtGI`?xS8wGB&IE+Cu zj9IMkIK$D79*RhOD4F&q$4bp9x*^h7UMjC>MpOByR}K!0Mu%3_Yimc7+rl2tWkMvC z_U83u#j+|%9mO5`>u4>BzLt=hY>ZB=xi7OPJ6;Y&n=2~Ksj%)w=Yz4XRaoAPCP&r+ zVPS=C*IKt8@)nlI2C_!5*h*(di)_XCRoy@HhtV;_B516k?O5TYH%XFm0CnCBq{6|< zc^jBQ2*cnN7V$1IJDI=p{5^J59gESa{*&q6lQa5(_3@9uLY^g`oZb{rnL;`sgQRR~?OFva7-K$fuDNe3CBUEIxJ?l)>0p z+6+=`Wrpo`Xy;5aeHvvBPF_eWe_)?f*-4nLTutud9-;37e6`A=|b>ANN-K0PtP&aevCa1VDGd{+v+1X?gEi-JEvErEA>>|g?z z=jef#ECh189md+y5`Nz4662N?6J0Tmmn4Bx`>gz8W6B>*rIX6U;KCmi=>CpAFYWLC zZ+!Pvn9~%ydJ!$c=zoo40UH>~be!2A_U%i)3HBV32V0nGV}vYCDqU%RTQrI~za;S} zM~X4aiilf*L*W57w9j`@@=+M&B9> zq8{w`u*E~QM6z9v^Jqp57;X_A{aPSo=+#JMAQ+M~!>dT%^&Vbuuk+HsZrT`%hI~j+ zwP>U{Uu$_?Zdh5jy6`xfZ)B?VR$%d>OV?>zb$eX0%vQO$yU)>2b8N-^cqfA`SEkAS z0@<1*`*E{u$%J3r&z(wF2xQW}WoI4m(YyZN-nY|ye3vD1X zjeKV)eH=@)W-^-d=q``ucDuau`IHNICmOloVj>kSASwVgT?&t0!}z5tShX#jK%{NT zdK@i9jTf>CFc%i92`(|<1FItCh3A3+w1S{53;qaT7l*EIL#O-E^CdDK4t5`-*CWbq zvx<7CK_sEUhYHY!@9eco*I-!Ge=Qb|RdhKu!p3@;2J^3E@yUeia z;;pnAEyvcbUcE9_O=!BiGP*3beExxODW-WtX_L!Q>d)uAeh9d#oPLhs1&$&5*38VF zokTARP&8SO1S*%z+*@>^anKWudMU?zdw=H7BCSqxhHy>Nu8{S9(%vGkmpQS`okC}Y z$$Fgz?Y!VPVW6Lnpzt?ytLf;Jxp*;}0W7ioswr5EvXJO~BKfQ1k#!WjPc3|2bHv zo<(qO3g!SJfYlzbP^>iN*wR{5x!cH*|K=`xeEy)%AKEm#1Ix6%YxsFpby;Z$ zzt_@3)$-6xF$j%T*70jp`ozbrSSV&Lzv$eS+Ef>wx#H5Ok&K4Y+4kYP4!s0JY^E)c zH*;Ucnu|s!ylT~GfTTU1!BIfzX?bUDLYteQb8L$`|me_xaHOX~u0hTIH`q5sgdhXWTSkjVBZd`l*+6r2+;SUwe;T?z~73_qu zkIZ-Kd&%&2vPPKNkxtL~i6LUyG$F>YXNPP+8&4L_K)tO&6vw$qd#56zU z;OBOP>6Bg3p5W9S85+_rxZ6&t-yvuFCnwosEMxgE^P(sP_MuWS$0yN_BHCyCa=KDU zr>oWb+?pa=&3tZIEu2pH6mL<}O#_RcGL2nZhqlk;tbvtvD_t+QsU^thI2a=|*H=Z9z>3kdAYsb{--QJtg5y~(jx z_%~_Wv1Lcy7#nZWcgVm;Lb2kIFNTVRjvP-OdBBh`R2c3JNyZ4B@>y;kR~|f)KC9`7G4YgD{lACrkqwMAe2c zKzDj|WylL_hfHxN9Hm9X1ngQ>D`Uh=MGTB=GDO8}r=sk0;Qwzp>W0;LF)@6Le=Bw6`Tn2CR(w+*Y)F)!%iMaK5c!TqU59C8OA8`JF zz}xq3rvv}5w|AnOVe+RU&V2}R?jE+vesGIP;&bw}oR!gjCvM?RqAh_S09aC+wj)0l zb{~fT+tKY(9bDoXTEol}oCp_yt6)A5nhei(#}Y8u<;S`~G2ksH5@oEgS2T1JHS?Q9 zEGGAe0j&~^6cis?g=JZon~IMZ9=L|3aInlvSW}}ieM5(l#DZTpRL>;_ecu}!x$=oX z0J#9-xua2W!2k4yt%-<=fDV%PVd&*+ZM`&^5lwQ$)WHaEyZc9&64{}A+B9Zm_gq{Vk*)qxsrmUw5 zV$|eiPUoaI;~_vL>XF1bnWBwp4!ttAb~CJoy8>Qq4A@98#r7|$%SD(6Z49dcj;2k> zo9x(RN#BR{fH zl6^o)*j^h)2yl|_0`BOiHcsMER}AC51xn-vLRu?r$-%+8>WZ*dn{P^RcCKn@q0a@ zJC_dCnR6+ADG$e zlA(&s*7ujBzhy}WiG(%69??*%2`i`hk!i^iFS(WN*p$TwEmRuWRN1YYiZ7&Hj6UyE zLTOYBJ#xZImt-tW4rtyh(d5gW9>`)*%+Usu=ex*GQI@t<6wP=@y0EjzZK`oAR-VgP zWdyGxiar%9%~PR|a7b*#9i|VcG7=j!@WEY*9>sHn!~U?$mXYs+i&b=MdCMdt$6&;& z%y=>0v0(f}HVc;LxRkuuw?u&$3P_^nS3I`Gsp~)@BA}rK>r8oZdb0nLpv!VD~xh-9TrrBXga~ZgTpTOUB6Q%}avh z^aJwgGPC5230HELa2L`Y0<-2ds`pVahFvi50=A&vZUkFwH*+%~_pktzxk_VjbEM=BXl6{!0{%#cDF0tCt5+h)-~Da% zi*`)vSuh0G&GVU7NUeihjw_RiS3afB>uY{Z^ev+^=IB}e3q+&VfWRO}_*wozIX zBBo)OU6%U&k0pp@kL((_#xUkZ$Jb>~zaCQfbbdtbD&>XkW$H^Hc$f`uW=%^Q=vKdA{?6Ryc z9noc%84Q+^hA)x{1S^@~X*grA*nbb`)Vi*Z51wgIE1$2=3p^*u;uQ%#w8dg2U7}nYgcX|&_)ZLH0sg#pi_Ft>r zLIn+dMfP7#%C&jCL9gEO0rLYxZ!_P%rL*PMEwfwhGT%A$#^CK+I$Lkudhpf5uj0P^ z%kf*se}R8^_~kEux$qNQveTRJAo6sEKV#K;l(>S#hwT)wir*3v{qm)gPPP|W?=*(A zm*nH&#OS)lFbe;P(G3HG8^@F17@b?*9-EtaYIOJVTy|#n=$P~P*2~Y`d+_pePdnSG z()JgV!}1j1|2Ex>*vvqhyjY-cFy*J1&0lgC7WAUuUNLt3I*G--*jU`%*Ps46iC+2Z zso~kF7XCgxym?^VXd*tmsy4bIC52a3SyPD2X;=`E9L@!K`CBQoGF8ltMZKax<(Feg zggl6CvFh~0m!EeUW6(K?aj4h6;-l*Zu>K*K!2*j|T$SXFPN6K3#CAdy zdmb0)HblIB66m-U;_~=4%E7rcnRhNA_Fy53-3AQ1*QSNDaH29y>cnz;TKl!x!jFxErzmE4l-RNCg|ljR1aN5dgjdu8XB(Js-zlHwHkQ zVBJ5Mi2RX(4u}!ah!?A+GgZ}XS|N|Zd&8O+yUpm{vFe(6m!_GjSJBu<`GFQytr5pI8JoyB6eAnu#&KvgH(r*gQu{QMjKgOsuP?dIU$Oj&9Gt#OJ^p8 zo_7P^TiUwK*Zf@ zB!L$3r0MrI6~sJ>77DFy#}PmcnOoxmB({ycD=Pc+^kfFoAd{TnR@t?^##;nPg%Wv-Rzp}>sG9G zbnFiFa#E(o;CBahO6k`+1sMGwFNGqzp(|P8V8fd#M8?M2kL{H#*5MgoG2ie4Q6LfZeP9T>T}GOUUt=*i(a|#)!gdx8Rx9a zZK$4lu(T+l%>Fty;UP#UhbT2qzkrx+8f&Qd&UV0Ykj1_k7+u^slofA_cX;Gz!b+h(3hNY6t=7uX zXd`IKs^Rg9R46wa>&EO3@$^^}c{R@!s=WsBD$4Z9pkMLYMf!y)IMiO)3!jONa00L9 zt->5@6Q4}Sl33rl@Y7EX51qNkX%eTT02O_b`zCVTbO$>>>V)WmPxi==Wd(wk~9$C*1yzKKZNq>fzYFodYKiOmp8vskyLrudr}E_rd44b01{7zpfjh)9}(M zM9vZsydf&uwgo5a@y)>#d&q>1CjykF!}3gidUow>W>i+ZW>hOT2TNKM0)2C(w&vpp z4?nazpG6_r7dEFJxb(7*Pnlt032cjk?tgb9Xy*spXJd%O5h{?6EYgE*))Ym9IdaM71I!jhpa z>RRG$UbwFi>!5HV(ho(O`A{g|M5Pg(N%4{&cuukB2&SU)>CyYP7bZT6U*tcH_omrt))yJB($ z=64p==r`L{em1|NYy%p0AIs88{^8^6^Z4XSDv~$S3xSLPKVv;fiz(F-2;{IH4(mF8 z#pJ?-(>$9X65}|3XbH#Hqr>Pdva2(38ZoyLbHj$+`TY1en(BJ&Um^D=U^P8O*oV%^ z7TqN5IBp_(Q{l`-uU6zBGJXI4|28L?p*O@tTUzhLSOamwGsEvvHP$HT7mRhC(>oBoA8|uY7juOuG;Ern#+tkBsdn zJYG+J#mQr%JEzil;SR%(y*d0cwp9m! zYn%W zJZdxuUj@6}hE;d^qHpw(W(0<)5iy?Hg$DcO-ZZ75V1?4ueHmH_hA2(b_xxD&2;s<( z%j5d-k42PChawTI%>OaIyU@LmCb23Ygndx3XQLG-aoHuK86}GBw%=-Vv}4K+l9-)x z!i-{z&E)ZeoAgLdF?8(8F2$lo>Z)U3o|-T#5-0hMOf)EZqSdi@wQ+(WCUx{JG!6U9 zuC34kq@LpWXe!EAga8si>u3+_QO@*w8tsaq6Bc7b`4bJ6QsE#9gn|B5zTvpn^!L>| zyDDDN18L_%+wm6;;VLVrCTF>u`W%c~E(#ocm5yiD2|2h;k7T`!gKlszXmilM zROcmkQ=GBT?OSAFqFO(8s0OaqnN6LdZz1ond5AT#SpOX8cYw0|;zW#@N`(!4c|bSp zFEp7KSoEN2d_K&yZ+G(@B!6^GSKCQehE03)r3D>iAH7X=Ti|e-KX~T}#{G z9mMO69(OE(pCv$HMZ?ajV!&SsN1H)db`?0DT#&JNz-PpYv3wf4ECJj!GeJ#J+`Qlo zbP0Cp?t$s3mmy)ZyS=`5nlIpshmz%DNOEKCdVh_M38Z{Cenn)uQ$F*|{kzGj!hUS! zunwD$XJ9!=2tfRvi5>KGVS-{?ml$7g*6Z|c5-WF{Kz%VMIa+-^X3b8|hGJc&-4G(d ztFn7%*%p2Yg7sME-~{bH60|=s7l`Emj^D^-bJ_lKp8Z$Nt+{HjHQGAk+LcRI^XzHV zY8SpZ7mMXSlZ*Pd8rZN$zWwWo#YA zksIk>=tbO5ZJa97@%ymQDS@=tV_Q%=>9uqD;}EK)zjATo-~W+{!~F&L{RR2Xk5^P7 zi)vJ@0@KoP3BGNu(u6g`5=F z=|Fk^)JbZz7zyPgY9&1qXYqxEEvVeuST;LRwFZW)LR8CP-&3!kc*Ftv#M+ri0rgX_ zX(fz89c{AsMTtrTwIa7K1Tbl6HtIEkmLAR2%y=dj4TEo^-SzhR`Yq^f&UeBmll9n2 zv?CxI@K+KbKvVE>tp!6u{7sPY?N% zl}NOa4wOo0yJ$>hvzM9q*myB&Hd1D&K;NI6$Y!e+Hm^{157yI1>XWO-$}5Wo8d8cY z^BZy#NiYEoPO9!TtV9&+HFP7>h!)lq>HKJZRo<0J&J3dErxdN5Y3z@{;g|L{l6&km zf(76zzMKzPj8BfGDb^8rVR)Xi8@Kv~x5pPAObLy>a7Eumy^v}KEBml{^U{TVOI8kk z6l?sj{m_y{e#PoQ0#cXjK1tury%>AdA`i2$F4N1l4zkh8-X@D7%id*=MSiH5!?4+* zYkRR#IQOQ)5VKjbZ=(992q&DCtGnF1;+2K#$5zOq%hb8cM64HRMDQytSQfVM>jN)R zO&sr1=&7%L9ov-}*Aa*Gzmm<9{T)=kA6J7x4)(_~+5x+p zy|>4SjSa?AV{0nKm92zX98DY97&foMCSjVVI6hFY>bX#SXs#44#(b(+nOK!uzlqZ6 zv)7gjo!!Hg`BuW~52B|{a?7WmvSoK+?zG9#^Um6yG7JTq1NxE!sk!^$jb5-`9w9GM z12%(v%XsFm>E3$z#ov-)`_wtV`?JjcEg812z#r*dz}mKA53I3H3eA1(cBuq2o=RXJkIRSU`?_4<&&ur^!9yHueZ zIKZ*lr4|~P5ga@C02K5Og@JM`5Hb925w-4CIXB&mMXWW-*(EVt(W{fS+~jDyVOaxt zD;D$z0Y-&1rCrsq=x?L?F(s+_E$m2?pet7GFK3&vbj%wFDN*dpusok#jqS#S6~jLK zM9OF>S6`hkWLwj*Y$1xqD-?UwV9-j9r(9vf8+85N3daMXhy{7^gKu3fiku+dF-oMF zF;&tuh23?L-U&xwLwF}N;oZla_!9e`k`hpV@YB)5s%Dr zH-$5KRWp3y@IbykUrr}9bQvq|T^k11x3Cs2SY6g??K;re6~yN8yl7aV!AuS73GjPZ zoQ2hhuS1-S8YxlukjJT!{-4&)1VFB;O4#?+`fBakdf%#-ba%R|J4shpXX_*#2oMr5 z5lGk!OghOxFzG-iA%=YfR1p0G1k?-!aYkga&_)QmU}TF?Y*0ZV=qREjD2@vJzat~{ zf9Jfa?j~e@_-E!O@6_%4?z{J%bI;w+Jx4XQOcIG=e^$4+5tD@BtR-j__my;nqI05b zdB<6=w8z7j-OOGak z5lmlNse9QBfDK2%$CK&#{5GqI`SAd;Q{NG<8jhgsW0@_4E3&D~@@rq%@dvg{#kvB9s}o(R1fQlfFohzG>~V9%J`})%x7j z43n)%*;&^_Yqn>e3M|lfsh9#imYxpN{A52wr4(eaLqJM}%wQUsLeis)Qi+00OJOHg zj!mR{x`ichB2wNIp|?oP@2i`Z!jytL9PCd>FT~4uR4x#@ha=%0ov_z>VsSZ8?q&C1anjSnea`9OJ92vHgv#lm z6MEXXP&qwxLYIvTmGeg@^kU9$E##t7*4xYm+=g30$Qg)aNUg;V)!W~iF@tgC&q(8b z!Fq^xfF`8|(^YMExneE|NXJ&_@TC)fA8{NNr3}xactZ@y|Hl3xF8gnBG%VL753m{SOZM1i9x zSY7|#H$&{q&zaEdXMuyg0Z$<4@pATDSNgEehpg70&>*mx^3TW0A{d-zf)ngotPm72 zP#x6;3`BIgP|Cu^qd6805-#`>Z?0a2qgFd)7=}mIjg~o|8*U6nJ&mcI;qbT0 z(-`9L`h%?3n24f^)f?!V@NQM3H3U?lSVp4)8|qO!8l18@#7cOI{Zuh2>EK6usry6| zYsA}>?wH0M5K&TV*Ccb--rD}1AELFTXmC%=Ow~;ckC~Yod1~TqpPwG9h;bqsb#pJU zG301vUFo$D7aOOQHQ-aNtlrk9f%M7s{($QnN4G5XQ2oj2Pu4Ygz0_qvHLJU{pIlm`g@55tna*4NEfU z+;}O(?%1TX^&nFZHp%?8Ga9_nU`gB;_1P}Zd$%OPnGVex@>aCP<0WO4fm)y2>$O%U zeaz5gHde)W{*QWUR*>5nvtJ@|I~?Q`<|TruPGXA-kS<5}feb&O^>XWRXlLm;p|$wi z+troJO`7ETTxQ8-ix*$MB*X8=7hkp{Q}g9*+rISWZD08^BZ%5bC3mrJiWJD0O;f0= zdZ=_w^FL_5^uKMQ^uK3_6pH6x#CGK!wAUN406e|F{+3%d{ev+VT(Im^b8KhlvQ4O^ zJeKp1GcKKc^QG3!vQa6!czV=M>(nNyhwjB`6|Lzg^noL#Rzwpr+{b)M7RziY6`QKQ zaX3$xf}=7?>@$71eMnhINsDHk)u9uSGHZHSi7Uz#E|=#}yav(#kT2zLteP+-QWpuw z8~nbd^n05lmZ%4hhWusd4_>yhoNdt{S{U47m%Q0 zF#566@VOO*;2f9pmdlZ}udTMZ)LT-KatuvYB|-_re%iZyNmj7ff$;@)s2vzJG`W-x zeZeDoSWrN*7_H zbm)YkOHqZz3fzCzS(iTD{M1LWQ|h-dRC=IU#~1FMY=>VLaH^A2vS1?#Xm^c6_)=n^?gH&MC*oYf54lA7t(1Si?DOg@rM(pO0C|k=co(!(8^ha!Nbh`_gq3I?R=( zsBKc3zN0ifm|uc!$wycn`8l77xcnS}sKSF$=>e3$z)naFxOooFo;}<3$a`P3hTaPc zq!o&0jYrUqK8aoRhW=!)sh@00>ut6g8j+u$?o@`eO{BAJS%;zwMrqzShuPly#59%q zx+ZOEERkKLq6p1j&rJlg6E`tUwZd1_Hv1>GWEM`VukBsfxoTso!v#)%0(5Q*CjFvz4V7!CTYI?m(4p4DhuRMD-!-$X z;5*!QnEbLxTzw8IcCl-Cp0v^dvt%af>?Td_FpZwc_7Z!VwZPLo8FLrhlGkP`nw<+> zmbOrbH40sPi^g9rh4rm~sF@I@%;hPoOStB5Pj&W0Cbmz^CabH_ zi4baRZK#)XT{+10JR?IVt`})pVVa^$)<6`@) z^ZGA3&$?(FEk`FQ&~tQ(qIY;01^z#%T29N8<|$W&oqH=xFUQwGv4iA2lMvZd;K#{B zHjR|dh2f;>Ba{0~zi(LXC$0;+y@3=`Oy1^37WLR|VixWWru~?CcKfWd2$Z$Y2%{-| z&V27jqy1m~zX>ONY$*pbkrFOIu>cH+r4pAX9Lj~LH?MC4s}wH9pN-iPcQT$iWszS_ zOnS|`ShT$oSqknJwZp)j!nJz0$XP>t2w7#~EJtOJx@=Fny{sk>N=N)Ij-<=Oc2mvd zPIoYXeQ4%5u2VxXU#OG?eZXcf<8XNy7h*ze^luX?mEv*JuQ%fdYvfB`H%KaW3B1vCkW1ju&C>)&{(8rYHjhc z0MI^a0{zwhXv?~aqh<~gm`GQ|l2sGxD{K7T+L}yvqPm`A%1AU&KD~N&^`ySa`szf( zL~E&bYX7xXb|q>S{cO%fBUP!&mhuF5e&SO)s@rQ+*VKQ*q(JW@q{AK^gf!>U82CO%W%QjN(WCJ2@BRCQ~*s@CtV zukGqd)}+IM7&??IX4cNFoieAYp(dG#XIxiB(ILdmxM;Mxtg0OoK8kCli(!nR zvZ=nVXV%G;ti0Up_t&JV8f6?Vr~h~tOnObKKQv{6yA%mZuXDXZ7uFvbzVt9h$FIVi zlrHxD1K8xL%RBob%`>}17Z}?UfoNT_dO~B}Qq1KsGTj&B+63F9-rDn#)>$-pYBbZ; zF%<=Mj7_0Lvc0LUuWcw0_Ju8fY`Psx213mCMt8Mj@7&qdn)w|G)m<0uah`R0oJaUU zYQmV`2QajViYRdy_2j%)eTcQ=FhzyL93!qeY!f(fBor^3Z(jY!E+t|($id4=fChQI zsM6Os++{7K&M?ZEHWM7jG3>hegNW)p>Sl+RRi4JG^gkQNX zOFH@=Q$gy;mlDZ7q85%XIm0JSc0I8Qj04#qyXlz0Dmb#ku{M^se2TdYZ0!_rMe0et zUcbhY^w>MaN+IUNG!4GMT9*8ye3B=&n?`YEBUW&g*FrPJ6-#Hozrqyi#(U z;u>Iw$tjV<=IGzSl{m!LI+8+5viz4lP7M=WQS-%pVj&y2hC(ib@>p@;p-7MwZ^f}k zN*LOW#VLjku2Kb3V!;&4AOX~+dbxQFg?tj^L*=+DpcRWG0(P;)c|**qNK>;SGlpjn zcNhqdi;mcF7J_c!G z!d1wsxQ4@`a8pqbTpe7-aD^~qxPpUX?bNhn0R9+533|h1%co?987jrqjj915c97y~ zVZ4~d4UXdKL$Xw^ITaWP<_iWfn@bK@_fl2@SMkBrZg+^2A_rFz;G!icktkIGu4JGN zt-p#Z*IK1yIG3aeu1uXATq6;dcn+@MQD9e^hdOp9XexXl4h)O9G9%VH5KL_j6TA^H z;&TdS3;Jw&u@fq|GH7F~Nt_RRmRJOGvLYe&)cK>pK;ViT3%f_qK#D0DXoDe1O3Go6 zFeXlM<-Ai!tN(RYz!y>w;eEcvBLUz_ny`z=p9}aTz0u7`H zLC~h<;W)$NOeM@+L2ZLXWhM$r4zBPK8K_gf7hK^F9ARkO;pmWLU?Ih|q{MAFZ50O= zPSa$y;@}F`foAvvxFYthb-*DT{}9V50V6)Av4|L?&DNhACFVLh`k8fW<|RRFr9nS& z5G|s(QfcaZ?nngw;T3y>DEY;wxRNBeMk5iB7VeP9v<7LOh{yWjBaJT{Da;R7`LQA{ zsA6B;Lz)F#eNwNnn1=yW(r0HZ06oQV9I6hkBa9Ekp-Dla;Fz^Y;?k@zW8_1dYK(UJ zeq1^ClD>wmf!Ug8AyW>@==zOQCx}c7DI@FtNxb^ z)G70`;_!zQ3Fs!chCmfO>9VMW!!6|=y~?r6=ReI+m;NbP|unX#l}Q3nbb#uHpo zm|Nf)?8~to?2r{)OQhhVxN?qI!Y&J6VrUg*k7OXYN|JP9v67N;xcbm)C~U-k+6)<} z(}vD+)kf1KDL^-uqzSGVZKS)TUXw`=x6U*+csSh<*XSHv;kr-={UGXu*a5{lfZ1nu zC!`C(Ua&ujP7P|0&*>OK1O~Cn=|MJ;x(~)MD=($D?PQpJ32GjSQxvR)f@`s{cx+EB zMqA-!iIjy5XnJ@^GVJlhV=*eYSg#yX(=fr6INYUoa1HwD49Od#wo+ky$y|;!86hy{ zNizo56c_7?xPq5tL~rEaN|#0t7>+r(2EyRr;L0LU**!?hMJaCFPEkP)uIL4$cPQfO z55_@9Ftr1z2-+;cRUEjYb#gqe+|lRO312F%k^z$#*hq0r#8H%4=$6r+5(6dDp@wKP zs9sU0xWZKd4o(DBaFsM!s|INPWrb6k>(ra7|EsR1g1YGYN^WxY9PleDgkBOBfA9bPbAY zdAZkwrJOKu7)|x!f>1*py$QHN9C1N(afh^qQCCDPs22`I*xG|>wwiYye@ii$B@!Arjjaz#QNy$P0u zk|pYd*kK3P_$aPX`jU!NumVmk;0gi2)#t@BE_@zNfvbaFMJ$|xf}kU138#+0HI<5w z;YtRhxR!XmWvLVuJc?@yl#nd*Dy}H4QCtJuD}(eH{~pEFmr50JMTiB5WEi_==65q+ zPM%xR_l~K=h8AwG=Y?g3-*Y${AU{DanC`Mr%B zoBwD6u6ZV|&!DMuCryou-=jU&uqh|Jo*S4c>ucN@`<1a>-IV8u$9f_En(NX0A(zSj zoArbI&-Ho51gy(V?dbEi*(-impNZ=))^g+*YJSf>*PL!`F**0k<^+xZByuvp$o~<# z9OPNbbGkLvoWs+H|8uU7nOm(3O@;Uizqea^%>wz`yov0`LC$x3%{v}Zfzl|PrzA=9?$LsSZxIM+Q*GzVP z^S{GiZryG|)^mivZEhg`KUnigcRpGMpF%OoQ_%27Cc?X6^9ydwlCSgR-!nhY{~Eu` zyp(?zz2YJBs)@+=k|&am$R(l$sVV=G^$IlGOPc(;(avu@kAK{Qy#}GlcQtIUImN0& zC&n`Pr5NWIn*RjoxWJm4|112`4z1?$%yZvt+9f}EtS3n)L47BvzlGfI;xw73m1iPx z`*>#YOfx%p*GpNUHThl(uC-E+)WNZovx%oh>rwc6uklzO6XUmqxYzT|CXFL}a^ypM zurA8~*|jYHC+nvCAMn2+kE@(C&PQf%FLWSH*ZuhyU8fWFRUY9__;r-`gm<3j%>UZ_ zCFU@iJRRI_Mx{Yk9xH8nwY<=Tzbp8=lBZnrA`e<5?KOOpv0PM-KR01(UkY+e?*)E`NNc{JO3Imn|~3Q(~#9z>j;=DxG@zp9Z)}rAKPAL7dj$> zXhfXAU1~q6h57cEz$|48^X-ekEA;IS(g~Ykg(JjF5dU#t2Wcj-J|%D(Zxd#g!bSN* z_?M7Q0?UHm2cD@R1N!y?^>0vkox&RwZqc_}6>d{_r+#~vzTJ`kC(;>KxJOgIPs8t5 z|30uzm=Q{qq-=+Q8K|8Em)C$fg+hTOaSmgXOX5_iznU6+4Gk(%chyGf4n@-nGYUHu zX7hUpA5i}mg`VWw1TI(?lpB%=Y(~zZLls2n5IZkVBrp=v%v}nv0jmgP9F zf5aUk!KICw5;#kt)KMGpM}Py=ew&fnX){;q+Zz;a(eSMbw<)|+HnUsd9*rq= z(PkdXKLC7&zO0QMVTm(B?(J}B5-3z{r_2I5@dZkm+u><>J4@kGg;!|!o$BAI{#~Ts zPFs-p_o#n_w;f88jN+I-4J|H0BolcB{f|3UAZ!JG3Ns=D$n) zyYkzCJ2V}kTSn=YfuAMiJ#bgX+^40zU(5E8roRtv$(Uy}wf&m%_cZ(fe3CKG!bKUS zZ6~(hX(A->?2fq}dHkB>tJ?)eSY|?FAYx z)aW*!0{3p{An;1f<+}W<_;1iSTPR7lxfwclo2}~Krtmg>dk2!O-B3W%kyhMocG9bK z)Bj8Z?pFUj>X+8t4K>~X-j{y?c)ylPII5eLC3qcxm%71pKQ%2}odvJmz&_eV7QDnS zcx9>a4xnI{RqV20_c;CmjU(7)scW$nE7)ZfyR5mA)6uNfZ&tC(nk^cCtHNyx1+T0T zyt0Z{7QAl6FL-4YudL#grFWf1$gsZMqj}w@-wIw?TFQ3dzWgh|17Mxi+U(Jm(xW3w z5A}E$4O9>pc_Ekc1#2nD@0SzC}GzT=V0qv1iGrCT}msFTmxQNtOqXAmr zfWj>b?*a}&?bCrvq17OC_zLh&_3t#x@b5C82JTk>J@_|}*Q;hD|B;rAeCw}rRcf%0~XzGdF0Au?v&rf+ZK?GNz_{cq##13;nwcBs7;n1R~c zl{2MfNJtKT*v?Grbl`2&%Xa860Cl9k?x4O7!To;I1r)B{!AwkG6;#?m+Yx_*!WM-x zBJZFKYk*mWJ+zJ;l;nQkeuW1#=7^^G9Ne>$R&y)x1hCjio+kpOf8GhdN%(X56Q~u5 zvs>frHrpxNZemUWO3d9FbGOF4NBh`eE%UIJd05LltYse7G7oE+hv~Nu(t4%L!&>HH zE%Pv~c>*C)=3y=KFujMwlrj$+Df1pJ$sTxVKmN_|;2!E$;1$H&qqBlNv@h{Xzp+RA zjXji9{4yupL;I4q`!wVk<~DoGe&#ECSRV;Iz$|2sd6u{LQNjm+Qp*p4#Q;$1=poV> z;Cp$yPq|_r<^LIesrRSh-_wEDz~@g>v*JGhe1?*r2wcjV=NX-iJVR;U!Y`D321<@l zj-`a`*SGui?SAbm_Jhj=!go=s{oo@0d(=P7?EL^KF90q@bM*oJ_5k0CU;3E?`t1Rw z!vX#FfYRZB_A?{e8`Fo<%0_f-9nrCMM8{TU5cE7FI?rb;h31S8^l~FQ&!^8*zs&PT zjLh>#jLh>#;J9f(ndgt_JReR`zs&PTs7ZM%^L+4T)&bs(cO%sGVc@g0g%SSMuqqjI zVMe}Y^P+jxI@S8R^-V4;J>Yu6HR3wxdfmOr{if$ZZ-sVHeKxglm^ zp;%cg8=DbaCm`rC%@oL0M&4PuZNZ zO=ZuQ{T@36rkGC{!R5CtKY5h)qJ7mg_^&h zN^yGarrP`KI_jRSZ>xVIU7P-T!$}QqH2NAF8aFpS+xWMp_NM!re%BmpUfaC6`P$|i zn{RJ^bHbJhKb`PaOQ2<><<-`n)^E2}v^BMDZhNrpiMAiMy)<$8#LrH=Y2s_`r?h{* z{b%jJ?pWTjrQ>@UD|1!m_RPbbL!GyEKHD{?>z1xROv+5UWYV*fYbMX1ykYWJCqFTz zdCIfhf$r7a?`7v@KbL(y`yV}a&sTfi&MnVylZYnRU~wduNx=?wo!3>@Bk&o^y78L;v~x z>-+zG?kmU4J?7S9?mT9f?h3t5oAA@`dSs^whYBe4 z;_C|vemD9rFDm#w#JRiR_nNr5zu@IU!l3u<(y?ijeaqz;818Y{V zKY!KA^rm$~pG*&IP9L*+!}<+FtCp`#pE$UpE1jOZW=&c@T%R6VwSLvm#j92ldhEKv zzhAv_)!>HJ%hz{tI{VdA6mY4-QdboR-LzT4gU4Z2gju^$q#HEO`No6q~HJD z3@zFF!HL$`*>ba9;UI7$ zWA=r>0kej<>xsL{tR#FBDGZrU;u|2Hv^j>i8+gBg&{d?cmN1zUte{U%^KUNSuigLWe`^R$(;F`5JIP66uS5oL6}W8V ztrNbU-@*T+{Ke8s**{ovr`$8N)c<*Y^1ev3|5v$|Qm!GeT&?9~WegsZkr+SP*GJ-{ z`?T=0$=}3G?`ZCI8jp)s<%atQ==WD>uipYaT3NZSVgxy0zRw<4J2R7v`2qdz59xI~ zDZ?a6F$F4jn{P7aJ`e4F%$*>{XvXIpa$8gBzkgz0pvGT>FJ@5UKJy4G+<9Q~N%IBh z{8d_L02*dzj?*{lpDMkDvd5;?_sC8*L(}=c+5Y+LEm9S*k|ry{9ZtBa;#}E|H8QQn0cHT z?!O|BbrRfhG2FP(oXqWrMQHT=XM@op^CfIu)-ad!!55pEJ6y(S|4ZhLDRVn>ushA= z=2Ui8L+lIL?B049y`xBlpJp1(*U+B%6!U?-^eqpVC+WGCnCscgTxvdp-qt6{kooUW8XVZ&4Y;I)^mt-{C!d~60<~4Q@e`kJc4w*O1 zqvqG<-^?G)+vXkfC-WQg2lKzpTjtN^_vUqP*WkuAYkX^$uNYc47`<@S(CT$7SI}Fm o8d|kdB+#U)u><^VdcCRCXgxXD{ACoQv#2$@<6)wBjlaYEUoys8<^TWy literal 0 HcmV?d00001 diff --git a/MeuLabApp/Resources/Fonts/Charcoal.ttf b/MeuLabApp/Resources/Fonts/Charcoal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fc8ad2bc300594939d5ab38e5d0da63e6e76fd46 GIT binary patch literal 63412 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 P`0C%>qWo<&`slv{kQoqS literal 0 HcmV?d00001 diff --git a/MeuLabApp/Views/Settings/ThemeManagerView.swift b/MeuLabApp/Views/Settings/ThemeManagerView.swift index c2d1bb6..7334bd0 100644 --- a/MeuLabApp/Views/Settings/ThemeManagerView.swift +++ b/MeuLabApp/Views/Settings/ThemeManagerView.swift @@ -378,7 +378,9 @@ struct AdaptiveThemeModifier: ViewModifier { func body(content: Content) -> some View { content - .preferredColorScheme(preferredColorScheme) + .preferredColorScheme(.light) + .tint(MacOS9Colors.selection) + .background(MacOS9Colors.windowBackground) .onAppear { setupThemeTimer() } @@ -423,4 +425,4 @@ struct AdaptiveThemeModifier: ViewModifier { #Preview { ThemeManagerView() .environmentObject(AppState()) -} \ No newline at end of file +} diff --git a/MeuLabApp/Views/Tabs/ACARSView.swift b/MeuLabApp/Views/Tabs/ACARSView.swift index d347978..04e24f0 100644 --- a/MeuLabApp/Views/Tabs/ACARSView.swift +++ b/MeuLabApp/Views/Tabs/ACARSView.swift @@ -16,42 +16,42 @@ private func acarsRGBA(_ red: CGFloat, _ green: CGFloat, _ blue: CGFloat, _ alph } private enum ACARSTheme { - static let violet = Color(red: 0.52, green: 0.34, blue: 0.88) - static let blue = Color(red: 0.14, green: 0.38, blue: 0.84) - static let cyan = Color(red: 0.18, green: 0.70, blue: 0.86) - static let green = Color(red: 0.27, green: 0.78, blue: 0.37) - static let amber = Color(red: 0.95, green: 0.57, blue: 0.15) + static let violet = MacOS9Colors.labelBadge + static let blue = MacOS9Colors.statusBlue + static let cyan = MacOS9Colors.scrollbarThumb + static let green = MacOS9Colors.statusGreen + static let amber = MacOS9Colors.statusOrange static let ink = acarsAdaptiveColor( - light: acarsRGBA(0.08, 0.11, 0.20), - dark: acarsRGBA(0.92, 0.95, 1.00) + light: acarsRGBA(0.149, 0.149, 0.149), + dark: acarsRGBA(0.149, 0.149, 0.149) ) static let mist = acarsAdaptiveColor( - light: acarsRGBA(0.94, 0.97, 1.00), - dark: acarsRGBA(0.09, 0.11, 0.18) + light: acarsRGBA(0.933, 0.933, 0.933), + dark: acarsRGBA(0.933, 0.933, 0.933) ) static let surfaceTop = acarsAdaptiveColor( - light: acarsRGBA(1.00, 1.00, 1.00, 0.98), - dark: acarsRGBA(0.13, 0.16, 0.24, 0.98) + light: acarsRGBA(0.867, 0.867, 0.867, 0.98), + dark: acarsRGBA(0.867, 0.867, 0.867, 0.98) ) static let surfaceStroke = acarsAdaptiveColor( - light: acarsRGBA(1.00, 1.00, 1.00, 0.92), - dark: acarsRGBA(0.26, 0.31, 0.42, 0.88) + light: acarsRGBA(0.149, 0.149, 0.149, 1.00), + dark: acarsRGBA(0.149, 0.149, 0.149, 1.00) ) static let canvasMid = acarsAdaptiveColor( - light: acarsRGBA(1.00, 1.00, 1.00), - dark: acarsRGBA(0.06, 0.08, 0.15) + light: acarsRGBA(0.933, 0.933, 0.933), + dark: acarsRGBA(0.933, 0.933, 0.933) ) static let canvasEnd = acarsAdaptiveColor( - light: acarsRGBA(0.98, 0.99, 0.97), - dark: acarsRGBA(0.08, 0.10, 0.17) + light: acarsRGBA(0.867, 0.867, 0.867), + dark: acarsRGBA(0.867, 0.867, 0.867) ) static let shadow = acarsAdaptiveColor( - light: acarsRGBA(0.05, 0.12, 0.26), + light: acarsRGBA(0.149, 0.149, 0.149), dark: acarsRGBA(0.00, 0.00, 0.00) ) static let toolbarBubble = acarsAdaptiveColor( - light: acarsRGBA(1.00, 1.00, 1.00, 0.78), - dark: acarsRGBA(0.16, 0.20, 0.28, 0.94) + light: acarsRGBA(0.867, 0.867, 0.867, 0.94), + dark: acarsRGBA(0.867, 0.867, 0.867, 0.94) ) } @@ -78,17 +78,10 @@ private struct ACARSToolbarTitle: View { var body: some View { HStack(spacing: 10) { ZStack { - Circle() - .fill( - LinearGradient( - colors: [ - ACARSTheme.violet.opacity(0.18), ACARSTheme.blue.opacity(0.12), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) + Rectangle() + .fill(MacOS9Colors.labelBadge) .frame(width: 28, height: 28) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) Image(systemName: "antenna.radiowaves.left.and.right") .font(.system(size: 14, weight: .bold)) @@ -96,15 +89,8 @@ private struct ACARSToolbarTitle: View { } Text("ACARS") - .font(.system(size: 23, weight: .black, design: .rounded)) - .tracking(0.5) - .foregroundStyle( - LinearGradient( - colors: [ACARSTheme.violet, ACARSTheme.blue], - startPoint: .leading, - endPoint: .trailing - ) - ) + .font(MacOS9Typography.editorialTitle(24)) + .foregroundStyle(MacOS9Colors.primaryText) } } } @@ -134,8 +120,9 @@ private struct ACARSInfoChip: View { } .padding(.horizontal, 12) .padding(.vertical, 9) - .background(Capsule().fill(tint.opacity(0.10))) - .overlay(Capsule().stroke(tint.opacity(0.18), lineWidth: 1)) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true, width: 1)) + .overlay(Rectangle().strokeBorder(tint.opacity(0.8), lineWidth: 1)) } } diff --git a/MeuLabApp/Views/Tabs/ADSBView.swift b/MeuLabApp/Views/Tabs/ADSBView.swift index 37c196c..c05e323 100644 --- a/MeuLabApp/Views/Tabs/ADSBView.swift +++ b/MeuLabApp/Views/Tabs/ADSBView.swift @@ -2040,6 +2040,8 @@ struct TuyaPrimaryMetricCard: View { Label(title, systemImage: icon) .font(.caption.weight(.semibold)) .foregroundStyle(ADSBTheme.secondaryInk) + .lineLimit(1) + .minimumScaleFactor(0.75) Text(value) .font(.system(size: 28, weight: .bold, design: .rounded)) diff --git a/MeuLabApp/Views/Tabs/BibleNavigateView.swift b/MeuLabApp/Views/Tabs/BibleNavigateView.swift index 10fa8a4..e20354f 100644 --- a/MeuLabApp/Views/Tabs/BibleNavigateView.swift +++ b/MeuLabApp/Views/Tabs/BibleNavigateView.swift @@ -126,13 +126,7 @@ struct BibleChaptersView: View { } .padding() } - .background { - LinearGradient( - colors: [Color.amber.opacity(0.06), Color(.systemBackground)], - startPoint: .top, endPoint: .bottom - ) - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle(book.name) .navigationBarTitleDisplayMode(.large) .navigationDestination(for: Int.self) { chapter in diff --git a/MeuLabApp/Views/Tabs/BibleSearchView.swift b/MeuLabApp/Views/Tabs/BibleSearchView.swift index 2cf7b41..017a5b6 100644 --- a/MeuLabApp/Views/Tabs/BibleSearchView.swift +++ b/MeuLabApp/Views/Tabs/BibleSearchView.swift @@ -32,12 +32,9 @@ struct BibleSearchView: View { } } .padding(12) - .background( - .ultraThinMaterial, in: RoundedRectangle(cornerRadius: 12, style: .continuous) - ) + .background(MacOS9Colors.contentPanel) .overlay( - RoundedRectangle(cornerRadius: 12, style: .continuous) - .strokeBorder(Color.amber.opacity(0.3), lineWidth: 1) + Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1) ) .padding(.horizontal) .padding(.top, 12) diff --git a/MeuLabApp/Views/Tabs/BibleView.swift b/MeuLabApp/Views/Tabs/BibleView.swift index 736d94c..199e1e2 100644 --- a/MeuLabApp/Views/Tabs/BibleView.swift +++ b/MeuLabApp/Views/Tabs/BibleView.swift @@ -56,12 +56,12 @@ struct BibleView: View { .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Text("ACF") - .font(.caption) - .fontWeight(.semibold) - .foregroundStyle(.secondary) + .font(MacOS9Typography.caption()) + .foregroundStyle(MacOS9Colors.secondaryText) .padding(.horizontal, 8) .padding(.vertical, 3) - .background(.ultraThinMaterial, in: Capsule()) + .background(MacOS9Colors.labelBadge) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } } @@ -78,19 +78,17 @@ struct BibleView: View { } } label: { Label(tab.rawValue, systemImage: tab.icon) - .font(.subheadline) - .fontWeight(selectedTab == tab ? .semibold : .regular) - .foregroundStyle(selectedTab == tab ? .primary : .secondary) + .font(MacOS9Typography.menuLabel()) + .foregroundStyle( + selectedTab == tab + ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .frame(maxWidth: .infinity) .padding(.vertical, 8) .background { if selectedTab == tab { - RoundedRectangle(cornerRadius: 10, style: .continuous) - .fill(Color.amber.opacity(0.18)) - .overlay( - RoundedRectangle(cornerRadius: 10, style: .continuous) - .strokeBorder(Color.amber.opacity(0.4), lineWidth: 1) - ) + Rectangle() + .fill(MacOS9Colors.selection) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } } @@ -99,11 +97,10 @@ struct BibleView: View { } .padding(4) .background( - MacOS9Colors.panelBackground, in: RoundedRectangle(cornerRadius: 14, style: .continuous) + MacOS9Colors.panelBackground ) .overlay( - RoundedRectangle(cornerRadius: 14, style: .continuous) - .strokeBorder(MacOS9Colors.border, lineWidth: 1) + Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1) ) } } @@ -111,9 +108,9 @@ struct BibleView: View { // MARK: - Amber Color Extension extension Color { - static let amber = Color(red: 0.83, green: 0.69, blue: 0.22) - static let mogno = Color(red: 0.24, green: 0.15, blue: 0.13) - static let parchment = Color(red: 0.96, green: 0.90, blue: 0.83) + static let amber = MacOS9Colors.statusOrange + static let mogno = MacOS9Colors.border + static let parchment = MacOS9Colors.contentPanel } #Preview { diff --git a/MeuLabApp/Views/Tabs/IntelligenceView.swift b/MeuLabApp/Views/Tabs/IntelligenceView.swift index 0508d81..e5aef51 100644 --- a/MeuLabApp/Views/Tabs/IntelligenceView.swift +++ b/MeuLabApp/Views/Tabs/IntelligenceView.swift @@ -164,10 +164,10 @@ private enum ChatStore { // MARK: - Modern Intelligence View (iOS 26+ com Foundation Models) private enum IntelligenceTheme { - static let accent = Color(red: 0.16, green: 0.42, blue: 0.94) - static let mint = Color(red: 0.12, green: 0.74, blue: 0.48) - static let amber = Color(red: 0.96, green: 0.63, blue: 0.19) - static let panel = Color.white.opacity(0.12) + static let accent = MacOS9Colors.statusBlue + static let mint = MacOS9Colors.statusGreen + static let amber = MacOS9Colors.statusOrange + static let panel = MacOS9Colors.panelBackground } private struct OperationalWorkflowItem: Identifiable { diff --git a/MeuLabApp/Views/Tabs/RemoteRadioView.swift b/MeuLabApp/Views/Tabs/RemoteRadioView.swift index 359aa7c..6665734 100644 --- a/MeuLabApp/Views/Tabs/RemoteRadioView.swift +++ b/MeuLabApp/Views/Tabs/RemoteRadioView.swift @@ -8,16 +8,15 @@ struct RemoteRadioView: View { @State private var gainIsAuto = true @State private var manualGain: Double = 30 - // Vintage color palette - private let woodDark = Color(red: 0.25, green: 0.15, blue: 0.08) - private let woodMid = Color(red: 0.35, green: 0.22, blue: 0.12) - private let woodLight = Color(red: 0.45, green: 0.30, blue: 0.18) - private let amber = Color(red: 1.0, green: 0.85, blue: 0.55) - private let amberDim = Color(red: 0.8, green: 0.65, blue: 0.35) - private let amberGlow = Color(red: 1.0, green: 0.9, blue: 0.6) - private let cream = Color(red: 0.96, green: 0.93, blue: 0.86) - private let brass = Color(red: 0.72, green: 0.60, blue: 0.35) - private let dialBg = Color(red: 0.12, green: 0.10, blue: 0.08) + private let woodDark = MacOS9Colors.border + private let woodMid = MacOS9Colors.panelBackground + private let woodLight = MacOS9Colors.windowBackground + private let amber = MacOS9Colors.labelBadge + private let amberDim = MacOS9Colors.secondaryText + private let amberGlow = MacOS9Colors.scrollbarThumb + private let cream = MacOS9Colors.contentPanel + private let brass = MacOS9Colors.statusOrange + private let dialBg = MacOS9Colors.contentPanel var body: some View { NavigationStack { @@ -40,7 +39,7 @@ struct RemoteRadioView: View { backendBanner( title: "Aviso de Hardware", icon: "exclamationmark.triangle.fill", - tint: .orange + tint: MacOS9Colors.statusOrange ) .padding(.horizontal, 16) .padding(.top, 12) @@ -199,12 +198,7 @@ struct RemoteRadioView: View { private var woodBackground: some View { ZStack { - LinearGradient( - colors: [woodDark, woodMid, woodDark], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - .ignoresSafeArea() + MacOS9Colors.windowBackground.ignoresSafeArea() // Subtle wood grain texture overlay GeometryReader { geo in diff --git a/MeuLabApp/Views/Tabs/SatelliteView.swift b/MeuLabApp/Views/Tabs/SatelliteView.swift index b63d805..6d29f0b 100644 --- a/MeuLabApp/Views/Tabs/SatelliteView.swift +++ b/MeuLabApp/Views/Tabs/SatelliteView.swift @@ -646,8 +646,12 @@ struct SatelliteImageCarouselCard: View { .padding(12) .background(MacOS9Colors.panelBackground) } + .background( + // Shadow on background shape only — prevents text ghosting + MacOS9Colors.panelBackground + .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 2, y: 2) + ) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 2, y: 2) .padding(.horizontal, 4) .onTapGesture { onTap() From c2656ef32ebd0fa38ffadb5f6ede08a247efd505 Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sat, 23 May 2026 18:00:09 -0300 Subject: [PATCH 05/10] Fix Mac OS 9 runtime polish --- MeuLabApp/ContentView.swift | 216 ++++++++++-------- MeuLabApp/Core/Secrets.swift | 1 - .../DesignSystem/MacOS9/MacOS9Modifiers.swift | 2 +- .../DesignSystem/MacOS9/MacOS9Theme.swift | 7 +- .../MacOS9/MacOS9Typography.swift | 19 +- MeuLabApp/EnhancedContentView.swift | 2 + MeuLabApp/Intents/LabIntents.swift | 4 +- MeuLabApp/MeuLabApp.swift | 8 +- MeuLabApp/Services/APIService.swift | 4 - .../Services/PushNotificationManager.swift | 2 - .../ViewModels/LocalNowPlayingFetcher.swift | 2 +- MeuLabApp/Views/Tabs/ADSBView.swift | 205 +++++------------ 12 files changed, 192 insertions(+), 280 deletions(-) diff --git a/MeuLabApp/ContentView.swift b/MeuLabApp/ContentView.swift index 0df0232..17b5455 100644 --- a/MeuLabApp/ContentView.swift +++ b/MeuLabApp/ContentView.swift @@ -23,6 +23,7 @@ struct ContentView: View { case remoteRadio case intelligence case bible + case more var title: String { switch self { @@ -42,6 +43,7 @@ struct ContentView: View { case .remoteRadio: return "SDR" case .intelligence: return "IA" case .bible: return "Bíblia" + case .more: return "Mais" } } @@ -63,6 +65,7 @@ struct ContentView: View { case .remoteRadio: return "antenna.radiowaves.left.and.right.circle" case .intelligence: return "brain.head.profile" case .bible: return "book.closed" + case .more: return "ellipsis" } } @@ -84,6 +87,7 @@ struct ContentView: View { case .remoteRadio: return "antenna.radiowaves.left.and.right.circle.fill" case .intelligence: return "brain.head.profile" case .bible: return "book.closed.fill" + case .more: return "ellipsis" } } @@ -107,107 +111,19 @@ struct ContentView: View { } var body: some View { - TabView(selection: $selectedTab) { - // -- Tabs Primárias -- - SwiftUI.Tab(value: Tab.adsb) { - tabView(for: .adsb) - } label: { - Label(Tab.adsb.title, systemImage: Tab.adsb.icon) - } - - SwiftUI.Tab(value: Tab.satellite) { - tabView(for: .satellite) - } label: { - Label(Tab.satellite.title, systemImage: Tab.satellite.icon) - } - - SwiftUI.Tab(value: Tab.system) { - tabView(for: .system) - } label: { - Label(Tab.system.title, systemImage: Tab.system.icon) - } - - SwiftUI.Tab(value: Tab.radio) { - tabView(for: .radio) - } label: { - Label(Tab.radio.title, systemImage: Tab.radio.icon) - } - - // -- Tabs Secundárias agrupadas em "Mais" -- - TabSection("Mais") { - Group { - SwiftUI.Tab(value: Tab.map) { - tabView(for: .map) - } label: { - Label(Tab.map.title, systemImage: Tab.map.icon) - } - - SwiftUI.Tab(value: Tab.acars) { - tabView(for: .acars) - } label: { - Label(Tab.acars.title, systemImage: Tab.acars.icon) - } - - SwiftUI.Tab(value: Tab.infra) { - tabView(for: .infra) - } label: { - Label(Tab.infra.title, systemImage: Tab.infra.icon) - } - - SwiftUI.Tab(value: Tab.weather) { - tabView(for: .weather) - } label: { - Label(Tab.weather.title, systemImage: Tab.weather.icon) - } + ZStack(alignment: .bottom) { + tabView(for: selectedTab) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .padding(.bottom, 76) - SwiftUI.Tab(value: Tab.alerts) { - tabView(for: .alerts) - } label: { - Label(Tab.alerts.title, systemImage: Tab.alerts.icon) - } - } - - Group { - SwiftUI.Tab(value: Tab.flightSearch) { - tabView(for: .flightSearch) - } label: { - Label(Tab.flightSearch.title, systemImage: Tab.flightSearch.icon) - } - - SwiftUI.Tab(value: Tab.export) { - tabView(for: .export) - } label: { - Label(Tab.export.title, systemImage: Tab.export.icon) - } - - SwiftUI.Tab(value: Tab.remote) { - tabView(for: .remote) - } label: { - Label(Tab.remote.title, systemImage: Tab.remote.icon) - } - - SwiftUI.Tab(value: Tab.remoteRadio) { - tabView(for: .remoteRadio) - } label: { - Label(Tab.remoteRadio.title, systemImage: Tab.remoteRadio.icon) - } - - SwiftUI.Tab(value: Tab.intelligence) { - tabView(for: .intelligence) - } label: { - Label(Tab.intelligence.title, systemImage: Tab.intelligence.icon) - } - - SwiftUI.Tab(value: Tab.bible) { - tabView(for: .bible) - } label: { - Label(Tab.bible.title, systemImage: Tab.bible.icon) - } - } + MacOS9RootTabBar( + selectedTab: bottomBarSelection, + tabs: Tab.primaryTabs + [.more] + ) { tab in + selectedTab = tab + appState.setActiveTab(tab.rawValue) } } - .tabViewStyle(.sidebarAdaptable) - .tabBarMinimizeBehavior(.onScrollDown) .tint(MacOS9Colors.selection) .background(MacOS9Colors.windowBackground) .adaptiveTheme() @@ -259,6 +175,10 @@ struct ContentView: View { } } + private var bottomBarSelection: Tab { + selectedTab.isPrimary ? selectedTab : .more + } + private static func launchTabOverride() -> Tab? { let env = ProcessInfo.processInfo.environment guard let raw = env["MEULAB_INITIAL_TAB"]?.trimmingCharacters(in: .whitespacesAndNewlines), @@ -289,11 +209,111 @@ struct ContentView: View { case .remoteRadio: RemoteRadioView() case .intelligence: IntelligenceView() case .bible: BibleView() + case .more: MoreMenuView(tabs: Tab.secondaryTabs) { selectedTab = $0 } } } } +private struct MacOS9RootTabBar: View { + let selectedTab: ContentView.Tab + let tabs: [ContentView.Tab] + let select: (ContentView.Tab) -> Void + + var body: some View { + HStack(spacing: 0) { + ForEach(tabs, id: \.self) { tab in + let isSelected = selectedTab == tab + Button { + select(tab) + } label: { + MacOS9RootTabItem(tab: tab, isSelected: isSelected) + } + .buttonStyle(.plain) + } + } + .padding(6) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .padding(.horizontal, 12) + .padding(.bottom, 8) + } +} + +private struct MacOS9RootTabItem: View { + let tab: ContentView.Tab + let isSelected: Bool + + private var iconName: String { + isSelected ? tab.filledIcon : tab.icon + } + + var body: some View { + VStack(spacing: 3) { + Image(systemName: iconName) + .font(.system(size: 20, weight: .semibold)) + .frame(height: 22) + Text(tab.title) + .font(MacOS9Typography.caption(10)) + .lineLimit(1) + .minimumScaleFactor(0.75) + } + .foregroundStyle(MacOS9Colors.primaryText) + .frame(maxWidth: .infinity) + .frame(height: 56) + .background(isSelected ? MacOS9Colors.labelBadge : MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: !isSelected)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + } +} + +private struct MoreMenuView: View { + let tabs: [ContentView.Tab] + let select: (ContentView.Tab) -> Void + + var body: some View { + NavigationStack { + ScrollView { + VStack(spacing: 0) { + ForEach(tabs, id: \.self) { tab in + Button { + select(tab) + } label: { + HStack(spacing: 14) { + Image(systemName: tab.icon) + .font(.system(size: 20, weight: .semibold)) + .frame(width: 28) + .foregroundStyle(MacOS9Colors.selection) + Text(tab.title) + .font(MacOS9Typography.body(18)) + .foregroundStyle(MacOS9Colors.primaryText) + Spacer() + Image(systemName: "chevron.right") + .font(.system(size: 14, weight: .bold)) + .foregroundStyle(MacOS9Colors.secondaryText) + } + .padding(.horizontal, 16) + .padding(.vertical, 14) + .background(MacOS9Colors.contentPanel) + } + .buttonStyle(.plain) + + Rectangle() + .fill(MacOS9Colors.border.opacity(0.2)) + .frame(height: 1) + .padding(.leading, 58) + } + } + .mac9Panel() + .padding(16) + } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) + .navigationTitle("Mais") + } + } +} + #Preview { ContentView() .environmentObject(AppState()) diff --git a/MeuLabApp/Core/Secrets.swift b/MeuLabApp/Core/Secrets.swift index 700de6a..8a15f42 100644 --- a/MeuLabApp/Core/Secrets.swift +++ b/MeuLabApp/Core/Secrets.swift @@ -98,7 +98,6 @@ enum Secrets { print("🔐 Secrets Configuration Status:") print(" API Base URL: \(apiBaseURL)") print(" API Token configured: \(isConfigured)") - print(" Token (first 10 chars): \(String(apiToken.prefix(10)))...") #endif } } diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift index c1dc428..e2102aa 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Modifiers.swift @@ -123,7 +123,7 @@ extension View { .padding(padding) .background(MacOS9Colors.contentPanel) .overlay( - RoundedRectangle(cornerRadius: MacOS9Metrics.panelCornerRadius) + Rectangle() .strokeBorder(MacOS9Colors.accentBorder, lineWidth: MacOS9Metrics.borderWidth) ) } diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift index 5261d6b..d115466 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift @@ -11,7 +11,6 @@ extension View { self .preferredColorScheme(.light) .tint(MacOS9Colors.selection) - .font(MacOS9Typography.body()) .foregroundStyle(MacOS9Colors.primaryText) .background(MacOS9Colors.windowBackground) .onAppear { MacOS9Theme.applyAppearance() } @@ -71,11 +70,7 @@ enum MacOS9Theme { appearance.backgroundColor = UIColor(MacOS9Colors.titleBar) appearance.shadowColor = UIColor(MacOS9Colors.border) - let normalFont = MacOS9Typography.uiFont( - ["GenevaPlain", "Geneva"], - fallback: .systemFont(ofSize: 10), - size: 10 - ) + let normalFont = UIFont.systemFont(ofSize: 10) let itemAppearance = UITabBarItemAppearance() itemAppearance.normal.titleTextAttributes = [ .font: normalFont, diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift index fe724ab..a79b300 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift @@ -89,23 +89,28 @@ public enum MacOS9Typography { // MARK: Geneva (Body, labels, lists) - /// Geneva 10pt — primary body text (HTML: "Body text for most content") + /// System body text. The classic Geneva TTF is MacRoman and breaks Portuguese accents. public static func body(_ size: CGFloat = 13) -> Font { - font([geneva, "Geneva"], fallback: genevaFallback, size: size) + .system(size: size) } - /// Geneva 10pt bold, letter-spaced — highlighted body text + /// System bold body text. Kept Unicode-safe for Portuguese labels and content. public static func bodyBold(_ size: CGFloat = 13) -> Font { - font([geneva, "Geneva"], fallback: genevaFallback, size: size) + .system(size: size, weight: .bold) } - /// Geneva 9pt — smaller body / list items + /// System caption text. Kept Unicode-safe for Portuguese labels and content. public static func caption(_ size: CGFloat = 11) -> Font { - font([geneva, "Geneva"], fallback: genevaFallback, size: size) + .system(size: size) } - /// Geneva 7pt — disclaimer / fine print + /// System fine print. Kept Unicode-safe for Portuguese labels and content. public static func finePrint(_ size: CGFloat = 9) -> Font { + .system(size: size) + } + + /// Classic Geneva for ASCII-only decorative labels. + public static func classicBody(_ size: CGFloat = 13) -> Font { font([geneva, "Geneva"], fallback: genevaFallback, size: size) } diff --git a/MeuLabApp/EnhancedContentView.swift b/MeuLabApp/EnhancedContentView.swift index d9a08f9..7338beb 100644 --- a/MeuLabApp/EnhancedContentView.swift +++ b/MeuLabApp/EnhancedContentView.swift @@ -145,6 +145,8 @@ struct EnhancedContentView: View { IntelligenceView() case .bible: BibleView() + case .more: + EmptyView() } } } diff --git a/MeuLabApp/Intents/LabIntents.swift b/MeuLabApp/Intents/LabIntents.swift index c5f2d1e..9b1d8a4 100644 --- a/MeuLabApp/Intents/LabIntents.swift +++ b/MeuLabApp/Intents/LabIntents.swift @@ -479,9 +479,7 @@ actor LabEntityIndexer { try await index.indexAppEntities(passes) lastIndexedAt = Date() } catch { - #if DEBUG - print("[LabEntityIndexer] index error:", error.localizedDescription) - #endif + return } } } diff --git a/MeuLabApp/MeuLabApp.swift b/MeuLabApp/MeuLabApp.swift index 5dd23ed..57d460a 100644 --- a/MeuLabApp/MeuLabApp.swift +++ b/MeuLabApp/MeuLabApp.swift @@ -14,7 +14,6 @@ struct MeuLabApp: App { var body: some Scene { WindowGroup { ContentView() - .radarSplash() .environmentObject(appState) .environmentObject(pushManager) .environmentObject(notificationFeed) @@ -45,7 +44,7 @@ struct MeuLabApp: App { guard startupTask == nil else { return } startupTask = Task { @MainActor in - try? await Task.sleep(nanoseconds: 300_000_000) + try? await Task.sleep(nanoseconds: 100_000_000) guard !Task.isCancelled else { return } _ = NetworkEnvironment.shared @@ -53,11 +52,6 @@ struct MeuLabApp: App { setupPushNotificationsIfNeeded() notificationFeed.start() appState.setRefreshEnabled(true) - if #available(iOS 18.0, *) { - Task { - await LabEntityIndexer.shared.reindexIfNeeded() - } - } startupTask = nil } } diff --git a/MeuLabApp/Services/APIService.swift b/MeuLabApp/Services/APIService.swift index d42d48b..f9a2d24 100644 --- a/MeuLabApp/Services/APIService.swift +++ b/MeuLabApp/Services/APIService.swift @@ -67,10 +67,6 @@ actor APIService { config.waitsForConnectivity = false config.requestCachePolicy = .reloadIgnoringLocalCacheData self.session = URLSession(configuration: config) - - #if DEBUG - Secrets.debugPrintStatus() - #endif } /// Called from MainActor when NetworkEnvironment detects a change. diff --git a/MeuLabApp/Services/PushNotificationManager.swift b/MeuLabApp/Services/PushNotificationManager.swift index 0a0d0c3..cf0f277 100644 --- a/MeuLabApp/Services/PushNotificationManager.swift +++ b/MeuLabApp/Services/PushNotificationManager.swift @@ -56,7 +56,6 @@ class PushNotificationManager: NSObject, ObservableObject { func handleDeviceToken(_ deviceToken: Data) { let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() self.deviceToken = tokenString - print("Device token: \(tokenString)") // Envia para o servidor Task { @@ -82,7 +81,6 @@ class PushNotificationManager: NSObject, ObservableObject { _ = try await APIService.shared.registerDeviceToken(token: token, deviceInfo: deviceInfo) isRegistered = true - print("Token registrado no servidor") } catch { print("Erro ao registrar token no servidor: \(error)") isRegistered = false diff --git a/MeuLabApp/ViewModels/LocalNowPlayingFetcher.swift b/MeuLabApp/ViewModels/LocalNowPlayingFetcher.swift index 7bb0f55..ebe04b5 100644 --- a/MeuLabApp/ViewModels/LocalNowPlayingFetcher.swift +++ b/MeuLabApp/ViewModels/LocalNowPlayingFetcher.swift @@ -22,7 +22,6 @@ enum LocalNowPlayingFetcher { if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { throw FetchError.unavailable } - #endif let center = MPNowPlayingInfoCenter.default() guard let info = center.nowPlayingInfo, !info.isEmpty else { @@ -56,6 +55,7 @@ enum LocalNowPlayingFetcher { // This will likely be replaced by the real initializer path in your project. throw FetchError.unavailable } + #endif #else throw FetchError.unavailable #endif diff --git a/MeuLabApp/Views/Tabs/ADSBView.swift b/MeuLabApp/Views/Tabs/ADSBView.swift index c05e323..e439433 100644 --- a/MeuLabApp/Views/Tabs/ADSBView.swift +++ b/MeuLabApp/Views/Tabs/ADSBView.swift @@ -21,58 +21,22 @@ private func adsbRGBA(_ red: CGFloat, _ green: CGFloat, _ blue: CGFloat, _ alpha } private enum ADSBTheme { - static let radarBlue = Color(red: 0.11, green: 0.31, blue: 0.82) - static let radarBlueDeep = Color(red: 0.05, green: 0.13, blue: 0.38) - static let radarGreen = Color(red: 0.31, green: 0.90, blue: 0.35) - static let radarMint = Color(red: 0.73, green: 0.98, blue: 0.62) - static let ink = adsbAdaptiveColor( - light: adsbRGBA(0.08, 0.11, 0.20), - dark: adsbRGBA(0.92, 0.95, 1.00) - ) - static let secondaryInk = adsbAdaptiveColor( - light: adsbRGBA(0.26, 0.31, 0.42), - dark: adsbRGBA(0.76, 0.82, 0.92) - ) - static let tertiaryInk = adsbAdaptiveColor( - light: adsbRGBA(0.43, 0.48, 0.58), - dark: adsbRGBA(0.61, 0.68, 0.79) - ) - static let sectionInk = adsbAdaptiveColor( - light: adsbRGBA(0.05, 0.13, 0.38), - dark: adsbRGBA(0.34, 0.52, 0.98) - ) - static let mist = adsbAdaptiveColor( - light: adsbRGBA(0.94, 0.97, 1.00), - dark: adsbRGBA(0.09, 0.11, 0.18) - ) - static let cloud = adsbAdaptiveColor( - light: adsbRGBA(0.97, 0.99, 1.00), - dark: adsbRGBA(0.04, 0.06, 0.12) - ) - static let canvasMid = adsbAdaptiveColor( - light: adsbRGBA(1.00, 1.00, 1.00), - dark: adsbRGBA(0.06, 0.08, 0.15) - ) - static let canvasEnd = adsbAdaptiveColor( - light: adsbRGBA(0.96, 0.99, 0.98), - dark: adsbRGBA(0.08, 0.10, 0.17) - ) - static let surfaceTop = adsbAdaptiveColor( - light: adsbRGBA(1.00, 1.00, 1.00, 0.98), - dark: adsbRGBA(0.13, 0.16, 0.24, 0.98) - ) - static let surfaceStroke = adsbAdaptiveColor( - light: adsbRGBA(1.00, 1.00, 1.00, 0.92), - dark: adsbRGBA(0.26, 0.31, 0.42, 0.88) - ) - static let toolbarBubble = adsbAdaptiveColor( - light: adsbRGBA(1.00, 1.00, 1.00, 0.78), - dark: adsbRGBA(0.16, 0.20, 0.28, 0.94) - ) - static let shadow = adsbAdaptiveColor( - light: adsbRGBA(0.06, 0.13, 0.34), - dark: adsbRGBA(0.00, 0.00, 0.00) - ) + static let radarBlue = MacOS9Colors.statusBlue + static let radarBlueDeep = MacOS9Colors.selection + static let radarGreen = MacOS9Colors.statusGreen + static let radarMint = MacOS9Colors.statusGreen.opacity(0.2) + static let ink = MacOS9Colors.primaryText + static let secondaryInk = MacOS9Colors.secondaryText + static let tertiaryInk = MacOS9Colors.secondaryText + static let sectionInk = MacOS9Colors.selection + static let mist = MacOS9Colors.windowBackground + static let cloud = MacOS9Colors.contentPanel + static let canvasMid = MacOS9Colors.windowBackground + static let canvasEnd = MacOS9Colors.windowBackground + static let surfaceTop = MacOS9Colors.panelBackground + static let surfaceStroke = MacOS9Colors.border + static let toolbarBubble = MacOS9Colors.panelBackground + static let shadow = MacOS9Colors.dropShadow } private struct ADSBPanelBackground: View { @@ -98,39 +62,21 @@ private struct ADSBToolbarTitle: View { var body: some View { HStack(spacing: 10) { ZStack { - Circle() - .fill( - LinearGradient( - colors: [ - ADSBTheme.radarGreen.opacity(0.22), - ADSBTheme.radarBlue.opacity(0.12), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) + Rectangle() + .fill(MacOS9Colors.panelBackground) .frame(width: 28, height: 28) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - Circle() - .stroke(ADSBTheme.radarGreen.opacity(0.45), lineWidth: 1.2) - .frame(width: 28, height: 28) - - Circle() + Rectangle() .fill(ADSBTheme.radarGreen) - .frame(width: 6, height: 6) - .shadow(color: ADSBTheme.radarGreen.opacity(0.45), radius: 6, x: 0, y: 0) + .frame(width: 8, height: 8) } Text("ADS-B") - .font(.system(size: 23, weight: .black, design: .rounded)) + .font(MacOS9Typography.editorialBold(24)) .tracking(0.8) - .foregroundStyle( - LinearGradient( - colors: [ADSBTheme.radarBlueDeep, ADSBTheme.radarBlue], - startPoint: .leading, - endPoint: .trailing - ) - ) + .foregroundStyle(MacOS9Colors.selection) } .accessibilityElement(children: .combine) .accessibilityLabel("ADS-B") @@ -162,13 +108,10 @@ private struct ADSBSourceChip: View { .padding(.horizontal, 12) .padding(.vertical, 9) .background( - Capsule() - .fill(tint.opacity(isActive ? 0.16 : 0.08)) - ) - .overlay( - Capsule() - .stroke(tint.opacity(isActive ? 0.28 : 0.12), lineWidth: 1) + MacOS9Colors.panelBackground ) + .overlay(Mac9BevelBorder(isRaised: isActive)) + .overlay(Rectangle().strokeBorder(tint.opacity(isActive ? 0.8 : 0.35), lineWidth: 1)) } } @@ -480,16 +423,16 @@ struct ADSBView: View { HStack(alignment: .center, spacing: 14) { // Large number Text("\(total)") - .font(.system(size: isCompactLayout ? 44 : 52, weight: .bold, design: .rounded)) + .font(MacOS9Typography.editorialBold(isCompactLayout ? 44 : 52)) .monospacedDigit() .foregroundStyle(ADSBTheme.ink) VStack(alignment: .leading, spacing: 3) { Text("Aeronaves") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(ADSBTheme.ink) Text("no ar agora") - .font(.caption.weight(.medium)) + .font(MacOS9Typography.caption(13)) .foregroundStyle(ADSBTheme.secondaryInk) } @@ -502,13 +445,15 @@ struct ADSBView: View { .frame(width: 8, height: 8) .shadow(color: ADSBTheme.radarGreen.opacity(0.6), radius: 4) Text("LIVE") - .font(.system(size: 10, weight: .black, design: .rounded)) + .font(MacOS9Typography.menuLabel(10)) .tracking(1.2) .foregroundStyle(ADSBTheme.radarGreen) } .padding(.horizontal, 10) .padding(.vertical, 6) - .background(ADSBTheme.radarGreen.opacity(0.12), in: Capsule()) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } Divider() @@ -529,25 +474,11 @@ struct ADSBView: View { } .padding(isCompactLayout ? 16 : 20) .background { - RoundedRectangle(cornerRadius: 24, style: .continuous) - .fill(.ultraThinMaterial) - .overlay { - LinearGradient( - colors: [ - ADSBTheme.radarGreen.opacity(0.08), - ADSBTheme.radarBlue.opacity(0.05), - .clear, - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - .clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous)) - } - .overlay { - RoundedRectangle(cornerRadius: 24, style: .continuous) - .strokeBorder(Color.white.opacity(0.35), lineWidth: 1) - } + MacOS9Colors.panelBackground + .shadow(color: MacOS9Colors.dropShadow, radius: 0, x: 4, y: 4) } + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } private func liveMetaPill(icon: String, text: String) -> some View { @@ -1247,15 +1178,11 @@ struct MiniStatCard: View { var body: some View { VStack(spacing: compact ? 6 : 10) { ZStack { - Circle() - .fill( - LinearGradient( - colors: [color.opacity(0.20), color.opacity(0.08)], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) + Rectangle() + .fill(MacOS9Colors.panelBackground) .frame(width: compact ? 36 : 44, height: compact ? 36 : 44) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) Image(systemName: icon) .font(.system(size: compact ? 15 : 18, weight: .semibold)) @@ -1263,33 +1190,21 @@ struct MiniStatCard: View { } Text(value) - .font(.system(size: compact ? 22 : 26, weight: .bold, design: .rounded)) + .font(MacOS9Typography.editorialBold(compact ? 22 : 26)) .monospacedDigit() .foregroundStyle(ADSBTheme.ink) .minimumScaleFactor(0.8) Text(label) - .font(.caption2.weight(.medium)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.secondaryInk) } .frame(maxWidth: .infinity) .padding(.vertical, compact ? 12 : 16) .padding(.horizontal, compact ? 6 : 8) - .background( - LinearGradient( - colors: [ - Color(.secondarySystemGroupedBackground), - color.opacity(compact ? 0.06 : 0.04), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous)) - .overlay( - RoundedRectangle(cornerRadius: 18, style: .continuous) - .strokeBorder(color.opacity(compact ? 0.18 : 0.10), lineWidth: 1) - ) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(color.opacity(compact ? 0.8 : 0.6), lineWidth: 1)) } } @@ -1302,18 +1217,11 @@ struct AverageStatCard: View { var body: some View { HStack(spacing: 12) { ZStack { - RoundedRectangle(cornerRadius: 12, style: .continuous) - .fill( - LinearGradient( - colors: [ - ADSBTheme.radarBlue.opacity(0.14), - ADSBTheme.radarBlue.opacity(0.06), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) + Rectangle() + .fill(MacOS9Colors.panelBackground) .frame(width: 40, height: 40) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) Image(systemName: icon) .font(.system(size: 16, weight: .semibold)) @@ -1326,7 +1234,7 @@ struct AverageStatCard: View { .foregroundStyle(ADSBTheme.tertiaryInk) Text(value) - .font(.system(size: 16, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(16)) .monospacedDigit() .foregroundStyle(ADSBTheme.ink) .minimumScaleFactor(0.7) @@ -1342,12 +1250,9 @@ struct AverageStatCard: View { } .padding(14) .frame(maxWidth: .infinity) - .background(Color(.secondarySystemGroupedBackground)) - .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous)) - .overlay( - RoundedRectangle(cornerRadius: 16, style: .continuous) - .strokeBorder(ADSBTheme.radarBlue.opacity(0.08), lineWidth: 1) - ) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } From f903f7e9a2d23e327e1a3d74a8607571661c89b6 Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sat, 23 May 2026 18:03:34 -0300 Subject: [PATCH 06/10] Improve Bible Mac OS 9 layout --- MeuLabApp/Views/Tabs/BibleNavigateView.swift | 181 +++++++++---------- MeuLabApp/Views/Tabs/BibleRandomView.swift | 68 ++++--- MeuLabApp/Views/Tabs/BibleSearchView.swift | 46 ++--- MeuLabApp/Views/Tabs/BibleView.swift | 98 ++++++---- 4 files changed, 207 insertions(+), 186 deletions(-) diff --git a/MeuLabApp/Views/Tabs/BibleNavigateView.swift b/MeuLabApp/Views/Tabs/BibleNavigateView.swift index e20354f..c5e6f25 100644 --- a/MeuLabApp/Views/Tabs/BibleNavigateView.swift +++ b/MeuLabApp/Views/Tabs/BibleNavigateView.swift @@ -7,20 +7,20 @@ struct BibleNavigateView: View { @Binding var selectedChapter: BibleChapter? var body: some View { - NavigationStack { - ScrollView { - LazyVStack(spacing: 20) { - ForEach([BibleBook.Testament.old, .new], id: \.self) { testament in - let books = BibleCatalogue.books.filter { $0.testament == testament } - TestamentSection(testament: testament.rawValue, books: books) - } + ScrollView { + LazyVStack(spacing: 14) { + ForEach([BibleBook.Testament.old, .new], id: \.self) { testament in + let books = BibleCatalogue.books.filter { $0.testament == testament } + TestamentSection(testament: testament.rawValue, books: books) } - .padding(.horizontal) - .padding(.vertical, 12) - } - .navigationDestination(for: BibleBook.self) { book in - BibleChaptersView(book: book) } + .padding(.horizontal, 16) + .padding(.vertical, 12) + .padding(.bottom, 92) + } + .background(MacOS9Colors.windowBackground) + .navigationDestination(for: BibleBook.self) { book in + BibleChaptersView(book: book) } } } @@ -35,32 +35,31 @@ private struct TestamentSection: View { var body: some View { VStack(alignment: .leading, spacing: 10) { - // Section header Button { - withAnimation(.spring(response: 0.3, dampingFraction: 0.8)) { - isExpanded.toggle() - } + isExpanded.toggle() } label: { HStack { Text(testament) - .font(.title3) - .fontWeight(.bold) - .foregroundStyle(Color.amber) + .font(MacOS9Typography.editorialBold(22)) + .foregroundStyle(MacOS9Colors.selection) Spacer() Image(systemName: isExpanded ? "chevron.up" : "chevron.down") - .font(.caption) - .foregroundStyle(.secondary) + .font(.system(size: 12, weight: .bold)) + .foregroundStyle(MacOS9Colors.secondaryText) } - .padding(.vertical, 4) + .padding(.horizontal, 8) + .padding(.vertical, 7) + .background(MacOS9Colors.labelBadge) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } .buttonStyle(.plain) if isExpanded { LazyVGrid( - columns: [GridItem(.adaptive(minimum: 110, maximum: 160), spacing: 10)], - spacing: 10 + columns: [GridItem(.adaptive(minimum: 118, maximum: 170), spacing: 8)], + spacing: 8 ) { ForEach(books) { book in NavigationLink(value: book) { @@ -71,8 +70,10 @@ private struct TestamentSection: View { } } } - .padding(14) - .glassCard(cornerRadius: 16) + .padding(10) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -84,27 +85,22 @@ private struct BookCard: View { var body: some View { VStack(spacing: 4) { Text(book.name) - .font(.subheadline) - .fontWeight(.medium) + .font(MacOS9Typography.bodyBold(15)) .multilineTextAlignment(.center) - .foregroundStyle(.primary) + .foregroundStyle(MacOS9Colors.primaryText) .minimumScaleFactor(0.75) .lineLimit(2) Text("\(book.chapterCount) cap.") - .font(.caption2) - .foregroundStyle(.secondary) + .font(MacOS9Typography.caption(11)) + .foregroundStyle(MacOS9Colors.secondaryText) } .frame(maxWidth: .infinity) - .padding(.vertical, 10) + .frame(minHeight: 58) .padding(.horizontal, 6) - .background( - Color.amber.opacity(0.10), in: RoundedRectangle(cornerRadius: 10, style: .continuous) - ) - .overlay( - RoundedRectangle(cornerRadius: 10, style: .continuous) - .strokeBorder(Color.amber.opacity(0.30), lineWidth: 1) - ) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.statusOrange.opacity(0.75), lineWidth: 1)) } } @@ -112,23 +108,34 @@ private struct BookCard: View { struct BibleChaptersView: View { let book: BibleBook - private let columns = [GridItem(.adaptive(minimum: 52, maximum: 64), spacing: 10)] + private let columns = [GridItem(.adaptive(minimum: 56, maximum: 70), spacing: 8)] var body: some View { ScrollView { - LazyVGrid(columns: columns, spacing: 10) { - ForEach(1...book.chapterCount, id: \.self) { chapter in - NavigationLink(value: chapter) { - ChapterButton(number: chapter) + VStack(alignment: .leading, spacing: 12) { + Text("\(book.chapterCount) capítulos") + .font(MacOS9Typography.menuLabel(12)) + .foregroundStyle(MacOS9Colors.secondaryText) + .padding(.horizontal, 8) + .padding(.vertical, 5) + .background(MacOS9Colors.labelBadge) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + + LazyVGrid(columns: columns, spacing: 8) { + ForEach(1...book.chapterCount, id: \.self) { chapter in + NavigationLink(value: chapter) { + ChapterButton(number: chapter) + } + .buttonStyle(.plain) } - .buttonStyle(.plain) } } - .padding() + .padding(16) + .padding(.bottom, 92) } .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .navigationTitle(book.name) - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .navigationDestination(for: Int.self) { chapter in BibleChapterView(bookSlug: book.slug, bookName: book.name, chapterNumber: chapter) } @@ -140,12 +147,12 @@ private struct ChapterButton: View { var body: some View { Text("\(number)") - .font(.callout) - .fontWeight(.semibold) - .frame(width: 52, height: 52) - .background(Color.amber.opacity(0.12), in: Circle()) - .overlay(Circle().strokeBorder(Color.amber.opacity(0.35), lineWidth: 1)) - .foregroundStyle(.primary) + .font(MacOS9Typography.bodyBold(16)) + .frame(width: 56, height: 44) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .foregroundStyle(MacOS9Colors.primaryText) } } @@ -193,9 +200,9 @@ struct BibleChapterView: View { PlaybackControlBar(viewModel: readerViewModel, highlightedIndex: $highlightedVerseIndex) .padding(Edge.Set.horizontal, 16) .padding(Edge.Set.vertical, 12) - .background(Color.amber.opacity(0.08)) - .borderTop(Color.amber.opacity(0.2), height: 1) - .borderBottom(Color.amber.opacity(0.2), height: 1) + .background(MacOS9Colors.panelBackground) + .borderTop(MacOS9Colors.border, height: 1) + .borderBottom(MacOS9Colors.border, height: 1) ScrollViewReader { proxy in ScrollView { @@ -218,13 +225,7 @@ struct BibleChapterView: View { .padding(.vertical, 12) .padding(.bottom, 44) } - .background { - LinearGradient( - colors: [Color.amber.opacity(0.05), Color(.systemBackground)], - startPoint: .top, endPoint: .bottom - ) - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) .onChange(of: readerViewModel.highlightedVerseIndex) { oldValue, newValue in if newValue != highlightedVerseIndex { highlightedVerseIndex = newValue @@ -289,30 +290,21 @@ struct VerseRowWithReader: View { var body: some View { HStack(alignment: .top, spacing: 10) { Text("\(verse.number)") - .font(.system(size: fontSize * 0.72, weight: .bold)) - .foregroundStyle(isHighlighted ? Color.white : Color.amber) + .font(MacOS9Typography.bodyBold(fontSize * 0.72)) + .foregroundStyle(isHighlighted ? MacOS9Colors.selectedText : MacOS9Colors.statusOrange) .frame(minWidth: 24, alignment: .trailing) .padding(.top, 3) Text(verse.text) .font(.system(size: fontSize)) - .foregroundStyle(isHighlighted ? Color.white : .primary) + .foregroundStyle(isHighlighted ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .lineSpacing(4) .frame(maxWidth: .infinity, alignment: .leading) } .padding(.horizontal, 12) .padding(.vertical, 10) - .background( - RoundedRectangle(cornerRadius: 8) - .fill(isHighlighted ? Color.amber.opacity(0.7) : Color.clear) - ) - .overlay( - RoundedRectangle(cornerRadius: 8) - .strokeBorder( - isHighlighted ? Color.amber : Color.amber.opacity(0.2), - lineWidth: isHighlighted ? 2 : 1 - ) - ) + .background(isHighlighted ? MacOS9Colors.selection : MacOS9Colors.contentPanel) + .overlay(Rectangle().strokeBorder(isHighlighted ? MacOS9Colors.border : MacOS9Colors.bevelShadowSubtle, lineWidth: 1)) .contentShape(Rectangle()) .onTapGesture(perform: onTap) } @@ -327,17 +319,16 @@ struct PlaybackControlBar: View { var body: some View { VStack(spacing: 12) { HStack(spacing: 12) { - // Stop Button Button(action: { viewModel.stop() }) { Image(systemName: "stop.fill") .frame(width: 36, height: 36) - .background(Color.red.opacity(0.2)) - .foregroundStyle(.red) - .clipShape(Circle()) + .background(MacOS9Colors.contentPanel) + .foregroundStyle(MacOS9Colors.statusRed) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } .disabled(!viewModel.isPlaying && !viewModel.isPaused) - // Play/Pause Button Button(action: { if viewModel.isPlaying { viewModel.pause() @@ -351,8 +342,12 @@ struct PlaybackControlBar: View { Image( systemName: viewModel.isPlaying ? "pause.circle.fill" : "play.circle.fill" ) - .font(.system(size: 40)) - .foregroundStyle(.blue) + .font(.system(size: 34)) + .frame(width: 42, height: 36) + .background(MacOS9Colors.contentPanel) + .foregroundStyle(MacOS9Colors.statusBlue) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } Spacer() @@ -362,25 +357,23 @@ struct PlaybackControlBar: View { Text( viewModel.isPlaying ? "Lendo..." : viewModel.isPaused ? "Pausado" : "Parado" ) - .font(.caption) - .foregroundStyle(.secondary) + .font(MacOS9Typography.caption(11)) + .foregroundStyle(MacOS9Colors.secondaryText) Text("\(viewModel.highlightedVerseIndex + 1)/\(viewModel.verses.count)") - .font(.caption2) - .fontWeight(.semibold) - .foregroundStyle(.primary) + .font(MacOS9Typography.bodyBold(12)) + .foregroundStyle(MacOS9Colors.primaryText) } } .padding(.horizontal, 12) .padding(.vertical, 10) - .background(Color.amber.opacity(0.05)) - .clipShape(RoundedRectangle(cornerRadius: 10)) + .background(MacOS9Colors.contentPanel) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - // Speed Info if viewModel.isPlaying || viewModel.isPaused { Text("Toque em um versículo para pular") - .font(.caption) - .foregroundStyle(.secondary) + .font(MacOS9Typography.caption(11)) + .foregroundStyle(MacOS9Colors.secondaryText) .frame(maxWidth: .infinity, alignment: .center) } } diff --git a/MeuLabApp/Views/Tabs/BibleRandomView.swift b/MeuLabApp/Views/Tabs/BibleRandomView.swift index c6d91d2..b15e319 100644 --- a/MeuLabApp/Views/Tabs/BibleRandomView.swift +++ b/MeuLabApp/Views/Tabs/BibleRandomView.swift @@ -8,13 +8,9 @@ struct BibleRandomView: View { var body: some View { ScrollView { - VStack(spacing: 24) { + VStack(spacing: 16) { if let verse { RandomVerseCard(verse: verse) - .transition(.asymmetric( - insertion: .scale(scale: 0.9).combined(with: .opacity), - removal: .scale(scale: 1.1).combined(with: .opacity) - )) } Button { @@ -27,13 +23,15 @@ struct BibleRandomView: View { } else { Image(systemName: "dice") } - Text(verse == nil ? "✨ Versículo Aleatório" : "🎲 Outro Versículo") - .fontWeight(.semibold) + Text(verse == nil ? "Versículo Aleatório" : "Outro Versículo") + .font(MacOS9Typography.bodyBold(14)) } .frame(maxWidth: .infinity) - .padding(.vertical, 14) - .background(Color.amber, in: RoundedRectangle(cornerRadius: 14, style: .continuous)) - .foregroundStyle(Color.mogno) + .frame(height: 44) + .background(MacOS9Colors.panelBackground) + .foregroundStyle(MacOS9Colors.primaryText) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } .buttonStyle(.plain) .disabled(isLoading) @@ -47,27 +45,25 @@ struct BibleRandomView: View { .padding(.horizontal) .padding(.top, 24) } - .background { - LinearGradient( - colors: [Color.amber.opacity(0.06), Color(.systemBackground)], - startPoint: .top, endPoint: .bottom - ) - .ignoresSafeArea() - } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) } private var inspireText: some View { VStack(spacing: 8) { Image(systemName: "book.closed") - .font(.system(size: 52)) - .foregroundStyle(Color.amber.opacity(0.5)) + .font(.system(size: 40)) + .foregroundStyle(MacOS9Colors.statusOrange) Text("Deixe a Palavra falar ao seu coração") - .font(.callout) - .foregroundStyle(.secondary) + .font(MacOS9Typography.body(14)) + .foregroundStyle(MacOS9Colors.secondaryText) .multilineTextAlignment(.center) } - .padding(.top, 8) + .padding(20) + .frame(maxWidth: .infinity) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } private func generateRandom() { @@ -93,43 +89,41 @@ private struct RandomVerseCard: View { var body: some View { VStack(alignment: .leading, spacing: 16) { - // Reference badge HStack { Image(systemName: "book.pages") - .foregroundStyle(Color.amber) + .foregroundStyle(MacOS9Colors.statusOrange) Text("\(bookName) \(verse.chapter):\(verse.number)") - .font(.subheadline) - .fontWeight(.bold) - .foregroundStyle(Color.amber) + .font(MacOS9Typography.menuLabel(13)) + .foregroundStyle(MacOS9Colors.statusOrange) Spacer() } - // Verse text Text(verse.text) - .font(.title3) - .fontWeight(.light) - .foregroundStyle(.primary) + .font(MacOS9Typography.editorialHeading(23)) + .foregroundStyle(MacOS9Colors.primaryText) .lineSpacing(6) .multilineTextAlignment(.leading) .frame(maxWidth: .infinity, alignment: .leading) - Divider() - .overlay(Color.amber.opacity(0.3)) + Rectangle() + .fill(MacOS9Colors.border) + .frame(height: 1) - // Navigate to chapter NavigationLink(destination: BibleChapterView( bookSlug: verse.book, bookName: bookName, chapterNumber: verse.chapter )) { Label("Ler \(bookName) \(verse.chapter)", systemImage: "arrow.right.circle") - .font(.subheadline) - .foregroundStyle(Color.amber) + .font(MacOS9Typography.bodyBold(13)) + .foregroundStyle(MacOS9Colors.selection) } .buttonStyle(.plain) } .padding(18) - .glassCard(tint: Color.amber, cornerRadius: 18) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.statusOrange, lineWidth: 1)) } } diff --git a/MeuLabApp/Views/Tabs/BibleSearchView.swift b/MeuLabApp/Views/Tabs/BibleSearchView.swift index 017a5b6..3119cf7 100644 --- a/MeuLabApp/Views/Tabs/BibleSearchView.swift +++ b/MeuLabApp/Views/Tabs/BibleSearchView.swift @@ -13,9 +13,10 @@ struct BibleSearchView: View { // Search bar HStack(spacing: 10) { Image(systemName: "magnifyingglass") - .foregroundStyle(.secondary) + .foregroundStyle(MacOS9Colors.secondaryText) - TextField("Buscar versículos… (min. 3 letras)", text: $query) + TextField("Buscar versículos... (min. 3 letras)", text: $query) + .font(MacOS9Typography.body(14)) .autocorrectionDisabled() .onChange(of: query) { _, newValue in performSearch(query: newValue) @@ -33,10 +34,9 @@ struct BibleSearchView: View { } .padding(12) .background(MacOS9Colors.contentPanel) - .overlay( - Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1) - ) - .padding(.horizontal) + .overlay(Mac9BevelBorder(isRaised: false)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .padding(.horizontal, 16) .padding(.top, 12) .padding(.bottom, 8) @@ -59,25 +59,26 @@ struct BibleSearchView: View { private var searchPrompt: some View { VStack(spacing: 12) { Image(systemName: "text.magnifyingglass") - .font(.system(size: 48)) - .foregroundStyle(Color.amber.opacity(0.6)) + .font(.system(size: 36)) + .foregroundStyle(MacOS9Colors.statusOrange) Text("Digite pelo menos 3 caracteres para buscar versículos.") - .font(.callout) - .foregroundStyle(.secondary) + .font(MacOS9Typography.body(14)) + .foregroundStyle(MacOS9Colors.secondaryText) .multilineTextAlignment(.center) } .padding(32) .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(MacOS9Colors.windowBackground) } private var noResultsView: some View { VStack(spacing: 12) { Image(systemName: "doc.text.magnifyingglass") - .font(.system(size: 48)) - .foregroundStyle(.secondary) + .font(.system(size: 36)) + .foregroundStyle(MacOS9Colors.secondaryText) Text("Nenhum versículo encontrado para \"\(query)\".") - .font(.callout) - .foregroundStyle(.secondary) + .font(MacOS9Typography.body(14)) + .foregroundStyle(MacOS9Colors.secondaryText) .multilineTextAlignment(.center) } .padding(32) @@ -100,6 +101,7 @@ struct BibleSearchView: View { } .listStyle(.plain) .scrollContentBackground(.hidden) + .background(MacOS9Colors.windowBackground) } // MARK: - Search @@ -143,18 +145,18 @@ private struct SearchResultRow: View { var body: some View { VStack(alignment: .leading, spacing: 5) { Text("\(bookName) \(verse.chapter):\(verse.number)") - .font(.caption) - .fontWeight(.semibold) - .foregroundStyle(Color.amber) + .font(MacOS9Typography.menuLabel(12)) + .foregroundStyle(MacOS9Colors.statusOrange) Text(verse.text) - .font(.callout) - .foregroundStyle(.primary) + .font(MacOS9Typography.body(14)) + .foregroundStyle(MacOS9Colors.primaryText) .lineLimit(3) } - .padding(.vertical, 8) - .padding(.horizontal, 10) - .background(Color.amber.opacity(0.07), in: RoundedRectangle(cornerRadius: 10)) + .padding(10) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } diff --git a/MeuLabApp/Views/Tabs/BibleView.swift b/MeuLabApp/Views/Tabs/BibleView.swift index 199e1e2..94657e9 100644 --- a/MeuLabApp/Views/Tabs/BibleView.swift +++ b/MeuLabApp/Views/Tabs/BibleView.swift @@ -23,21 +23,23 @@ struct BibleView: View { var body: some View { NavigationStack { ZStack { - // Mac OS 9 window background MacOS9Colors.windowBackground .ignoresSafeArea() VStack(spacing: 0) { - // Custom tab picker + BibleHeader(selectedTab: selectedTab) + .padding(.horizontal, 16) + .padding(.top, 10) + .padding(.bottom, 8) + bibleTabPicker - .padding(.horizontal) - .padding(.top, 8) - .padding(.bottom, 4) + .padding(.horizontal, 16) + .padding(.bottom, 10) - Divider() - .opacity(0.3) + Rectangle() + .fill(MacOS9Colors.border) + .frame(height: 1) - // Tab content switch selectedTab { case .navegar: BibleNavigateView( @@ -51,16 +53,17 @@ struct BibleView: View { } } } - .navigationTitle("📖 A Bíblia") - .navigationBarTitleDisplayMode(.large) + .navigationTitle("A Bíblia") + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Text("ACF") - .font(MacOS9Typography.caption()) - .foregroundStyle(MacOS9Colors.secondaryText) - .padding(.horizontal, 8) - .padding(.vertical, 3) + .font(MacOS9Typography.menuLabel(12)) + .foregroundStyle(MacOS9Colors.primaryText) + .padding(.horizontal, 10) + .padding(.vertical, 5) .background(MacOS9Colors.labelBadge) + .overlay(Mac9BevelBorder(isRaised: true)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -70,38 +73,67 @@ struct BibleView: View { // MARK: - Tab Picker private var bibleTabPicker: some View { - HStack(spacing: 6) { + HStack(spacing: 0) { ForEach(BibleTab.allCases, id: \.self) { tab in Button { - withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) { - selectedTab = tab - } + selectedTab = tab } label: { Label(tab.rawValue, systemImage: tab.icon) - .font(MacOS9Typography.menuLabel()) + .font(MacOS9Typography.menuLabel(12)) .foregroundStyle( selectedTab == tab ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .frame(maxWidth: .infinity) - .padding(.vertical, 8) - .background { - if selectedTab == tab { - Rectangle() - .fill(MacOS9Colors.selection) - .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - } - } + .frame(height: 44) + .background(selectedTab == tab ? MacOS9Colors.selection : MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: selectedTab != tab)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } .buttonStyle(.plain) } } .padding(4) - .background( - MacOS9Colors.panelBackground - ) - .overlay( - Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1) - ) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + } +} + +private struct BibleHeader: View { + let selectedTab: BibleView.BibleTab + + private var subtitle: String { + switch selectedTab { + case .navegar: return "Livros e capítulos" + case .buscar: return "Busca textual" + case .aleatorio: return "Versículo aleatório" + } + } + + var body: some View { + HStack(spacing: 12) { + Image(systemName: "book.closed") + .font(.system(size: 22, weight: .semibold)) + .frame(width: 40, height: 40) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + + VStack(alignment: .leading, spacing: 2) { + Text("A Bíblia") + .font(MacOS9Typography.editorialTitle(28)) + .foregroundStyle(MacOS9Colors.primaryText) + Text(subtitle) + .font(MacOS9Typography.caption(12)) + .foregroundStyle(MacOS9Colors.secondaryText) + } + + Spacer() + } + .padding(12) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } From a0c669c1019bd2f39a9ec3de1f4c33ad0cc98829 Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sun, 24 May 2026 14:07:56 -0300 Subject: [PATCH 07/10] Improve iPhone performance and Mac OS 9 font --- .../DesignSystem/MacOS9/MacOS9Theme.swift | 7 +- .../MacOS9/MacOS9Typography.swift | 18 ++--- MeuLabApp/MeuLabApp.swift | 8 +- .../Services/NotificationFeedManager.swift | 6 +- MeuLabApp/ViewModels/AppState.swift | 73 ++++++------------- MeuLabApp/ViewModels/OpenSkyService.swift | 10 --- MeuLabApp/Views/Tabs/ADSBView.swift | 9 --- 7 files changed, 45 insertions(+), 86 deletions(-) diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift index d115466..8637875 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift @@ -11,6 +11,7 @@ extension View { self .preferredColorScheme(.light) .tint(MacOS9Colors.selection) + .font(MacOS9Typography.body()) .foregroundStyle(MacOS9Colors.primaryText) .background(MacOS9Colors.windowBackground) .onAppear { MacOS9Theme.applyAppearance() } @@ -70,7 +71,11 @@ enum MacOS9Theme { appearance.backgroundColor = UIColor(MacOS9Colors.titleBar) appearance.shadowColor = UIColor(MacOS9Colors.border) - let normalFont = UIFont.systemFont(ofSize: 10) + let normalFont = MacOS9Typography.uiFont( + ["Charcoal"], + fallback: .systemFont(ofSize: 10), + size: 10 + ) let itemAppearance = UITabBarItemAppearance() itemAppearance.normal.titleTextAttributes = [ .font: normalFont, diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift index a79b300..6f70f3f 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Typography.swift @@ -87,26 +87,26 @@ public enum MacOS9Typography { font([charcoal], fallback: charcoalFallback, size: size) } - // MARK: Geneva (Body, labels, lists) + // MARK: Charcoal Body (Mac OS 9 system UI) - /// System body text. The classic Geneva TTF is MacRoman and breaks Portuguese accents. + /// Charcoal body text. This is the Mac OS 9 UI face and supports Portuguese accents. public static func body(_ size: CGFloat = 13) -> Font { - .system(size: size) + font([charcoal], fallback: charcoalFallback, size: size) } - /// System bold body text. Kept Unicode-safe for Portuguese labels and content. + /// Bold body text using Charcoal where available. public static func bodyBold(_ size: CGFloat = 13) -> Font { - .system(size: size, weight: .bold) + font([charcoal], fallback: charcoalFallback, size: size).weight(.bold) } - /// System caption text. Kept Unicode-safe for Portuguese labels and content. + /// Charcoal caption text. public static func caption(_ size: CGFloat = 11) -> Font { - .system(size: size) + font([charcoal], fallback: charcoalFallback, size: size) } - /// System fine print. Kept Unicode-safe for Portuguese labels and content. + /// Charcoal fine print. public static func finePrint(_ size: CGFloat = 9) -> Font { - .system(size: size) + font([charcoal], fallback: charcoalFallback, size: size) } /// Classic Geneva for ASCII-only decorative labels. diff --git a/MeuLabApp/MeuLabApp.swift b/MeuLabApp/MeuLabApp.swift index 57d460a..c10f22d 100644 --- a/MeuLabApp/MeuLabApp.swift +++ b/MeuLabApp/MeuLabApp.swift @@ -28,7 +28,6 @@ struct MeuLabApp: App { .onChange(of: scenePhase) { _, newPhase in if newPhase == .active { scheduleDeferredStartup() - notificationFeed.start() appState.setRefreshEnabled(true) } else if newPhase == .background { startupTask?.cancel() @@ -44,14 +43,17 @@ struct MeuLabApp: App { guard startupTask == nil else { return } startupTask = Task { @MainActor in - try? await Task.sleep(nanoseconds: 100_000_000) + try? await Task.sleep(nanoseconds: 250_000_000) guard !Task.isCancelled else { return } _ = NetworkEnvironment.shared appState.bootstrapIfNeeded() + appState.setRefreshEnabled(true) + + try? await Task.sleep(nanoseconds: 2_000_000_000) + guard !Task.isCancelled else { return } setupPushNotificationsIfNeeded() notificationFeed.start() - appState.setRefreshEnabled(true) startupTask = nil } } diff --git a/MeuLabApp/Services/NotificationFeedManager.swift b/MeuLabApp/Services/NotificationFeedManager.swift index 2a24eb2..50c987c 100644 --- a/MeuLabApp/Services/NotificationFeedManager.swift +++ b/MeuLabApp/Services/NotificationFeedManager.swift @@ -8,11 +8,11 @@ final class NotificationFeedManager: ObservableObject { private let api = APIService.shared private let defaults = UserDefaults.standard private let latestIdKey = "notification_feed_latest_id" - private let basePollInterval: TimeInterval = 20 + private let basePollInterval: TimeInterval = 60 private let maxPollInterval: TimeInterval = 300 private struct State { - var currentPollInterval: TimeInterval = 20 + var currentPollInterval: TimeInterval = 60 var pollTask: Task? var isFetching = false } @@ -49,7 +49,7 @@ final class NotificationFeedManager: ObservableObject { } private func runLoop() async { - // Run immediately, then back off based on success/failure. + try? await Task.sleep(nanoseconds: 10_000_000_000) while !Task.isCancelled { await poll() let interval = stateLock.withLock { s in diff --git a/MeuLabApp/ViewModels/AppState.swift b/MeuLabApp/ViewModels/AppState.swift index bb633bf..4700222 100644 --- a/MeuLabApp/ViewModels/AppState.swift +++ b/MeuLabApp/ViewModels/AppState.swift @@ -159,13 +159,13 @@ class AppState: ObservableObject { private var acarsInFlight = false // Intervalos de cada módulo quando a tab está ativa - private let adsbTimerInterval: TimeInterval = 0.75 - private let adsbSummaryInterval: TimeInterval = 0.75 - private let adsbAircraftInterval: TimeInterval = 1.5 + private let adsbTimerInterval: TimeInterval = 2.0 + private let adsbSummaryInterval: TimeInterval = 2.0 + private let adsbAircraftInterval: TimeInterval = 4.0 private let systemInterval: TimeInterval = 5.0 private let firestickInterval: TimeInterval = 10.0 - private let radioInterval: TimeInterval = 1.0 - private let radioBackgroundInterval: TimeInterval = 5.0 + private let radioInterval: TimeInterval = 3.0 + private let radioBackgroundInterval: TimeInterval = 60.0 private let weatherInterval: TimeInterval = 60.0 private let satelliteInterval: TimeInterval = 120.0 private let acarsInterval: TimeInterval = 10.0 @@ -234,7 +234,7 @@ class AppState: ObservableObject { } } // Timer para os demais módulos — cada grupo roda independente via in-flight flags - moduleTimer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { [weak self] _ in + moduleTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak self] _ in Task { @MainActor [weak self] in await self?.tickActiveModules() } @@ -248,8 +248,6 @@ class AppState: ObservableObject { Task { @MainActor [weak self] in await self?.refreshActiveTabNow(force: true) - // Pré-carrega rádio em background para já ter album/artista ao abrir - await self?.refreshRadio() } } @@ -263,7 +261,7 @@ class AppState: ObservableObject { adsbTimer = nil moduleTimer?.invalidate() moduleTimer = nil - startRadioBackgroundTimer() + stopRadioBackgroundTimer() } } @@ -314,9 +312,6 @@ class AppState: ObservableObject { let active = activeTabRawValue let now = Date() - // Rádio sempre atualiza em background (intervalo maior quando não é a tab ativa) - await tickRadio(now, background: active != "radio") - switch active { case "adsb", "map": // ADSB live já roda no seu próprio timer rápido. @@ -329,6 +324,9 @@ class AppState: ObservableObject { case "weather": await tickWeather(now) + case "radio": + await tickRadio(now, background: false) + case "satellite": await tickSatellite(now) @@ -1270,7 +1268,7 @@ class AppState: ObservableObject { } } - adsbAirlines = grouped.values + let nextAirlines = grouped.values .map { Airline(name: $0.displayName, count: $0.count) } .sorted { if $0.count == $1.count { @@ -1278,16 +1276,25 @@ class AppState: ObservableObject { } return $0.count > $1.count } + if adsbAirlines != nextAirlines { + adsbAirlines = nextAirlines + } } else { - adsbAirlines = adsbSummary?.airlines ?? [] + let nextAirlines = adsbSummary?.airlines ?? [] + if adsbAirlines != nextAirlines { + adsbAirlines = nextAirlines + } } - adsbNearbyAircraftPreview = + let nextNearbyAircraftPreview = aircraftList .filter { $0.computedDistanceNm < 100000 } .sorted { $0.computedDistanceNm < $1.computedDistanceNm } .prefix(5) .map { $0 } + if adsbNearbyAircraftPreview != nextNearbyAircraftPreview { + adsbNearbyAircraftPreview = nextNearbyAircraftPreview + } } private func normalizedAirlineDisplayName(_ value: String?) -> String? { @@ -1302,58 +1309,35 @@ class AppState: ObservableObject { func refreshACARS() async { guard !acarsLoading else { - print("[ACARS] ⏭️ Skipping refresh - already loading") return } acarsLoading = true defer { acarsLoading = false } - print("[ACARS] 🔄 Starting refresh...") - do { - print("[ACARS] 📡 Fetching summary...") let summary = try await api.fetchACARSSummary() - print("[ACARS] ✅ Summary received: \(summary.today.messages) messages today") - print("[ACARS] 📡 Fetching messages...") let messageList = try await api.fetchACARSMessages(limit: 20) - print("[ACARS] ✅ Messages received: \(messageList.messages.count) messages") // Populate registration cache from ACARS - var newRegistrations = 0 for msg in messageList.messages { if let flight = msg.flight, !flight.isEmpty, let tail = msg.tail, !tail.isEmpty { if registrationCache[flight] == nil { registrationCache[flight] = tail - newRegistrations += 1 } } } - if newRegistrations > 0 { - print("[ACARS] 💾 Cached \(newRegistrations) new registrations from ACARS") - } - print("[ACARS] 📡 Fetching hourly stats...") let hourly = try await api.fetchACARSHourly() - print("[ACARS] ✅ Hourly stats received: \(hourly.hours.count) hours") if self.acarsSummary != summary { - print("[ACARS] 📝 Updating summary (changed)") self.acarsSummary = summary - } else { - print("[ACARS] ⏭️ Summary unchanged, skipping update") } let newMessages = messageList.messages if self.acarsMessages != newMessages { - print("[ACARS] 📝 Updating messages: \(newMessages.count) messages") - if let first = newMessages.first { - print( - "[ACARS] First message: \(first.flight ?? "N/A") - \(first.label ?? "N/A")" - ) - } self.acarsMessages = newMessages if let msg = newMessages.first { @@ -1363,30 +1347,17 @@ class AppState: ObservableObject { time: msg.time ) } - } else { - print("[ACARS] ⏭️ Messages unchanged, skipping update") } let newHourly = hourly.hours if self.acarsHourly != newHourly { - print("[ACARS] 📝 Updating hourly stats: \(newHourly.count) hours") self.acarsHourly = newHourly - } else { - print("[ACARS] ⏭️ Hourly stats unchanged, skipping update") } self.acarsError = nil - print("[ACARS] ✅ Refresh completed successfully") } catch { - print("[ACARS] ❌ Error during refresh: \(error.localizedDescription)") - if let apiError = error as? APIError { - print("[ACARS] API Error details: \(apiError)") - } if acarsSummary == nil { - print("[ACARS] 📝 Setting error message (no previous data)") self.acarsError = error.localizedDescription - } else { - print("[ACARS] ⏭️ Keeping previous data despite error") } } } diff --git a/MeuLabApp/ViewModels/OpenSkyService.swift b/MeuLabApp/ViewModels/OpenSkyService.swift index 718174c..4886bf3 100644 --- a/MeuLabApp/ViewModels/OpenSkyService.swift +++ b/MeuLabApp/ViewModels/OpenSkyService.swift @@ -69,8 +69,6 @@ actor OpenSkyService { private func refreshToken() async throws -> String? { guard !clientSecret.isEmpty else { return nil } - print("[OpenSky] 🔑 Requesting new access token...") - guard let url = URL(string: authURL) else { throw OpenSkyError.invalidURL } var request = URLRequest(url: url) @@ -96,7 +94,6 @@ actor OpenSkyService { } guard (200...299).contains(httpResponse.statusCode) else { - print("[OpenSky] ❌ Auth failed: \(httpResponse.statusCode)") return nil } @@ -104,7 +101,6 @@ actor OpenSkyService { self.accessToken = tokenResponse.access_token self.tokenExpiration = Date().addingTimeInterval(Double(tokenResponse.expires_in)) - print("[OpenSky] ✅ Token received, expires in \(tokenResponse.expires_in)s") return tokenResponse.access_token } @@ -146,9 +142,6 @@ actor OpenSkyService { // Add Bearer Token if we have one if let token = token { request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") - print("[OpenSky] 🔐 Using Bearer Token auth") - } else { - print("[OpenSky] 👤 Using anonymous request") } let (data, response) = try await session.data(for: request) @@ -159,19 +152,16 @@ actor OpenSkyService { // Handle token expiration if httpResponse.statusCode == 401 && token != nil { - print("[OpenSky] ❌ Token expired or invalid (401). Retrying with new token...") self.accessToken = nil let newToken = try await refreshToken() return try await performFetch(boundingBox: boundingBox, token: newToken) } if httpResponse.statusCode == 429 { - print("[OpenSky] ⚠️ Rate limit exceeded (429)") throw OpenSkyError.rateLimited } guard (200...299).contains(httpResponse.statusCode) else { - print("[OpenSky] ⚠️ Server error: \(httpResponse.statusCode)") throw OpenSkyError.serverError(httpResponse.statusCode) } diff --git a/MeuLabApp/Views/Tabs/ADSBView.swift b/MeuLabApp/Views/Tabs/ADSBView.swift index e439433..40f8551 100644 --- a/MeuLabApp/Views/Tabs/ADSBView.swift +++ b/MeuLabApp/Views/Tabs/ADSBView.swift @@ -806,16 +806,7 @@ struct ADSBView: View { // MARK: - Helpers private func filteredAircraft(for filter: MovementFilter) -> [Aircraft] { - print("[ADSBView] 🔍 Filtering aircraft for: \(filter.title)") - print("[ADSBView] Total aircraft in list: \(appState.aircraftList.count)") - let filtered = appState.aircraftList.filter { filter.matches($0) } - print("[ADSBView] Filtered count: \(filtered.count)") - - if filtered.count > 0, let first = filtered.first { - print( - "[ADSBView] First aircraft: \(first.callsign) - VR: \(first.verticalRateFpm) fpm") - } switch filter { case .climbing: From d01000ebf2347f06b942fd5405bbf936252fd2e6 Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sun, 24 May 2026 14:21:22 -0300 Subject: [PATCH 08/10] Enforce Mac OS 9 font in main views --- MeuLabApp/ContentView.swift | 6 +- .../DesignSystem/MacOS9/MacOS9Theme.swift | 6 +- MeuLabApp/MeuLabApp.swift | 4 + MeuLabApp/Views/Tabs/ADSBView.swift | 238 +++++++++--------- .../Views/Tabs/BibleChapterReaderView.swift | 20 +- MeuLabApp/Views/Tabs/BibleNavigateView.swift | 16 +- MeuLabApp/Views/Tabs/BibleRandomView.swift | 4 +- MeuLabApp/Views/Tabs/BibleSearchView.swift | 4 +- MeuLabApp/Views/Tabs/BibleView.swift | 4 +- MeuLabApp/Views/Tabs/WeatherView.swift | 113 ++++----- 10 files changed, 204 insertions(+), 211 deletions(-) diff --git a/MeuLabApp/ContentView.swift b/MeuLabApp/ContentView.swift index 17b5455..d44e2f5 100644 --- a/MeuLabApp/ContentView.swift +++ b/MeuLabApp/ContentView.swift @@ -252,7 +252,7 @@ private struct MacOS9RootTabItem: View { var body: some View { VStack(spacing: 3) { Image(systemName: iconName) - .font(.system(size: 20, weight: .semibold)) + .font(MacOS9Typography.bodyBold(20)) .frame(height: 22) Text(tab.title) .font(MacOS9Typography.caption(10)) @@ -282,7 +282,7 @@ private struct MoreMenuView: View { } label: { HStack(spacing: 14) { Image(systemName: tab.icon) - .font(.system(size: 20, weight: .semibold)) + .font(MacOS9Typography.bodyBold(20)) .frame(width: 28) .foregroundStyle(MacOS9Colors.selection) Text(tab.title) @@ -290,7 +290,7 @@ private struct MoreMenuView: View { .foregroundStyle(MacOS9Colors.primaryText) Spacer() Image(systemName: "chevron.right") - .font(.system(size: 14, weight: .bold)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(MacOS9Colors.secondaryText) } .padding(.horizontal, 16) diff --git a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift index 8637875..748ac91 100644 --- a/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift +++ b/MeuLabApp/DesignSystem/MacOS9/MacOS9Theme.swift @@ -50,9 +50,9 @@ enum MacOS9Theme { ] appearance.largeTitleTextAttributes = [ .font: MacOS9Typography.uiFont( - ["AppleGaramondLight", "AppleGaramond-Light"], - fallback: .systemFont(ofSize: 24, weight: .light), - size: 24 + ["Charcoal"], + fallback: .systemFont(ofSize: 20, weight: .bold), + size: 20 ), .foregroundColor: UIColor(MacOS9Colors.primaryText), ] diff --git a/MeuLabApp/MeuLabApp.swift b/MeuLabApp/MeuLabApp.swift index c10f22d..8a77e23 100644 --- a/MeuLabApp/MeuLabApp.swift +++ b/MeuLabApp/MeuLabApp.swift @@ -11,6 +11,10 @@ struct MeuLabApp: App { @State private var startupTask: Task? @State private var didConfigurePushNotifications = false + init() { + MacOS9Theme.applyAppearance() + } + var body: some Scene { WindowGroup { ContentView() diff --git a/MeuLabApp/Views/Tabs/ADSBView.swift b/MeuLabApp/Views/Tabs/ADSBView.swift index 40f8551..b53b5cc 100644 --- a/MeuLabApp/Views/Tabs/ADSBView.swift +++ b/MeuLabApp/Views/Tabs/ADSBView.swift @@ -74,7 +74,7 @@ private struct ADSBToolbarTitle: View { } Text("ADS-B") - .font(MacOS9Typography.editorialBold(24)) + .font(MacOS9Typography.bodyBold(24)) .tracking(0.8) .foregroundStyle(MacOS9Colors.selection) } @@ -92,7 +92,7 @@ private struct ADSBSourceChip: View { var body: some View { VStack(alignment: .leading, spacing: 4) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) HStack(spacing: 6) { @@ -101,7 +101,7 @@ private struct ADSBSourceChip: View { .frame(width: 7, height: 7) Text(value) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.ink) } } @@ -258,11 +258,11 @@ struct ADSBView: View { "Fonte do Radar", systemImage: "antenna.radiowaves.left.and.right" ) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(ADSBTheme.ink.opacity(0.82)) Text(appState.isOpenSkyEnabled ? "EXPANDIDO" : "LOCAL") - .font(.system(size: 10, weight: .black, design: .rounded)) + .font(MacOS9Typography.menuLabel(10)) .tracking(1.0) .foregroundStyle( appState.isOpenSkyEnabled @@ -279,7 +279,7 @@ struct ADSBView: View { } Text("Escolha entre radar local e leitura global.") - .font(.caption) + .font(MacOS9Typography.caption(12)) .foregroundStyle(ADSBTheme.secondaryInk) } @@ -314,11 +314,11 @@ struct ADSBView: View { Label( "Fonte do Radar", systemImage: "antenna.radiowaves.left.and.right" ) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(ADSBTheme.ink.opacity(0.82)) Text(appState.isOpenSkyEnabled ? "EXPANDIDO" : "LOCAL") - .font(.system(size: 10, weight: .black, design: .rounded)) + .font(MacOS9Typography.menuLabel(10)) .tracking(1.0) .foregroundStyle( appState.isOpenSkyEnabled @@ -335,7 +335,7 @@ struct ADSBView: View { } Text("Controle de cobertura e origem dos dados") - .font(.caption) + .font(MacOS9Typography.caption(12)) .foregroundStyle(ADSBTheme.secondaryInk) HStack(spacing: 10) { @@ -423,7 +423,7 @@ struct ADSBView: View { HStack(alignment: .center, spacing: 14) { // Large number Text("\(total)") - .font(MacOS9Typography.editorialBold(isCompactLayout ? 44 : 52)) + .font(MacOS9Typography.bodyBold(isCompactLayout ? 44 : 52)) .monospacedDigit() .foregroundStyle(ADSBTheme.ink) @@ -483,7 +483,7 @@ struct ADSBView: View { private func liveMetaPill(icon: String, text: String) -> some View { Label(text, systemImage: icon) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.secondaryInk) } @@ -661,7 +661,7 @@ struct ADSBView: View { showAircraftList = true } label: { Text("Ver Todas") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(ADSBTheme.radarBlue) } } @@ -744,7 +744,7 @@ struct ADSBView: View { ForEach(peaks, id: \.0) { day, value in HStack(spacing: 12) { Text(formatDay(day)) - .font(.caption.monospaced()) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) .frame(width: 44, alignment: .leading) @@ -770,7 +770,7 @@ struct ADSBView: View { .frame(height: 8) Text("\(value)") - .font(.caption.monospaced().bold()) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.primary) .frame(width: 32, alignment: .trailing) } @@ -880,7 +880,7 @@ private struct MovementAircraftSheet: View { VStack(alignment: .leading, spacing: 14) { HStack(spacing: 10) { Label("\(aircraft.count) aeronaves", systemImage: "airplane") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .padding(.horizontal, 10) .padding(.vertical, 6) .materialCard(cornerRadius: 10) @@ -890,7 +890,7 @@ private struct MovementAircraftSheet: View { ProgressView() .scaleEffect(0.75) Text("Buscando FlightAware...") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } .padding(.horizontal, 10) @@ -1010,7 +1010,7 @@ private struct MovementAircraftRow: View { .frame(width: 34, height: 34) .overlay( Image(systemName: "airplane") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.blue) ) } @@ -1021,7 +1021,7 @@ private struct MovementAircraftRow: View { .frame(width: 34, height: 34) .overlay( Image(systemName: "airplane") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.blue) ) } @@ -1029,11 +1029,11 @@ private struct MovementAircraftRow: View { VStack(alignment: .leading, spacing: 3) { HStack(spacing: 8) { Text(ac.displayCallsign) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(.primary) if let reg = ac.registration, !reg.isEmpty { Text(reg) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -1041,12 +1041,12 @@ private struct MovementAircraftRow: View { HStack(spacing: 8) { if let model = ac.model, !model.isEmpty { Text(model) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } if let airline = ac.airline { Text(airline) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.blue) } } @@ -1056,10 +1056,10 @@ private struct MovementAircraftRow: View { VStack(alignment: .trailing, spacing: 3) { Text("\(ac.altitudeFt) ft") - .font(.caption.monospacedDigit()) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Text("\(ac.speedKt) kt") - .font(.caption.monospacedDigit()) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -1072,7 +1072,7 @@ private struct MovementAircraftRow: View { ? "arrow.up" : (ac.verticalRateFpm < 0 ? "arrow.down" : "arrow.left.and.right") ) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle( ac.verticalRateFpm > 0 ? .green : (ac.verticalRateFpm < 0 ? .orange : .secondary) @@ -1085,13 +1085,13 @@ private struct MovementAircraftRow: View { .opacity(0.12), in: Capsule()) Text("\(abs(ac.verticalRateFpm)) fpm") - .font(.caption2.monospacedDigit()) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Spacer() Image(systemName: "chevron.right") - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.tertiary) } @@ -1101,13 +1101,13 @@ private struct MovementAircraftRow: View { let origin = faFlight.origin?.bestCode ?? "-" let destination = faFlight.destination?.bestCode ?? "-" Text(origin) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .monospaced() Image(systemName: "arrow.right") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Text(destination) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .monospaced() Spacer() @@ -1123,11 +1123,11 @@ private struct MovementAircraftRow: View { if let outTime, let inTime { Text("\(outTime) • \(inTime)") - .font(.caption2.monospacedDigit()) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) } else { Text("FlightAware") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) } } @@ -1149,10 +1149,10 @@ struct SectionHeader: View { var body: some View { HStack(spacing: 6) { Image(systemName: icon) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(ADSBTheme.sectionInk) Text(title) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(ADSBTheme.sectionInk) .textCase(.uppercase) } @@ -1176,12 +1176,12 @@ struct MiniStatCard: View { .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) Image(systemName: icon) - .font(.system(size: compact ? 15 : 18, weight: .semibold)) + .font(MacOS9Typography.bodyBold(compact ? 15 : 18)) .foregroundStyle(color) } Text(value) - .font(MacOS9Typography.editorialBold(compact ? 22 : 26)) + .font(MacOS9Typography.bodyBold(compact ? 22 : 26)) .monospacedDigit() .foregroundStyle(ADSBTheme.ink) .minimumScaleFactor(0.8) @@ -1215,13 +1215,13 @@ struct AverageStatCard: View { .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) Image(systemName: icon) - .font(.system(size: 16, weight: .semibold)) + .font(MacOS9Typography.bodyBold(16)) .foregroundStyle(ADSBTheme.radarBlue) } VStack(alignment: .leading, spacing: 2) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.tertiaryInk) Text(value) @@ -1232,7 +1232,7 @@ struct AverageStatCard: View { .lineLimit(1) Text(subtitle) - .font(.caption2.weight(.medium)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.tertiaryInk) .lineLimit(1) } @@ -1260,11 +1260,11 @@ private struct ADSBStatusPill: View { VStack(alignment: .leading, spacing: 1) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) Text(value) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.ink) } } @@ -1292,18 +1292,18 @@ struct HighlightRowApple: View { var body: some View { HStack(spacing: 12) { Image(systemName: icon) - .font(.title3) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(iconColor) .frame(width: 32) VStack(alignment: .leading, spacing: 1) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) .textCase(.uppercase) Text(callsign) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .monospacedDigit() } @@ -1311,11 +1311,11 @@ struct HighlightRowApple: View { VStack(alignment: .trailing, spacing: 1) { Text(value) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .monospacedDigit() Text(subtitle) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) } } @@ -1342,7 +1342,7 @@ struct AirlineChip: View { .frame(width: 28, height: 28) .overlay( Text(String(airline.name.prefix(1))) - .font(.caption.bold()) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.radarBlue) ) } @@ -1353,19 +1353,19 @@ struct AirlineChip: View { .frame(width: 28, height: 28) .overlay( Text(String(airline.name.prefix(1))) - .font(.caption.bold()) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.radarBlue) ) } VStack(alignment: .leading, spacing: 0) { Text(airline.name) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .lineLimit(1) .foregroundStyle(ADSBTheme.ink) Text("\(airline.count) voos") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) } } @@ -1398,7 +1398,7 @@ struct AircraftRowApple: View { .frame(width: 40, height: 40) Image(systemName: aircraft.movementIcon) - .font(.system(size: 16, weight: .semibold)) + .font(MacOS9Typography.bodyBold(16)) .foregroundStyle(movementColor) } @@ -1416,7 +1416,7 @@ struct AircraftRowApple: View { } Text(aircraft.displayCallsign) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .monospacedDigit() // Source badge @@ -1424,7 +1424,7 @@ struct AircraftRowApple: View { aircraft.isDualTracked ? "DUAL" : (aircraft.source == .local ? "LOCAL" : "REDE") ) - .font(.system(size: 8, weight: .bold)) + .font(MacOS9Typography.bodyBold(8)) .padding(.horizontal, 5) .padding(.vertical, 2) .background(badgeColor.opacity(0.15)) @@ -1434,7 +1434,7 @@ struct AircraftRowApple: View { if let model = aircraft.model { Text(model) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.secondaryInk) } } @@ -1448,27 +1448,27 @@ struct AircraftRowApple: View { // Distance is primary let distFmt = Formatters.distanceDual(dist) Text(distFmt.aviation) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .monospacedDigit() .foregroundStyle(.blue) Text(distFmt.metric) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) // Altitude secondary Text(Formatters.altitudeDual(aircraft.altitudeFt).aviation) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.primary) } else { // Fallback to Altitude (Distance unavailable) let alt = Formatters.altitudeDual(aircraft.altitudeFt) Text(alt.aviation) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .monospacedDigit() Text(alt.metric) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.secondaryInk) } } @@ -1495,23 +1495,23 @@ struct RecordBubble: View { VStack(spacing: 2) { HStack(spacing: 4) { Image(systemName: icon) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(ADSBTheme.radarBlue) Text(value) - .font(.caption.bold()) + .font(MacOS9Typography.caption(11)) .monospacedDigit() .foregroundStyle(ADSBTheme.ink) } if let subtitle = subtitle { Text(subtitle) - .font(.system(size: 8)) + .font(MacOS9Typography.body(8)) .foregroundStyle(ADSBTheme.tertiaryInk) .monospacedDigit() } Text(label) - .font(.system(size: 9)) + .font(MacOS9Typography.body(9)) .foregroundStyle(ADSBTheme.secondaryInk) } .padding(.horizontal, 10) @@ -1599,11 +1599,11 @@ struct ADSBAirlineFullscreenView: View { VStack(alignment: .leading, spacing: 4) { Text(airline.name) - .font(.system(size: 28, weight: .black, design: .rounded)) + .font(MacOS9Typography.bodyBold(28)) .foregroundStyle(ADSBTheme.ink) Text("\(sortedAircraft.count) aeronaves monitoradas agora") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(ADSBTheme.secondaryInk) } @@ -1664,7 +1664,7 @@ struct ADSBAirlineFullscreenView: View { SectionHeader(title: "Aeronaves da Companhia", icon: "airplane") Spacer() Text("\(sortedAircraft.count)") - .font(.subheadline.weight(.bold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(ADSBTheme.radarBlue) .padding(.horizontal, 10) .padding(.vertical, 6) @@ -1766,7 +1766,7 @@ private struct AirlineHeaderBadge: View { .fill(ADSBTheme.radarBlue.opacity(0.12)) .overlay( Text(String(airline.name.prefix(1))) - .font(.headline.bold()) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(ADSBTheme.radarBlue) ) } @@ -1778,11 +1778,11 @@ struct ErrorCard: View { var body: some View { VStack(spacing: 12) { Image(systemName: "exclamationmark.triangle.fill") - .font(.largeTitle) + .font(MacOS9Typography.windowTitle(26)) .foregroundStyle(.orange) Text(message) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(.primary) .multilineTextAlignment(.center) } @@ -1801,11 +1801,11 @@ struct TuyaSensorCard: View { HStack(alignment: .top, spacing: 12) { VStack(alignment: .leading, spacing: 4) { Text("Sensor Casa") - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) if let source = sensor.source, !source.isEmpty { Text(source.capitalized) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -1814,12 +1814,12 @@ struct TuyaSensorCard: View { VStack(alignment: .trailing, spacing: 2) { Text(lastUpdatedTimeText) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) if let date = sensor.lastUpdatedAt { Text(date.timeAgoDisplay()) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.tertiary) } } @@ -1934,13 +1934,13 @@ struct TuyaPrimaryMetricCard: View { var body: some View { VStack(alignment: .leading, spacing: 10) { Label(title, systemImage: icon) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(ADSBTheme.secondaryInk) .lineLimit(1) .minimumScaleFactor(0.75) Text(value) - .font(.system(size: 28, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(28)) .monospacedDigit() .foregroundStyle(color) } @@ -1957,7 +1957,7 @@ struct TuyaInfoPill: View { var body: some View { Label(text, systemImage: icon) - .font(.caption.weight(.medium)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) .padding(.horizontal, 10) .padding(.vertical, 8) @@ -1974,11 +1974,11 @@ struct TuyaSensorStatusCard: View { var body: some View { HStack(spacing: 10) { Image(systemName: "exclamationmark.circle.fill") - .font(.title3) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(.orange) Text(message) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(.secondary) .multilineTextAlignment(.leading) @@ -1997,7 +1997,7 @@ struct LoadingCard: View { .scaleEffect(1.2) Text("Carregando...") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(.secondary) } .padding(32) @@ -2256,7 +2256,7 @@ struct AircraftDetailView: View { image.resizable().aspectRatio(contentMode: .fit) case .failure, .empty: Image(systemName: "airplane.circle.fill") - .font(.system(size: 40)) + .font(MacOS9Typography.body(40)) .foregroundStyle(.blue.opacity(0.3)) @unknown default: EmptyView() @@ -2276,23 +2276,23 @@ struct AircraftDetailView: View { VStack(alignment: .leading, spacing: 4) { Text(ac.displayCallsign) - .font(.system(size: 30, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(30)) .lineLimit(1) if let airline = classifiedAirlineName ?? ac.airline { Text(airline) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(.blue) } if let faFlight { HStack(spacing: 6) { Text(faFlight.origin?.bestCode ?? "-") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) Image(systemName: "arrow.right") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Text(faFlight.destination?.bestCode ?? "-") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) } .foregroundStyle(.secondary) } @@ -2332,10 +2332,10 @@ struct AircraftDetailView: View { Label( "Classificar empresa aérea", systemImage: "building.2.crop.circle" ) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) Spacer() Image(systemName: "chevron.right") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } .padding(.vertical, 4) @@ -2347,7 +2347,7 @@ struct AircraftDetailView: View { ProgressView() .scaleEffect(0.85) Text("Carregando classificação...") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Spacer() } @@ -2355,7 +2355,7 @@ struct AircraftDetailView: View { if let message = classificationMessage { Text(message) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) .frame(maxWidth: .infinity, alignment: .leading) } @@ -2406,7 +2406,7 @@ struct AircraftDetailView: View { Image(systemName: "map.fill") Text("Ver no Mapa") } - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .frame(maxWidth: .infinity) .padding() .foregroundStyle(.primary) @@ -2425,7 +2425,7 @@ struct AircraftDetailView: View { VStack(alignment: .leading, spacing: 12) { HStack { Label("FlightAware", systemImage: "clock.badge.checkmark") - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) Spacer() if faLoading { ProgressView().scaleEffect(0.9) @@ -2438,16 +2438,16 @@ struct AircraftDetailView: View { HStack(spacing: 10) { Text(orig) - .font(.title3.bold()) + .font(MacOS9Typography.bodyBold(17)) .monospaced() Image(systemName: "arrow.right") .foregroundStyle(.secondary) Text(dest) - .font(.title3.bold()) + .font(MacOS9Typography.bodyBold(17)) .monospaced() Spacer() Text(faFlight.bestIdent) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(.secondary) .monospaced() } @@ -2457,7 +2457,7 @@ struct AircraftDetailView: View { HStack(spacing: 16) { VStack(alignment: .leading, spacing: 6) { Text("Saída") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Text( FlightAwareTime.short(faFlight.actualOut) @@ -2465,11 +2465,11 @@ struct AircraftDetailView: View { ?? FlightAwareTime.short(faFlight.scheduledOut) ?? "-" ) - .font(.headline.monospacedDigit()) + .font(MacOS9Typography.bodyBold(15)) Text( "T\(faFlight.terminalOrigin ?? "-") • G\(faFlight.gateOrigin ?? "-")" ) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } @@ -2477,7 +2477,7 @@ struct AircraftDetailView: View { VStack(alignment: .leading, spacing: 6) { Text("Chegada") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Text( FlightAwareTime.short(faFlight.actualIn) @@ -2485,11 +2485,11 @@ struct AircraftDetailView: View { ?? FlightAwareTime.short(faFlight.scheduledIn) ?? "-" ) - .font(.headline.monospacedDigit()) + .font(MacOS9Typography.bodyBold(15)) Text( "T\(faFlight.terminalDestination ?? "-") • G\(faFlight.gateDestination ?? "-")" ) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -2499,10 +2499,10 @@ struct AircraftDetailView: View { HStack(spacing: 16) { VStack(alignment: .leading, spacing: 6) { Text("Operadora") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Text(faFlight.operator ?? faFlight.operatorIcao ?? "-") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .lineLimit(1) } @@ -2510,21 +2510,21 @@ struct AircraftDetailView: View { VStack(alignment: .leading, spacing: 6) { Text("Status") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Text(flightAwareStatus(faFlight)) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(.primary) .lineLimit(1) } } } else if let faError { Text(faError) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } else { Text("Sem dados de horário/gate para este ident agora.") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -2701,7 +2701,7 @@ private struct AirlineClassificationSheet: View { .frame(width: 30, height: 30) } Text(aircraft.displayCallsign) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) Spacer() } } @@ -2744,7 +2744,7 @@ private struct AirlineClassificationSheet: View { } } label: { Text("Salvar") - .bold() + .font(MacOS9Typography.bodyBold(15)) .frame(maxWidth: .infinity) .padding() .background(selected != nil ? Color.blue : Color.gray.opacity(0.3)) @@ -2781,7 +2781,7 @@ struct AircraftRouteView: View { VStack(spacing: 8) { Image(systemName: "airplane") - .font(.title3) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(.blue) HStack(spacing: 4) { @@ -2812,7 +2812,7 @@ struct AircraftRouteView: View { HStack(spacing: 6) { Image(systemName: "airplane") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(.blue) ForEach(0..<8) { _ in Circle() @@ -2840,11 +2840,11 @@ struct AirportBlock_Legacy: View { var body: some View { VStack(alignment: alignment, spacing: 4) { Text(code) - .font(.system(size: 26, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(26)) .lineLimit(1) .minimumScaleFactor(0.85) Text(city) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) .multilineTextAlignment(alignment == .leading ? .leading : .trailing) .lineLimit(2) @@ -2886,7 +2886,7 @@ struct AircraftPhotoView: View { VStack(alignment: .trailing, spacing: 2) { if let photographer { Text("© \(photographer)") - .font(.system(size: 8)) + .font(MacOS9Typography.body(8)) .foregroundStyle(.white) .padding(.horizontal, 4) .padding(.vertical, 2) @@ -2896,7 +2896,7 @@ struct AircraftPhotoView: View { if let sourceName { Text(sourceName) - .font(.system(size: 8, weight: .bold)) + .font(MacOS9Typography.bodyBold(8)) .foregroundStyle(.white) .padding(.horizontal, 4) .padding(.vertical, 2) @@ -2921,10 +2921,10 @@ struct AircraftPhotoView: View { private var fallbackView: some View { VStack(spacing: 8) { Image(systemName: "photo.badge.exclamationmark") - .font(.largeTitle) + .font(MacOS9Typography.windowTitle(26)) .foregroundStyle(.secondary) Text("Erro ao carregar imagem") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } .frame(maxWidth: .infinity, maxHeight: .infinity) @@ -2933,10 +2933,10 @@ struct AircraftPhotoView: View { private var noPhotoView: some View { VStack(spacing: 8) { Image(systemName: "photo") - .font(.largeTitle) + .font(MacOS9Typography.windowTitle(26)) .foregroundStyle(.secondary) Text("Sem foto disponível") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } .frame(maxWidth: .infinity, maxHeight: .infinity) @@ -3081,7 +3081,7 @@ struct DetailRow_Legacy: View { .foregroundStyle(.secondary) Spacer() Text(value) - .bold() + .font(MacOS9Typography.bodyBold(13)) } } } diff --git a/MeuLabApp/Views/Tabs/BibleChapterReaderView.swift b/MeuLabApp/Views/Tabs/BibleChapterReaderView.swift index c8f83ff..c985dfa 100644 --- a/MeuLabApp/Views/Tabs/BibleChapterReaderView.swift +++ b/MeuLabApp/Views/Tabs/BibleChapterReaderView.swift @@ -54,11 +54,10 @@ struct BibleChapterReaderView: View { HStack { VStack(alignment: .leading, spacing: 2) { Text(viewModel.currentBook) - .font(.headline) - .fontWeight(.semibold) + .font(MacOS9Typography.bodyBold(15)) Text("Capítulo \(viewModel.currentChapterNumber)") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } @@ -66,12 +65,11 @@ struct BibleChapterReaderView: View { VStack(alignment: .trailing, spacing: 2) { Text("Versículos") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) Text("\(viewModel.highlightedVerseIndex + 1)/\(viewModel.verses.count)") - .font(.caption2) - .fontWeight(.semibold) + .font(MacOS9Typography.bodyBold(10)) } } } @@ -107,12 +105,11 @@ struct BibleChapterReaderView: View { VStack(alignment: .center, spacing: 4) { Text(viewModel.isPlaying ? "Lendo..." : viewModel.isPaused ? "Pausado" : "Parado") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Text("\(viewModel.highlightedVerseIndex + 1)/\(viewModel.verses.count)") - .font(.caption) - .fontWeight(.semibold) + .font(MacOS9Typography.bodyBold(11)) } } .padding() @@ -147,13 +144,12 @@ struct ReaderVerseRow: View { var body: some View { HStack(alignment: .top, spacing: 12) { Text("\(verseNumber)") - .font(.caption) - .fontWeight(.semibold) + .font(MacOS9Typography.bodyBold(11)) .foregroundStyle(.blue) .frame(width: 24, alignment: .center) Text(text) - .font(.body) + .font(MacOS9Typography.body(13)) .lineLimit(nil) .foregroundStyle(.primary) diff --git a/MeuLabApp/Views/Tabs/BibleNavigateView.swift b/MeuLabApp/Views/Tabs/BibleNavigateView.swift index c5e6f25..19c53d5 100644 --- a/MeuLabApp/Views/Tabs/BibleNavigateView.swift +++ b/MeuLabApp/Views/Tabs/BibleNavigateView.swift @@ -38,15 +38,15 @@ private struct TestamentSection: View { Button { isExpanded.toggle() } label: { - HStack { - Text(testament) - .font(MacOS9Typography.editorialBold(22)) + HStack { + Text(testament) + .font(MacOS9Typography.windowTitle(18)) .foregroundStyle(MacOS9Colors.selection) Spacer() Image(systemName: isExpanded ? "chevron.up" : "chevron.down") - .font(.system(size: 12, weight: .bold)) + .font(MacOS9Typography.bodyBold(12)) .foregroundStyle(MacOS9Colors.secondaryText) } .padding(.horizontal, 8) @@ -264,13 +264,13 @@ struct VerseRow: View { var body: some View { HStack(alignment: .top, spacing: 10) { Text("\(verse.number)") - .font(.system(size: fontSize * 0.72, weight: .bold)) + .font(MacOS9Typography.bodyBold(fontSize * 0.72)) .foregroundStyle(Color.amber) .frame(minWidth: 24, alignment: .trailing) .padding(.top, 3) Text(verse.text) - .font(.system(size: fontSize)) + .font(MacOS9Typography.body(fontSize)) .foregroundStyle(.primary) .lineSpacing(4) .frame(maxWidth: .infinity, alignment: .leading) @@ -296,7 +296,7 @@ struct VerseRowWithReader: View { .padding(.top, 3) Text(verse.text) - .font(.system(size: fontSize)) + .font(MacOS9Typography.body(fontSize)) .foregroundStyle(isHighlighted ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .lineSpacing(4) .frame(maxWidth: .infinity, alignment: .leading) @@ -342,7 +342,7 @@ struct PlaybackControlBar: View { Image( systemName: viewModel.isPlaying ? "pause.circle.fill" : "play.circle.fill" ) - .font(.system(size: 34)) + .font(MacOS9Typography.body(34)) .frame(width: 42, height: 36) .background(MacOS9Colors.contentPanel) .foregroundStyle(MacOS9Colors.statusBlue) diff --git a/MeuLabApp/Views/Tabs/BibleRandomView.swift b/MeuLabApp/Views/Tabs/BibleRandomView.swift index b15e319..5827fb4 100644 --- a/MeuLabApp/Views/Tabs/BibleRandomView.swift +++ b/MeuLabApp/Views/Tabs/BibleRandomView.swift @@ -51,7 +51,7 @@ struct BibleRandomView: View { private var inspireText: some View { VStack(spacing: 8) { Image(systemName: "book.closed") - .font(.system(size: 40)) + .font(MacOS9Typography.body(40)) .foregroundStyle(MacOS9Colors.statusOrange) Text("Deixe a Palavra falar ao seu coração") @@ -99,7 +99,7 @@ private struct RandomVerseCard: View { } Text(verse.text) - .font(MacOS9Typography.editorialHeading(23)) + .font(MacOS9Typography.windowTitle(23)) .foregroundStyle(MacOS9Colors.primaryText) .lineSpacing(6) .multilineTextAlignment(.leading) diff --git a/MeuLabApp/Views/Tabs/BibleSearchView.swift b/MeuLabApp/Views/Tabs/BibleSearchView.swift index 3119cf7..0e9c17c 100644 --- a/MeuLabApp/Views/Tabs/BibleSearchView.swift +++ b/MeuLabApp/Views/Tabs/BibleSearchView.swift @@ -59,7 +59,7 @@ struct BibleSearchView: View { private var searchPrompt: some View { VStack(spacing: 12) { Image(systemName: "text.magnifyingglass") - .font(.system(size: 36)) + .font(MacOS9Typography.body(36)) .foregroundStyle(MacOS9Colors.statusOrange) Text("Digite pelo menos 3 caracteres para buscar versículos.") .font(MacOS9Typography.body(14)) @@ -74,7 +74,7 @@ struct BibleSearchView: View { private var noResultsView: some View { VStack(spacing: 12) { Image(systemName: "doc.text.magnifyingglass") - .font(.system(size: 36)) + .font(MacOS9Typography.body(36)) .foregroundStyle(MacOS9Colors.secondaryText) Text("Nenhum versículo encontrado para \"\(query)\".") .font(MacOS9Typography.body(14)) diff --git a/MeuLabApp/Views/Tabs/BibleView.swift b/MeuLabApp/Views/Tabs/BibleView.swift index 94657e9..4356b37 100644 --- a/MeuLabApp/Views/Tabs/BibleView.swift +++ b/MeuLabApp/Views/Tabs/BibleView.swift @@ -113,7 +113,7 @@ private struct BibleHeader: View { var body: some View { HStack(spacing: 12) { Image(systemName: "book.closed") - .font(.system(size: 22, weight: .semibold)) + .font(MacOS9Typography.bodyBold(22)) .frame(width: 40, height: 40) .background(MacOS9Colors.contentPanel) .overlay(Mac9BevelBorder(isRaised: true)) @@ -121,7 +121,7 @@ private struct BibleHeader: View { VStack(alignment: .leading, spacing: 2) { Text("A Bíblia") - .font(MacOS9Typography.editorialTitle(28)) + .font(MacOS9Typography.windowTitle(20)) .foregroundStyle(MacOS9Colors.primaryText) Text(subtitle) .font(MacOS9Typography.caption(12)) diff --git a/MeuLabApp/Views/Tabs/WeatherView.swift b/MeuLabApp/Views/Tabs/WeatherView.swift index c352e83..1ca7288 100644 --- a/MeuLabApp/Views/Tabs/WeatherView.swift +++ b/MeuLabApp/Views/Tabs/WeatherView.swift @@ -268,20 +268,13 @@ private struct WeatherToolbarTitle: View { .frame(width: compact ? 24 : 28, height: compact ? 24 : 28) Image(systemName: "cloud.sun.fill") - .font(.system(size: compact ? 12 : 14, weight: .bold)) + .font(MacOS9Typography.bodyBold(compact ? 12 : 14)) .foregroundStyle(WeatherTheme.skyBlue) } Text("Clima") - .font(.system(size: compact ? 20 : 23, weight: .black, design: .rounded)) - .tracking(0.4) - .foregroundStyle( - LinearGradient( - colors: [WeatherTheme.sunAmber, WeatherTheme.skyBlue], - startPoint: .leading, - endPoint: .trailing - ) - ) + .font(MacOS9Typography.windowTitle(compact ? 16 : 18)) + .foregroundStyle(MacOS9Colors.primaryText) } .frame(maxWidth: compact ? .infinity : nil, alignment: .leading) .accessibilityElement(children: .combine) @@ -299,16 +292,16 @@ private struct WeatherMetricTile: View { VStack(alignment: .leading, spacing: 8) { HStack(spacing: 8) { Image(systemName: icon) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) Text(title) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) } Text(value) - .font(.headline.weight(.bold)) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(WeatherTheme.ink) .monospacedDigit() .lineLimit(2) @@ -329,14 +322,14 @@ private struct WeatherDayChip: View { VStack(alignment: .leading, spacing: 10) { HStack { Text(day.title) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle( isSelected ? Color.white.opacity(0.88) : WeatherTheme.ink.opacity(0.62)) Spacer() Image(systemName: day.icon) - .font(.subheadline.weight(.bold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle( isSelected ? .white @@ -344,18 +337,18 @@ private struct WeatherDayChip: View { } Text(day.maxTempLabel) - .font(.title3.weight(.bold)) + .font(MacOS9Typography.bodyBold(18)) .monospacedDigit() .foregroundStyle(isSelected ? .white : WeatherTheme.ink) HStack(spacing: 8) { Label("\(day.rainChance)%", systemImage: "drop.fill") - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle( isSelected ? Color.white.opacity(0.9) : WeatherTheme.ink.opacity(0.56)) Text(day.shortDate) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle( isSelected ? Color.white.opacity(0.74) : WeatherTheme.ink.opacity(0.50)) } @@ -403,23 +396,23 @@ private struct WeatherInsightCard: View { .frame(width: 34, height: 34) Image(systemName: icon) - .font(.body.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(tint) } VStack(alignment: .leading, spacing: 2) { Text(title) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(WeatherTheme.ink) Text(highlightCaption) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) } } Text(highlight) - .font(.system(size: 30, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(30)) .foregroundStyle(tint) .monospacedDigit() @@ -427,13 +420,13 @@ private struct WeatherInsightCard: View { ForEach(Array(rows.enumerated()), id: \.offset) { _, row in HStack(spacing: 12) { Text(row.0) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.54)) Spacer() Text(row.1) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink) .multilineTextAlignment(.trailing) } @@ -453,26 +446,26 @@ private struct HourlyForecastCell: View { var body: some View { VStack(spacing: 10) { Text(hour.timeLabel) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.54)) Image(systemName: hour.weatherIcon) - .font(.title3.weight(.semibold)) + .font(MacOS9Typography.bodyBold(17)) .foregroundStyle(hour.rainChance >= 45 ? WeatherTheme.rainBlue : tint) Text("\(hour.tempC)°") - .font(.headline.weight(.bold)) + .font(MacOS9Typography.bodyBold(15)) .monospacedDigit() .foregroundStyle(WeatherTheme.ink) VStack(spacing: 4) { Text("\(hour.rainChance)%") - .font(.caption2.weight(.bold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(WeatherTheme.rainBlue) .monospacedDigit() Text("\(hour.rainMm.formattedBR(decimals: 1)) mm") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(WeatherTheme.ink.opacity(0.54)) .monospacedDigit() } @@ -491,7 +484,7 @@ private struct WeatherForecastRow: View { var body: some View { HStack(spacing: 14) { Image(systemName: day.icon) - .font(.title3.weight(.semibold)) + .font(MacOS9Typography.bodyBold(17)) .foregroundStyle( day.rainChance >= 45 ? WeatherTheme.rainBlue : WeatherTheme.sunAmber ) @@ -499,11 +492,11 @@ private struct WeatherForecastRow: View { VStack(alignment: .leading, spacing: 4) { Text(day.rowTitle) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(WeatherTheme.ink) Text(day.description) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) .lineLimit(1) } @@ -513,11 +506,11 @@ private struct WeatherForecastRow: View { VStack(alignment: .trailing, spacing: 4) { HStack(spacing: 8) { Label("\(day.rainChance)%", systemImage: "drop.fill") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.rainBlue) Text("\(day.rainMm.formattedBR(decimals: 1)) mm") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.54)) .monospacedDigit() } @@ -532,14 +525,14 @@ private struct WeatherForecastRow: View { Text(day.maxTempLabel) .foregroundStyle(Color.red.opacity(0.82)) } - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .monospacedDigit() } if isSelected { Image(systemName: "checkmark.circle.fill") .foregroundStyle(WeatherTheme.mint) - .font(.body.weight(.bold)) + .font(MacOS9Typography.bodyBold(13)) } } .padding(.vertical, 10) @@ -719,7 +712,7 @@ struct WeatherView: View { Task { await appState.refreshWeather() } } label: { Image(systemName: "arrow.clockwise") - .font(.system(size: 17, weight: .semibold)) + .font(MacOS9Typography.bodyBold(17)) .foregroundStyle(WeatherTheme.skyBlue) .padding(8) .background( @@ -767,19 +760,19 @@ struct WeatherView: View { .controlSize(.regular) Text("Carregando clima...") - .font(.headline.weight(.medium)) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(WeatherTheme.ink.opacity(0.72)) } else { Image(systemName: "cloud.sun") - .font(.system(size: 24, weight: .semibold)) + .font(MacOS9Typography.bodyBold(24)) .foregroundStyle(WeatherTheme.skyBlue) Text("Atualize a previsão") - .font(.headline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(WeatherTheme.ink) Text("Se o clima não entrou sozinho, toque para buscar a leitura agora.") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(WeatherTheme.ink.opacity(0.65)) .multilineTextAlignment(.center) @@ -787,7 +780,7 @@ struct WeatherView: View { Task { await appState.refreshWeather() } } label: { Label("Buscar agora", systemImage: "arrow.clockwise") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(WeatherTheme.skyBlue) .padding(.horizontal, 14) .padding(.vertical, 10) @@ -852,11 +845,11 @@ struct WeatherView: View { VStack(alignment: .leading, spacing: 8) { HStack(spacing: 10) { Label("Condição atual", systemImage: "cloud.sun.fill") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(WeatherTheme.ink.opacity(0.82)) Text(styleBadgeTitle(for: style)) - .font(.system(size: 10, weight: .black, design: .rounded)) + .font(MacOS9Typography.bodyBold(10)) .tracking(1) .foregroundStyle(style.accent) .padding(.horizontal, 10) @@ -869,7 +862,7 @@ struct WeatherView: View { .foregroundStyle(WeatherTheme.skyBlue) Text(weather.location) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(WeatherTheme.ink) } .onTapGesture { @@ -879,7 +872,7 @@ struct WeatherView: View { } Text(updatedWeatherText(weather.timestamp)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) } @@ -889,7 +882,7 @@ struct WeatherView: View { Button("Usar minha localização") { LocationManager.shared.requestPermission() } - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(WeatherTheme.skyBlue) .padding(.horizontal, 14) .padding(.vertical, 10) @@ -902,20 +895,20 @@ struct WeatherView: View { VStack(alignment: .leading, spacing: 8) { HStack(alignment: .top, spacing: 6) { Text("\(weather.current.tempC)") - .font(.system(size: 78, weight: .thin, design: .rounded)) + .font(MacOS9Typography.body(72)) .foregroundStyle(WeatherTheme.ink) Text("°C") - .font(.title.weight(.medium)) + .font(MacOS9Typography.bodyBold(28)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) } Text(weather.current.description) - .font(.title3.weight(.semibold)) + .font(MacOS9Typography.bodyBold(22)) .foregroundStyle(WeatherTheme.ink) Text(heroSummary(for: weather.current)) - .font(.subheadline) + .font(MacOS9Typography.body(15)) .foregroundStyle(WeatherTheme.ink.opacity(0.62)) } @@ -931,7 +924,7 @@ struct WeatherView: View { .frame(width: 96, height: 96) Image(systemName: currentWeatherIcon(for: weather.current)) - .font(.system(size: 36, weight: .semibold)) + .font(MacOS9Typography.bodyBold(36)) .foregroundStyle(style.accent) } } @@ -1051,15 +1044,15 @@ struct WeatherView: View { HStack(alignment: .top, spacing: 16) { VStack(alignment: .leading, spacing: 6) { Text(day.rowTitle) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) Text(day.title) - .font(.system(size: 34, weight: .black, design: .rounded)) + .font(MacOS9Typography.bodyBold(34)) .foregroundStyle(WeatherTheme.ink) Text(day.description) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(WeatherTheme.ink.opacity(0.62)) } @@ -1071,7 +1064,7 @@ struct WeatherView: View { .frame(width: 72, height: 72) Image(systemName: day.icon) - .font(.system(size: 28, weight: .semibold)) + .font(MacOS9Typography.bodyBold(28)) .foregroundStyle(tint) } } @@ -1217,7 +1210,7 @@ struct WeatherView: View { Text( "Esse dia ainda não tem previsão horária detalhada disponível. A leitura acima usa os dados diários consolidados." ) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(WeatherTheme.ink.opacity(0.62)) .padding(18) .frame(maxWidth: .infinity, alignment: .leading) @@ -1277,17 +1270,17 @@ struct WeatherView: View { .frame(width: 38, height: 38) Image(systemName: icon) - .font(.body.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(WeatherTheme.skyBlue) } VStack(alignment: .leading, spacing: 2) { Text(title) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(WeatherTheme.ink) Text(subtitle) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(WeatherTheme.ink.opacity(0.56)) } } From 9c9ad64d95cedd745492c8caca8b7c4286d074c7 Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sun, 24 May 2026 14:29:49 -0300 Subject: [PATCH 09/10] Polish Mac OS 9 layout for system and menu views --- MeuLabApp/ContentView.swift | 45 ++- MeuLabApp/Views/Tabs/BibleNavigateView.swift | 24 +- MeuLabApp/Views/Tabs/BibleView.swift | 22 +- MeuLabApp/Views/Tabs/SystemView.swift | 396 ++++++++----------- 4 files changed, 224 insertions(+), 263 deletions(-) diff --git a/MeuLabApp/ContentView.swift b/MeuLabApp/ContentView.swift index d44e2f5..7db5299 100644 --- a/MeuLabApp/ContentView.swift +++ b/MeuLabApp/ContentView.swift @@ -273,28 +273,49 @@ private struct MoreMenuView: View { let select: (ContentView.Tab) -> Void var body: some View { - NavigationStack { + VStack(spacing: 10) { + HStack(spacing: 10) { + Image(systemName: "ellipsis") + .font(MacOS9Typography.bodyBold(16)) + .frame(width: 28, height: 28) + .background(MacOS9Colors.labelBadge) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + + Text("Mais") + .font(MacOS9Typography.windowTitle(18)) + .foregroundStyle(MacOS9Colors.primaryText) + + Spacer() + } + .padding(10) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) + .padding(.horizontal, 14) + .padding(.top, 10) + ScrollView { VStack(spacing: 0) { ForEach(tabs, id: \.self) { tab in Button { select(tab) } label: { - HStack(spacing: 14) { + HStack(spacing: 10) { Image(systemName: tab.icon) - .font(MacOS9Typography.bodyBold(20)) - .frame(width: 28) + .font(MacOS9Typography.bodyBold(15)) + .frame(width: 22) .foregroundStyle(MacOS9Colors.selection) Text(tab.title) - .font(MacOS9Typography.body(18)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(MacOS9Colors.primaryText) Spacer() Image(systemName: "chevron.right") - .font(MacOS9Typography.bodyBold(14)) + .font(MacOS9Typography.bodyBold(11)) .foregroundStyle(MacOS9Colors.secondaryText) } - .padding(.horizontal, 16) - .padding(.vertical, 14) + .padding(.horizontal, 12) + .frame(height: 46) .background(MacOS9Colors.contentPanel) } .buttonStyle(.plain) @@ -302,15 +323,15 @@ private struct MoreMenuView: View { Rectangle() .fill(MacOS9Colors.border.opacity(0.2)) .frame(height: 1) - .padding(.leading, 58) + .padding(.leading, 44) } } .mac9Panel() - .padding(16) + .padding(.horizontal, 14) + .padding(.bottom, 12) } - .background(MacOS9Colors.windowBackground.ignoresSafeArea()) - .navigationTitle("Mais") } + .background(MacOS9Colors.windowBackground.ignoresSafeArea()) } } diff --git a/MeuLabApp/Views/Tabs/BibleNavigateView.swift b/MeuLabApp/Views/Tabs/BibleNavigateView.swift index 19c53d5..7da771f 100644 --- a/MeuLabApp/Views/Tabs/BibleNavigateView.swift +++ b/MeuLabApp/Views/Tabs/BibleNavigateView.swift @@ -8,14 +8,14 @@ struct BibleNavigateView: View { var body: some View { ScrollView { - LazyVStack(spacing: 14) { + LazyVStack(spacing: 10) { ForEach([BibleBook.Testament.old, .new], id: \.self) { testament in let books = BibleCatalogue.books.filter { $0.testament == testament } TestamentSection(testament: testament.rawValue, books: books) } } - .padding(.horizontal, 16) - .padding(.vertical, 12) + .padding(.horizontal, 12) + .padding(.vertical, 10) .padding(.bottom, 92) } .background(MacOS9Colors.windowBackground) @@ -34,13 +34,13 @@ private struct TestamentSection: View { @State private var isExpanded = true var body: some View { - VStack(alignment: .leading, spacing: 10) { + VStack(alignment: .leading, spacing: 8) { Button { isExpanded.toggle() } label: { HStack { Text(testament) - .font(MacOS9Typography.windowTitle(18)) + .font(MacOS9Typography.windowTitle(16)) .foregroundStyle(MacOS9Colors.selection) Spacer() @@ -50,7 +50,7 @@ private struct TestamentSection: View { .foregroundStyle(MacOS9Colors.secondaryText) } .padding(.horizontal, 8) - .padding(.vertical, 7) + .frame(height: 36) .background(MacOS9Colors.labelBadge) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } @@ -58,7 +58,7 @@ private struct TestamentSection: View { if isExpanded { LazyVGrid( - columns: [GridItem(.adaptive(minimum: 118, maximum: 170), spacing: 8)], + columns: [GridItem(.adaptive(minimum: 108, maximum: 160), spacing: 8)], spacing: 8 ) { ForEach(books) { book in @@ -70,7 +70,7 @@ private struct TestamentSection: View { } } } - .padding(10) + .padding(8) .background(MacOS9Colors.panelBackground) .overlay(Mac9BevelBorder(isRaised: true)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) @@ -85,19 +85,19 @@ private struct BookCard: View { var body: some View { VStack(spacing: 4) { Text(book.name) - .font(MacOS9Typography.bodyBold(15)) + .font(MacOS9Typography.bodyBold(13)) .multilineTextAlignment(.center) .foregroundStyle(MacOS9Colors.primaryText) .minimumScaleFactor(0.75) .lineLimit(2) Text("\(book.chapterCount) cap.") - .font(MacOS9Typography.caption(11)) + .font(MacOS9Typography.caption(10)) .foregroundStyle(MacOS9Colors.secondaryText) } .frame(maxWidth: .infinity) - .frame(minHeight: 58) - .padding(.horizontal, 6) + .frame(minHeight: 46) + .padding(.horizontal, 5) .background(MacOS9Colors.contentPanel) .overlay(Mac9BevelBorder(isRaised: true)) .overlay(Rectangle().strokeBorder(MacOS9Colors.statusOrange.opacity(0.75), lineWidth: 1)) diff --git a/MeuLabApp/Views/Tabs/BibleView.swift b/MeuLabApp/Views/Tabs/BibleView.swift index 4356b37..cd1a4de 100644 --- a/MeuLabApp/Views/Tabs/BibleView.swift +++ b/MeuLabApp/Views/Tabs/BibleView.swift @@ -28,13 +28,13 @@ struct BibleView: View { VStack(spacing: 0) { BibleHeader(selectedTab: selectedTab) - .padding(.horizontal, 16) - .padding(.top, 10) - .padding(.bottom, 8) + .padding(.horizontal, 12) + .padding(.top, 8) + .padding(.bottom, 6) bibleTabPicker - .padding(.horizontal, 16) - .padding(.bottom, 10) + .padding(.horizontal, 12) + .padding(.bottom, 8) Rectangle() .fill(MacOS9Colors.border) @@ -84,7 +84,7 @@ struct BibleView: View { selectedTab == tab ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .frame(maxWidth: .infinity) - .frame(height: 44) + .frame(height: 38) .background(selectedTab == tab ? MacOS9Colors.selection : MacOS9Colors.panelBackground) .overlay(Mac9BevelBorder(isRaised: selectedTab != tab)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) @@ -113,24 +113,24 @@ private struct BibleHeader: View { var body: some View { HStack(spacing: 12) { Image(systemName: "book.closed") - .font(MacOS9Typography.bodyBold(22)) - .frame(width: 40, height: 40) + .font(MacOS9Typography.bodyBold(18)) + .frame(width: 34, height: 34) .background(MacOS9Colors.contentPanel) .overlay(Mac9BevelBorder(isRaised: true)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) VStack(alignment: .leading, spacing: 2) { Text("A Bíblia") - .font(MacOS9Typography.windowTitle(20)) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(MacOS9Colors.primaryText) Text(subtitle) - .font(MacOS9Typography.caption(12)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(MacOS9Colors.secondaryText) } Spacer() } - .padding(12) + .padding(9) .background(MacOS9Colors.panelBackground) .overlay(Mac9BevelBorder(isRaised: true)) .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) diff --git a/MeuLabApp/Views/Tabs/SystemView.swift b/MeuLabApp/Views/Tabs/SystemView.swift index 8abe53c..deaba76 100644 --- a/MeuLabApp/Views/Tabs/SystemView.swift +++ b/MeuLabApp/Views/Tabs/SystemView.swift @@ -163,35 +163,18 @@ private struct RaspberryPiGlyph: View { private struct SystemToolbarTitle: View { var body: some View { - HStack(spacing: 10) { - ZStack { - Circle() - .fill( - LinearGradient( - colors: [ - SystemTheme.piGreen.opacity(0.2), SystemTheme.piBlue.opacity(0.12), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .frame(width: 28, height: 28) - - Image(systemName: "cpu") - .font(.system(size: 14, weight: .bold)) - .foregroundStyle(SystemTheme.piBlue) - } + HStack(spacing: 8) { + Image(systemName: "cpu") + .font(MacOS9Typography.bodyBold(13)) + .foregroundStyle(MacOS9Colors.selection) + .frame(width: 24, height: 24) + .background(MacOS9Colors.labelBadge) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) Text("Sistema") - .font(.system(size: 23, weight: .black, design: .rounded)) - .tracking(0.5) - .foregroundStyle( - LinearGradient( - colors: [SystemTheme.piLeaf, SystemTheme.piBlue], - startPoint: .leading, - endPoint: .trailing - ) - ) + .font(MacOS9Typography.windowTitle(18)) + .foregroundStyle(MacOS9Colors.primaryText) } .accessibilityElement(children: .combine) .accessibilityLabel("Sistema") @@ -208,7 +191,7 @@ private struct SystemInfoChip: View { var body: some View { VStack(alignment: .leading, spacing: 4) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(SystemTheme.ink.opacity(0.56)) HStack(spacing: 6) { @@ -216,26 +199,21 @@ private struct SystemInfoChip: View { RaspberryPiGlyph(size: 16) } else if let icon { Image(systemName: icon) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) } Text(value) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.bodyBold(12)) .foregroundStyle(SystemTheme.ink) .lineLimit(1) } } - .padding(.horizontal, 12) - .padding(.vertical, 9) - .background( - Capsule() - .fill(tint.opacity(0.10)) - ) - .overlay( - Capsule() - .stroke(tint.opacity(0.18), lineWidth: 1) - ) + .padding(.horizontal, 10) + .padding(.vertical, 7) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -248,16 +226,16 @@ private struct SystemQuickMetric: View { var body: some View { HStack(spacing: 6) { Image(systemName: icon) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) Text(value) - .font(.callout.bold()) + .font(MacOS9Typography.bodyBold(13)) .monospacedDigit() .foregroundStyle(SystemTheme.ink) Text(label) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink.opacity(0.56)) } } @@ -353,23 +331,23 @@ private struct SystemAnalyticsLaunchTile: View { .frame(width: 34, height: 34) Image(systemName: destination.icon) - .font(.system(size: 14, weight: .semibold)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(destination.tint) } Spacer() Image(systemName: "arrow.up.right") - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(destination.tint.opacity(0.82)) } Text(destination.title) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(SystemTheme.ink) Text(destination.subtitle) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink.opacity(0.58)) .lineLimit(2) } @@ -514,14 +492,14 @@ struct SystemView: View { let l15 = cpu.load15min { Text("Load Avg") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Text(String(format: "%.2f %.2f %.2f", l1, l5, l15)) - .font(.callout.monospacedDigit()) + .font(MacOS9Typography.body(13)) } Text("\(cpu.cores ?? 4) cores") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -549,15 +527,15 @@ struct SystemView: View { let l15 = cpu.load15min { Text("Load Avg") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Text(String(format: "%.2f %.2f %.2f", l1, l5, l15)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() } Text("\(cpu.cores ?? 4) Cores") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) .padding(.top, 2) } @@ -578,10 +556,10 @@ struct SystemView: View { ProgressView(value: Double(used), total: Double(total)) { HStack { Text("\(used) MB usado") - .font(.caption) + .font(MacOS9Typography.caption(11)) Spacer() Text(String(format: "%.1f%%", memory.usedPercent ?? 0)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() } } @@ -592,7 +570,7 @@ struct SystemView: View { Spacer() Label("\(available) MB livre", systemImage: "checkmark.circle") } - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -609,10 +587,10 @@ struct SystemView: View { ProgressView(value: used, total: total) { HStack { Text(String(format: "%.1f GB usado", used)) - .font(.caption) + .font(MacOS9Typography.caption(11)) Spacer() Text(String(format: "%.1f%%", disk.usedPercent ?? 0)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() } } @@ -627,7 +605,7 @@ struct SystemView: View { String(format: "%.1f GB livre", available), systemImage: "checkmark.circle") } - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -641,8 +619,8 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 4) { if let ssid = wifi.ssid { Text(ssid) - .font(.subheadline) - .fontWeight(.medium) + .font(MacOS9Typography.body(13)) + } if let signal = wifi.signalDbm { @@ -650,7 +628,7 @@ struct SystemView: View { Image(systemName: "antenna.radiowaves.left.and.right") Text("\(signal) dBm") } - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) .monospacedDigit() } @@ -676,7 +654,7 @@ struct SystemView: View { SystemCard(title: "TVs (Fire Stick)", icon: "tv", color: .red) { if let err = appState.firestickError, appState.firestickDeviceStatuses.isEmpty { Text(err) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } else { VStack(spacing: 10) { @@ -695,7 +673,7 @@ struct SystemView: View { id: item.device.id, name: item.device.name) } label: { Image(systemName: "camera") - .font(.system(size: 16, weight: .semibold)) + .font(MacOS9Typography.bodyBold(16)) } .adaptiveGlassButton() } @@ -713,13 +691,13 @@ struct SystemView: View { ForEach(appState.processes.prefix(5)) { process in HStack { Text(process.command) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .lineLimit(1) Spacer() Text(String(format: "%.1f%%", process.cpuPercent)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() .foregroundStyle(.secondary) } @@ -737,11 +715,11 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 4) { HStack { Text(partition.mount) - .font(.subheadline) - .fontWeight(.medium) + .font(MacOS9Typography.body(13)) + Spacer() Text(partition.usedPercent) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } ProgressView( @@ -753,7 +731,7 @@ struct SystemView: View { Text( "\(formatBytes(partition.usedBytes)) / \(formatBytes(partition.totalBytes))" ) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) } } @@ -768,13 +746,13 @@ struct SystemView: View { ForEach(appState.networkInterfaces) { iface in HStack { Text(iface.iface) - .font(.subheadline) + .font(MacOS9Typography.body(13)) Spacer() VStack(alignment: .trailing, spacing: 2) { Text("RX \(formatBytes(iface.rxBytes))") Text("TX \(formatBytes(iface.txBytes))") } - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) } Divider() @@ -799,40 +777,29 @@ struct SystemView: View { HStack(spacing: 0) { ForEach(SystemNode.allCases) { node in Button { - withAnimation(.easeInOut(duration: 0.25)) { - selectedNode = node - } + selectedNode = node } label: { HStack(spacing: 8) { Image(systemName: node.icon) - .font(.system(size: 13, weight: .bold)) + .font(MacOS9Typography.bodyBold(13)) Text(node.label) - .font(.subheadline.weight(.bold)) + .font(MacOS9Typography.bodyBold(13)) } - .foregroundStyle(selectedNode == node ? .white : SystemTheme.ink.opacity(0.6)) + .foregroundStyle(selectedNode == node ? MacOS9Colors.selectedText : MacOS9Colors.primaryText) .frame(maxWidth: .infinity) - .padding(.vertical, 10) - .background { - if selectedNode == node { - Capsule() - .fill(node.tint) - .shadow(color: node.tint.opacity(0.3), radius: 8, y: 2) - } - } + .frame(height: 40) + .background(selectedNode == node ? MacOS9Colors.selection : MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: selectedNode != node)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } .buttonStyle(.plain) } } .padding(4) - .background( - Capsule() - .fill(Color(.secondarySystemGroupedBackground)) - ) - .overlay( - Capsule() - .strokeBorder(Color.white.opacity(0.08), lineWidth: 1) - ) + .background(MacOS9Colors.panelBackground) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } // MARK: - Mac Mini Content @@ -869,14 +836,14 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 6) { if let l1 = cpu.load1min, let l5 = cpu.load5min, let l15 = cpu.load15min { Text("Load Avg") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) Text(String(format: "%.2f %.2f %.2f", l1, l5, l15)) - .font(.callout.monospacedDigit()) + .font(MacOS9Typography.body(13)) } Text("\(cpu.cores ?? 8) cores") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -893,10 +860,10 @@ struct SystemView: View { ProgressView(value: Double(used), total: Double(total)) { HStack { Text("\(used) MB usado") - .font(.caption) + .font(MacOS9Typography.caption(11)) Spacer() Text(String(format: "%.1f%%", memory.usedPercent ?? 0)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() } } @@ -907,7 +874,7 @@ struct SystemView: View { Spacer() Label("\(available) MB livre", systemImage: "checkmark.circle") } - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -924,10 +891,10 @@ struct SystemView: View { ProgressView(value: used, total: total) { HStack { Text(String(format: "%.1f GB usado", used)) - .font(.caption) + .font(MacOS9Typography.caption(11)) Spacer() Text(String(format: "%.1f%%", disk.usedPercent ?? 0)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() } } @@ -942,7 +909,7 @@ struct SystemView: View { String(format: "%.1f GB livre", available), systemImage: "checkmark.circle") } - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -956,11 +923,11 @@ struct SystemView: View { ForEach(appState.macMiniProcesses.prefix(5)) { process in HStack { Text(process.command) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .lineLimit(1) Spacer() Text(String(format: "%.1f%%", process.cpuPercent)) - .font(.caption) + .font(MacOS9Typography.caption(11)) .monospacedDigit() .foregroundStyle(.secondary) } @@ -978,11 +945,11 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 4) { HStack { Text(partition.mount) - .font(.subheadline) - .fontWeight(.medium) + .font(MacOS9Typography.body(13)) + Spacer() Text(partition.usedPercent) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } ProgressView( @@ -994,7 +961,7 @@ struct SystemView: View { Text( "\(formatBytes(partition.usedBytes)) / \(formatBytes(partition.totalBytes))" ) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) } } @@ -1013,13 +980,13 @@ struct SystemView: View { ForEach(activeInterfaces) { iface in HStack { Text(iface.iface) - .font(.subheadline) + .font(MacOS9Typography.body(13)) Spacer() VStack(alignment: .trailing, spacing: 2) { Text("RX \(formatBytes(iface.rxBytes))") Text("TX \(formatBytes(iface.txBytes))") } - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) } Divider() @@ -1036,11 +1003,11 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 10) { HStack(spacing: 10) { Label("Nó monitorado", systemImage: "desktopcomputer") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(SystemTheme.ink.opacity(0.82)) Text("ONLINE") - .font(.system(size: 10, weight: .black, design: .rounded)) + .font(MacOS9Typography.bodyBold(10)) .tracking(1.0) .foregroundStyle(SystemTheme.piBlue) .padding(.horizontal, 10) @@ -1050,16 +1017,16 @@ struct SystemView: View { HStack(spacing: 10) { Image(systemName: "desktopcomputer") - .font(.system(size: 22, weight: .semibold)) + .font(MacOS9Typography.bodyBold(22)) .foregroundStyle(SystemTheme.piBlue) VStack(alignment: .leading, spacing: 2) { Text("Mac Mini") - .font(.system(size: 28, weight: .black, design: .rounded)) + .font(MacOS9Typography.bodyBold(28)) .foregroundStyle(SystemTheme.ink) Text(status.location) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) } } @@ -1086,19 +1053,19 @@ struct SystemView: View { .frame(width: 64, height: 64) Image(systemName: "desktopcomputer") - .font(.system(size: 26, weight: .semibold)) + .font(MacOS9Typography.bodyBold(26)) .foregroundStyle(SystemTheme.piBlue) } Text(statusUpdateText(status)) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) .multilineTextAlignment(.trailing) } } Text("Telemetria ao vivo do Mac Mini e seus serviços.") - .font(.callout) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) ScrollView(.horizontal, showsIndicators: false) { @@ -1144,11 +1111,11 @@ struct SystemView: View { HStack(alignment: .firstTextBaseline) { VStack(alignment: .leading, spacing: 4) { Text("CPU") - .font(.title3.weight(.bold)) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(SystemTheme.ink) Text("Histórico das últimas 24 horas") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.58)) } @@ -1159,7 +1126,7 @@ struct SystemView: View { format: "%.1f%% agora", cpuMetrics.dataPoints.last?.usage ?? cpuMetrics.average) ) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(SystemTheme.piBlue) .monospacedDigit() } @@ -1194,71 +1161,43 @@ struct SystemView: View { private func systemNodeBar(_ status: SystemStatus) -> some View { Group { if isCompactLayout { - VStack(alignment: .leading, spacing: 16) { - HStack(alignment: .top) { - VStack(alignment: .leading, spacing: 10) { - HStack(spacing: 10) { - Label("Nó monitorado", systemImage: "desktopcomputer") - .font(.subheadline.weight(.semibold)) - .foregroundStyle(SystemTheme.ink.opacity(0.82)) - - Text("ONLINE") - .font(.system(size: 10, weight: .black, design: .rounded)) - .tracking(1.0) - .foregroundStyle(SystemTheme.piGreen) - .padding(.horizontal, 10) - .padding(.vertical, 5) - .background(SystemTheme.piGreen.opacity(0.14), in: Capsule()) - } - - HStack(spacing: 10) { - RaspberryPiGlyph(size: 28) + VStack(alignment: .leading, spacing: 12) { + HStack(spacing: 8) { + Label("Nó", systemImage: "desktopcomputer") + .font(MacOS9Typography.bodyBold(13)) + .foregroundStyle(SystemTheme.ink.opacity(0.82)) - VStack(alignment: .leading, spacing: 2) { - Text(status.hostname) - .font(.system(size: 28, weight: .black, design: .rounded)) - .foregroundStyle(SystemTheme.ink) + Text("ONLINE") + .font(MacOS9Typography.menuLabel(10)) + .foregroundStyle(SystemTheme.piGreen) + .padding(.horizontal, 8) + .padding(.vertical, 4) + .background(MacOS9Colors.labelBadge) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) - Text(status.location) - .font(.subheadline) - .foregroundStyle(SystemTheme.ink.opacity(0.62)) - } - } - } + Spacer() - Spacer(minLength: 12) - - VStack(alignment: .trailing, spacing: 8) { - ZStack { - Circle() - .fill( - LinearGradient( - colors: [ - SystemTheme.piGreen.opacity(0.16), - SystemTheme.piBlue.opacity(0.10), - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - ) - .frame(width: 64, height: 64) + Text(statusUpdateText(status)) + .font(MacOS9Typography.finePrint(9)) + .foregroundStyle(SystemTheme.ink.opacity(0.62)) + } - Circle() - .stroke(SystemTheme.piGreen.opacity(0.22), lineWidth: 1.2) - .frame(width: 64, height: 64) + HStack(spacing: 10) { + RaspberryPiGlyph(size: 24) - RaspberryPiGlyph(size: 30) - } + VStack(alignment: .leading, spacing: 1) { + Text(status.hostname) + .font(MacOS9Typography.windowTitle(22)) + .foregroundStyle(SystemTheme.ink) - Text(statusUpdateText(status)) - .font(.caption2.weight(.semibold)) + Text(status.location) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) - .multilineTextAlignment(.trailing) } } - Text("Telemetria ao vivo do Raspberry Pi e dos dispositivos conectados.") - .font(.callout) + Text("Telemetria ao vivo do Raspberry Pi e dispositivos conectados.") + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) ScrollView(.horizontal, showsIndicators: false) { @@ -1287,16 +1226,16 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 12) { HStack(spacing: 10) { Label("Nó monitorado", systemImage: "desktopcomputer") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(SystemTheme.ink.opacity(0.82)) Text("ONLINE") - .font(.system(size: 10, weight: .black, design: .rounded)) - .tracking(1.0) + .font(MacOS9Typography.menuLabel(10)) .foregroundStyle(SystemTheme.piGreen) - .padding(.horizontal, 10) - .padding(.vertical, 5) - .background(SystemTheme.piGreen.opacity(0.14), in: Capsule()) + .padding(.horizontal, 8) + .padding(.vertical, 4) + .background(MacOS9Colors.labelBadge) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } HStack(spacing: 10) { @@ -1304,17 +1243,17 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 2) { Text(status.hostname) - .font(.system(size: 28, weight: .black, design: .rounded)) + .font(MacOS9Typography.windowTitle(22)) .foregroundStyle(SystemTheme.ink) Text(status.location) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) } } Text("Telemetria ao vivo do Raspberry Pi e dos dispositivos conectados.") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink.opacity(0.56)) ViewThatFits(in: .horizontal) { @@ -1395,7 +1334,7 @@ struct SystemView: View { } Text(statusUpdateText(status)) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) .multilineTextAlignment(.trailing) } @@ -1412,25 +1351,25 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 14) { VStack(alignment: .leading, spacing: 6) { Text("Visão geral") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.piBlue.opacity(0.72)) .textCase(.uppercase) HStack(alignment: .firstTextBaseline, spacing: 8) { Text(cpuUsageHeadline(status)) - .font(.system(size: 42, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(42)) .monospacedDigit() .foregroundStyle(SystemTheme.ink) if let temp = status.cpu?.temperatureC { Text("\(Int(temp))°C") - .font(.title3.weight(.bold)) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(Color.fromName(status.cpu?.temperatureColor)) } } Text("uso do processador") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) } @@ -1469,25 +1408,25 @@ struct SystemView: View { HStack(spacing: 16) { VStack(alignment: .leading, spacing: 6) { Text("Visão geral") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.piBlue.opacity(0.72)) .textCase(.uppercase) HStack(alignment: .firstTextBaseline, spacing: 8) { Text(cpuUsageHeadline(status)) - .font(.system(size: 42, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(42)) .monospacedDigit() .foregroundStyle(SystemTheme.ink) if let temp = status.cpu?.temperatureC { Text("\(Int(temp))°C") - .font(.title3.weight(.bold)) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(Color.fromName(status.cpu?.temperatureColor)) } } Text("uso do processador") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.62)) } @@ -1533,18 +1472,18 @@ struct SystemView: View { HStack { VStack(alignment: .leading, spacing: 4) { Text("Saúde em Tempo Real") - .font(.title3.weight(.bold)) + .font(MacOS9Typography.windowTitle(18)) .foregroundStyle(SystemTheme.ink) Text("CPU, RAM e temperatura do nó monitorado") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.58)) } Spacer() } - HStack(spacing: isCompactLayout ? 10 : 20) { + HStack(spacing: isCompactLayout ? 8 : 12) { RealtimeGaugeCard( title: "CPU", value: status.cpu?.usagePercent ?? 0, @@ -1587,11 +1526,11 @@ struct SystemView: View { HStack(alignment: .firstTextBaseline) { VStack(alignment: .leading, spacing: 4) { Text("CPU") - .font(.title3.weight(.bold)) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(SystemTheme.ink) Text("Histórico das últimas 24 horas") - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(SystemTheme.ink.opacity(0.58)) } @@ -1602,7 +1541,7 @@ struct SystemView: View { format: "%.1f%% agora", cpuMetrics.dataPoints.last?.usage ?? cpuMetrics.average) ) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(SystemTheme.piBlue) .monospacedDigit() } @@ -1680,13 +1619,13 @@ struct SystemView: View { VStack(alignment: .leading, spacing: 14) { HStack { Text("Históricos e Análises") - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(SystemTheme.ink) Spacer() Text("fullscreen") - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(SystemTheme.ink.opacity(0.48)) } @@ -1720,7 +1659,7 @@ struct SystemView: View { analyticsDestination = .environment } label: { Label("Abrir histórico do sensor", systemImage: "arrow.up.right") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(.cyan) .padding(.horizontal, 14) .padding(.vertical, 10) @@ -1770,11 +1709,11 @@ struct SystemCard: View { Image(systemName: icon) .foregroundStyle(color) - .font(.body.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) } Text(title) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(SystemTheme.ink) Spacer() @@ -1812,15 +1751,14 @@ struct GaugeView: View { ? String(format: "%.0f%@", value, suffix) : String(format: "%.0f%@", value, suffix) ) - .font(.caption) - .fontWeight(.bold) + .font(MacOS9Typography.bodyBold(11)) .monospacedDigit() .foregroundStyle(SystemTheme.ink) } .frame(width: 60, height: 60) Text(title) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(SystemTheme.ink.opacity(0.56)) } } @@ -1851,23 +1789,25 @@ private struct RealtimeGaugeCard: View { EmptyView() } currentValueLabel: { Text(valueLabel) - .font(.caption2.weight(.bold)) + .font(MacOS9Typography.bodyBold(11)) .monospacedDigit() .foregroundStyle(SystemTheme.ink) } .gaugeStyle(.accessoryCircular) .tint(tint) - .scaleEffect(1.12) + .scaleEffect(0.98) Label(title, systemImage: symbol) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink.opacity(0.68)) .labelStyle(.titleAndIcon) } .frame(maxWidth: .infinity) - .padding(.vertical, 18) - .background(Color(.secondarySystemGroupedBackground)) - .clipShape(RoundedRectangle(cornerRadius: 22, style: .continuous)) + .padding(.vertical, 12) + .padding(.horizontal, 6) + .background(MacOS9Colors.contentPanel) + .overlay(Mac9BevelBorder(isRaised: true)) + .overlay(Rectangle().strokeBorder(MacOS9Colors.border, lineWidth: 1)) } } @@ -2045,22 +1985,22 @@ private struct SystemChartTooltip: View { .frame(width: 8, height: 8) Text(point.valueText) - .font(.headline.weight(.bold)) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(SystemTheme.ink) .monospacedDigit() } Text("CPU") - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink) Text(point.timestampText) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(SystemTheme.ink.opacity(0.58)) if let loadText = point.loadText { Text(loadText) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(SystemTheme.ink.opacity(0.58)) } } @@ -2082,11 +2022,11 @@ private struct SystemTrendStat: View { var body: some View { VStack(alignment: .leading, spacing: 6) { Text(title) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(SystemTheme.ink.opacity(0.56)) Text(value) - .font(.headline.weight(.bold)) + .font(MacOS9Typography.bodyBold(15)) .monospacedDigit() .foregroundStyle(tint) } @@ -2114,11 +2054,11 @@ private struct FirestickRowView: View { VStack(alignment: .leading, spacing: 2) { Text(item.device.name) - .font(.subheadline) - .fontWeight(.medium) + .font(MacOS9Typography.body(13)) + Text(subtitle(tvOn: tvOn, showing: showing, adbState: adbState, package: pkg)) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) .lineLimit(2) } @@ -2184,7 +2124,7 @@ private struct FirestickSnapshotView: View { .foregroundStyle(.secondary) if let error { Text(error) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -2208,7 +2148,7 @@ private struct FirestickSnapshotView: View { .foregroundStyle(.secondary) if let error { Text(error) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } @@ -2219,7 +2159,7 @@ private struct FirestickSnapshotView: View { Text( "Atualizado \(Formatters.relativeDate.localizedString(for: lastUpdated, relativeTo: Date()))" ) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.secondary) .padding(.bottom, 6) } @@ -2318,7 +2258,7 @@ private struct FirestickDetailView: View { } } else { Text("Toque em Atualizar para gerar um link temporario.") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } From b79e7ccd56f87a37084cd8a114298c3923bc2b3d Mon Sep 17 00:00:00 2001 From: Eliel <141689593+eliel9012@users.noreply.github.com> Date: Sun, 24 May 2026 14:37:07 -0300 Subject: [PATCH 10/10] Defer launch networking and fix radio fonts --- MeuLabApp/MeuLabApp.swift | 2 +- MeuLabApp/Services/APIService.swift | 4 +- MeuLabApp/ViewModels/AppState.swift | 18 +++--- MeuLabApp/Views/Tabs/RadioView.swift | 74 +++++++++++----------- MeuLabApp/Views/Tabs/RemoteRadioView.swift | 60 +++++++++--------- 5 files changed, 78 insertions(+), 80 deletions(-) diff --git a/MeuLabApp/MeuLabApp.swift b/MeuLabApp/MeuLabApp.swift index 8a77e23..d0b1664 100644 --- a/MeuLabApp/MeuLabApp.swift +++ b/MeuLabApp/MeuLabApp.swift @@ -54,7 +54,7 @@ struct MeuLabApp: App { appState.bootstrapIfNeeded() appState.setRefreshEnabled(true) - try? await Task.sleep(nanoseconds: 2_000_000_000) + try? await Task.sleep(nanoseconds: 20_000_000_000) guard !Task.isCancelled else { return } setupPushNotificationsIfNeeded() notificationFeed.start() diff --git a/MeuLabApp/Services/APIService.swift b/MeuLabApp/Services/APIService.swift index f9a2d24..e38b180 100644 --- a/MeuLabApp/Services/APIService.swift +++ b/MeuLabApp/Services/APIService.swift @@ -62,8 +62,8 @@ actor APIService { private init() { let config = URLSessionConfiguration.default - config.timeoutIntervalForRequest = 10 - config.timeoutIntervalForResource = 30 + config.timeoutIntervalForRequest = 4 + config.timeoutIntervalForResource = 8 config.waitsForConnectivity = false config.requestCachePolicy = .reloadIgnoringLocalCacheData self.session = URLSession(configuration: config) diff --git a/MeuLabApp/ViewModels/AppState.swift b/MeuLabApp/ViewModels/AppState.swift index 4700222..6737ba7 100644 --- a/MeuLabApp/ViewModels/AppState.swift +++ b/MeuLabApp/ViewModels/AppState.swift @@ -159,9 +159,9 @@ class AppState: ObservableObject { private var acarsInFlight = false // Intervalos de cada módulo quando a tab está ativa - private let adsbTimerInterval: TimeInterval = 2.0 - private let adsbSummaryInterval: TimeInterval = 2.0 - private let adsbAircraftInterval: TimeInterval = 4.0 + private let adsbTimerInterval: TimeInterval = 4.0 + private let adsbSummaryInterval: TimeInterval = 8.0 + private let adsbAircraftInterval: TimeInterval = 10.0 private let systemInterval: TimeInterval = 5.0 private let firestickInterval: TimeInterval = 10.0 private let radioInterval: TimeInterval = 3.0 @@ -177,11 +177,11 @@ class AppState: ObservableObject { private let systemdInterval: TimeInterval = 30.0 private let satDumpStatusInterval: TimeInterval = 60.0 private let adsbHistoryInterval: TimeInterval = 300.0 - private let adsbAlertsInterval: TimeInterval = 60.0 - private let tuyaSensorInterval: TimeInterval = 30.0 + private let adsbAlertsInterval: TimeInterval = 120.0 + private let tuyaSensorInterval: TimeInterval = 120.0 private let acarsHistoryInterval: TimeInterval = 300.0 private let acarsAlertsInterval: TimeInterval = 60.0 - private let metricsInterval: TimeInterval = 10.0 + private let metricsInterval: TimeInterval = 60.0 private var lastADSBSummaryRefresh: Date? private var lastADSBListRefresh: Date? @@ -245,10 +245,6 @@ class AppState: ObservableObject { guard !hasBootstrapped else { return } hasBootstrapped = true startRefreshTimers() - - Task { @MainActor [weak self] in - await self?.refreshActiveTabNow(force: true) - } } func setRefreshEnabled(_ enabled: Bool) { @@ -344,6 +340,8 @@ class AppState: ObservableObject { // --- Grupos de refresh isolados --- private func tickADSBExtras(_ now: Date) async { + guard adsbSummary != nil || !aircraftList.isEmpty else { return } + let doHistory = shouldRefresh( last: lastADSBHistoryRefresh, interval: adsbHistoryInterval, now: now) let doAlerts = shouldRefresh( diff --git a/MeuLabApp/Views/Tabs/RadioView.swift b/MeuLabApp/Views/Tabs/RadioView.swift index c291bc6..fc89fab 100644 --- a/MeuLabApp/Views/Tabs/RadioView.swift +++ b/MeuLabApp/Views/Tabs/RadioView.swift @@ -92,12 +92,12 @@ private struct RadioToolbarTitle: View { .frame(width: 28, height: 28) Image(systemName: "dot.radiowaves.left.and.right") - .font(.system(size: 14, weight: .bold)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(RadioTheme.blue) } Text("Rádio") - .font(.system(size: 23, weight: .black, design: .rounded)) + .font(MacOS9Typography.bodyBold(23)) .tracking(0.5) .foregroundStyle( LinearGradient( @@ -121,16 +121,16 @@ private struct RadioInfoChip: View { var body: some View { VStack(alignment: .leading, spacing: 4) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(RadioTheme.ink.opacity(0.56)) HStack(spacing: 6) { Image(systemName: icon) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) Text(value) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(RadioTheme.ink) .lineLimit(1) } @@ -200,7 +200,7 @@ struct RadioView: View { .environmentObject(appState) } label: { Image(systemName: "music.note.list") - .font(.system(size: 18, weight: .semibold)) + .font(MacOS9Typography.bodyBold(18)) .foregroundStyle(RadioTheme.blue) .padding(8) .background( @@ -310,7 +310,7 @@ struct RadioView: View { VStack(spacing: 8) { Text(effectiveTitle) - .font(.system(size: 17, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(17)) .foregroundStyle(.white) .multilineTextAlignment(.center) .lineLimit(3) @@ -319,7 +319,7 @@ struct RadioView: View { if !shouldHideArtistLine { Text(effectiveArtist.isEmpty ? "Diário FM" : effectiveArtist) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(.white.opacity(0.78)) .multilineTextAlignment(.center) .lineLimit(2) @@ -329,7 +329,7 @@ struct RadioView: View { if let album = effectiveAlbum, !album.isEmpty { Text(album) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(.white.opacity(0.62)) .multilineTextAlignment(.center) .lineLimit(2) @@ -370,7 +370,7 @@ struct RadioView: View { VStack(spacing: 8) { Text(effectiveTitle) - .font(.system(size: 32, weight: .bold, design: .rounded)) + .font(MacOS9Typography.bodyBold(32)) .foregroundStyle(.white) .multilineTextAlignment(.center) .lineLimit(2) @@ -379,7 +379,7 @@ struct RadioView: View { if !shouldHideArtistLine { Text(effectiveArtist.isEmpty ? "Diário FM" : effectiveArtist) - .font(.title3) + .font(MacOS9Typography.windowTitle(17)) .foregroundStyle(.white.opacity(0.78)) .multilineTextAlignment(.center) .lineLimit(2) @@ -389,7 +389,7 @@ struct RadioView: View { if let album = effectiveAlbum, !album.isEmpty { Text(album) - .font(.subheadline.weight(.medium)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(.white.opacity(0.62)) .multilineTextAlignment(.center) .lineLimit(2) @@ -576,7 +576,7 @@ struct RadioView: View { VStack(alignment: .leading, spacing: 10) { HStack { Label(title, systemImage: systemImage) - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(RadioTheme.ink) Spacer() if isLoading { @@ -586,7 +586,7 @@ struct RadioView: View { } Text(text) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(RadioTheme.ink.opacity(0.82)) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) @@ -647,14 +647,14 @@ struct RadioView: View { VStack(alignment: .leading, spacing: 5) { HStack(spacing: 6) { Image(systemName: icon) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) Text(title) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(RadioTheme.ink.opacity(0.56)) } Text(value) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(RadioTheme.ink) .lineLimit(1) } @@ -668,14 +668,14 @@ struct RadioView: View { VStack(alignment: .leading, spacing: 10) { HStack { Label("Últimas tocadas", systemImage: "music.note.list") - .font(.subheadline.weight(.semibold)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(RadioTheme.ink) Spacer() NavigationLink("Ver histórico") { RadioSongsView() .environmentObject(appState) } - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) } if loadingRecentTracks && recentTracks.isEmpty { @@ -687,7 +687,7 @@ struct RadioView: View { .padding(.vertical, 10) } else if recentTracks.isEmpty { Text("Sem histórico recente disponível.") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(RadioTheme.ink.opacity(0.56)) .padding(.vertical, 6) } else { @@ -699,11 +699,11 @@ struct RadioView: View { VStack(alignment: .leading, spacing: 2) { Text(track.title) - .font(.caption.weight(.semibold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(RadioTheme.ink) .lineLimit(1) Text(track.artist) - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(RadioTheme.ink.opacity(0.56)) .lineLimit(1) } @@ -711,7 +711,7 @@ struct RadioView: View { Spacer() Text(relativeTimestamp(track.timestamp) ?? "agora") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(RadioTheme.ink.opacity(0.56)) } .padding(isWide ? 12 : 10) @@ -752,7 +752,7 @@ struct RadioView: View { .fill(RadioTheme.blue.opacity(0.12)) .overlay( Image(systemName: "music.note") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(RadioTheme.blue) ) } @@ -764,7 +764,7 @@ struct RadioView: View { .fill(RadioTheme.blue.opacity(0.12)) .overlay( Image(systemName: "music.note") - .font(.caption2) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(RadioTheme.blue) ) .frame(width: size, height: size) @@ -806,7 +806,7 @@ struct RadioView: View { .tint(.white) } else { Image(systemName: player.isPlaying ? "pause.fill" : "play.fill") - .font(.largeTitle.weight(.bold)) + .font(MacOS9Typography.windowTitle(26)) .foregroundStyle(.white) .offset(x: player.isPlaying ? 0 : 2) } @@ -818,7 +818,7 @@ struct RadioView: View { private func playbackIconButton(systemName: String, action: @escaping () -> Void) -> some View { Button(action: action) { Image(systemName: systemName) - .font(.system(size: isWide ? 32 : 26, weight: .semibold)) + .font(MacOS9Typography.bodyBold(isWide ? 32 : 26)) .frame(width: isWide ? 54 : 46, height: isWide ? 54 : 46) } .buttonStyle(.plain) @@ -829,16 +829,16 @@ struct RadioView: View { { HStack(spacing: 8) { Image(systemName: icon) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(tint) VStack(alignment: .leading, spacing: 1) { Text(title) - .font(.caption2.weight(.semibold)) + .font(MacOS9Typography.finePrint(9)) .foregroundStyle(.white.opacity(0.6)) Text(value) - .font(.caption.weight(.bold)) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.white) .lineLimit(2) .minimumScaleFactor(0.8) @@ -1308,17 +1308,17 @@ struct RadioSongsView: View { VStack(alignment: .leading, spacing: 3) { Text(track.title) - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .lineLimit(1) Text(track.artist) - .font(.subheadline) + .font(MacOS9Typography.body(13)) .foregroundStyle(.secondary) .lineLimit(1) if let album = track.album, !album.isEmpty { Text(album) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) .lineLimit(1) } @@ -1329,8 +1329,8 @@ struct RadioSongsView: View { VStack(alignment: .trailing, spacing: 4) { if isNow { Text("AGORA") - .font(.caption2) - .fontWeight(.bold) + .font(MacOS9Typography.finePrint(9)) + .padding(.horizontal, 8) .padding(.vertical, 4) .background(Color.red.opacity(0.12)) @@ -1338,14 +1338,14 @@ struct RadioSongsView: View { .clipShape(Capsule()) } else if let rel = relativeTimestamp(track.timestamp) { Text(rel) - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } if let urlString = track.itunesUrl, let url = URL(string: urlString) { Link(destination: url) { Image(systemName: "link") - .font(.caption) + .font(MacOS9Typography.caption(11)) .foregroundStyle(.secondary) } } diff --git a/MeuLabApp/Views/Tabs/RemoteRadioView.swift b/MeuLabApp/Views/Tabs/RemoteRadioView.swift index 6665734..f19f87b 100644 --- a/MeuLabApp/Views/Tabs/RemoteRadioView.swift +++ b/MeuLabApp/Views/Tabs/RemoteRadioView.swift @@ -88,9 +88,9 @@ struct RemoteRadioView: View { HStack(spacing: 6) { Image(systemName: "antenna.radiowaves.left.and.right") .foregroundStyle(amber) - .font(.subheadline) + .font(MacOS9Typography.body(13)) Text("SDR Remote") - .font(.headline) + .font(MacOS9Typography.bodyBold(15)) .foregroundStyle(cream) } } @@ -111,16 +111,16 @@ struct RemoteRadioView: View { HStack(spacing: 8) { Image(systemName: icon) .foregroundStyle(tint) - .font(.system(size: 16)) + .font(MacOS9Typography.body(16)) Text(title) - .font(.system(size: 14, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(cream) Spacer() } if let error = vm.errorMessage { Text(error) - .font(.system(size: 12, design: .monospaced)) + .font(MacOS9Typography.body(12)) .foregroundStyle(cream.opacity(0.7)) .frame(maxWidth: .infinity, alignment: .leading) } @@ -153,7 +153,7 @@ struct RemoteRadioView: View { Image(systemName: "arrow.clockwise") Text("Verificar Novamente") } - .font(.system(size: 12, weight: .semibold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(12)) .foregroundStyle(.white) .frame(maxWidth: .infinity) .frame(height: 36) @@ -178,9 +178,9 @@ struct RemoteRadioView: View { private func statusPill(label: String, ok: Bool, icon: String) -> some View { HStack(spacing: 4) { Image(systemName: icon) - .font(.system(size: 9)) + .font(MacOS9Typography.body(9)) Text(label) - .font(.system(size: 10, weight: .medium, design: .monospaced)) + .font(MacOS9Typography.bodyBold(10)) Circle() .fill(ok ? Color.green : Color.red) .frame(width: 6, height: 6) @@ -248,7 +248,7 @@ struct RemoteRadioView: View { VStack(spacing: 2) { // Band indicator Text(vm.mode.displayName) - .font(.system(size: 11, weight: .medium, design: .monospaced)) + .font(MacOS9Typography.bodyBold(11)) .foregroundStyle(amberDim.opacity(0.7)) .tracking(4) @@ -268,7 +268,7 @@ struct RemoteRadioView: View { // Unit label Text(vm.freqUnitLabel) - .font(.system(size: 13, weight: .medium, design: .monospaced)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(amberDim.opacity(0.5)) .tracking(3) } @@ -294,7 +294,7 @@ struct RemoteRadioView: View { } } label: { Text(radioMode.displayName) - .font(.system(size: 14, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(14)) .foregroundStyle(vm.mode == radioMode ? woodDark : cream.opacity(0.7)) .frame(width: 60, height: 36) .background( @@ -339,7 +339,7 @@ struct RemoteRadioView: View { Task { await vm.stepFrequency(by: delta) } } label: { Text(label) - .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(cream) .frame(maxWidth: .infinity) .frame(height: 38) @@ -362,7 +362,7 @@ struct RemoteRadioView: View { // Gain control VStack(spacing: 6) { Text("GAIN") - .font(.system(size: 10, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(10)) .foregroundStyle(amberDim) .tracking(2) @@ -375,7 +375,7 @@ struct RemoteRadioView: View { } } label: { Text(gainIsAuto ? "AUTO" : String(format: "%.0f", manualGain)) - .font(.system(size: 13, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(gainIsAuto ? amber : cream) .frame(width: 64, height: 32) .background( @@ -401,12 +401,12 @@ struct RemoteRadioView: View { // Squelch control VStack(spacing: 6) { Text("SQUELCH") - .font(.system(size: 10, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(10)) .foregroundStyle(amberDim) .tracking(2) Text("\(vm.squelch)") - .font(.system(size: 13, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(13)) .foregroundStyle(cream) .frame(width: 64, height: 32) .background( @@ -441,7 +441,7 @@ struct RemoteRadioView: View { VStack(spacing: 8) { HStack { Text("PRESETS") - .font(.system(size: 10, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(10)) .foregroundStyle(amberDim) .tracking(3) Spacer() @@ -467,15 +467,15 @@ struct RemoteRadioView: View { } label: { VStack(spacing: 4) { Image(systemName: preset.icon) - .font(.system(size: 16)) + .font(MacOS9Typography.body(16)) .foregroundStyle(isPresetActive(preset) ? woodDark : amber) Text(preset.name) - .font(.system(size: 10, weight: .semibold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(10)) .foregroundStyle(isPresetActive(preset) ? woodDark : cream.opacity(0.8)) Text(String(format: "%.1f", preset.freqMHz)) - .font(.system(size: 9, weight: .medium, design: .monospaced)) + .font(MacOS9Typography.bodyBold(9)) .foregroundStyle( isPresetActive(preset) ? woodDark.opacity(0.7) : amberDim.opacity(0.6)) } @@ -513,7 +513,7 @@ struct RemoteRadioView: View { ProgressView() .tint(amber) Text("Conectando ao SDR…") - .font(.system(size: 12, design: .monospaced)) + .font(MacOS9Typography.body(12)) .foregroundStyle(amber) } .padding(.vertical, 4) @@ -534,9 +534,9 @@ struct RemoteRadioView: View { Button(action: action) { HStack(spacing: 8) { Image(systemName: icon) - .font(.system(size: 14, weight: .bold)) + .font(MacOS9Typography.bodyBold(14)) Text(label) - .font(.system(size: 13, weight: .bold, design: .monospaced)) + .font(MacOS9Typography.bodyBold(13)) } .foregroundStyle(.white) .frame(maxWidth: .infinity) @@ -563,7 +563,7 @@ struct RemoteRadioView: View { .shadow(color: statusLEDColor.opacity(0.6), radius: 4) Text(vm.connectionState.displayText) - .font(.system(size: 11, weight: .medium, design: .monospaced)) + .font(MacOS9Typography.bodyBold(11)) .foregroundStyle(cream.opacity(0.8)) Spacer() @@ -572,9 +572,9 @@ struct RemoteRadioView: View { if vm.isAudioPlaying { HStack(spacing: 4) { Image(systemName: "speaker.wave.2.fill") - .font(.system(size: 9)) + .font(MacOS9Typography.body(9)) Text("\(vm.audioFrameCount)f") - .font(.system(size: 10, weight: .medium, design: .monospaced)) + .font(MacOS9Typography.bodyBold(10)) } .foregroundStyle(amber.opacity(0.7)) } @@ -595,9 +595,9 @@ struct RemoteRadioView: View { HStack(spacing: 6) { Image(systemName: "exclamationmark.triangle.fill") .foregroundStyle(.red) - .font(.system(size: 11)) + .font(MacOS9Typography.body(11)) Text(errorMsg) - .font(.system(size: 11, design: .monospaced)) + .font(MacOS9Typography.body(11)) .foregroundStyle(.red.opacity(0.9)) } .padding(.horizontal, 12) @@ -613,12 +613,12 @@ struct RemoteRadioView: View { if !vm.backendType.isEmpty { HStack(spacing: 8) { Label(vm.backendType.uppercased(), systemImage: "cpu") - .font(.system(size: 10, design: .monospaced)) + .font(MacOS9Typography.body(10)) .foregroundStyle(amberDim.opacity(0.5)) if !vm.rtlSerial.isEmpty { Text("SN: \(vm.rtlSerial)") - .font(.system(size: 10, design: .monospaced)) + .font(MacOS9Typography.body(10)) .foregroundStyle(amberDim.opacity(0.5)) } Spacer()

31RQ&O&4kpw=ty1Ldq+p5MlvLgx( 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