From 4fd4d5a4db16c0033779e3f05a6f8341d6ce3f99 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 15 Feb 2023 13:56:11 +0800 Subject: [PATCH] New library item cards, fix issue with read position --- .../Components/FeedCardNavigationLink.swift | 2 +- .../App/Views/Home/HomeFeedViewIOS.swift | 38 +- .../App/Views/Home/LibraryAddLinkView.swift | 110 ++ .../App/Views/Profile/ProfileView.swift | 16 +- .../App/Views/Profile/Subscriptions.swift | 72 +- .../App/Views/WebReader/WebReader.swift | 3 + .../Views/WebReader/WebReaderContainer.swift | 26 +- .../WebReader/WebReaderCoordinator.swift | 4 + .../CoreDataModel.xcdatamodel/contents | 1 + .../Sources/Models/DataModels/FeedItem.swift | 5 + .../Services/DataService/GQLSchema.swift | 1384 ++++++++++++++++- .../UpdateArticleReadingProgress.swift | 1 + .../Queries/ArticleContentQuery.swift | 1 + .../Queries/LinkedItemNetworkQuery.swift | 2 + .../InternalModels/InternalLinkedItem.swift | 3 + .../Sources/Utils/UserDefaultKeys.swift | 1 + .../Views/Article/OmnivoreWebView.swift | 14 +- .../Sources/Views/Colors/Colors.swift | 2 +- .../_appGreenSuccess.colorset/Contents.json | 12 +- .../Contents.json | 12 +- .../Views/FeedItem/LibraryItemCard.swift | 221 +++ .../OmnivoreKit/Sources/Views/LocalText.swift | 6 + .../Sources/Views/Resources/bundle.js | 2 +- .../Resources/en.lproj/Localizable.strings | 1 - .../en.lproj/Localizable.stringsdict | 38 + .../OmnivoreKit/Sources/Views/TextChip.swift | 1 - packages/appreader/src/index.jsx | 2 +- .../web/components/elements/LabelChip.tsx | 5 - .../components/templates/article/Article.tsx | 19 +- .../templates/article/ArticleContainer.tsx | 7 + .../web/components/tokens/stitches.config.ts | 2 +- 31 files changed, 1935 insertions(+), 78 deletions(-) create mode 100644 apple/OmnivoreKit/Sources/App/Views/Home/LibraryAddLinkView.swift rename apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/{_checkmarkBlue.colorset => _indicatorBlue.colorset}/Contents.json (76%) create mode 100644 apple/OmnivoreKit/Sources/Views/FeedItem/LibraryItemCard.swift create mode 100644 apple/OmnivoreKit/Sources/Views/Resources/en.lproj/Localizable.stringsdict diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift b/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift index c080ec145..8437868c1 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift @@ -58,7 +58,7 @@ struct FeedCardNavigationLink: View { .onAppear { Task { await viewModel.itemAppeared(item: item, dataService: dataService) } } - FeedCard(item: item, viewer: dataService.currentViewer) + LibraryItemCard(item: item, viewer: dataService.currentViewer) } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index 69bcd13a0..e28691269 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift @@ -13,6 +13,8 @@ import Views struct HomeFeedContainerView: View { @State var hasHighlightMutations = false @State var searchPresented = false + @State var addLinkPresented = false + @State var settingsPresented = false @EnvironmentObject var dataService: DataService @EnvironmentObject var audioController: AudioController @@ -129,16 +131,18 @@ import Views } ToolbarItem(placement: .barTrailing) { if UIDevice.isIPhone { - NavigationLink( - destination: { ProfileView() }, - label: { - Image(systemName: "person.circle") - .resizable() - .frame(width: 22, height: 22) - .padding(.vertical, 16) - .foregroundColor(.appGrayTextContrast) - } - ) + Menu(content: { + Button(action: { settingsPresented = true }, label: { + Label(LocalText.genericProfile, systemImage: "person.circle") + }) + Button(action: { addLinkPresented = true }, label: { + Label("Add Link", systemImage: "plus.square") + }) + }, label: { + Image(systemName: "ellipsis") + .foregroundColor(.appGrayTextContrast) + .frame(width: 24, height: 24) + }) } else { EmptyView() } @@ -189,6 +193,16 @@ import Views .fullScreenCover(isPresented: $searchPresented) { LibrarySearchView(homeFeedViewModel: self.viewModel) } + .sheet(isPresented: $addLinkPresented) { + NavigationView { + LibraryAddLinkView() + } + } + .sheet(isPresented: $settingsPresented) { + NavigationView { + ProfileView() + } + } .task { if viewModel.items.isEmpty { loadItems(isRefresh: false) @@ -364,6 +378,7 @@ import Views item: item, viewModel: viewModel ) + .listRowInsets(.init(top: 0, leading: 8, bottom: 8, trailing: 8)) .contextMenu { menuItems(for: item) } @@ -407,8 +422,9 @@ import Views } } } - .padding(.top, 0) + .padding(0) .listStyle(PlainListStyle()) + .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) .alert("Are you sure you want to delete this item? All associated notes and highlights will be deleted.", isPresented: $confirmationShown) { Button("Remove Item", role: .destructive) { diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/LibraryAddLinkView.swift b/apple/OmnivoreKit/Sources/App/Views/Home/LibraryAddLinkView.swift new file mode 100644 index 000000000..9298fe44e --- /dev/null +++ b/apple/OmnivoreKit/Sources/App/Views/Home/LibraryAddLinkView.swift @@ -0,0 +1,110 @@ + +import Introspect +import Models +import Services +import SwiftUI +import UIKit +import Views + +@MainActor final class LibraryAddLinkViewModel: NSObject, ObservableObject { + @Published var isLoading = false + @Published var errorMessage: String = "" + @Published var showErrorMessage: Bool = false + + func addLink(dataService: DataService, newLinkURL: String, dismiss: DismissAction) { + isLoading = true + Task { + if URL(string: newLinkURL) == nil { + error("Invalid link") + } else { + let result = try? await dataService.saveURL(id: UUID().uuidString, url: newLinkURL) + if result == nil { + error("Error adding link") + } else { + dismiss() + } + } + isLoading = false + } + } + + func error(_ msg: String) { + errorMessage = msg + showErrorMessage = true + isLoading = false + } +} + +struct LibraryAddLinkView: View { + @StateObject var viewModel = LibraryAddLinkViewModel() + + @State var newLinkURL: String = "" + @EnvironmentObject var dataService: DataService + @Environment(\.dismiss) private var dismiss + + enum FocusField: Hashable { + case addLinkEditor + } + + @FocusState private var focusedField: FocusField? + + var body: some View { + innerBody + .navigationTitle("Add Link") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + focusedField = .addLinkEditor + } + } + + var innerBody: some View { + Form { + TextField("Add Link", text: $newLinkURL) + .keyboardType(.URL) + .textFieldStyle(StandardTextFieldStyle()) + .focused($focusedField, equals: .addLinkEditor) + + Button(action: { + if let url = UIPasteboard.general.url { + newLinkURL = url.absoluteString + } else { + viewModel.error("No URL on pasteboard") + } + }, label: { + Text("Get from pasteboard") + }) + } + .navigationTitle("Add Link") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + dismissButton + } + ToolbarItem(placement: .navigationBarTrailing) { + viewModel.isLoading ? AnyView(ProgressView()) : AnyView(addButton) + } + } + .alert(viewModel.errorMessage, + isPresented: $viewModel.showErrorMessage) { + Button(LocalText.genericOk, role: .cancel) { viewModel.showErrorMessage = false } + } + } + + var addButton: some View { + Button( + action: { + viewModel.addLink(dataService: dataService, newLinkURL: newLinkURL, dismiss: dismiss) + }, + label: { Text("Add").bold() } + ) + .disabled(viewModel.isLoading) + } + + var dismissButton: some View { + Button( + action: { dismiss() }, + label: { Text(LocalText.genericClose) } + ) + .disabled(viewModel.isLoading) + } +} diff --git a/apple/OmnivoreKit/Sources/App/Views/Profile/ProfileView.swift b/apple/OmnivoreKit/Sources/App/Views/Profile/ProfileView.swift index cf9273d20..ad7c53cbc 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Profile/ProfileView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Profile/ProfileView.swift @@ -59,6 +59,7 @@ struct ProfileView: View { @EnvironmentObject var authenticator: Authenticator @EnvironmentObject var dataService: DataService @Environment(\.openURL) var openURL + @Environment(\.dismiss) var dismiss @StateObject private var viewModel = ProfileContainerViewModel() @@ -69,6 +70,13 @@ struct ProfileView: View { Form { innerBody } + .navigationTitle(LocalText.genericProfile) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + dismissButton + } + } #elseif os(macOS) List { innerBody @@ -77,6 +85,13 @@ struct ProfileView: View { #endif } + var dismissButton: some View { + Button( + action: { dismiss() }, + label: { Text(LocalText.genericClose) } + ) + } + private var accountSection: some View { Section { NavigationLink(destination: LabelsView()) { @@ -171,7 +186,6 @@ struct ProfileView: View { } } } - .navigationTitle(LocalText.genericProfile) } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift b/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift index d9fee2c93..2f868cf92 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift @@ -46,44 +46,48 @@ struct SubscriptionsView: View { @State private var progressViewOpacity = 0.0 var body: some View { - if viewModel.isLoading { - ProgressView() - .opacity(progressViewOpacity) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) { - progressViewOpacity = 1 + Group { + if viewModel.isLoading { + ProgressView() + .opacity(progressViewOpacity) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) { + progressViewOpacity = 1 + } } + .task { await viewModel.loadSubscriptions(dataService: dataService) } + } else if viewModel.hasNetworkError { + VStack { + Text(LocalText.subscriptionsErrorRetrieving).multilineTextAlignment(.center) + Button( + action: { Task { await viewModel.loadSubscriptions(dataService: dataService) } }, + label: { Text(LocalText.genericRetry) } + ) + .buttonStyle(RoundedRectButtonStyle()) + } + } else if viewModel.subscriptions.isEmpty { + VStack(alignment: .center) { + Spacer() + Text(LocalText.subscriptionsNone) + Spacer() + } + } else { + Group { + #if os(iOS) + Form { + innerBody + } + #elseif os(macOS) + List { + innerBody + } + .listStyle(InsetListStyle()) + #endif } - .task { await viewModel.loadSubscriptions(dataService: dataService) } - } else if viewModel.hasNetworkError { - VStack { - Text(LocalText.subscriptionsErrorRetrieving).multilineTextAlignment(.center) - Button( - action: { Task { await viewModel.loadSubscriptions(dataService: dataService) } }, - label: { Text(LocalText.genericRetry) } - ) - .buttonStyle(RoundedRectButtonStyle()) - } - } else if viewModel.subscriptions.isEmpty { - VStack(alignment: .center) { - Spacer() - Text(LocalText.subscriptionsNone) - Spacer() - } - } else { - Group { - #if os(iOS) - Form { - innerBody - } - #elseif os(macOS) - List { - innerBody - } - .listStyle(InsetListStyle()) - #endif } } + .navigationTitle("Subscriptions") + .navigationBarTitleDisplayMode(.inline) } private var innerBody: some View { diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift index 667d980c2..a2537feea 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift @@ -9,6 +9,7 @@ struct WebReader: PlatformViewRepresentable { let articleContent: ArticleContent let openLinkAction: (URL) -> Void let tapHandler: () -> Void + let scrollPercentHandler: (Int) -> Void let webViewActionHandler: (WKScriptMessage, WKScriptMessageReplyHandler?) -> Void let navBarVisibilityRatioUpdater: (Double) -> Void @@ -52,6 +53,7 @@ struct WebReader: PlatformViewRepresentable { webView.configuration.userContentController = contentController webView.configuration.userContentController.removeAllScriptMessageHandlers() + webView.uiDelegate #if os(iOS) webView.isOpaque = false webView.backgroundColor = .clear @@ -74,6 +76,7 @@ struct WebReader: PlatformViewRepresentable { context.coordinator.linkHandler = openLinkAction context.coordinator.webViewActionHandler = webViewActionHandler context.coordinator.updateNavBarVisibilityRatio = navBarVisibilityRatioUpdater + context.coordinator.scrollPercentHandler = scrollPercentHandler context.coordinator.updateShowBottomBar = { newValue in self.showBottomBar = newValue } diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift index cbe02bc0a..0efa6e090 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift @@ -30,6 +30,7 @@ struct WebReaderContainerView: View { @State private var errorAlertMessage: String? @State private var showErrorAlertMessage = false @State private var showRecommendSheet = false + @State private var lastScrollPercentage: Int? @State var safariWebLink: SafariWebLink? @State var displayLinkSheet = false @@ -56,6 +57,10 @@ struct WebReaderContainerView: View { } } + func scrollPercentHandler(percent: Int) { + lastScrollPercentage = percent + } + func onHighlightListViewDismissal() { // Reload the web view if mutation happened in highlights list modal guard hasPerformedHighlightMutations else { return } @@ -369,6 +374,7 @@ struct WebReaderContainerView: View { #endif }, tapHandler: tapHandler, + scrollPercentHandler: scrollPercentHandler, webViewActionHandler: webViewActionHandler, navBarVisibilityRatioUpdater: { navBarVisibilityRatio = $0 @@ -381,6 +387,20 @@ struct WebReaderContainerView: View { showBottomBar: $showBottomBar, showHighlightAnnotationModal: $showHighlightAnnotationModal ) + .onAppear { + if item.isUnread { + dataService.updateLinkReadingProgress(itemID: item.unwrappedID, readingProgress: 0.1, anchorIndex: 0) + } + } + .onDisappear { +// if let lastScrollPercentage = self.lastScrollPercentage { +// dataService.updateLinkReadingProgress( +// itemID: item.unwrappedID, +// readingProgress: Double(lastScrollPercentage), +// anchorIndex: 0 +// ) +// } + } .confirmationDialog(linkToOpen?.absoluteString ?? "", isPresented: $displayLinkSheet) { Button(action: { if let linkToOpen = linkToOpen { @@ -495,9 +515,13 @@ struct WebReaderContainerView: View { readerSettingsChangedTransactionID = UUID() } #endif + .onAppear { + try? WebViewManager.shared().dispatchEvent(.saveReadPosition) + } .onDisappear { + try? WebViewManager.shared().dispatchEvent(.saveReadPosition) // Clear the shared webview content when exiting - WebViewManager.shared().loadHTMLString("", baseURL: nil) + // WebViewManager.shared().loadHTMLString("", baseURL: nil) } } diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift index cffc3a7df..88d9d5603 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderCoordinator.swift @@ -13,6 +13,7 @@ typealias WKScriptMessageReplyHandler = (Any?, String?) -> Void final class WebReaderCoordinator: NSObject { var webViewActionHandler: (WKScriptMessage, WKScriptMessageReplyHandler?) -> Void = { _, _ in } var linkHandler: (URL) -> Void = { _ in } + var scrollPercentHandler: ((Int) -> Void) = { _ in } var needsReload = false var lastSavedAnnotationID: UUID? var previousReaderSettingsChangedUUID: UUID? @@ -128,6 +129,9 @@ extension WebReaderCoordinator: WKNavigationDelegate { } else { updateShowBottomBar(false) } + + let percent = Int(((yOffset + scrollView.visibleSize.height) / scrollView.contentSize.height) * 100) + scrollPercentHandler(max(0, min(percent, 100))) } func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { diff --git a/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents b/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents index 589583ad6..fe602d2a1 100644 --- a/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents +++ b/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents @@ -56,6 +56,7 @@ + diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift index e07f2edf9..6ab31e75b 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift @@ -55,6 +55,7 @@ public struct JSONArticle: Decodable { public let url: String public let isArchived: Bool public let language: String? + public let wordsCount: Int? } public extension LinkedItem { @@ -69,6 +70,10 @@ public extension LinkedItem { (labels?.count ?? 0) > 0 } + var isUnread: Bool { + readingProgress <= 0 + } + var isRead: Bool { readingProgress >= 0.98 } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/GQLSchema.swift b/apple/OmnivoreKit/Sources/Services/DataService/GQLSchema.swift index 492f79f51..6ad1da397 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/GQLSchema.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/GQLSchema.swift @@ -700,6 +700,7 @@ extension Objects { let updatedAt: [String: DateTime] let uploadFileId: [String: String] let url: [String: String] + let wordsCount: [String: Int] enum TypeName: String, Codable { case article = "Article" @@ -871,6 +872,10 @@ extension Objects.Article: Decodable { if let value = try container.decode(String?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "wordsCount": + if let value = try container.decode(Int?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -919,6 +924,7 @@ extension Objects.Article: Decodable { updatedAt = map["updatedAt"] uploadFileId = map["uploadFileId"] url = map["url"] + wordsCount = map["wordsCount"] } } @@ -1538,6 +1544,21 @@ extension Fields where TypeLock == Objects.Article { return String.mockValue } } + + func wordsCount() throws -> Int? { + let field = GraphQLField.leaf( + name: "wordsCount", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + return data.wordsCount[field.alias!] + case .mocking: + return nil + } + } } extension Selection where TypeLock == Never, Type == Never { @@ -2307,6 +2328,136 @@ extension Selection where TypeLock == Never, Type == Never { typealias ArticlesSuccess = Selection } +extension Objects { + struct BulkActionError { + let __typename: TypeName = .bulkActionError + let errorCodes: [String: [Enums.BulkActionErrorCode]] + + enum TypeName: String, Codable { + case bulkActionError = "BulkActionError" + } + } +} + +extension Objects.BulkActionError: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.BulkActionErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + errorCodes = map["errorCodes"] + } +} + +extension Fields where TypeLock == Objects.BulkActionError { + func errorCodes() throws -> [Enums.BulkActionErrorCode] { + let field = GraphQLField.leaf( + name: "errorCodes", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.errorCodes[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return [] + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias BulkActionError = Selection +} + +extension Objects { + struct BulkActionSuccess { + let __typename: TypeName = .bulkActionSuccess + let success: [String: Bool] + + enum TypeName: String, Codable { + case bulkActionSuccess = "BulkActionSuccess" + } + } +} + +extension Objects.BulkActionSuccess: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "success": + if let value = try container.decode(Bool?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + success = map["success"] + } +} + +extension Fields where TypeLock == Objects.BulkActionSuccess { + func success() throws -> Bool { + let field = GraphQLField.leaf( + name: "success", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.success[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return Bool.mockValue + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias BulkActionSuccess = Selection +} + extension Objects { struct CreateArticleError { let __typename: TypeName = .createArticleError @@ -9356,6 +9507,136 @@ extension Selection where TypeLock == Never, Type == Never { typealias LoginSuccess = Selection } +extension Objects { + struct MarkEmailAsItemError { + let __typename: TypeName = .markEmailAsItemError + let errorCodes: [String: [Enums.MarkEmailAsItemErrorCode]] + + enum TypeName: String, Codable { + case markEmailAsItemError = "MarkEmailAsItemError" + } + } +} + +extension Objects.MarkEmailAsItemError: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.MarkEmailAsItemErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + errorCodes = map["errorCodes"] + } +} + +extension Fields where TypeLock == Objects.MarkEmailAsItemError { + func errorCodes() throws -> [Enums.MarkEmailAsItemErrorCode] { + let field = GraphQLField.leaf( + name: "errorCodes", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.errorCodes[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return [] + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias MarkEmailAsItemError = Selection +} + +extension Objects { + struct MarkEmailAsItemSuccess { + let __typename: TypeName = .markEmailAsItemSuccess + let success: [String: Bool] + + enum TypeName: String, Codable { + case markEmailAsItemSuccess = "MarkEmailAsItemSuccess" + } + } +} + +extension Objects.MarkEmailAsItemSuccess: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "success": + if let value = try container.decode(Bool?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + success = map["success"] + } +} + +extension Fields where TypeLock == Objects.MarkEmailAsItemSuccess { + func success() throws -> Bool { + let field = GraphQLField.leaf( + name: "success", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.success[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return Bool.mockValue + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias MarkEmailAsItemSuccess = Selection +} + extension Objects { struct MergeHighlightError { let __typename: TypeName = .mergeHighlightError @@ -9777,6 +10058,7 @@ extension Objects { struct Mutation { let __typename: TypeName = .mutation let addPopularRead: [String: Unions.AddPopularReadResult] + let bulkAction: [String: Unions.BulkActionResult] let createArticle: [String: Unions.CreateArticleResult] let createArticleSavingRequest: [String: Unions.CreateArticleSavingRequestResult] let createGroup: [String: Unions.CreateGroupResult] @@ -9803,6 +10085,7 @@ extension Objects { let joinGroup: [String: Unions.JoinGroupResult] let leaveGroup: [String: Unions.LeaveGroupResult] let logOut: [String: Unions.LogOutResult] + let markEmailAsItem: [String: Unions.MarkEmailAsItemResult] let mergeHighlight: [String: Unions.MergeHighlightResult] let moveFilter: [String: Unions.MoveFilterResult] let moveLabel: [String: Unions.MoveLabelResult] @@ -9840,6 +10123,7 @@ extension Objects { let updateUser: [String: Unions.UpdateUserResult] let updateUserProfile: [String: Unions.UpdateUserProfileResult] let uploadFileRequest: [String: Unions.UploadFileRequestResult] + let uploadImportFile: [String: Unions.UploadImportFileResult] enum TypeName: String, Codable { case mutation = "Mutation" @@ -9863,6 +10147,10 @@ extension Objects.Mutation: Decodable { if let value = try container.decode(Unions.AddPopularReadResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "bulkAction": + if let value = try container.decode(Unions.BulkActionResult?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } case "createArticle": if let value = try container.decode(Unions.CreateArticleResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) @@ -9967,6 +10255,10 @@ extension Objects.Mutation: Decodable { if let value = try container.decode(Unions.LogOutResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "markEmailAsItem": + if let value = try container.decode(Unions.MarkEmailAsItemResult?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } case "mergeHighlight": if let value = try container.decode(Unions.MergeHighlightResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) @@ -10115,6 +10407,10 @@ extension Objects.Mutation: Decodable { if let value = try container.decode(Unions.UploadFileRequestResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "uploadImportFile": + if let value = try container.decode(Unions.UploadImportFileResult?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -10126,6 +10422,7 @@ extension Objects.Mutation: Decodable { } addPopularRead = map["addPopularRead"] + bulkAction = map["bulkAction"] createArticle = map["createArticle"] createArticleSavingRequest = map["createArticleSavingRequest"] createGroup = map["createGroup"] @@ -10152,6 +10449,7 @@ extension Objects.Mutation: Decodable { joinGroup = map["joinGroup"] leaveGroup = map["leaveGroup"] logOut = map["logOut"] + markEmailAsItem = map["markEmailAsItem"] mergeHighlight = map["mergeHighlight"] moveFilter = map["moveFilter"] moveLabel = map["moveLabel"] @@ -10189,6 +10487,7 @@ extension Objects.Mutation: Decodable { updateUser = map["updateUser"] updateUserProfile = map["updateUserProfile"] uploadFileRequest = map["uploadFileRequest"] + uploadImportFile = map["uploadImportFile"] } } @@ -10212,6 +10511,25 @@ extension Fields where TypeLock == Objects.Mutation { } } + func bulkAction(action: Enums.BulkActionType, query: OptionalArgument = .absent(), selection: Selection) throws -> Type { + let field = GraphQLField.composite( + name: "bulkAction", + arguments: [Argument(name: "action", type: "BulkActionType!", value: action), Argument(name: "query", type: "String", value: query)], + selection: selection.selection + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.bulkAction[field.alias!] { + return try selection.decode(data: data) + } + throw HttpError.badpayload + case .mocking: + return selection.mock() + } + } + func createArticle(input: InputObjects.CreateArticleInput, selection: Selection) throws -> Type { let field = GraphQLField.composite( name: "createArticle", @@ -10706,6 +11024,25 @@ extension Fields where TypeLock == Objects.Mutation { } } + func markEmailAsItem(recentEmailId: String, selection: Selection) throws -> Type { + let field = GraphQLField.composite( + name: "markEmailAsItem", + arguments: [Argument(name: "recentEmailId", type: "ID!", value: recentEmailId)], + selection: selection.selection + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.markEmailAsItem[field.alias!] { + return try selection.decode(data: data) + } + throw HttpError.badpayload + case .mocking: + return selection.mock() + } + } + func mergeHighlight(input: InputObjects.MergeHighlightInput, selection: Selection) throws -> Type { let field = GraphQLField.composite( name: "mergeHighlight", @@ -11408,6 +11745,25 @@ extension Fields where TypeLock == Objects.Mutation { return selection.mock() } } + + func uploadImportFile(contentType: String, type: Enums.UploadImportFileType, selection: Selection) throws -> Type { + let field = GraphQLField.composite( + name: "uploadImportFile", + arguments: [Argument(name: "contentType", type: "String!", value: contentType), Argument(name: "type", type: "UploadImportFileType!", value: type)], + selection: selection.selection + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.uploadImportFile[field.alias!] { + return try selection.decode(data: data) + } + throw HttpError.badpayload + case .mocking: + return selection.mock() + } + } } extension Selection where TypeLock == Never, Type == Never { @@ -11419,7 +11775,9 @@ extension Objects { let __typename: TypeName = .newsletterEmail let address: [String: String] let confirmationCode: [String: String] + let createdAt: [String: DateTime] let id: [String: String] + let subscriptionCount: [String: Int] enum TypeName: String, Codable { case newsletterEmail = "NewsletterEmail" @@ -11447,10 +11805,18 @@ extension Objects.NewsletterEmail: Decodable { if let value = try container.decode(String?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "createdAt": + if let value = try container.decode(DateTime?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } case "id": if let value = try container.decode(String?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "subscriptionCount": + if let value = try container.decode(Int?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -11463,7 +11829,9 @@ extension Objects.NewsletterEmail: Decodable { address = map["address"] confirmationCode = map["confirmationCode"] + createdAt = map["createdAt"] id = map["id"] + subscriptionCount = map["subscriptionCount"] } } @@ -11501,6 +11869,24 @@ extension Fields where TypeLock == Objects.NewsletterEmail { } } + func createdAt() throws -> DateTime { + let field = GraphQLField.leaf( + name: "createdAt", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.createdAt[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return DateTime.mockValue + } + } + func id() throws -> String { let field = GraphQLField.leaf( name: "id", @@ -11518,6 +11904,24 @@ extension Fields where TypeLock == Objects.NewsletterEmail { return String.mockValue } } + + func subscriptionCount() throws -> Int { + let field = GraphQLField.leaf( + name: "subscriptionCount", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.subscriptionCount[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return Int.mockValue + } + } } extension Selection where TypeLock == Never, Type == Never { @@ -12480,6 +12884,7 @@ extension Objects { let labels: [String: Unions.LabelsResult] let me: [String: Objects.User] let newsletterEmails: [String: Unions.NewsletterEmailsResult] + let recentEmails: [String: Unions.RecentEmailsResult] let recentSearches: [String: Unions.RecentSearchesResult] let reminder: [String: Unions.ReminderResult] let rules: [String: Unions.RulesResult] @@ -12577,6 +12982,10 @@ extension Objects.Query: Decodable { if let value = try container.decode(Unions.NewsletterEmailsResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "recentEmails": + if let value = try container.decode(Unions.RecentEmailsResult?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } case "recentSearches": if let value = try container.decode(Unions.RecentSearchesResult?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) @@ -12659,6 +13068,7 @@ extension Objects.Query: Decodable { labels = map["labels"] me = map["me"] newsletterEmails = map["newsletterEmails"] + recentEmails = map["recentEmails"] recentSearches = map["recentSearches"] reminder = map["reminder"] rules = map["rules"] @@ -12696,10 +13106,10 @@ extension Fields where TypeLock == Objects.Query { } } - func article(slug: String, username: String, selection: Selection) throws -> Type { + func article(format: OptionalArgument = .absent(), slug: String, username: String, selection: Selection) throws -> Type { let field = GraphQLField.composite( name: "article", - arguments: [Argument(name: "slug", type: "String!", value: slug), Argument(name: "username", type: "String!", value: username)], + arguments: [Argument(name: "format", type: "String", value: format), Argument(name: "slug", type: "String!", value: slug), Argument(name: "username", type: "String!", value: username)], selection: selection.selection ) select(field) @@ -12974,6 +13384,25 @@ extension Fields where TypeLock == Objects.Query { } } + func recentEmails(selection: Selection) throws -> Type { + let field = GraphQLField.composite( + name: "recentEmails", + arguments: [], + selection: selection.selection + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.recentEmails[field.alias!] { + return try selection.decode(data: data) + } + throw HttpError.badpayload + case .mocking: + return selection.mock() + } + } + func recentSearches(selection: Selection) throws -> Type { let field = GraphQLField.composite( name: "recentSearches", @@ -13031,10 +13460,10 @@ extension Fields where TypeLock == Objects.Query { } } - func search(after: OptionalArgument = .absent(), first: OptionalArgument = .absent(), query: OptionalArgument = .absent(), selection: Selection) throws -> Type { + func search(after: OptionalArgument = .absent(), first: OptionalArgument = .absent(), format: OptionalArgument = .absent(), includeContent: OptionalArgument = .absent(), query: OptionalArgument = .absent(), selection: Selection) throws -> Type { let field = GraphQLField.composite( name: "search", - arguments: [Argument(name: "after", type: "String", value: after), Argument(name: "first", type: "Int", value: first), Argument(name: "query", type: "String", value: query)], + arguments: [Argument(name: "after", type: "String", value: after), Argument(name: "first", type: "Int", value: first), Argument(name: "format", type: "String", value: format), Argument(name: "includeContent", type: "Boolean", value: includeContent), Argument(name: "query", type: "String", value: query)], selection: selection.selection ) select(field) @@ -13534,6 +13963,367 @@ extension Selection where TypeLock == Never, Type == Never { typealias ReadState = Selection } +extension Objects { + struct RecentEmail { + let __typename: TypeName = .recentEmail + let createdAt: [String: DateTime] + let from: [String: String] + let html: [String: String] + let id: [String: String] + let subject: [String: String] + let text: [String: String] + let to: [String: String] + let type: [String: String] + + enum TypeName: String, Codable { + case recentEmail = "RecentEmail" + } + } +} + +extension Objects.RecentEmail: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "createdAt": + if let value = try container.decode(DateTime?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "from": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "html": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "id": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "subject": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "text": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "to": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "type": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + createdAt = map["createdAt"] + from = map["from"] + html = map["html"] + id = map["id"] + subject = map["subject"] + text = map["text"] + to = map["to"] + type = map["type"] + } +} + +extension Fields where TypeLock == Objects.RecentEmail { + func createdAt() throws -> DateTime { + let field = GraphQLField.leaf( + name: "createdAt", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.createdAt[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return DateTime.mockValue + } + } + + func from() throws -> String { + let field = GraphQLField.leaf( + name: "from", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.from[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return String.mockValue + } + } + + func html() throws -> String? { + let field = GraphQLField.leaf( + name: "html", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + return data.html[field.alias!] + case .mocking: + return nil + } + } + + func id() throws -> String { + let field = GraphQLField.leaf( + name: "id", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.id[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return String.mockValue + } + } + + func subject() throws -> String { + let field = GraphQLField.leaf( + name: "subject", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.subject[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return String.mockValue + } + } + + func text() throws -> String { + let field = GraphQLField.leaf( + name: "text", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.text[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return String.mockValue + } + } + + func to() throws -> String { + let field = GraphQLField.leaf( + name: "to", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.to[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return String.mockValue + } + } + + func type() throws -> String { + let field = GraphQLField.leaf( + name: "type", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.type[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return String.mockValue + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias RecentEmail = Selection +} + +extension Objects { + struct RecentEmailsError { + let __typename: TypeName = .recentEmailsError + let errorCodes: [String: [Enums.RecentEmailsErrorCode]] + + enum TypeName: String, Codable { + case recentEmailsError = "RecentEmailsError" + } + } +} + +extension Objects.RecentEmailsError: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.RecentEmailsErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + errorCodes = map["errorCodes"] + } +} + +extension Fields where TypeLock == Objects.RecentEmailsError { + func errorCodes() throws -> [Enums.RecentEmailsErrorCode] { + let field = GraphQLField.leaf( + name: "errorCodes", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.errorCodes[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return [] + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias RecentEmailsError = Selection +} + +extension Objects { + struct RecentEmailsSuccess { + let __typename: TypeName = .recentEmailsSuccess + let recentEmails: [String: [Objects.RecentEmail]] + + enum TypeName: String, Codable { + case recentEmailsSuccess = "RecentEmailsSuccess" + } + } +} + +extension Objects.RecentEmailsSuccess: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "recentEmails": + if let value = try container.decode([Objects.RecentEmail]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + recentEmails = map["recentEmails"] + } +} + +extension Fields where TypeLock == Objects.RecentEmailsSuccess { + func recentEmails(selection: Selection) throws -> Type { + let field = GraphQLField.composite( + name: "recentEmails", + arguments: [], + selection: selection.selection + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.recentEmails[field.alias!] { + return try selection.decode(data: data) + } + throw HttpError.badpayload + case .mocking: + return selection.mock() + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias RecentEmailsSuccess = Selection +} + extension Objects { struct RecentSearch { let __typename: TypeName = .recentSearch @@ -16030,6 +16820,7 @@ extension Objects { let __typename: TypeName = .searchItem let annotation: [String: String] let author: [String: String] + let content: [String: String] let contentReader: [String: Enums.ContentReader] let createdAt: [String: DateTime] let description: [String: String] @@ -16062,6 +16853,7 @@ extension Objects { let updatedAt: [String: DateTime] let uploadFileId: [String: String] let url: [String: String] + let wordsCount: [String: Int] enum TypeName: String, Codable { case searchItem = "SearchItem" @@ -16089,6 +16881,10 @@ extension Objects.SearchItem: Decodable { if let value = try container.decode(String?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "content": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } case "contentReader": if let value = try container.decode(Enums.ContentReader?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) @@ -16217,6 +17013,10 @@ extension Objects.SearchItem: Decodable { if let value = try container.decode(String?.self, forKey: codingKey) { map.set(key: field, hash: alias, value: value as Any) } + case "wordsCount": + if let value = try container.decode(Int?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -16229,6 +17029,7 @@ extension Objects.SearchItem: Decodable { annotation = map["annotation"] author = map["author"] + content = map["content"] contentReader = map["contentReader"] createdAt = map["createdAt"] description = map["description"] @@ -16261,6 +17062,7 @@ extension Objects.SearchItem: Decodable { updatedAt = map["updatedAt"] uploadFileId = map["uploadFileId"] url = map["url"] + wordsCount = map["wordsCount"] } } @@ -16295,6 +17097,21 @@ extension Fields where TypeLock == Objects.SearchItem { } } + func content() throws -> String? { + let field = GraphQLField.leaf( + name: "content", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + return data.content[field.alias!] + case .mocking: + return nil + } + } + func contentReader() throws -> Enums.ContentReader { let field = GraphQLField.leaf( name: "contentReader", @@ -16810,6 +17627,21 @@ extension Fields where TypeLock == Objects.SearchItem { return String.mockValue } } + + func wordsCount() throws -> Int? { + let field = GraphQLField.leaf( + name: "wordsCount", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + return data.wordsCount[field.alias!] + case .mocking: + return nil + } + } } extension Selection where TypeLock == Never, Type == Never { @@ -21357,6 +22189,133 @@ extension Selection where TypeLock == Never, Type == Never { typealias UploadFileRequestSuccess = Selection } +extension Objects { + struct UploadImportFileError { + let __typename: TypeName = .uploadImportFileError + let errorCodes: [String: [Enums.UploadImportFileErrorCode]] + + enum TypeName: String, Codable { + case uploadImportFileError = "UploadImportFileError" + } + } +} + +extension Objects.UploadImportFileError: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.UploadImportFileErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + errorCodes = map["errorCodes"] + } +} + +extension Fields where TypeLock == Objects.UploadImportFileError { + func errorCodes() throws -> [Enums.UploadImportFileErrorCode] { + let field = GraphQLField.leaf( + name: "errorCodes", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + if let data = data.errorCodes[field.alias!] { + return data + } + throw HttpError.badpayload + case .mocking: + return [] + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias UploadImportFileError = Selection +} + +extension Objects { + struct UploadImportFileSuccess { + let __typename: TypeName = .uploadImportFileSuccess + let uploadSignedUrl: [String: String] + + enum TypeName: String, Codable { + case uploadImportFileSuccess = "UploadImportFileSuccess" + } + } +} + +extension Objects.UploadImportFileSuccess: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "uploadSignedUrl": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + uploadSignedUrl = map["uploadSignedUrl"] + } +} + +extension Fields where TypeLock == Objects.UploadImportFileSuccess { + func uploadSignedUrl() throws -> String? { + let field = GraphQLField.leaf( + name: "uploadSignedUrl", + arguments: [] + ) + select(field) + + switch response { + case let .decoding(data): + return data.uploadSignedUrl[field.alias!] + case .mocking: + return nil + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias UploadImportFileSuccess = Selection +} + extension Objects { struct User { let __typename: TypeName = .user @@ -23178,6 +24137,80 @@ extension Selection where TypeLock == Never, Type == Never { typealias ArticlesResult = Selection } +extension Unions { + struct BulkActionResult { + let __typename: TypeName + let errorCodes: [String: [Enums.BulkActionErrorCode]] + let success: [String: Bool] + + enum TypeName: String, Codable { + case bulkActionError = "BulkActionError" + case bulkActionSuccess = "BulkActionSuccess" + } + } +} + +extension Unions.BulkActionResult: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.BulkActionErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "success": + if let value = try container.decode(Bool?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + __typename = try container.decode(TypeName.self, forKey: DynamicCodingKeys(stringValue: "__typename")!) + + errorCodes = map["errorCodes"] + success = map["success"] + } +} + +extension Fields where TypeLock == Unions.BulkActionResult { + func on(bulkActionError: Selection, bulkActionSuccess: Selection) throws -> Type { + select([GraphQLField.fragment(type: "BulkActionError", selection: bulkActionError.selection), GraphQLField.fragment(type: "BulkActionSuccess", selection: bulkActionSuccess.selection)]) + + switch response { + case let .decoding(data): + switch data.__typename { + case .bulkActionError: + let data = Objects.BulkActionError(errorCodes: data.errorCodes) + return try bulkActionError.decode(data: data) + case .bulkActionSuccess: + let data = Objects.BulkActionSuccess(success: data.success) + return try bulkActionSuccess.decode(data: data) + } + case .mocking: + return bulkActionError.mock() + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias BulkActionResult = Selection +} + extension Unions { struct CreateArticleResult { let __typename: TypeName @@ -25786,6 +26819,80 @@ extension Selection where TypeLock == Never, Type == Never { typealias LoginResult = Selection } +extension Unions { + struct MarkEmailAsItemResult { + let __typename: TypeName + let errorCodes: [String: [Enums.MarkEmailAsItemErrorCode]] + let success: [String: Bool] + + enum TypeName: String, Codable { + case markEmailAsItemError = "MarkEmailAsItemError" + case markEmailAsItemSuccess = "MarkEmailAsItemSuccess" + } + } +} + +extension Unions.MarkEmailAsItemResult: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.MarkEmailAsItemErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "success": + if let value = try container.decode(Bool?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + __typename = try container.decode(TypeName.self, forKey: DynamicCodingKeys(stringValue: "__typename")!) + + errorCodes = map["errorCodes"] + success = map["success"] + } +} + +extension Fields where TypeLock == Unions.MarkEmailAsItemResult { + func on(markEmailAsItemError: Selection, markEmailAsItemSuccess: Selection) throws -> Type { + select([GraphQLField.fragment(type: "MarkEmailAsItemError", selection: markEmailAsItemError.selection), GraphQLField.fragment(type: "MarkEmailAsItemSuccess", selection: markEmailAsItemSuccess.selection)]) + + switch response { + case let .decoding(data): + switch data.__typename { + case .markEmailAsItemError: + let data = Objects.MarkEmailAsItemError(errorCodes: data.errorCodes) + return try markEmailAsItemError.decode(data: data) + case .markEmailAsItemSuccess: + let data = Objects.MarkEmailAsItemSuccess(success: data.success) + return try markEmailAsItemSuccess.decode(data: data) + } + case .mocking: + return markEmailAsItemError.mock() + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias MarkEmailAsItemResult = Selection +} + extension Unions { struct MergeHighlightResult { let __typename: TypeName @@ -26162,6 +27269,80 @@ extension Selection where TypeLock == Never, Type == Never { typealias OptInFeatureResult = Selection } +extension Unions { + struct RecentEmailsResult { + let __typename: TypeName + let errorCodes: [String: [Enums.RecentEmailsErrorCode]] + let recentEmails: [String: [Objects.RecentEmail]] + + enum TypeName: String, Codable { + case recentEmailsError = "RecentEmailsError" + case recentEmailsSuccess = "RecentEmailsSuccess" + } + } +} + +extension Unions.RecentEmailsResult: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.RecentEmailsErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "recentEmails": + if let value = try container.decode([Objects.RecentEmail]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + __typename = try container.decode(TypeName.self, forKey: DynamicCodingKeys(stringValue: "__typename")!) + + errorCodes = map["errorCodes"] + recentEmails = map["recentEmails"] + } +} + +extension Fields where TypeLock == Unions.RecentEmailsResult { + func on(recentEmailsError: Selection, recentEmailsSuccess: Selection) throws -> Type { + select([GraphQLField.fragment(type: "RecentEmailsError", selection: recentEmailsError.selection), GraphQLField.fragment(type: "RecentEmailsSuccess", selection: recentEmailsSuccess.selection)]) + + switch response { + case let .decoding(data): + switch data.__typename { + case .recentEmailsError: + let data = Objects.RecentEmailsError(errorCodes: data.errorCodes) + return try recentEmailsError.decode(data: data) + case .recentEmailsSuccess: + let data = Objects.RecentEmailsSuccess(recentEmails: data.recentEmails) + return try recentEmailsSuccess.decode(data: data) + } + case .mocking: + return recentEmailsError.mock() + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias RecentEmailsResult = Selection +} + extension Unions { struct RecentSearchesResult { let __typename: TypeName @@ -28960,6 +30141,80 @@ extension Selection where TypeLock == Never, Type == Never { typealias UploadFileRequestResult = Selection } +extension Unions { + struct UploadImportFileResult { + let __typename: TypeName + let errorCodes: [String: [Enums.UploadImportFileErrorCode]] + let uploadSignedUrl: [String: String] + + enum TypeName: String, Codable { + case uploadImportFileError = "UploadImportFileError" + case uploadImportFileSuccess = "UploadImportFileSuccess" + } + } +} + +extension Unions.UploadImportFileResult: Decodable { + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: DynamicCodingKeys.self) + + var map = HashMap() + for codingKey in container.allKeys { + if codingKey.isTypenameKey { continue } + + let alias = codingKey.stringValue + let field = GraphQLField.getFieldNameFromAlias(alias) + + switch field { + case "errorCodes": + if let value = try container.decode([Enums.UploadImportFileErrorCode]?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + case "uploadSignedUrl": + if let value = try container.decode(String?.self, forKey: codingKey) { + map.set(key: field, hash: alias, value: value as Any) + } + default: + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Unknown key \(field)." + ) + ) + } + } + + __typename = try container.decode(TypeName.self, forKey: DynamicCodingKeys(stringValue: "__typename")!) + + errorCodes = map["errorCodes"] + uploadSignedUrl = map["uploadSignedUrl"] + } +} + +extension Fields where TypeLock == Unions.UploadImportFileResult { + func on(uploadImportFileError: Selection, uploadImportFileSuccess: Selection) throws -> Type { + select([GraphQLField.fragment(type: "UploadImportFileError", selection: uploadImportFileError.selection), GraphQLField.fragment(type: "UploadImportFileSuccess", selection: uploadImportFileSuccess.selection)]) + + switch response { + case let .decoding(data): + switch data.__typename { + case .uploadImportFileError: + let data = Objects.UploadImportFileError(errorCodes: data.errorCodes) + return try uploadImportFileError.decode(data: data) + case .uploadImportFileSuccess: + let data = Objects.UploadImportFileSuccess(uploadSignedUrl: data.uploadSignedUrl) + return try uploadImportFileSuccess.decode(data: data) + } + case .mocking: + return uploadImportFileError.mock() + } + } +} + +extension Selection where TypeLock == Never, Type == Never { + typealias UploadImportFileResult = Selection +} + extension Unions { struct UserResult { let __typename: TypeName @@ -29328,6 +30583,22 @@ extension Enums { } } +extension Enums { + /// BulkActionErrorCode + enum BulkActionErrorCode: String, CaseIterable, Codable { + case unauthorized = "UNAUTHORIZED" + } +} + +extension Enums { + /// BulkActionType + enum BulkActionType: String, CaseIterable, Codable { + case archive = "ARCHIVE" + + case delete = "DELETE" + } +} + extension Enums { /// ContentReader enum ContentReader: String, CaseIterable, Codable { @@ -29710,6 +30981,17 @@ extension Enums { } } +extension Enums { + /// MarkEmailAsItemErrorCode + enum MarkEmailAsItemErrorCode: String, CaseIterable, Codable { + case badRequest = "BAD_REQUEST" + + case notFound = "NOT_FOUND" + + case unauthorized = "UNAUTHORIZED" + } +} + extension Enums { /// MergeHighlightErrorCode enum MergeHighlightErrorCode: String, CaseIterable, Codable { @@ -29801,6 +31083,15 @@ extension Enums { } } +extension Enums { + /// RecentEmailsErrorCode + enum RecentEmailsErrorCode: String, CaseIterable, Codable { + case badRequest = "BAD_REQUEST" + + case unauthorized = "UNAUTHORIZED" + } +} + extension Enums { /// RecentSearchesErrorCode enum RecentSearchesErrorCode: String, CaseIterable, Codable { @@ -30302,6 +31593,28 @@ extension Enums { } } +extension Enums { + /// UploadImportFileErrorCode + enum UploadImportFileErrorCode: String, CaseIterable, Codable { + case badRequest = "BAD_REQUEST" + + case unauthorized = "UNAUTHORIZED" + + case uploadDailyLimitExceeded = "UPLOAD_DAILY_LIMIT_EXCEEDED" + } +} + +extension Enums { + /// UploadImportFileType + enum UploadImportFileType: String, CaseIterable, Codable { + case matter = "MATTER" + + case pocket = "POCKET" + + case urlList = "URL_LIST" + } +} + extension Enums { /// UserErrorCode enum UserErrorCode: String, CaseIterable, Codable { @@ -30868,6 +32181,65 @@ extension InputObjects { } } +extension InputObjects { + struct ParseResult: Encodable, Hashable { + var byline: OptionalArgument = .absent() + + var content: String + + var dir: OptionalArgument = .absent() + + var excerpt: String + + var language: OptionalArgument = .absent() + + var length: Int + + var previewImage: OptionalArgument = .absent() + + var publishedDate: OptionalArgument = .absent() + + var siteIcon: OptionalArgument = .absent() + + var siteName: OptionalArgument = .absent() + + var textContent: String + + var title: String + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if byline.hasValue { try container.encode(byline, forKey: .byline) } + try container.encode(content, forKey: .content) + if dir.hasValue { try container.encode(dir, forKey: .dir) } + try container.encode(excerpt, forKey: .excerpt) + if language.hasValue { try container.encode(language, forKey: .language) } + try container.encode(length, forKey: .length) + if previewImage.hasValue { try container.encode(previewImage, forKey: .previewImage) } + if publishedDate.hasValue { try container.encode(publishedDate, forKey: .publishedDate) } + if siteIcon.hasValue { try container.encode(siteIcon, forKey: .siteIcon) } + if siteName.hasValue { try container.encode(siteName, forKey: .siteName) } + try container.encode(textContent, forKey: .textContent) + try container.encode(title, forKey: .title) + } + + enum CodingKeys: String, CodingKey { + case byline + case content + case dir + case excerpt + case language + case length + case previewImage + case publishedDate + case siteIcon + case siteName + case textContent + case title + } + } +} + extension InputObjects { struct PreparedDocumentInput: Encodable, Hashable { var document: String @@ -31074,6 +32446,8 @@ extension InputObjects { var originalContent: String + var parseResult: OptionalArgument = .absent() + var source: String var title: OptionalArgument = .absent() @@ -31084,6 +32458,7 @@ extension InputObjects { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(clientRequestId, forKey: .clientRequestId) try container.encode(originalContent, forKey: .originalContent) + if parseResult.hasValue { try container.encode(parseResult, forKey: .parseResult) } try container.encode(source, forKey: .source) if title.hasValue { try container.encode(title, forKey: .title) } try container.encode(url, forKey: .url) @@ -31092,6 +32467,7 @@ extension InputObjects { enum CodingKeys: String, CodingKey { case clientRequestId case originalContent + case parseResult case source case title case url diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleReadingProgress.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleReadingProgress.swift index 33711f651..0473a56ff 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleReadingProgress.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleReadingProgress.swift @@ -9,6 +9,7 @@ extension DataService { guard let self = self else { return } guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) else { return } + print("updateLinkReadingProgress", readingProgress, anchorIndex) linkedItem.update( inContext: self.backgroundContext, newReadingProgress: readingProgress, diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift index a9170e38e..56e7a77ea 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift @@ -44,6 +44,7 @@ extension DataService { contentReader: try $0.contentReader().rawValue, originalHtml: nil, language: try $0.language(), + wordsCount: try $0.wordsCount(), recommendations: try $0.recommendations(selection: recommendationSelection.list.nullable) ?? [], labels: try $0.labels(selection: feedItemLabelSelection.list.nullable) ?? [] ), diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift index eac3e5e26..c560cbcb1 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift @@ -275,6 +275,7 @@ private let libraryArticleSelection = Selection.Article { contentReader: try $0.contentReader().rawValue, originalHtml: nil, language: try $0.language(), + wordsCount: try $0.wordsCount(), recommendations: try $0.recommendations(selection: recommendationSelection.list.nullable) ?? [], labels: try $0.labels(selection: feedItemLabelSelection.list.nullable) ?? [] ) @@ -313,6 +314,7 @@ private let searchItemSelection = Selection.SearchItem { contentReader: try $0.contentReader().rawValue, originalHtml: nil, language: try $0.language(), + wordsCount: try $0.wordsCount(), recommendations: try $0.recommendations(selection: recommendationSelection.list.nullable) ?? [], labels: try $0.labels(selection: feedItemLabelSelection.list.nullable) ?? [] ) diff --git a/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift b/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift index 46827adf8..4f914d7e8 100644 --- a/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift +++ b/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift @@ -26,6 +26,7 @@ struct InternalLinkedItem { let contentReader: String? let originalHtml: String? let language: String? + let wordsCount: Int? let recommendations: [InternalRecommendation] var labels: [InternalLinkedItemLabel] @@ -63,6 +64,7 @@ struct InternalLinkedItem { linkedItem.contentReader = contentReader linkedItem.originalHtml = originalHtml linkedItem.language = language + linkedItem.wordsCount = Int64(wordsCount ?? 0) // Remove existing labels in case a label had been deleted if let existingLabels = linkedItem.labels { @@ -142,6 +144,7 @@ extension JSONArticle { contentReader: contentReader, originalHtml: nil, language: language, + wordsCount: wordsCount, recommendations: [], // TODO: labels: [] ) diff --git a/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift b/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift index 6cafc7cd1..9549f5fc8 100644 --- a/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift +++ b/apple/OmnivoreKit/Sources/Utils/UserDefaultKeys.swift @@ -28,4 +28,5 @@ public enum UserDefaultKey: String { case notificationsEnabled case deviceTokenID case shouldPromptCommunityModal + case userWordsPerMinute } diff --git a/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift b/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift index 013e05dda..523f2515b 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/OmnivoreWebView.swift @@ -415,6 +415,7 @@ public enum WebViewDispatchEvent { case speakingSection(anchorIdx: String) case updateLabels(labels: String) case updateTitle(title: String) + case saveReadPosition var script: String { get throws { @@ -463,6 +464,8 @@ public enum WebViewDispatchEvent { return "updateTitle" case .handleAutoHighlightModeChange: return "handleAutoHighlightModeChange" + case .saveReadPosition: + return "saveReadPosition" } } @@ -503,10 +506,17 @@ public enum WebViewDispatchEvent { } case let .speakingSection(anchorIdx: anchorIdx): return "event.anchorIdx = '\(anchorIdx)';" - case .annotate, .highlight, .setHighlightLabels, .share, .remove, .copyHighlight, .dismissHighlight: - return "" case let .handleAutoHighlightModeChange(isEnabled: isEnabled): return "event.enableHighlightOnRelease = '\(isEnabled ? "on" : "off")';" + case .annotate, + .highlight, + .setHighlightLabels, + .share, + .remove, + .copyHighlight, + .dismissHighlight, + .saveReadPosition: + return "" } } } diff --git a/apple/OmnivoreKit/Sources/Views/Colors/Colors.swift b/apple/OmnivoreKit/Sources/Views/Colors/Colors.swift index cdb0cf5a5..15d2e2014 100644 --- a/apple/OmnivoreKit/Sources/Views/Colors/Colors.swift +++ b/apple/OmnivoreKit/Sources/Views/Colors/Colors.swift @@ -19,7 +19,7 @@ public extension Color { static var appButtonBackground: Color { Color("_buttonBackground", bundle: .module) } static var appTextDefault: Color { Color("_utilityTextDefault", bundle: .module) } static var appPrimaryBackground: Color { Color("_appPrimaryBackground", bundle: .module) } - static var checkmarkBlue: Color { Color("_checkmarkBlue", bundle: .module) } + static var indicatorBlue: Color { Color("_indicatorBlue", bundle: .module) } static var webControlButtonBackground: Color { Color("_webControlButtonBackground", bundle: .module) } // Apple system UIColor equivalents diff --git a/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_appGreenSuccess.colorset/Contents.json b/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_appGreenSuccess.colorset/Contents.json index 6f5bd0010..8ac27726e 100644 --- a/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_appGreenSuccess.colorset/Contents.json +++ b/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_appGreenSuccess.colorset/Contents.json @@ -5,9 +5,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0.294", - "green" : "0.843", - "red" : "0.196" + "blue" : "0.220", + "green" : "0.725", + "red" : "0.333" } }, "idiom" : "universal" @@ -23,9 +23,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0.294", - "green" : "0.843", - "red" : "0.196" + "blue" : "0.220", + "green" : "0.725", + "red" : "0.333" } }, "idiom" : "universal" diff --git a/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_checkmarkBlue.colorset/Contents.json b/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_indicatorBlue.colorset/Contents.json similarity index 76% rename from apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_checkmarkBlue.colorset/Contents.json rename to apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_indicatorBlue.colorset/Contents.json index c285b1550..e21405bea 100644 --- a/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_checkmarkBlue.colorset/Contents.json +++ b/apple/OmnivoreKit/Sources/Views/Colors/Colors.xcassets/_indicatorBlue.colorset/Contents.json @@ -5,9 +5,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0xFF", - "green" : "0x84", - "red" : "0x0A" + "blue" : "0xF7", + "green" : "0x82", + "red" : "0x3A" } }, "idiom" : "universal" @@ -23,9 +23,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0xFF", - "green" : "0x84", - "red" : "0x0A" + "blue" : "0xF7", + "green" : "0x82", + "red" : "0x3A" } }, "idiom" : "universal" diff --git a/apple/OmnivoreKit/Sources/Views/FeedItem/LibraryItemCard.swift b/apple/OmnivoreKit/Sources/Views/FeedItem/LibraryItemCard.swift new file mode 100644 index 000000000..29d84b04d --- /dev/null +++ b/apple/OmnivoreKit/Sources/Views/FeedItem/LibraryItemCard.swift @@ -0,0 +1,221 @@ +import Models +import SwiftUI +import Utils + +public struct LibraryItemCard: View { + let viewer: Viewer? + let tapHandler: () -> Void + @ObservedObject var item: LinkedItem + + public init(item: LinkedItem, viewer: Viewer?, tapHandler: @escaping () -> Void = {}) { + self.item = item + self.viewer = viewer + self.tapHandler = tapHandler + } + + public var body: some View { + VStack { + HStack(alignment: .top, spacing: 0) { + readIndicator + articleInfo + imageBox + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + + if item.hasLabels { + labels + } + } + .padding(.bottom, 8) + } + + var isFullyRead: Bool { + item.readingProgress > 95 + } + + var isPartiallyRead: Bool { + Int(item.readingProgress) > 0 + } + + var readIndicator: some View { + HStack { + Circle() + .foregroundColor(item.readingProgress > 0 ? .clear : .indicatorBlue) + .frame(width: 9, height: 9, alignment: .topLeading) + .padding(.top, 22) + .padding(.leading, 0) + .padding(.trailing, 8) + } + .padding(0) + .frame(width: 20) + } + + var readingSpeed: Int64 { + var result = UserDefaults.standard.integer(forKey: UserDefaultKey.userWordsPerMinute.rawValue) + if result <= 0 { + result = 235 + } + return Int64(result) + } + + var estimatedReadingTime: String { + if item.wordsCount > 0 { + let readLen = max(1, item.wordsCount / readingSpeed) + return "\(readLen) MIN READ • " + } + return "" + } + + var readingProgress: String { + // If there is no wordsCount don't show progress because it will make no sense + if item.wordsCount > 0 { + return "\(String(format: "%d", Int(item.readingProgress)))%" + } + return "" + } + + var highlightsText: String { + if let highlights = item.highlights, highlights.count > 0 { + let fmted = LocalText.pluralizedText(key: "number_of_highlights", count: highlights.count) + if item.wordsCount > 0 { + return " • \(fmted)" + } + return fmted + } + return "" + } + + var notesText: String { + let notes = item.highlights?.filter { item in + if let highlight = item as? Highlight { + return !(highlight.annotation ?? "").isEmpty + } + return false + } + + if let notes = notes, notes.count > 0 { + let fmted = LocalText.pluralizedText(key: "number_of_notes", count: notes.count) + if item.wordsCount > 0 { + return " • \(fmted)" + } + return fmted + } + return "" + } + + var readInfo: some View { + AnyView(HStack { + Text("\(estimatedReadingTime)") + .font(Font.system(size: 11, weight: .medium)) + .foregroundColor(Color(hex: "#898989")) + + + Text("\(readingProgress)") + .font(Font.system(size: 11, weight: .medium)) + .foregroundColor(isPartiallyRead ? Color.appGreenSuccess : Color(hex: "#898989")) + + + + Text("\(highlightsText)") + .font(Font.system(size: 11, weight: .medium)) + .foregroundColor(Color(hex: "#898989")) + + + + Text("\(notesText)") + .font(Font.system(size: 11, weight: .medium)) + .foregroundColor(Color(hex: "#898989")) + } + .frame(maxWidth: .infinity, alignment: .leading)) + } + + var imageBox: some View { + Group { + if let imageURL = item.imageURL { + AsyncImage(url: imageURL) { phase in + if let image = phase.image { + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 55, height: 73) + .cornerRadius(4) + .padding(.top, 2) + } else { + Color.systemBackground + .frame(width: 55, height: 73) + .cornerRadius(4) + .padding(.top, 2) + } + } + } + }.opacity(isFullyRead ? 0.4 : 1.0) + } + + var bylineStr: String { + // It seems like it could be cleaner just having author, instead of + // concating, maybe we fall back + if let author = item.author { + return author + } else if let publisherDisplayName = item.publisherDisplayName { + return publisherDisplayName + } + + return "" + +// var str = "" +// if let author = item.author { +// str += author +// } +// +// if item.author != nil, item.publisherDisplayName != nil { +// str += ", " +// } +// +// if let publisherDisplayName = item.publisherDisplayName { +// str += publisherDisplayName +// } +// +// return str + } + + var byLine: some View { + Text(bylineStr) + .font(Font.system(size: 15, weight: .regular)) + .foregroundColor(Color(hex: "#898989")) + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) + } + + public var articleInfo: some View { + VStack(alignment: .leading, spacing: 5) { + readInfo + + Text(item.unwrappedTitle) + .font(Font.system(size: 18, weight: .semibold)) + .lineSpacing(1.25) + .foregroundColor(isFullyRead ? Color(hex: "#898989") : .appGrayTextContrast) + .fixedSize(horizontal: false, vertical: true) + + byLine + } + .padding(0) + .padding(.trailing, 8) + } + + var labels: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack { + ForEach(item.sortedLabels, id: \.self) { + TextChip(feedItemLabel: $0) + } + Spacer() + } + }.introspectScrollView { scrollView in + scrollView.bounces = false + } + .padding(.top, 0) + .padding(.leading, 20) + #if os(macOS) + .onTapGesture { + tapHandler() + } + #endif + } +} diff --git a/apple/OmnivoreKit/Sources/Views/LocalText.swift b/apple/OmnivoreKit/Sources/Views/LocalText.swift index c1186301f..ff21ce662 100644 --- a/apple/OmnivoreKit/Sources/Views/LocalText.swift +++ b/apple/OmnivoreKit/Sources/Views/LocalText.swift @@ -5,6 +5,12 @@ public enum LocalText { NSLocalizedString(key, bundle: .module, comment: comment ?? "no comment provided by developer") } + public static func pluralizedText(key: String, count: Int) -> String { + let format = NSLocalizedString(key, bundle: .module, comment: "") + print("key", key, "format", format) + return String.localizedStringWithFormat(format, count) + } + // Share extension public static let saveArticleSavedState = localText(key: "saveArticleSavedState") public static let saveArticleProcessingState = localText(key: "saveArticleProcessingState") diff --git a/apple/OmnivoreKit/Sources/Views/Resources/bundle.js b/apple/OmnivoreKit/Sources/Views/Resources/bundle.js index ee45d7e5d..dc9d5e930 100644 --- a/apple/OmnivoreKit/Sources/Views/Resources/bundle.js +++ b/apple/OmnivoreKit/Sources/Views/Resources/bundle.js @@ -1,2 +1,2 @@ /*! For license information please see bundle.js.LICENSE.txt */ -(()=>{var e,t,n={7162:(e,t,n)=>{e.exports=n(5047)},6279:function(e,t){var n="undefined"!=typeof self?self:this,r=function(){function e(){this.fetch=!1,this.DOMException=n.DOMException}return e.prototype=n,new e}();!function(e){!function(t){var n="URLSearchParams"in e,r="Symbol"in e&&"iterator"in Symbol,o="FileReader"in e&&"Blob"in e&&function(){try{return new Blob,!0}catch(e){return!1}}(),i="FormData"in e,a="ArrayBuffer"in e;if(a)var l=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],s=ArrayBuffer.isView||function(e){return e&&l.indexOf(Object.prototype.toString.call(e))>-1};function u(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function c(e){return"string"!=typeof e&&(e=String(e)),e}function f(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return r&&(t[Symbol.iterator]=function(){return t}),t}function d(e){this.map={},e instanceof d?e.forEach((function(e,t){this.append(t,e)}),this):Array.isArray(e)?e.forEach((function(e){this.append(e[0],e[1])}),this):e&&Object.getOwnPropertyNames(e).forEach((function(t){this.append(t,e[t])}),this)}function p(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function h(e){return new Promise((function(t,n){e.onload=function(){t(e.result)},e.onerror=function(){n(e.error)}}))}function g(e){var t=new FileReader,n=h(t);return t.readAsArrayBuffer(e),n}function m(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function v(){return this.bodyUsed=!1,this._initBody=function(e){var t;this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:o&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:i&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:n&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():a&&o&&(t=e)&&DataView.prototype.isPrototypeOf(t)?(this._bodyArrayBuffer=m(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):a&&(ArrayBuffer.prototype.isPrototypeOf(e)||s(e))?this._bodyArrayBuffer=m(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):n&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},o&&(this.blob=function(){var e=p(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?p(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(g)}),this.text=function(){var e,t,n,r=p(this);if(r)return r;if(this._bodyBlob)return e=this._bodyBlob,n=h(t=new FileReader),t.readAsText(e),n;if(this._bodyArrayBuffer)return Promise.resolve(function(e){for(var t=new Uint8Array(e),n=new Array(t.length),r=0;r-1?r:n),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&o)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(o)}function w(e){var t=new FormData;return e.trim().split("&").forEach((function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),o=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(o))}})),t}function x(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new d(t.headers),this.url=t.url||"",this._initBody(e)}b.prototype.clone=function(){return new b(this,{body:this._bodyInit})},v.call(b.prototype),v.call(x.prototype),x.prototype.clone=function(){return new x(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new d(this.headers),url:this.url})},x.error=function(){var e=new x(null,{status:0,statusText:""});return e.type="error",e};var E=[301,302,303,307,308];x.redirect=function(e,t){if(-1===E.indexOf(t))throw new RangeError("Invalid status code");return new x(null,{status:t,headers:{location:e}})},t.DOMException=e.DOMException;try{new t.DOMException}catch(e){t.DOMException=function(e,t){this.message=e,this.name=t;var n=Error(e);this.stack=n.stack},t.DOMException.prototype=Object.create(Error.prototype),t.DOMException.prototype.constructor=t.DOMException}function k(e,n){return new Promise((function(r,i){var a=new b(e,n);if(a.signal&&a.signal.aborted)return i(new t.DOMException("Aborted","AbortError"));var l=new XMLHttpRequest;function s(){l.abort()}l.onload=function(){var e,t,n={status:l.status,statusText:l.statusText,headers:(e=l.getAllResponseHeaders()||"",t=new d,e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(e){var n=e.split(":"),r=n.shift().trim();if(r){var o=n.join(":").trim();t.append(r,o)}})),t)};n.url="responseURL"in l?l.responseURL:n.headers.get("X-Request-URL");var o="response"in l?l.response:l.responseText;r(new x(o,n))},l.onerror=function(){i(new TypeError("Network request failed"))},l.ontimeout=function(){i(new TypeError("Network request failed"))},l.onabort=function(){i(new t.DOMException("Aborted","AbortError"))},l.open(a.method,a.url,!0),"include"===a.credentials?l.withCredentials=!0:"omit"===a.credentials&&(l.withCredentials=!1),"responseType"in l&&o&&(l.responseType="blob"),a.headers.forEach((function(e,t){l.setRequestHeader(t,e)})),a.signal&&(a.signal.addEventListener("abort",s),l.onreadystatechange=function(){4===l.readyState&&a.signal.removeEventListener("abort",s)}),l.send(void 0===a._bodyInit?null:a._bodyInit)}))}k.polyfill=!0,e.fetch||(e.fetch=k,e.Headers=d,e.Request=b,e.Response=x),t.Headers=d,t.Request=b,t.Response=x,t.fetch=k,Object.defineProperty(t,"__esModule",{value:!0})}({})}(r),r.fetch.ponyfill=!0,delete r.fetch.polyfill;var o=r;(t=o.fetch).default=o.fetch,t.fetch=o.fetch,t.Headers=o.Headers,t.Request=o.Request,t.Response=o.Response,e.exports=t},1427:e=>{var t=function(){this.Diff_Timeout=1,this.Diff_EditCost=4,this.Match_Threshold=.5,this.Match_Distance=1e3,this.Patch_DeleteThreshold=.5,this.Patch_Margin=4,this.Match_MaxBits=32},n=-1;t.Diff=function(e,t){return[e,t]},t.prototype.diff_main=function(e,n,r,o){void 0===o&&(o=this.Diff_Timeout<=0?Number.MAX_VALUE:(new Date).getTime()+1e3*this.Diff_Timeout);var i=o;if(null==e||null==n)throw new Error("Null input. (diff_main)");if(e==n)return e?[new t.Diff(0,e)]:[];void 0===r&&(r=!0);var a=r,l=this.diff_commonPrefix(e,n),s=e.substring(0,l);e=e.substring(l),n=n.substring(l),l=this.diff_commonSuffix(e,n);var u=e.substring(e.length-l);e=e.substring(0,e.length-l),n=n.substring(0,n.length-l);var c=this.diff_compute_(e,n,a,i);return s&&c.unshift(new t.Diff(0,s)),u&&c.push(new t.Diff(0,u)),this.diff_cleanupMerge(c),c},t.prototype.diff_compute_=function(e,r,o,i){var a;if(!e)return[new t.Diff(1,r)];if(!r)return[new t.Diff(n,e)];var l=e.length>r.length?e:r,s=e.length>r.length?r:e,u=l.indexOf(s);if(-1!=u)return a=[new t.Diff(1,l.substring(0,u)),new t.Diff(0,s),new t.Diff(1,l.substring(u+s.length))],e.length>r.length&&(a[0][0]=a[2][0]=n),a;if(1==s.length)return[new t.Diff(n,e),new t.Diff(1,r)];var c=this.diff_halfMatch_(e,r);if(c){var f=c[0],d=c[1],p=c[2],h=c[3],g=c[4],m=this.diff_main(f,p,o,i),v=this.diff_main(d,h,o,i);return m.concat([new t.Diff(0,g)],v)}return o&&e.length>100&&r.length>100?this.diff_lineMode_(e,r,i):this.diff_bisect_(e,r,i)},t.prototype.diff_lineMode_=function(e,r,o){var i=this.diff_linesToChars_(e,r);e=i.chars1,r=i.chars2;var a=i.lineArray,l=this.diff_main(e,r,!1,o);this.diff_charsToLines_(l,a),this.diff_cleanupSemantic(l),l.push(new t.Diff(0,""));for(var s=0,u=0,c=0,f="",d="";s=1&&c>=1){l.splice(s-u-c,u+c),s=s-u-c;for(var p=this.diff_main(f,d,!1,o),h=p.length-1;h>=0;h--)l.splice(s,0,p[h]);s+=p.length}c=0,u=0,f="",d=""}s++}return l.pop(),l},t.prototype.diff_bisect_=function(e,r,o){for(var i=e.length,a=r.length,l=Math.ceil((i+a)/2),s=l,u=2*l,c=new Array(u),f=new Array(u),d=0;do);b++){for(var w=-b+g;w<=b-m;w+=2){for(var x=s+w,E=(O=w==-b||w!=b&&c[x-1]i)m+=2;else if(E>a)g+=2;else if(h&&(_=s+p-w)>=0&&_=(S=i-f[_]))return this.diff_bisectSplit_(e,r,O,E,o)}for(var k=-b+v;k<=b-y;k+=2){for(var S,_=s+k,C=(S=k==-b||k!=b&&f[_-1]i)y+=2;else if(C>a)v+=2;else if(!h){var O;if((x=s+p-k)>=0&&x=(S=i-S))return this.diff_bisectSplit_(e,r,O,E,o)}}}return[new t.Diff(n,e),new t.Diff(1,r)]},t.prototype.diff_bisectSplit_=function(e,t,n,r,o){var i=e.substring(0,n),a=t.substring(0,r),l=e.substring(n),s=t.substring(r),u=this.diff_main(i,a,!1,o),c=this.diff_main(l,s,!1,o);return u.concat(c)},t.prototype.diff_linesToChars_=function(e,t){var n=[],r={};function o(e){for(var t="",o=0,a=-1,l=n.length;ar?e=e.substring(n-r):nt.length?e:t,r=e.length>t.length?t:e;if(n.length<4||2*r.length=e.length?[r,i,a,l,c]:null}var a,l,s,u,c,f=i(n,r,Math.ceil(n.length/4)),d=i(n,r,Math.ceil(n.length/2));return f||d?(a=d?f&&f[4].length>d[4].length?f:d:f,e.length>t.length?(l=a[0],s=a[1],u=a[2],c=a[3]):(u=a[0],c=a[1],l=a[2],s=a[3]),[l,s,u,c,a[4]]):null},t.prototype.diff_cleanupSemantic=function(e){for(var r=!1,o=[],i=0,a=null,l=0,s=0,u=0,c=0,f=0;l0?o[i-1]:-1,s=0,u=0,c=0,f=0,a=null,r=!0)),l++;for(r&&this.diff_cleanupMerge(e),this.diff_cleanupSemanticLossless(e),l=1;l=g?(h>=d.length/2||h>=p.length/2)&&(e.splice(l,0,new t.Diff(0,p.substring(0,h))),e[l-1][1]=d.substring(0,d.length-h),e[l+1][1]=p.substring(h),l++):(g>=d.length/2||g>=p.length/2)&&(e.splice(l,0,new t.Diff(0,d.substring(0,g))),e[l-1][0]=1,e[l-1][1]=p.substring(0,p.length-g),e[l+1][0]=n,e[l+1][1]=d.substring(g),l++),l++}l++}},t.prototype.diff_cleanupSemanticLossless=function(e){function n(e,n){if(!e||!n)return 6;var r=e.charAt(e.length-1),o=n.charAt(0),i=r.match(t.nonAlphaNumericRegex_),a=o.match(t.nonAlphaNumericRegex_),l=i&&r.match(t.whitespaceRegex_),s=a&&o.match(t.whitespaceRegex_),u=l&&r.match(t.linebreakRegex_),c=s&&o.match(t.linebreakRegex_),f=u&&e.match(t.blanklineEndRegex_),d=c&&n.match(t.blanklineStartRegex_);return f||d?5:u||c?4:i&&!l&&s?3:l||s?2:i||a?1:0}for(var r=1;r=d&&(d=p,u=o,c=i,f=a)}e[r-1][1]!=u&&(u?e[r-1][1]=u:(e.splice(r-1,1),r--),e[r][1]=c,f?e[r+1][1]=f:(e.splice(r+1,1),r--))}r++}},t.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/,t.whitespaceRegex_=/\s/,t.linebreakRegex_=/[\r\n]/,t.blanklineEndRegex_=/\n\r?\n$/,t.blanklineStartRegex_=/^\r?\n\r?\n/,t.prototype.diff_cleanupEfficiency=function(e){for(var r=!1,o=[],i=0,a=null,l=0,s=!1,u=!1,c=!1,f=!1;l0?o[i-1]:-1,c=f=!1),r=!0)),l++;r&&this.diff_cleanupMerge(e)},t.prototype.diff_cleanupMerge=function(e){e.push(new t.Diff(0,""));for(var r,o=0,i=0,a=0,l="",s="";o1?(0!==i&&0!==a&&(0!==(r=this.diff_commonPrefix(s,l))&&(o-i-a>0&&0==e[o-i-a-1][0]?e[o-i-a-1][1]+=s.substring(0,r):(e.splice(0,0,new t.Diff(0,s.substring(0,r))),o++),s=s.substring(r),l=l.substring(r)),0!==(r=this.diff_commonSuffix(s,l))&&(e[o][1]=s.substring(s.length-r)+e[o][1],s=s.substring(0,s.length-r),l=l.substring(0,l.length-r))),o-=i+a,e.splice(o,i+a),l.length&&(e.splice(o,0,new t.Diff(n,l)),o++),s.length&&(e.splice(o,0,new t.Diff(1,s)),o++),o++):0!==o&&0==e[o-1][0]?(e[o-1][1]+=e[o][1],e.splice(o,1)):o++,a=0,i=0,l="",s=""}""===e[e.length-1][1]&&e.pop();var u=!1;for(o=1;ot));r++)a=o,l=i;return e.length!=r&&e[r][0]===n?l:l+(t-a)},t.prototype.diff_prettyHtml=function(e){for(var t=[],r=/&/g,o=//g,a=/\n/g,l=0;l");switch(s){case 1:t[l]=''+u+"";break;case n:t[l]=''+u+"";break;case 0:t[l]=""+u+""}}return t.join("")},t.prototype.diff_text1=function(e){for(var t=[],n=0;nthis.Match_MaxBits)throw new Error("Pattern too long for this browser.");var r=this.match_alphabet_(t),o=this;function i(e,r){var i=e/t.length,a=Math.abs(n-r);return o.Match_Distance?i+a/o.Match_Distance:a?1:i}var a=this.Match_Threshold,l=e.indexOf(t,n);-1!=l&&(a=Math.min(i(0,l),a),-1!=(l=e.lastIndexOf(t,n+t.length))&&(a=Math.min(i(0,l),a)));var s,u,c=1<=h;v--){var y=r[e.charAt(v-1)];if(m[v]=0===p?(m[v+1]<<1|1)&y:(m[v+1]<<1|1)&y|(f[v+1]|f[v])<<1|1|f[v+1],m[v]&c){var b=i(p,v-1);if(b<=a){if(a=b,!((l=v-1)>n))break;h=Math.max(1,2*n-l)}}}if(i(p+1,n)>a)break;f=m}return l},t.prototype.match_alphabet_=function(e){for(var t={},n=0;n2&&(this.diff_cleanupSemantic(a),this.diff_cleanupEfficiency(a));else if(e&&"object"==typeof e&&void 0===r&&void 0===o)a=e,i=this.diff_text1(a);else if("string"==typeof e&&r&&"object"==typeof r&&void 0===o)i=e,a=r;else{if("string"!=typeof e||"string"!=typeof r||!o||"object"!=typeof o)throw new Error("Unknown call format to patch_make.");i=e,a=o}if(0===a.length)return[];for(var l=[],s=new t.patch_obj,u=0,c=0,f=0,d=i,p=i,h=0;h=2*this.Patch_Margin&&u&&(this.patch_addContext_(s,d),l.push(s),s=new t.patch_obj,u=0,d=p,c=f)}1!==g&&(c+=m.length),g!==n&&(f+=m.length)}return u&&(this.patch_addContext_(s,d),l.push(s)),l},t.prototype.patch_deepCopy=function(e){for(var n=[],r=0;rthis.Match_MaxBits?-1!=(l=this.match_main(t,c.substring(0,this.Match_MaxBits),u))&&(-1==(f=this.match_main(t,c.substring(c.length-this.Match_MaxBits),u+c.length-this.Match_MaxBits))||l>=f)&&(l=-1):l=this.match_main(t,c,u),-1==l)i[a]=!1,o-=e[a].length2-e[a].length1;else if(i[a]=!0,o=l-u,c==(s=-1==f?t.substring(l,l+c.length):t.substring(l,f+this.Match_MaxBits)))t=t.substring(0,l)+this.diff_text2(e[a].diffs)+t.substring(l+c.length);else{var d=this.diff_main(c,s,!1);if(c.length>this.Match_MaxBits&&this.diff_levenshtein(d)/c.length>this.Patch_DeleteThreshold)i[a]=!1;else{this.diff_cleanupSemanticLossless(d);for(var p,h=0,g=0;ga[0][1].length){var l=n-a[0][1].length;a[0][1]=r.substring(a[0][1].length)+a[0][1],i.start1-=l,i.start2-=l,i.length1+=l,i.length2+=l}return 0==(a=(i=e[e.length-1]).diffs).length||0!=a[a.length-1][0]?(a.push(new t.Diff(0,r)),i.length1+=n,i.length2+=n):n>a[a.length-1][1].length&&(l=n-a[a.length-1][1].length,a[a.length-1][1]+=r.substring(0,l),i.length1+=l,i.length2+=l),r},t.prototype.patch_splitMax=function(e){for(var r=this.Match_MaxBits,o=0;o2*r?(u.length1+=d.length,a+=d.length,c=!1,u.diffs.push(new t.Diff(f,d)),i.diffs.shift()):(d=d.substring(0,r-u.length1-this.Patch_Margin),u.length1+=d.length,a+=d.length,0===f?(u.length2+=d.length,l+=d.length):c=!1,u.diffs.push(new t.Diff(f,d)),d==i.diffs[0][1]?i.diffs.shift():i.diffs[0][1]=i.diffs[0][1].substring(d.length))}s=(s=this.diff_text2(u.diffs)).substring(s.length-this.Patch_Margin);var p=this.diff_text1(i.diffs).substring(0,this.Patch_Margin);""!==p&&(u.length1+=p.length,u.length2+=p.length,0!==u.diffs.length&&0===u.diffs[u.diffs.length-1][0]?u.diffs[u.diffs.length-1][1]+=p:u.diffs.push(new t.Diff(0,p))),c||e.splice(++o,0,u)}}},t.prototype.patch_toText=function(e){for(var t=[],n=0;n{"use strict";e.exports=function(e){var t=e.uri,n=e.name,r=e.type;this.uri=t,this.name=n,this.type=r}},2929:(e,t,n)=>{"use strict";var r=n(1278);e.exports=function e(t,n,o){var i;void 0===n&&(n=""),void 0===o&&(o=r);var a=new Map;function l(e,t){var n=a.get(t);n?n.push.apply(n,e):a.set(t,e)}if(o(t))i=null,l([n],t);else{var s=n?n+".":"";if("undefined"!=typeof FileList&&t instanceof FileList)i=Array.prototype.map.call(t,(function(e,t){return l([""+s+t],e),null}));else if(Array.isArray(t))i=t.map((function(t,n){var r=e(t,""+s+n,o);return r.files.forEach(l),r.clone}));else if(t&&t.constructor===Object)for(var u in i={},t){var c=e(t[u],""+s+u,o);c.files.forEach(l),i[u]=c.clone}else i=t}return{clone:i,files:a}}},9384:(e,t,n)=>{"use strict";t.ReactNativeFile=n(7570),t.extractFiles=n(2929),t.isExtractableFile=n(1278)},1278:(e,t,n)=>{"use strict";var r=n(7570);e.exports=function(e){return"undefined"!=typeof File&&e instanceof File||"undefined"!=typeof Blob&&e instanceof Blob||e instanceof r}},1688:e=>{e.exports="object"==typeof self?self.FormData:window.FormData},8749:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(9384),i=r(n(1688)),a=function(e){return o.isExtractableFile(e)||null!==e&&"object"==typeof e&&"function"==typeof e.pipe};t.default=function(e,t,n){var r=o.extractFiles({query:e,variables:t,operationName:n},"",a),l=r.clone,s=r.files;if(0===s.size){if(!Array.isArray(e))return JSON.stringify(l);if(void 0!==t&&!Array.isArray(t))throw new Error("Cannot create request body with given variable type, array expected");var u=e.reduce((function(e,n,r){return e.push({query:n,variables:t?t[r]:void 0}),e}),[]);return JSON.stringify(u)}var c=new("undefined"==typeof FormData?i.default:FormData);c.append("operations",JSON.stringify(l));var f={},d=0;return s.forEach((function(e){f[++d]=e})),c.append("map",JSON.stringify(f)),d=0,s.forEach((function(e,t){c.append(""+ ++d,t)})),c}},6647:function(e,t,n){"use strict";var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.prototype.toJSON;"function"==typeof t||(0,r.default)(0),e.prototype.inspect=t,o.default&&(e.prototype[o.default]=t)};var r=i(n(5006)),o=i(n(8019));function i(e){return e&&e.__esModule?e:{default:e}}},8048:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return a(e,[])};var r,o=(r=n(8019))&&r.__esModule?r:{default:r};function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function a(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":return null===e?"null":function(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=function(e){var t=e[String(o.default)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:a(i,n)}else if(Array.isArray(e))return function(e,t){if(0===e.length)return"[]";if(t.length>2)return"[Array]";for(var n=Math.min(10,e.length),r=e.length-n,o=[],i=0;i1&&o.push("... ".concat(r," more items")),"["+o.join(", ")+"]"}(e,n);return function(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>2?"["+function(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}(e)+"]":"{ "+n.map((function(n){return n+": "+a(e[n],t)})).join(", ")+" }"}(e,n)}(e,t);default:return String(e)}}},5006:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){if(!Boolean(e))throw new Error(null!=t?t:"Unexpected invariant triggered.")}},8019:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;t.default=n},4560:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isNode=function(e){return null!=e&&"string"==typeof e.kind},t.Token=t.Location=void 0;var r,o=(r=n(2678))&&r.__esModule?r:{default:r},i=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();t.Location=i,(0,o.default)(i);var a=function(){function e(e,t,n,r,o,i,a){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=o,this.value=a,this.prev=i,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();t.Token=a,(0,o.default)(a)},9501:(e,t)=>{"use strict";function n(e){for(var t=0;ta&&n(t[l-1]);)--l;return t.slice(a,l).join("\n")},t.getBlockStringIndentation=r,t.printBlockString=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),o=" "===e[0]||"\t"===e[0],i='"'===e[e.length-1],a="\\"===e[e.length-1],l=!r||i||a||n,s="";return!l||r&&o||(s+="\n"+t),s+=t?e.replace(/\n/g,"\n"+t):e,l&&(s+="\n"),'"""'+s.replace(/"""/g,'\\"""')+'"""'}},3083:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.print=function(e){return(0,r.visit)(e,{leave:i})};var r=n(2624),o=n(9501),i={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return l(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=u("(",l(e.variableDefinitions,", "),")"),o=l(e.directives," "),i=e.selectionSet;return n||o||r||"query"!==t?l([t,l([n,r]),o,i]," "):i},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,o=e.directives;return t+": "+n+u(" = ",r)+u(" ",l(o," "))},SelectionSet:function(e){return s(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,o=e.directives,i=e.selectionSet,a=u("",t,": ")+n,s=a+u("(",l(r,", "),")");return s.length>80&&(s=a+u("(\n",c(l(r,"\n")),"\n)")),l([s,l(o," "),i]," ")},Argument:function(e){return e.name+": "+e.value},FragmentSpread:function(e){return"..."+e.name+u(" ",l(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return l(["...",u("on ",t),l(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,o=e.directives,i=e.selectionSet;return"fragment ".concat(t).concat(u("(",l(r,", "),")")," ")+"on ".concat(n," ").concat(u("",l(o," ")," "))+i},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,o.printBlockString)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+l(e.values,", ")+"]"},ObjectValue:function(e){return"{"+l(e.fields,", ")+"}"},ObjectField:function(e){return e.name+": "+e.value},Directive:function(e){return"@"+e.name+u("(",l(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:a((function(e){var t=e.directives,n=e.operationTypes;return l(["schema",l(t," "),s(n)]," ")})),OperationTypeDefinition:function(e){return e.operation+": "+e.type},ScalarTypeDefinition:a((function(e){return l(["scalar",e.name,l(e.directives," ")]," ")})),ObjectTypeDefinition:a((function(e){var t=e.name,n=e.interfaces,r=e.directives,o=e.fields;return l(["type",t,u("implements ",l(n," & ")),l(r," "),s(o)]," ")})),FieldDefinition:a((function(e){var t=e.name,n=e.arguments,r=e.type,o=e.directives;return t+(d(n)?u("(\n",c(l(n,"\n")),"\n)"):u("(",l(n,", "),")"))+": "+r+u(" ",l(o," "))})),InputValueDefinition:a((function(e){var t=e.name,n=e.type,r=e.defaultValue,o=e.directives;return l([t+": "+n,u("= ",r),l(o," ")]," ")})),InterfaceTypeDefinition:a((function(e){var t=e.name,n=e.interfaces,r=e.directives,o=e.fields;return l(["interface",t,u("implements ",l(n," & ")),l(r," "),s(o)]," ")})),UnionTypeDefinition:a((function(e){var t=e.name,n=e.directives,r=e.types;return l(["union",t,l(n," "),r&&0!==r.length?"= "+l(r," | "):""]," ")})),EnumTypeDefinition:a((function(e){var t=e.name,n=e.directives,r=e.values;return l(["enum",t,l(n," "),s(r)]," ")})),EnumValueDefinition:a((function(e){return l([e.name,l(e.directives," ")]," ")})),InputObjectTypeDefinition:a((function(e){var t=e.name,n=e.directives,r=e.fields;return l(["input",t,l(n," "),s(r)]," ")})),DirectiveDefinition:a((function(e){var t=e.name,n=e.arguments,r=e.repeatable,o=e.locations;return"directive @"+t+(d(n)?u("(\n",c(l(n,"\n")),"\n)"):u("(",l(n,", "),")"))+(r?" repeatable":"")+" on "+l(o," | ")})),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return l(["extend schema",l(t," "),s(n)]," ")},ScalarTypeExtension:function(e){return l(["extend scalar",e.name,l(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,o=e.fields;return l(["extend type",t,u("implements ",l(n," & ")),l(r," "),s(o)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,o=e.fields;return l(["extend interface",t,u("implements ",l(n," & ")),l(r," "),s(o)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return l(["extend union",t,l(n," "),r&&0!==r.length?"= "+l(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return l(["extend enum",t,l(n," "),s(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return l(["extend input",t,l(n," "),s(r)]," ")}};function a(e){return function(t){return l([t.description,e(t)],"\n")}}function l(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter((function(e){return e})).join(n))&&void 0!==t?t:""}function s(e){return u("{\n",c(l(e,"\n")),"\n}")}function u(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function c(e){return u(" ",e.replace(/\n/g,"\n "))}function f(e){return-1!==e.indexOf("\n")}function d(e){return null!=e&&e.some(f)}},2624:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.visit=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:a,r=void 0,u=Array.isArray(e),c=[e],f=-1,d=[],p=void 0,h=void 0,g=void 0,m=[],v=[],y=e;do{var b=++f===c.length,w=b&&0!==d.length;if(b){if(h=0===v.length?void 0:m[m.length-1],p=g,g=v.pop(),w){if(u)p=p.slice();else{for(var x={},E=0,k=Object.keys(p);E{var r=n(7772).Symbol;e.exports=r},3366:(e,t,n)=>{var r=n(857),o=n(2107),i=n(7157),a=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":a&&a in Object(e)?o(e):i(e)}},1704:(e,t,n)=>{var r=n(2153),o=/^\s+/;e.exports=function(e){return e?e.slice(0,r(e)+1).replace(o,""):e}},1242:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},2107:(e,t,n)=>{var r=n(857),o=Object.prototype,i=o.hasOwnProperty,a=o.toString,l=r?r.toStringTag:void 0;e.exports=function(e){var t=i.call(e,l),n=e[l];try{e[l]=void 0;var r=!0}catch(e){}var o=a.call(e);return r&&(t?e[l]=n:delete e[l]),o}},7157:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},7772:(e,t,n)=>{var r=n(1242),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},2153:e=>{var t=/\s/;e.exports=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n}},4073:(e,t,n)=>{var r=n(9259),o=n(1100),i=n(7642),a=Math.max,l=Math.min;e.exports=function(e,t,n){var s,u,c,f,d,p,h=0,g=!1,m=!1,v=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function y(t){var n=s,r=u;return s=u=void 0,h=t,f=e.apply(r,n)}function b(e){return h=e,d=setTimeout(x,t),g?y(e):f}function w(e){var n=e-p;return void 0===p||n>=t||n<0||m&&e-h>=c}function x(){var e=o();if(w(e))return E(e);d=setTimeout(x,function(e){var n=t-(e-p);return m?l(n,c-(e-h)):n}(e))}function E(e){return d=void 0,v&&s?y(e):(s=u=void 0,f)}function k(){var e=o(),n=w(e);if(s=arguments,u=this,p=e,n){if(void 0===d)return b(p);if(m)return clearTimeout(d),d=setTimeout(x,t),y(p)}return void 0===d&&(d=setTimeout(x,t)),f}return t=i(t)||0,r(n)&&(g=!!n.leading,c=(m="maxWait"in n)?a(i(n.maxWait)||0,t):c,v="trailing"in n?!!n.trailing:v),k.cancel=function(){void 0!==d&&clearTimeout(d),h=0,s=p=u=d=void 0},k.flush=function(){return void 0===d?f:E(o())},k}},9259:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},5125:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},4795:(e,t,n)=>{var r=n(3366),o=n(5125);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},1100:(e,t,n)=>{var r=n(7772);e.exports=function(){return r.Date.now()}},7642:(e,t,n)=>{var r=n(1704),o=n(9259),i=n(4795),a=/^[-+]0x[0-9a-f]+$/i,l=/^0b[01]+$/i,s=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(i(e))return NaN;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=r(e);var n=l.test(e);return n||s.test(e)?u(e.slice(2),n?2:8):a.test(e)?NaN:+e}},9410:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){let e=null;return{mountedInstances:new Set,updateHead:t=>{const n=e=Promise.resolve().then((()=>{if(n!==e)return;e=null;const i={};t.forEach((e=>{if("link"===e.type&&e.props["data-optimized-fonts"]){if(document.querySelector(`style[data-href="${e.props["data-href"]}"]`))return;e.props.href=e.props["data-href"],e.props["data-href"]=void 0}const t=i[e.type]||[];t.push(e),i[e.type]=t}));const a=i.title?i.title[0]:null;let l="";if(a){const{children:e}=a.props;l="string"==typeof e?e:Array.isArray(e)?e.join(""):""}l!==document.title&&(document.title=l),["meta","base","link","style","script"].forEach((e=>{!function(e,t){const n=document.getElementsByTagName("head")[0],i=n.querySelector("meta[name=next-head-count]"),a=Number(i.content),l=[];for(let t=0,n=i.previousElementSibling;t{for(let t=0,n=l.length;t{var t;return null===(t=e.parentNode)||void 0===t?void 0:t.removeChild(e)})),u.forEach((e=>n.insertBefore(e,i))),i.content=(a-l.length+u.length).toString()}(e,i[e]||[])}))}))}}},t.isEqualNode=o,t.DOMAttributeNames=void 0;const n={acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv",noModule:"noModule"};function r({type:e,props:t}){const r=document.createElement(e);for(const o in t){if(!t.hasOwnProperty(o))continue;if("children"===o||"dangerouslySetInnerHTML"===o)continue;if(void 0===t[o])continue;const i=n[o]||o.toLowerCase();"script"!==e||"async"!==i&&"defer"!==i&&"noModule"!==i?r.setAttribute(i,t[o]):r[i]=!!t[o]}const{children:o,dangerouslySetInnerHTML:i}=t;return i?r.innerHTML=i.__html||"":o&&(r.textContent="string"==typeof o?o:Array.isArray(o)?o.join(""):""),r}function o(e,t){if(e instanceof HTMLElement&&t instanceof HTMLElement){const n=t.getAttribute("nonce");if(n&&!e.getAttribute("nonce")){const r=t.cloneNode(!0);return r.setAttribute("nonce",""),r.nonce=n,n===e.nonce&&e.isEqualNode(r)}}return e.isEqualNode(t)}t.DOMAttributeNames=n,("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},4529:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r,o=(r=n(2784))&&r.__esModule?r:{default:r},i=n(6640),a=n(9518),l=n(3321);const s={};function u(e,t,n,r){if("undefined"==typeof window||!e)return;if(!i.isLocalURL(t))return;e.prefetch(t,n,r).catch((e=>{}));const o=r&&void 0!==r.locale?r.locale:e&&e.locale;s[t+"%"+n+(o?"%"+o:"")]=!0}var c=o.default.forwardRef(((e,t)=>{const{legacyBehavior:n=!0!==Boolean(window.omnivoreEnv.__NEXT_NEW_LINK_BEHAVIOR)}=e;let r;const{href:c,as:f,children:d,prefetch:p,passHref:h,replace:g,shallow:m,scroll:v,locale:y,onClick:b,onMouseEnter:w}=e,x=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["href","as","children","prefetch","passHref","replace","shallow","scroll","locale","onClick","onMouseEnter"]);r=d,n&&"string"==typeof r&&(r=o.default.createElement("a",null,r));const E=!1!==p,k=a.useRouter(),{href:S,as:_}=o.default.useMemo((()=>{const[e,t]=i.resolveHref(k,c,!0);return{href:e,as:f?i.resolveHref(k,f):t||e}}),[k,c,f]),C=o.default.useRef(S),O=o.default.useRef(_);let L;n&&(L=o.default.Children.only(r));const P=n?L&&"object"==typeof L&&L.ref:t,[R,j,T]=l.useIntersection({rootMargin:"200px"}),A=o.default.useCallback((e=>{O.current===_&&C.current===S||(T(),O.current=_,C.current=S),R(e),P&&("function"==typeof P?P(e):"object"==typeof P&&(P.current=e))}),[_,P,S,T,R]);o.default.useEffect((()=>{const e=j&&E&&i.isLocalURL(S),t=void 0!==y?y:k&&k.locale,n=s[S+"%"+_+(t?"%"+t:"")];e&&!n&&u(k,S,_,{locale:t})}),[_,S,j,y,E,k]);const M={ref:A,onClick:e=>{n||"function"!=typeof b||b(e),n&&L.props&&"function"==typeof L.props.onClick&&L.props.onClick(e),e.defaultPrevented||function(e,t,n,r,o,a,l,s){const{nodeName:u}=e.currentTarget;("A"!==u.toUpperCase()||!function(e){const{target:t}=e.currentTarget;return t&&"_self"!==t||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.nativeEvent&&2===e.nativeEvent.which}(e)&&i.isLocalURL(n))&&(e.preventDefault(),t[o?"replace":"push"](n,r,{shallow:a,locale:s,scroll:l}))}(e,k,S,_,g,m,v,y)},onMouseEnter:e=>{n||"function"!=typeof w||w(e),n&&L.props&&"function"==typeof L.props.onMouseEnter&&L.props.onMouseEnter(e),i.isLocalURL(S)&&u(k,S,_,{priority:!0})}};if(!n||h||"a"===L.type&&!("href"in L.props)){const e=void 0!==y?y:k&&k.locale,t=k&&k.isLocaleDomain&&i.getDomainLocale(_,e,k&&k.locales,k&&k.domainLocales);M.href=t||i.addBasePath(i.addLocale(_,e,k&&k.defaultLocale))}return n?o.default.cloneElement(L,M):o.default.createElement("a",Object.assign({},x,M),r)}));t.default=c,("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},1119:(e,t)=>{"use strict";function n(e){return e.endsWith("/")&&"/"!==e?e.slice(0,-1):e}Object.defineProperty(t,"__esModule",{value:!0}),t.removePathTrailingSlash=n,t.normalizePathTrailingSlash=void 0;const r=window.omnivoreEnv.__NEXT_TRAILING_SLASH?e=>/\.[^/]+\/?$/.test(e)?n(e):e.endsWith("/")?e:e+"/":n;t.normalizePathTrailingSlash=r,("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},1976:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.cancelIdleCallback=t.requestIdleCallback=void 0;const n="undefined"!=typeof self&&self.requestIdleCallback&&self.requestIdleCallback.bind(window)||function(e){let t=Date.now();return setTimeout((function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})}),1)};t.requestIdleCallback=n;const r="undefined"!=typeof self&&self.cancelIdleCallback&&self.cancelIdleCallback.bind(window)||function(e){return clearTimeout(e)};t.cancelIdleCallback=r,("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},7928:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.markAssetError=u,t.isAssetError=function(e){return e&&s in e},t.getClientBuildManifest=f,t.getMiddlewareManifest=function(){return self.__MIDDLEWARE_MANIFEST?Promise.resolve(self.__MIDDLEWARE_MANIFEST):c(new Promise((e=>{const t=self.__MIDDLEWARE_MANIFEST_CB;self.__MIDDLEWARE_MANIFEST_CB=()=>{e(self.__MIDDLEWARE_MANIFEST),t&&t()}})),i,u(new Error("Failed to load client middleware manifest")))},t.createRouteLoader=function(e){const t=new Map,n=new Map,r=new Map,s=new Map;function f(e){{let t=n.get(e);return t||(document.querySelector(`script[src^="${e}"]`)?Promise.resolve():(n.set(e,t=function(e,t){return new Promise(((n,r)=>{(t=document.createElement("script")).onload=n,t.onerror=()=>r(u(new Error(`Failed to load script: ${e}`))),t.crossOrigin=window.omnivoreEnv.__NEXT_CROSS_ORIGIN,t.src=e,document.body.appendChild(t)}))}(e)),t))}}function p(e){let t=r.get(e);return t||(r.set(e,t=fetch(e).then((t=>{if(!t.ok)throw new Error(`Failed to load stylesheet: ${e}`);return t.text().then((t=>({href:e,content:t})))})).catch((e=>{throw u(e)}))),t)}return{whenEntrypoint:e=>a(e,t),onEntrypoint(e,n){(n?Promise.resolve().then((()=>n())).then((e=>({component:e&&e.default||e,exports:e})),(e=>({error:e}))):Promise.resolve(void 0)).then((n=>{const r=t.get(e);r&&"resolve"in r?n&&(t.set(e,n),r.resolve(n)):(n?t.set(e,n):t.delete(e),s.delete(e))}))},loadRoute(n,r){return a(n,s,(()=>c(d(e,n).then((({scripts:e,css:r})=>Promise.all([t.has(n)?[]:Promise.all(e.map(f)),Promise.all(r.map(p))]))).then((e=>this.whenEntrypoint(n).then((t=>({entrypoint:t,styles:e[1]}))))),i,u(new Error(`Route did not complete loading: ${n}`))).then((({entrypoint:e,styles:t})=>{const n=Object.assign({styles:t},e);return"error"in e?e:n})).catch((e=>{if(r)throw e;return{error:e}})).finally((()=>{}))))},prefetch(t){let n;return(n=navigator.connection)&&(n.saveData||/2g/.test(n.effectiveType))?Promise.resolve():d(e,t).then((e=>Promise.all(l?e.scripts.map((e=>{return t=e,n="script",new Promise(((e,o)=>{const i=`\n link[rel="prefetch"][href^="${t}"],\n link[rel="preload"][href^="${t}"],\n script[src^="${t}"]`;if(document.querySelector(i))return e();(r=document.createElement("link")).as=n,r.rel="prefetch",r.crossOrigin=window.omnivoreEnv.__NEXT_CROSS_ORIGIN,r.onload=e,r.onerror=o,r.href=t,document.head.appendChild(r)}));var t,n,r})):[]))).then((()=>{o.requestIdleCallback((()=>this.loadRoute(t,!0).catch((()=>{}))))})).catch((()=>{}))}}},(r=n(9983))&&r.__esModule;var r,o=n(1976);const i=3800;function a(e,t,n){let r,o=t.get(e);if(o)return"future"in o?o.future:Promise.resolve(o);const i=new Promise((e=>{r=e}));return t.set(e,o={resolve:r,future:i}),n?n().then((e=>(r(e),e))).catch((n=>{throw t.delete(e),n})):i}const l=function(e){try{return e=document.createElement("link"),!!window.MSInputMethodContext&&!!document.documentMode||e.relList.supports("prefetch")}catch(e){return!1}}(),s=Symbol("ASSET_LOAD_ERROR");function u(e){return Object.defineProperty(e,s,{})}function c(e,t,n){return new Promise(((r,i)=>{let a=!1;e.then((e=>{a=!0,r(e)})).catch(i),o.requestIdleCallback((()=>setTimeout((()=>{a||i(n)}),t)))}))}function f(){return self.__BUILD_MANIFEST?Promise.resolve(self.__BUILD_MANIFEST):c(new Promise((e=>{const t=self.__BUILD_MANIFEST_CB;self.__BUILD_MANIFEST_CB=()=>{e(self.__BUILD_MANIFEST),t&&t()}})),i,u(new Error("Failed to load client build manifest")))}function d(e,t){return f().then((n=>{if(!(t in n))throw u(new Error(`Failed to lookup route: ${t}`));const r=n[t].map((t=>e+"/_next/"+encodeURI(t)));return{scripts:r.filter((e=>e.endsWith(".js"))),css:r.filter((e=>e.endsWith(".css")))}}))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},9518:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"Router",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(t,"withRouter",{enumerable:!0,get:function(){return l.default}}),t.useRouter=function(){return r.default.useContext(i.RouterContext)},t.createRouter=function(...e){return u.router=new o.default(...e),u.readyCallbacks.forEach((e=>e())),u.readyCallbacks=[],u.router},t.makePublicRouterInstance=function(e){const t=e,n={};for(const e of c)"object"!=typeof t[e]?n[e]=t[e]:n[e]=Object.assign(Array.isArray(t[e])?[]:{},t[e]);return n.events=o.default.events,f.forEach((e=>{n[e]=(...n)=>t[e](...n)})),n},t.default=void 0;var r=s(n(2784)),o=s(n(6640)),i=n(6510),a=s(n(274)),l=s(n(9564));function s(e){return e&&e.__esModule?e:{default:e}}const u={router:null,readyCallbacks:[],ready(e){if(this.router)return e();"undefined"!=typeof window&&this.readyCallbacks.push(e)}},c=["pathname","route","query","asPath","components","isFallback","basePath","locale","locales","defaultLocale","isReady","isPreview","isLocaleDomain","domainLocales"],f=["push","replace","reload","back","prefetch","beforePopState"];function d(){if(!u.router)throw new Error('No router instance found.\nYou should only use "next/router" on the client side of your app.\n');return u.router}Object.defineProperty(u,"events",{get:()=>o.default.events}),c.forEach((e=>{Object.defineProperty(u,e,{get:()=>d()[e]})})),f.forEach((e=>{u[e]=(...t)=>d()[e](...t)})),["routeChangeStart","beforeHistoryChange","routeChangeComplete","routeChangeError","hashChangeStart","hashChangeComplete"].forEach((e=>{u.ready((()=>{o.default.events.on(e,((...t)=>{const n=`on${e.charAt(0).toUpperCase()}${e.substring(1)}`,r=u;if(r[n])try{r[n](...t)}catch(e){console.error(`Error when running the Router event: ${n}`),console.error(a.default(e)?`${e.message}\n${e.stack}`:e+"")}}))}))}));var p=u;t.default=p,("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},9515:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.handleClientScriptLoad=p,t.initScriptLoader=function(e){e.forEach(p),[...document.querySelectorAll('[data-nscript="beforeInteractive"]'),...document.querySelectorAll('[data-nscript="beforePageRender"]')].forEach((e=>{const t=e.id||e.getAttribute("src");c.add(t)}))},t.default=void 0;var r=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(e,n):{};r.get||r.set?Object.defineProperty(t,n,r):t[n]=e[n]}return t.default=e,t}(n(2784)),o=n(7177),i=n(9410),a=n(1976);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e){for(var t=1;t{const{src:t,id:n,onLoad:r=(()=>{}),dangerouslySetInnerHTML:o,children:a="",strategy:l="afterInteractive",onError:s}=e,d=n||t;if(d&&c.has(d))return;if(u.has(t))return c.add(d),void u.get(t).then(r,s);const p=document.createElement("script"),h=new Promise(((e,t)=>{p.addEventListener("load",(function(t){e(),r&&r.call(this,t)})),p.addEventListener("error",(function(e){t(e)}))})).catch((function(e){s&&s(e)}));t&&u.set(t,h),c.add(d),o?p.innerHTML=o.__html||"":a?p.textContent="string"==typeof a?a:Array.isArray(a)?a.join(""):"":t&&(p.src=t);for(const[t,n]of Object.entries(e)){if(void 0===n||f.includes(t))continue;const e=i.DOMAttributeNames[t]||t.toLowerCase();p.setAttribute(e,n)}"worker"===l&&p.setAttribute("type","text/partytown"),p.setAttribute("data-nscript",l),document.body.appendChild(p)};function p(e){const{strategy:t="afterInteractive"}=e;"lazyOnload"===t?window.addEventListener("load",(()=>{a.requestIdleCallback((()=>d(e)))})):d(e)}t.default=function(e){const{src:t="",onLoad:n=(()=>{}),strategy:i="afterInteractive",onError:l}=e,u=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,["src","onLoad","strategy","onError"]),{updateScripts:f,scripts:p,getIsSsr:h}=r.useContext(o.HeadManagerContext);return r.useEffect((()=>{"afterInteractive"===i?d(e):"lazyOnload"===i&&function(e){"complete"===document.readyState?a.requestIdleCallback((()=>d(e))):window.addEventListener("load",(()=>{a.requestIdleCallback((()=>d(e)))}))}(e)}),[e,i]),"beforeInteractive"!==i&&"worker"!==i||(f?(p[i]=(p[i]||[]).concat([s({src:t,onLoad:n,onError:l},u)]),f(p)):h&&h()?c.add(u.id||t):h&&!h()&&d(e)),null},("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},3321:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useIntersection=function({rootRef:e,rootMargin:t,disabled:n}){const s=n||!i,u=r.useRef(),[c,f]=r.useState(!1),[d,p]=r.useState(e?e.current:null),h=r.useCallback((e=>{u.current&&(u.current(),u.current=void 0),s||c||e&&e.tagName&&(u.current=function(e,t,n){const{id:r,observer:o,elements:i}=function(e){const t={root:e.root||null,margin:e.rootMargin||""};let n,r=l.find((e=>e.root===t.root&&e.margin===t.margin));if(r?n=a.get(r):(n=a.get(t),l.push(t)),n)return n;const o=new Map,i=new IntersectionObserver((e=>{e.forEach((e=>{const t=o.get(e.target),n=e.isIntersecting||e.intersectionRatio>0;t&&n&&t(n)}))}),e);return a.set(t,n={id:t,observer:i,elements:o}),n}(n);return i.set(e,(e=>e&&f(e))),o.observe(e),function(){if(i.delete(e),o.unobserve(e),0===i.size){o.disconnect(),a.delete(r);let e=l.findIndex((e=>e.root===r.root&&e.margin===r.margin));e>-1&&l.splice(e,1)}}}(e,0,{root:d,rootMargin:t}))}),[s,d,t,c]),g=r.useCallback((()=>{f(!1)}),[]);return r.useEffect((()=>{if(!i&&!c){const e=o.requestIdleCallback((()=>f(!0)));return()=>o.cancelIdleCallback(e)}}),[c]),r.useEffect((()=>{e&&p(e.current)}),[e]),[h,c,g]};var r=n(2784),o=n(1976);const i="undefined"!=typeof IntersectionObserver,a=new Map,l=[];("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},9564:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){function t(t){return o.default.createElement(e,Object.assign({router:i.useRouter()},t))}return t.getInitialProps=e.getInitialProps,t.origGetInitialProps=e.origGetInitialProps,t};var r,o=(r=n(2784))&&r.__esModule?r:{default:r},i=n(9518);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&(Object.assign(t.default,t),e.exports=t.default)},9264:(e,t)=>{"use strict";function n(e,t){void 0===t&&(t={});for(var n=function(e){for(var t=[],n=0;n=48&&s<=57||s>=65&&s<=90||s>=97&&s<=122||95===s))break;a+=e[l++]}if(!a)throw new TypeError("Missing parameter name at "+n);t.push({type:"NAME",index:n,value:a}),n=l}else t.push({type:"CLOSE",index:n,value:e[n++]});else t.push({type:"OPEN",index:n,value:e[n++]});else t.push({type:"ESCAPED_CHAR",index:n++,value:e[n++]});else t.push({type:"MODIFIER",index:n,value:e[n++]})}return t.push({type:"END",index:n,value:""}),t}(e),r=t.prefixes,o=void 0===r?"./":r,a="[^"+i(t.delimiter||"/#?")+"]+?",l=[],s=0,u=0,c="",f=function(e){if(u-1:void 0===E;o||(g+="(?:"+h+"(?="+p+"))?"),k||(g+="(?="+h+"|"+p+")")}return new RegExp(g,a(n))}function s(e,t,r){return e instanceof RegExp?function(e,t){if(!t)return e;var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=o,t.getProperError=function(e){return o(e)?e:new Error(r.isPlainObject(e)?JSON.stringify(e):e+"")};var r=n(9910);function o(e){return"object"==typeof e&&null!==e&&"name"in e&&"message"in e}},8058:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.escapeStringRegexp=function(e){return n.test(e)?e.replace(r,"\\$&"):e};const n=/[|\\{}()[\]^$+*?.-]/,r=/[|\\{}()[\]^$+*?.-]/g},7177:(e,t,n)=>{"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),t.HeadManagerContext=void 0;const o=((r=n(2784))&&r.__esModule?r:{default:r}).default.createContext({});t.HeadManagerContext=o},927:(e,t)=>{"use strict";t.D=function(e,t,n){let r;if(e){n&&(n=n.toLowerCase());for(const a of e){var o,i;if(t===(null===(o=a.domain)||void 0===o?void 0:o.split(":")[0].toLowerCase())||n===a.defaultLocale.toLowerCase()||(null===(i=a.locales)||void 0===i?void 0:i.some((e=>e.toLowerCase()===n)))){r=a;break}}}return r}},816:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.normalizeLocalePath=function(e,t){let n;const r=e.split("/");return(t||[]).some((t=>!(!r[1]||r[1].toLowerCase()!==t.toLowerCase()||(n=t,r.splice(1,1),e=r.join("/")||"/",0)))),{pathname:e,detectedLocale:n}}},9910:(e,t)=>{"use strict";function n(e){return Object.prototype.toString.call(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.getObjectClassLabel=n,t.isPlainObject=function(e){if("[object Object]"!==n(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}},7471:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){const e=Object.create(null);return{on(t,n){(e[t]||(e[t]=[])).push(n)},off(t,n){e[t]&&e[t].splice(e[t].indexOf(n)>>>0,1)},emit(t,...n){(e[t]||[]).slice().map((e=>{e(...n)}))}}}},997:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.denormalizePagePath=function(e){let t=o.normalizePathSep(e);return t.startsWith("/index/")&&!r.isDynamicRoute(t)?t.slice(6):"/index"!==t?t:"/"};var r=n(9150),o=n(9356)},9356:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.normalizePathSep=function(e){return e.replace(/\\/g,"/")}},6510:(e,t,n)=>{"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),t.RouterContext=void 0;const o=((r=n(2784))&&r.__esModule?r:{default:r}).default.createContext(null);t.RouterContext=o},6640:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getDomainLocale=function(e,t,n,r){if(window.omnivoreEnv.__NEXT_I18N_SUPPORT){t=t||s.normalizeLocalePath(e,n).detectedLocale;const o=w(r,void 0,t);return!!o&&`http${o.http?"":"s"}://${o.domain}${x||""}${t===o.defaultLocale?"":`/${t}`}${e}`}return!1},t.addLocale=_,t.delLocale=C,t.hasBasePath=L,t.addBasePath=P,t.delBasePath=R,t.isLocalURL=j,t.interpolateAs=T,t.resolveHref=M,t.default=void 0;var r=n(1119),o=n(7928),i=n(9515),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(e,n):{};r.get||r.set?Object.defineProperty(t,n,r):t[n]=e[n]}return t.default=e,t}(n(274)),l=n(997),s=n(816),u=b(n(7471)),c=n(1624),f=n(7482),d=n(1577),p=n(646),h=b(n(5317)),g=n(3107),m=n(4794),v=n(2763),y=n(6555);function b(e){return e&&e.__esModule?e:{default:e}}let w;window.omnivoreEnv.__NEXT_I18N_SUPPORT&&(w=n(927).D);const x=window.omnivoreEnv.__NEXT_ROUTER_BASEPATH||"";function E(){return Object.assign(new Error("Route Cancelled"),{cancelled:!0})}function k(e,t){if(!e.startsWith("/")||!t)return e;const n=O(e);return r.normalizePathTrailingSlash(`${t}${n}`)+e.slice(n.length)}function S(e,t){return(e=O(e))===t||e.startsWith(t+"/")}function _(e,t,n){if(window.omnivoreEnv.__NEXT_I18N_SUPPORT&&t&&t!==n){const n=O(e).toLowerCase();if(!S(n,"/"+t.toLowerCase())&&!S(n,"/api"))return k(e,"/"+t)}return e}function C(e,t){if(window.omnivoreEnv.__NEXT_I18N_SUPPORT){const n=O(e),r=n.toLowerCase(),o=t&&t.toLowerCase();return t&&(r.startsWith("/"+o+"/")||r==="/"+o)?(n.length===t.length+1?"/":"")+e.slice(t.length+1):e}return e}function O(e){const t=e.indexOf("?"),n=e.indexOf("#");return(t>-1||n>-1)&&(e=e.substring(0,t>-1?t:n)),e}function L(e){return S(e,x)}function P(e){return k(e,x)}function R(e){return(e=e.slice(x.length)).startsWith("/")||(e=`/${e}`),e}function j(e){if(e.startsWith("/")||e.startsWith("#")||e.startsWith("?"))return!0;try{const t=c.getLocationOrigin(),n=new URL(e,t);return n.origin===t&&L(n.pathname)}catch(e){return!1}}function T(e,t,n){let r="";const o=m.getRouteRegex(e),i=o.groups,a=(t!==e?g.getRouteMatcher(o)(t):"")||n;r=e;const l=Object.keys(i);return l.every((e=>{let t=a[e]||"";const{repeat:n,optional:o}=i[e];let l=`[${n?"...":""}${e}]`;return o&&(l=`${t?"":"/"}[${l}]`),n&&!Array.isArray(t)&&(t=[t]),(o||e in a)&&(r=r.replace(l,n?t.map((e=>encodeURIComponent(e))).join("/"):encodeURIComponent(t))||"/")}))||(r=""),{params:l,result:r}}function A(e,t){const n={};return Object.keys(e).forEach((r=>{t.includes(r)||(n[r]=e[r])})),n}function M(e,t,n){let o,i="string"==typeof t?t:y.formatWithValidation(t);const a=i.match(/^[a-zA-Z]{1,}:\/\//),l=a?i.slice(a[0].length):i;if((l.split("?")[0]||"").match(/(\/\/|\\)/)){console.error(`Invalid href passed to next/router: ${i}, repeated forward-slashes (//) or backslashes \\ are not valid in the href`);const e=c.normalizeRepeatedSlashes(l);i=(a?a[0]:"")+e}if(!j(i))return n?[i]:i;try{o=new URL(i.startsWith("#")?e.asPath:e.pathname,"http://n")}catch(e){o=new URL("/","http://n")}try{const e=new URL(i,o);e.pathname=r.normalizePathTrailingSlash(e.pathname);let t="";if(f.isDynamicRoute(e.pathname)&&e.searchParams&&n){const n=p.searchParamsToUrlQuery(e.searchParams),{result:r,params:o}=T(e.pathname,e.pathname,n);r&&(t=y.formatWithValidation({pathname:r,hash:e.hash,query:A(n,o)}))}const a=e.origin===o.origin?e.href.slice(e.origin.length):e.href;return n?[a,t||a]:a}catch(e){return n?[i]:i}}function I(e){const t=c.getLocationOrigin();return e.startsWith(t)?e.substring(t.length):e}function D(e,t,n){let[r,o]=M(e,t,!0);const i=c.getLocationOrigin(),a=r.startsWith(i),l=o&&o.startsWith(i);r=I(r),o=o?I(o):o;const s=a?r:P(r),u=n?I(M(e,n)):o||r;return{url:s,as:l?u:P(u)}}function N(e,t){const n=r.removePathTrailingSlash(l.denormalizePagePath(e));return"/404"===n||"/_error"===n?e:(t.includes(n)||t.some((t=>{if(f.isDynamicRoute(t)&&m.getRouteRegex(t).re.test(n))return e=t,!0})),r.removePathTrailingSlash(e))}const F=window.omnivoreEnv.__NEXT_SCROLL_RESTORATION&&"undefined"!=typeof window&&"scrollRestoration"in window.history&&!!function(){try{let e="__next";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(e){}}(),z=Symbol("SSG_DATA_NOT_FOUND");function B(e,t,n){return fetch(e,{credentials:"same-origin"}).then((r=>{if(!r.ok){if(t>1&&r.status>=500)return B(e,t-1,n);if(404===r.status)return r.json().then((e=>{if(e.notFound)return{notFound:z};throw new Error("Failed to load static props")}));throw new Error("Failed to load static props")}return n.text?r.text():r.json()}))}function $(e,t,n,r,i){const{href:a}=new URL(e,window.location.href);return void 0!==r[a]?r[a]:r[a]=B(e,t?3:1,{text:n}).catch((e=>{throw t||o.markAssetError(e),e})).then((e=>(i||delete r[a],e))).catch((e=>{throw delete r[a],e}))}class W{constructor(e,t,n,{initialProps:o,pageLoader:i,App:a,wrapApp:l,Component:s,err:u,subscription:p,isFallback:h,locale:g,locales:m,defaultLocale:v,domainLocales:b,isPreview:E,isRsc:k}){this.sdc={},this.sdr={},this.sde={},this._idx=0,this.onPopState=e=>{const t=e.state;if(!t){const{pathname:e,query:t}=this;return void this.changeState("replaceState",y.formatWithValidation({pathname:P(e),query:t}),c.getURL())}if(!t.__N)return;let n;const{url:r,as:o,options:i,idx:a}=t;if(window.omnivoreEnv.__NEXT_SCROLL_RESTORATION&&F&&this._idx!==a){try{sessionStorage.setItem("__next_scroll_"+this._idx,JSON.stringify({x:self.pageXOffset,y:self.pageYOffset}))}catch{}try{const e=sessionStorage.getItem("__next_scroll_"+a);n=JSON.parse(e)}catch{n={x:0,y:0}}}this._idx=a;const{pathname:l}=d.parseRelativeUrl(r);this.isSsr&&o===P(this.asPath)&&l===P(this.pathname)||this._bps&&!this._bps(t)||this.change("replaceState",r,o,Object.assign({},i,{shallow:i.shallow&&this._shallow,locale:i.locale||this.defaultLocale}),n)};const S=r.removePathTrailingSlash(e);this.components={},"/_error"!==e&&(this.components[S]={Component:s,initial:!0,props:o,err:u,__N_SSG:o&&o.__N_SSG,__N_SSP:o&&o.__N_SSP,__N_RSC:!!k}),this.components["/_app"]={Component:a,styleSheets:[]},this.events=W.events,this.pageLoader=i;const _=f.isDynamicRoute(e)&&self.__NEXT_DATA__.autoExport;if(this.basePath=x,this.sub=p,this.clc=null,this._wrapApp=l,this.isSsr=!0,this.isLocaleDomain=!1,this.isReady=!(!(self.__NEXT_DATA__.gssp||self.__NEXT_DATA__.gip||self.__NEXT_DATA__.appGip&&!self.__NEXT_DATA__.gsp)&&(_||self.location.search||window.omnivoreEnv.__NEXT_HAS_REWRITES)),window.omnivoreEnv.__NEXT_I18N_SUPPORT&&(this.locales=m,this.defaultLocale=v,this.domainLocales=b,this.isLocaleDomain=!!w(b,self.location.hostname)),this.state={route:S,pathname:e,query:t,asPath:_?e:n,isPreview:!!E,locale:window.omnivoreEnv.__NEXT_I18N_SUPPORT?g:void 0,isFallback:h},"undefined"!=typeof window){if(!n.startsWith("//")){const r={locale:g};r._shouldResolveHref=n!==e,this.changeState("replaceState",y.formatWithValidation({pathname:P(e),query:t}),c.getURL(),r)}window.addEventListener("popstate",this.onPopState),window.omnivoreEnv.__NEXT_SCROLL_RESTORATION&&F&&(window.history.scrollRestoration="manual")}}reload(){window.location.reload()}back(){window.history.back()}push(e,t,n={}){if(window.omnivoreEnv.__NEXT_SCROLL_RESTORATION&&F)try{sessionStorage.setItem("__next_scroll_"+this._idx,JSON.stringify({x:self.pageXOffset,y:self.pageYOffset}))}catch{}return({url:e,as:t}=D(this,e,t)),this.change("pushState",e,t,n)}replace(e,t,n={}){return({url:e,as:t}=D(this,e,t)),this.change("replaceState",e,t,n)}async change(e,t,n,l,u){if(!j(t))return window.location.href=t,!1;const p=l._h||l._shouldResolveHref||O(t)===O(n),v={...this.state};l._h&&(this.isReady=!0);const b=v.locale;if(window.omnivoreEnv.__NEXT_I18N_SUPPORT){v.locale=!1===l.locale?this.defaultLocale:l.locale||v.locale,void 0===l.locale&&(l.locale=v.locale);const e=d.parseRelativeUrl(L(n)?R(n):n),r=s.normalizeLocalePath(e.pathname,this.locales);r.detectedLocale&&(v.locale=r.detectedLocale,e.pathname=P(e.pathname),n=y.formatWithValidation(e),t=P(s.normalizeLocalePath(L(t)?R(t):t,this.locales).pathname));let o=!1;var x;window.omnivoreEnv.__NEXT_I18N_SUPPORT&&((null===(x=this.locales)||void 0===x?void 0:x.includes(v.locale))||(e.pathname=_(e.pathname,v.locale),window.location.href=y.formatWithValidation(e),o=!0));const i=w(this.domainLocales,void 0,v.locale);if(window.omnivoreEnv.__NEXT_I18N_SUPPORT&&!o&&i&&this.isLocaleDomain&&self.location.hostname!==i.domain){const e=R(n);window.location.href=`http${i.http?"":"s"}://${i.domain}${P(`${v.locale===i.defaultLocale?"":`/${v.locale}`}${"/"===e?"":e}`||"/")}`,o=!0}if(o)return new Promise((()=>{}))}l._h||(this.isSsr=!1),c.ST&&performance.mark("routeChange");const{shallow:E=!1,scroll:k=!0}=l,S={shallow:E};this._inFlightRoute&&this.abortComponentLoad(this._inFlightRoute,S),n=P(_(L(n)?R(n):n,l.locale,this.defaultLocale));const M=C(L(n)?R(n):n,v.locale);this._inFlightRoute=n;let I=b!==v.locale;if(!l._h&&this.onlyAHashChange(M)&&!I)return v.asPath=M,W.events.emit("hashChangeStart",n,S),this.changeState(e,t,n,{...l,scroll:!1}),k&&this.scrollToHash(M),this.set(v,this.components[v.route],null),W.events.emit("hashChangeComplete",n,S),!0;let F,B,$=d.parseRelativeUrl(t),{pathname:H,query:U}=$;try{[F,{__rewrites:B}]=await Promise.all([this.pageLoader.getPageList(),o.getClientBuildManifest(),this.pageLoader.getMiddlewareList()])}catch(e){return window.location.href=n,!1}this.urlIsNew(M)||I||(e="replaceState");let V=n;if(H=H?r.removePathTrailingSlash(R(H)):H,p&&"/_error"!==H)if(l._shouldResolveHref=!0,window.omnivoreEnv.__NEXT_HAS_REWRITES&&n.startsWith("/")){const e=h.default(P(_(M,v.locale)),F,B,U,(e=>N(e,F)),this.locales);if(e.externalDest)return location.href=n,!0;V=e.asPath,e.matchedPage&&e.resolvedHref&&(H=e.resolvedHref,$.pathname=P(H),t=y.formatWithValidation($))}else $.pathname=N(H,F),$.pathname!==H&&(H=$.pathname,$.pathname=P(H),t=y.formatWithValidation($));if(!j(n))return window.location.href=n,!1;if(V=C(R(V),v.locale),(!l.shallow||1===l._h)&&(1!==l._h||f.isDynamicRoute(r.removePathTrailingSlash(H)))){const r=await this._preflightRequest({as:n,cache:!0,pages:F,pathname:H,query:U,locale:v.locale,isPreview:v.isPreview});if("rewrite"===r.type)U={...U,...r.parsedAs.query},V=r.asPath,H=r.resolvedHref,$.pathname=r.resolvedHref,t=y.formatWithValidation($);else{if("redirect"===r.type&&r.newAs)return this.change(e,r.newUrl,r.newAs,l);if("redirect"===r.type&&r.destination)return window.location.href=r.destination,new Promise((()=>{}));if("refresh"===r.type&&n!==window.location.pathname)return window.location.href=n,new Promise((()=>{}))}}const q=r.removePathTrailingSlash(H);if(f.isDynamicRoute(q)){const e=d.parseRelativeUrl(V),r=e.pathname,o=m.getRouteRegex(q),i=g.getRouteMatcher(o)(r),a=q===r,l=a?T(q,r,U):{};if(!i||a&&!l.result){const e=Object.keys(o.groups).filter((e=>!U[e]));if(e.length>0)throw new Error((a?`The provided \`href\` (${t}) value is missing query values (${e.join(", ")}) to be interpolated properly. `:`The provided \`as\` value (${r}) is incompatible with the \`href\` value (${q}). `)+"Read more: https://nextjs.org/docs/messages/"+(a?"href-interpolation-failed":"incompatible-href-as"))}else a?n=y.formatWithValidation(Object.assign({},e,{pathname:l.result,query:A(U,l.params)})):Object.assign(U,i)}W.events.emit("routeChangeStart",n,S);try{var K,G;let r=await this.getRouteInfo(q,H,U,n,V,S,v.locale,v.isPreview),{error:o,props:a,__N_SSG:s,__N_SSP:c}=r;const f=r.Component;if(f&&f.unstable_scriptLoader&&[].concat(f.unstable_scriptLoader()).forEach((e=>{i.handleClientScriptLoad(e.props)})),(s||c)&&a){if(a.pageProps&&a.pageProps.__N_REDIRECT){const t=a.pageProps.__N_REDIRECT;if(t.startsWith("/")&&!1!==a.pageProps.__N_REDIRECT_BASE_PATH){const n=d.parseRelativeUrl(t);n.pathname=N(n.pathname,F);const{url:r,as:o}=D(this,t,t);return this.change(e,r,o,l)}return window.location.href=t,new Promise((()=>{}))}if(v.isPreview=!!a.__N_PREVIEW,a.notFound===z){let e;try{await this.fetchComponent("/404"),e="/404"}catch(t){e="/_error"}r=await this.getRouteInfo(e,e,U,n,V,{shallow:!1},v.locale,v.isPreview)}}W.events.emit("beforeHistoryChange",n,S),this.changeState(e,t,n,l),l._h&&"/_error"===H&&500===(null===(K=self.__NEXT_DATA__.props)||void 0===K||null===(G=K.pageProps)||void 0===G?void 0:G.statusCode)&&(null==a?void 0:a.pageProps)&&(a.pageProps.statusCode=500);const p=l.shallow&&v.route===q;var X;const h=(null!==(X=l.scroll)&&void 0!==X?X:!p)?{x:0,y:0}:null;if(await this.set({...v,route:q,pathname:H,query:U,asPath:M,isFallback:!1},r,null!=u?u:h).catch((e=>{if(!e.cancelled)throw e;o=o||e})),o)throw W.events.emit("routeChangeError",o,M,S),o;return window.omnivoreEnv.__NEXT_I18N_SUPPORT&&v.locale&&(document.documentElement.lang=v.locale),W.events.emit("routeChangeComplete",n,S),!0}catch(e){if(a.default(e)&&e.cancelled)return!1;throw e}}changeState(e,t,n,r={}){"pushState"===e&&c.getURL()===n||(this._shallow=r.shallow,window.history[e]({url:t,as:n,options:r,__N:!0,idx:this._idx="pushState"!==e?this._idx:this._idx+1},"",n))}async handleRouteInfoError(e,t,n,r,i,l){if(e.cancelled)throw e;if(o.isAssetError(e)||l)throw W.events.emit("routeChangeError",e,r,i),window.location.href=r,E();try{let r,o,i;void 0!==r&&void 0!==o||({page:r,styleSheets:o}=await this.fetchComponent("/_error"));const a={props:i,Component:r,styleSheets:o,err:e,error:e};if(!a.props)try{a.props=await this.getInitialProps(r,{err:e,pathname:t,query:n})}catch(e){console.error("Error in error page `getInitialProps`: ",e),a.props={}}return a}catch(e){return this.handleRouteInfoError(a.default(e)?e:new Error(e+""),t,n,r,i,!0)}}async getRouteInfo(e,t,n,r,o,i,l,s){try{const a=this.components[e];if(i.shallow&&a&&this.route===e)return a;let u;a&&!("initial"in a)&&(u=a);const c=u||await this.fetchComponent(e).then((e=>({Component:e.page,styleSheets:e.styleSheets,__N_SSG:e.mod.__N_SSG,__N_SSP:e.mod.__N_SSP,__N_RSC:!!e.mod.__next_rsc__}))),{Component:f,__N_SSG:d,__N_SSP:p,__N_RSC:h}=c;let g;const m=p&&h;(d||p||h)&&(g=this.pageLoader.getDataHref({href:y.formatWithValidation({pathname:t,query:n}),asPath:o,ssg:d,flight:m,locale:l}));const v=await this._getData((()=>(d||p||h)&&!m?$(g,this.isSsr,!1,d?this.sdc:this.sdr,!!d&&!s):this.getInitialProps(f,{pathname:t,query:n,asPath:r,locale:l,locales:this.locales,defaultLocale:this.defaultLocale})));if(h)if(m){const{data:e}=await this._getData((()=>this._getFlightData(g)));v.pageProps=Object.assign(v.pageProps,{__flight__:e})}else{const{__flight__:e}=v;v.pageProps=Object.assign({},v.pageProps,{__flight__:e})}return c.props=v,this.components[e]=c,c}catch(e){return this.handleRouteInfoError(a.getProperError(e),t,n,r,i)}}set(e,t,n){return this.state=e,this.sub(t,this.components["/_app"].Component,n)}beforePopState(e){this._bps=e}onlyAHashChange(e){if(!this.asPath)return!1;const[t,n]=this.asPath.split("#"),[r,o]=e.split("#");return!(!o||t!==r||n!==o)||t===r&&n!==o}scrollToHash(e){const[,t=""]=e.split("#");if(""===t||"top"===t)return void window.scrollTo(0,0);const n=document.getElementById(t);if(n)return void n.scrollIntoView();const r=document.getElementsByName(t)[0];r&&r.scrollIntoView()}urlIsNew(e){return this.asPath!==e}async prefetch(e,t=e,n={}){let i=d.parseRelativeUrl(e),{pathname:a,query:l}=i;if(window.omnivoreEnv.__NEXT_I18N_SUPPORT&&!1===n.locale){a=s.normalizeLocalePath(a,this.locales).pathname,i.pathname=a,e=y.formatWithValidation(i);let r=d.parseRelativeUrl(t);const o=s.normalizeLocalePath(r.pathname,this.locales);r.pathname=o.pathname,n.locale=o.detectedLocale||this.defaultLocale,t=y.formatWithValidation(r)}const u=await this.pageLoader.getPageList();let c=t;if(window.omnivoreEnv.__NEXT_HAS_REWRITES&&t.startsWith("/")){let n;({__rewrites:n}=await o.getClientBuildManifest());const r=h.default(P(_(t,this.locale)),u,n,i.query,(e=>N(e,u)),this.locales);if(r.externalDest)return;c=C(R(r.asPath),this.locale),r.matchedPage&&r.resolvedHref&&(a=r.resolvedHref,i.pathname=a,e=y.formatWithValidation(i))}else i.pathname=N(i.pathname,u),i.pathname!==a&&(a=i.pathname,i.pathname=a,e=y.formatWithValidation(i));const f=await this._preflightRequest({as:P(t),cache:!0,pages:u,pathname:a,query:l,locale:this.locale,isPreview:this.isPreview});"rewrite"===f.type&&(i.pathname=f.resolvedHref,a=f.resolvedHref,l={...l,...f.parsedAs.query},c=f.asPath,e=y.formatWithValidation(i));const p=r.removePathTrailingSlash(a);await Promise.all([this.pageLoader._isSsg(p).then((t=>!!t&&$(this.pageLoader.getDataHref({href:e,asPath:c,ssg:!0,locale:void 0!==n.locale?n.locale:this.locale}),!1,!1,this.sdc,!0))),this.pageLoader[n.priority?"loadPage":"prefetch"](p)])}async fetchComponent(e){let t=!1;const n=this.clc=()=>{t=!0},r=()=>{if(t){const t=new Error(`Abort fetching component for route: "${e}"`);throw t.cancelled=!0,t}n===this.clc&&(this.clc=null)};try{const t=await this.pageLoader.loadPage(e);return r(),t}catch(e){throw r(),e}}_getData(e){let t=!1;const n=()=>{t=!0};return this.clc=n,e().then((e=>{if(n===this.clc&&(this.clc=null),t){const e=new Error("Loading initial props cancelled");throw e.cancelled=!0,e}return e}))}_getFlightData(e){return $(e,!0,!0,this.sdc,!1).then((e=>({data:e})))}async _preflightRequest(e){const t=O(e.as),n=C(L(t)?R(t):t,e.locale);if(!(await this.pageLoader.getMiddlewareList()).some((([e,t])=>g.getRouteMatcher(v.getMiddlewareRegex(e,!t))(n))))return{type:"next"};const o=_(e.as,e.locale);let i;try{i=await this._getPreflightData({preflightHref:o,shouldCache:e.cache,isPreview:e.isPreview})}catch(t){return{type:"redirect",destination:e.as}}if(i.rewrite){if(!i.rewrite.startsWith("/"))return{type:"redirect",destination:e.as};const t=d.parseRelativeUrl(s.normalizeLocalePath(L(i.rewrite)?R(i.rewrite):i.rewrite,this.locales).pathname),n=r.removePathTrailingSlash(t.pathname);let o,a;return e.pages.includes(n)?(o=!0,a=n):(a=N(n,e.pages),a!==t.pathname&&e.pages.includes(a)&&(o=!0)),{type:"rewrite",asPath:t.pathname,parsedAs:t,matchedPage:o,resolvedHref:a}}if(i.redirect){if(i.redirect.startsWith("/")){const e=r.removePathTrailingSlash(s.normalizeLocalePath(L(i.redirect)?R(i.redirect):i.redirect,this.locales).pathname),{url:t,as:n}=D(this,e,e);return{type:"redirect",newUrl:t,newAs:n}}return{type:"redirect",destination:i.redirect}}return i.refresh&&!i.ssr?{type:"refresh"}:{type:"next"}}_getPreflightData(e){const{preflightHref:t,shouldCache:n=!1,isPreview:r}=e,{href:o}=new URL(t,window.location.href);return!r&&n&&this.sde[o]?Promise.resolve(this.sde[o]):fetch(t,{method:"HEAD",credentials:"same-origin",headers:{"x-middleware-preflight":"1"}}).then((e=>{if(!e.ok)throw new Error("Failed to preflight request");return{cache:e.headers.get("x-middleware-cache"),redirect:e.headers.get("Location"),refresh:e.headers.has("x-middleware-refresh"),rewrite:e.headers.get("x-middleware-rewrite"),ssr:!!e.headers.get("x-middleware-ssr")}})).then((e=>(n&&"no-cache"!==e.cache&&(this.sde[o]=e),e))).catch((e=>{throw delete this.sde[o],e}))}getInitialProps(e,t){const{Component:n}=this.components["/_app"],r=this._wrapApp(n);return t.AppTree=r,c.loadGetInitialProps(n,{AppTree:r,Component:e,router:this,ctx:t})}abortComponentLoad(e,t){this.clc&&(W.events.emit("routeChangeError",E(),e,t),this.clc(),this.clc=null)}get route(){return this.state.route}get pathname(){return this.state.pathname}get query(){return this.state.query}get asPath(){return this.state.asPath}get locale(){return this.state.locale}get isFallback(){return this.state.isFallback}get isPreview(){return this.state.isPreview}}t.default=W,W.events=u.default()},6555:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.formatUrl=i,t.formatWithValidation=function(e){return i(e)},t.urlObjectKeys=void 0;var r=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(e,n):{};r.get||r.set?Object.defineProperty(t,n,r):t[n]=e[n]}return t.default=e,t}(n(646));const o=/https?|ftp|gopher|file/;function i(e){let{auth:t,hostname:n}=e,i=e.protocol||"",a=e.pathname||"",l=e.hash||"",s=e.query||"",u=!1;t=t?encodeURIComponent(t).replace(/%3A/i,":")+"@":"",e.host?u=t+e.host:n&&(u=t+(~n.indexOf(":")?`[${n}]`:n),e.port&&(u+=":"+e.port)),s&&"object"==typeof s&&(s=String(r.urlQueryToSearchParams(s)));let c=e.search||s&&`?${s}`||"";return i&&!i.endsWith(":")&&(i+=":"),e.slashes||(!i||o.test(i))&&!1!==u?(u="//"+(u||""),a&&"/"!==a[0]&&(a="/"+a)):u||(u=""),l&&"#"!==l[0]&&(l="#"+l),c&&"?"!==c[0]&&(c="?"+c),a=a.replace(/[?#]/g,encodeURIComponent),c=c.replace("#","%23"),`${i}${u}${a}${c}${l}`}t.urlObjectKeys=["auth","hash","host","hostname","href","path","pathname","port","protocol","query","search","slashes"]},9983:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t=""){return("/"===e?"/index":/^\/index(\/|$)/.test(e)?`/index${e}`:`${e}`)+t}},2763:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getMiddlewareRegex=function(e,t=!0){const n=r.getParametrizedRoute(e);let o=t?"(?!_next).*":"",i=t?"(?:(/.*)?)":"";return"routeKeys"in n?"/"===n.parameterizedRoute?{groups:{},namedRegex:`^/${o}$`,re:new RegExp(`^/${o}$`),routeKeys:{}}:{groups:n.groups,namedRegex:`^${n.namedParameterizedRoute}${i}$`,re:new RegExp(`^${n.parameterizedRoute}${i}$`),routeKeys:n.routeKeys}:"/"===n.parameterizedRoute?{groups:{},re:new RegExp(`^/${o}$`)}:{groups:{},re:new RegExp(`^${n.parameterizedRoute}${i}$`)}};var r=n(4794)},9150:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getMiddlewareRegex",{enumerable:!0,get:function(){return r.getMiddlewareRegex}}),Object.defineProperty(t,"getRouteMatcher",{enumerable:!0,get:function(){return o.getRouteMatcher}}),Object.defineProperty(t,"getRouteRegex",{enumerable:!0,get:function(){return i.getRouteRegex}}),Object.defineProperty(t,"getSortedRoutes",{enumerable:!0,get:function(){return a.getSortedRoutes}}),Object.defineProperty(t,"isDynamicRoute",{enumerable:!0,get:function(){return l.isDynamicRoute}});var r=n(2763),o=n(3107),i=n(4794),a=n(9036),l=n(7482)},7482:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isDynamicRoute=function(e){return n.test(e)};const n=/\/\[[^/]+?\](?=\/|$)/},1577:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.parseRelativeUrl=function(e,t){const n=new URL("undefined"==typeof window?"http://n":r.getLocationOrigin()),i=t?new URL(t,n):n,{pathname:a,searchParams:l,search:s,hash:u,href:c,origin:f}=new URL(e,i);if(f!==n.origin)throw new Error(`invariant: invalid relative URL, router received ${e}`);return{pathname:a,query:o.searchParamsToUrlQuery(l),search:s,hash:u,href:c.slice(n.origin.length)}};var r=n(1624),o=n(646)},2011:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.parseUrl=function(e){if(e.startsWith("/"))return o.parseRelativeUrl(e);const t=new URL(e);return{hash:t.hash,hostname:t.hostname,href:t.href,pathname:t.pathname,port:t.port,protocol:t.protocol,query:r.searchParamsToUrlQuery(t.searchParams),search:t.search}};var r=n(646),o=n(1577)},1095:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getPathMatch=function(e,t){const n=[],o=r.pathToRegexp(e,n,{delimiter:"/",sensitive:!1,strict:null==t?void 0:t.strict}),i=r.regexpToFunction((null==t?void 0:t.regexModifier)?new RegExp(t.regexModifier(o.source),o.flags):o,n);return(e,r)=>{const o=null!=e&&i(e);if(!o)return!1;if(null==t?void 0:t.removeUnnamedParams)for(const e of n)"number"==typeof e.name&&delete o.params[e.name];return{...r,...o.params}}};var r=n(9264)},9716:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.matchHas=function(e,t,n){const r={};return!!t.every((t=>{let o,i=t.key;switch(t.type){case"header":i=i.toLowerCase(),o=e.headers[i];break;case"cookie":o=e.cookies[t.key];break;case"query":o=n[i];break;case"host":{const{host:t}=(null==e?void 0:e.headers)||{};o=null==t?void 0:t.split(":")[0].toLowerCase();break}}if(!t.value&&o)return r[function(e){let t="";for(let n=0;n64&&r<91||r>96&&r<123)&&(t+=e[n])}return t}(i)]=o,!0;if(o){const e=new RegExp(`^${t.value}$`),n=Array.isArray(o)?o.slice(-1)[0].match(e):o.match(e);if(n)return Array.isArray(n)&&(n.groups?Object.keys(n.groups).forEach((e=>{r[e]=n.groups[e]})):"host"===t.type&&n[0]&&(r.host=n[0])),!0}return!1}))&&r},t.compileNonPath=a,t.prepareDestination=function(e){const t=Object.assign({},e.query);delete t.__nextLocale,delete t.__nextDefaultLocale;let n=e.destination;for(const r of Object.keys({...e.params,...t}))s=r,n=n.replace(new RegExp(`:${o.escapeStringRegexp(s)}`,"g"),`__ESC_COLON_${s}`);var s;const u=i.parseUrl(n),c=u.query,f=l(`${u.pathname}${u.hash||""}`),d=l(u.hostname||""),p=[],h=[];r.pathToRegexp(f,p),r.pathToRegexp(d,h);const g=[];p.forEach((e=>g.push(e.name))),h.forEach((e=>g.push(e.name)));const m=r.compile(f,{validate:!1}),v=r.compile(d,{validate:!1});for(const[t,n]of Object.entries(c))Array.isArray(n)?c[t]=n.map((t=>a(l(t),e.params))):c[t]=a(l(n),e.params);let y,b=Object.keys(e.params).filter((e=>"nextInternalLocale"!==e));if(e.appendParamsToQuery&&!b.some((e=>g.includes(e))))for(const t of b)t in c||(c[t]=e.params[t]);try{y=m(e.params);const[t,n]=y.split("#");u.hostname=v(e.params),u.pathname=t,u.hash=`${n?"#":""}${n||""}`,delete u.search}catch(e){if(e.message.match(/Expected .*? to not repeat, but got an array/))throw new Error("To use a multi-match in the destination you must add `*` at the end of the param name to signify it should repeat. https://nextjs.org/docs/messages/invalid-multi-match");throw e}return u.query={...t,...u.query},{newUrl:y,destQuery:c,parsedDestination:u}};var r=n(9264),o=n(8058),i=n(2011);function a(e,t){if(!e.includes(":"))return e;for(const n of Object.keys(t))e.includes(`:${n}`)&&(e=e.replace(new RegExp(`:${n}\\*`,"g"),`:${n}--ESCAPED_PARAM_ASTERISKS`).replace(new RegExp(`:${n}\\?`,"g"),`:${n}--ESCAPED_PARAM_QUESTION`).replace(new RegExp(`:${n}\\+`,"g"),`:${n}--ESCAPED_PARAM_PLUS`).replace(new RegExp(`:${n}(?!\\w)`,"g"),`--ESCAPED_PARAM_COLON${n}`));return e=e.replace(/(:|\*|\?|\+|\(|\)|\{|\})/g,"\\$1").replace(/--ESCAPED_PARAM_PLUS/g,"+").replace(/--ESCAPED_PARAM_COLON/g,":").replace(/--ESCAPED_PARAM_QUESTION/g,"?").replace(/--ESCAPED_PARAM_ASTERISKS/g,"*"),r.compile(`/${e}`,{validate:!1})(t).slice(1)}function l(e){return e.replace(/__ESC_COLON_/gi,":")}},646:(e,t)=>{"use strict";function n(e){return"string"==typeof e||"number"==typeof e&&!isNaN(e)||"boolean"==typeof e?String(e):""}Object.defineProperty(t,"__esModule",{value:!0}),t.searchParamsToUrlQuery=function(e){const t={};return e.forEach(((e,n)=>{void 0===t[n]?t[n]=e:Array.isArray(t[n])?t[n].push(e):t[n]=[t[n],e]})),t},t.urlQueryToSearchParams=function(e){const t=new URLSearchParams;return Object.entries(e).forEach((([e,r])=>{Array.isArray(r)?r.forEach((r=>t.append(e,n(r)))):t.set(e,n(r))})),t},t.assign=function(e,...t){return t.forEach((t=>{Array.from(t.keys()).forEach((t=>e.delete(t))),t.forEach(((t,n)=>e.append(n,t)))})),e}},5317:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,u,c,f){let d,p=!1,h=!1,g=l.parseRelativeUrl(e),m=i.removePathTrailingSlash(a.normalizeLocalePath(s.delBasePath(g.pathname),f).pathname);const v=n=>{let l=r.getPathMatch(n.source,{removeUnnamedParams:!0,strict:!0})(g.pathname);if(n.has&&l){const e=o.matchHas({headers:{host:document.location.hostname},cookies:document.cookie.split("; ").reduce(((e,t)=>{const[n,...r]=t.split("=");return e[n]=r.join("="),e}),{})},n.has,g.query);e?Object.assign(l,e):l=!1}if(l){if(!n.destination)return h=!0,!0;const r=o.prepareDestination({appendParamsToQuery:!0,destination:n.destination,params:l,query:u});if(g=r.parsedDestination,e=r.newUrl,Object.assign(u,r.parsedDestination.query),m=i.removePathTrailingSlash(a.normalizeLocalePath(s.delBasePath(e),f).pathname),t.includes(m))return p=!0,d=m,!0;if(d=c(m),d!==e&&t.includes(d))return p=!0,!0}};let y=!1;for(let e=0;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getRouteMatcher=function(e){const{re:t,groups:n}=e;return e=>{const o=t.exec(e);if(!o)return!1;const i=e=>{try{return decodeURIComponent(e)}catch(e){throw new r.DecodeError("failed to decode param")}},a={};return Object.keys(n).forEach((e=>{const t=n[e],r=o[t.pos];void 0!==r&&(a[e]=~r.indexOf("/")?r.split("/").map((e=>i(e))):t.repeat?[i(r)]:i(r))})),a}};var r=n(1624)},4794:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getParametrizedRoute=i,t.getRouteRegex=function(e){const t=i(e);return"routeKeys"in t?{re:new RegExp(`^${t.parameterizedRoute}(?:/)?$`),groups:t.groups,routeKeys:t.routeKeys,namedRegex:`^${t.namedParameterizedRoute}(?:/)?$`}:{re:new RegExp(`^${t.parameterizedRoute}(?:/)?$`),groups:t.groups}};var r=n(8058);function o(e){const t=e.startsWith("[")&&e.endsWith("]");t&&(e=e.slice(1,-1));const n=e.startsWith("...");return n&&(e=e.slice(3)),{key:e,repeat:n,optional:t}}function i(e){const t=(e.replace(/\/$/,"")||"/").slice(1).split("/"),n={};let i=1;const a=t.map((e=>{if(e.startsWith("[")&&e.endsWith("]")){const{key:t,optional:r,repeat:a}=o(e.slice(1,-1));return n[t]={pos:i++,repeat:a,optional:r},a?r?"(?:/(.+?))?":"/(.+?)":"/([^/]+?)"}return`/${r.escapeStringRegexp(e)}`})).join("");if("undefined"==typeof window){let e=97,i=1;const l=()=>{let t="";for(let n=0;n122&&(i++,e=97);return t},s={};return{parameterizedRoute:a,namedParameterizedRoute:t.map((e=>{if(e.startsWith("[")&&e.endsWith("]")){const{key:t,optional:n,repeat:r}=o(e.slice(1,-1));let i=t.replace(/\W/g,""),a=!1;return(0===i.length||i.length>30)&&(a=!0),isNaN(parseInt(i.slice(0,1)))||(a=!0),a&&(i=l()),s[i]=t,r?n?`(?:/(?<${i}>.+?))?`:`/(?<${i}>.+?)`:`/(?<${i}>[^/]+?)`}return`/${r.escapeStringRegexp(e)}`})).join(""),groups:n,routeKeys:s}}return{parameterizedRoute:a,groups:n}}},9036:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getSortedRoutes=function(e){const t=new n;return e.forEach((e=>t.insert(e))),t.smoosh()};class n{insert(e){this._insert(e.split("/").filter(Boolean),[],!1)}smoosh(){return this._smoosh()}_smoosh(e="/"){const t=[...this.children.keys()].sort();null!==this.slugName&&t.splice(t.indexOf("[]"),1),null!==this.restSlugName&&t.splice(t.indexOf("[...]"),1),null!==this.optionalRestSlugName&&t.splice(t.indexOf("[[...]]"),1);const n=t.map((t=>this.children.get(t)._smoosh(`${e}${t}/`))).reduce(((e,t)=>[...e,...t]),[]);if(null!==this.slugName&&n.push(...this.children.get("[]")._smoosh(`${e}[${this.slugName}]/`)),!this.placeholder){const t="/"===e?"/":e.slice(0,-1);if(null!=this.optionalRestSlugName)throw new Error(`You cannot define a route with the same specificity as a optional catch-all route ("${t}" and "${t}[[...${this.optionalRestSlugName}]]").`);n.unshift(t)}return null!==this.restSlugName&&n.push(...this.children.get("[...]")._smoosh(`${e}[...${this.restSlugName}]/`)),null!==this.optionalRestSlugName&&n.push(...this.children.get("[[...]]")._smoosh(`${e}[[...${this.optionalRestSlugName}]]/`)),n}_insert(e,t,r){if(0===e.length)return void(this.placeholder=!1);if(r)throw new Error("Catch-all must be the last part of the URL.");let o=e[0];if(o.startsWith("[")&&o.endsWith("]")){let i=o.slice(1,-1),a=!1;if(i.startsWith("[")&&i.endsWith("]")&&(i=i.slice(1,-1),a=!0),i.startsWith("...")&&(i=i.substring(3),r=!0),i.startsWith("[")||i.endsWith("]"))throw new Error(`Segment names may not start or end with extra brackets ('${i}').`);if(i.startsWith("."))throw new Error(`Segment names may not start with erroneous periods ('${i}').`);function l(e,n){if(null!==e&&e!==n)throw new Error(`You cannot use different slug names for the same dynamic path ('${e}' !== '${n}').`);t.forEach((e=>{if(e===n)throw new Error(`You cannot have the same slug name "${n}" repeat within a single dynamic path`);if(e.replace(/\W/g,"")===o.replace(/\W/g,""))throw new Error(`You cannot have the slug names "${e}" and "${n}" differ only by non-word symbols within a single dynamic path`)})),t.push(n)}if(r)if(a){if(null!=this.restSlugName)throw new Error(`You cannot use both an required and optional catch-all route at the same level ("[...${this.restSlugName}]" and "${e[0]}" ).`);l(this.optionalRestSlugName,i),this.optionalRestSlugName=i,o="[[...]]"}else{if(null!=this.optionalRestSlugName)throw new Error(`You cannot use both an optional and required catch-all route at the same level ("[[...${this.optionalRestSlugName}]]" and "${e[0]}").`);l(this.restSlugName,i),this.restSlugName=i,o="[...]"}else{if(a)throw new Error(`Optional route parameters are not yet supported ("${e[0]}").`);l(this.slugName,i),this.slugName=i,o="[]"}}this.children.has(o)||this.children.set(o,new n),this.children.get(o)._insert(e.slice(1),t,r)}constructor(){this.placeholder=!0,this.children=new Map,this.slugName=null,this.restSlugName=null,this.optionalRestSlugName=null}}},1624:(e,t)=>{"use strict";function n(){const{protocol:e,hostname:t,port:n}=window.location;return`${e}//${t}${n?":"+n:""}`}function r(e){return"string"==typeof e?e:e.displayName||e.name||"Unknown"}function o(e){return e.finished||e.headersSent}Object.defineProperty(t,"__esModule",{value:!0}),t.execOnce=function(e){let t,n=!1;return(...r)=>(n||(n=!0,t=e(...r)),t)},t.getLocationOrigin=n,t.getURL=function(){const{href:e}=window.location,t=n();return e.substring(t.length)},t.getDisplayName=r,t.isResSent=o,t.normalizeRepeatedSlashes=function(e){const t=e.split("?");return t[0].replace(/\\/g,"/").replace(/\/\/+/g,"/")+(t[1]?`?${t.slice(1).join("?")}`:"")},t.loadGetInitialProps=async function e(t,n){const i=n.res||n.ctx&&n.ctx.res;if(!t.getInitialProps)return n.ctx&&n.Component?{pageProps:await e(n.Component,n.ctx)}:{};const a=await t.getInitialProps(n);if(i&&o(i))return a;if(!a){const e=`"${r(t)}.getInitialProps()" should resolve to an object. But found "${a}" instead.`;throw new Error(e)}return a},t.ST=t.SP=t.warnOnce=void 0,t.warnOnce=e=>{};const i="undefined"!=typeof performance;t.SP=i;const a=i&&"function"==typeof performance.mark&&"function"==typeof performance.measure;t.ST=a;class l extends Error{}t.DecodeError=l;class s extends Error{}t.NormalizeError=s},9097:(e,t,n)=>{e.exports=n(4529)},5632:(e,t,n)=>{e.exports=n(9518)},7320:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,i){for(var a,l,s=o(e),u=1;u{"use strict";var r=n(2784),o=n(7320),i=n(4616);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n