diff --git a/DevLog.xcodeproj/project.pbxproj b/DevLog.xcodeproj/project.pbxproj index 266721bf..9bac419a 100644 --- a/DevLog.xcodeproj/project.pbxproj +++ b/DevLog.xcodeproj/project.pbxproj @@ -149,6 +149,7 @@ hasScannedForEncodings = 0; knownRegions = ( ko, + en, ); mainGroup = DFD48AF72DC4D6E2005905C5; minimizedProjectReferenceProxies = 1; diff --git a/DevLog/App/RootView.swift b/DevLog/App/RootView.swift index b69ba037..f2e8f4ed 100644 --- a/DevLog/App/RootView.swift +++ b/DevLog/App/RootView.swift @@ -33,7 +33,7 @@ struct RootView: View { get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert($0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } diff --git a/DevLog/Presentation/Structure/Profile/ProfileActivityType.swift b/DevLog/Presentation/Structure/Profile/ProfileActivityType.swift index f2ef586d..5ffaefe9 100644 --- a/DevLog/Presentation/Structure/Profile/ProfileActivityType.swift +++ b/DevLog/Presentation/Structure/Profile/ProfileActivityType.swift @@ -13,8 +13,8 @@ enum ProfileActivityType: String, CaseIterable, Hashable { var title: String { switch self { - case .created: return "생성" - case .completed: return "완료" + case .created: return String(localized: "profile_activity_created") + case .completed: return String(localized: "profile_activity_completed") } } } diff --git a/DevLog/Presentation/Structure/Profile/ProfileSelectedDayActivity.swift b/DevLog/Presentation/Structure/Profile/ProfileSelectedDayActivity.swift index fb56c40e..8cf1dfe9 100644 --- a/DevLog/Presentation/Structure/Profile/ProfileSelectedDayActivity.swift +++ b/DevLog/Presentation/Structure/Profile/ProfileSelectedDayActivity.swift @@ -16,8 +16,10 @@ struct ProfileSelectedDayActivity: Identifiable, Hashable { var activityLabel: String { if showsCreated && showsCompleted { - return "생성/완료" + return String(localized: "profile_activity_created_completed") } - return showsCreated ? "생성" : "완료" + return showsCreated + ? String(localized: "profile_activity_created") + : String(localized: "profile_activity_completed") } } diff --git a/DevLog/Presentation/Structure/WebPageItem.swift b/DevLog/Presentation/Structure/WebPageItem.swift index bc143168..9cb403d5 100644 --- a/DevLog/Presentation/Structure/WebPageItem.swift +++ b/DevLog/Presentation/Structure/WebPageItem.swift @@ -15,7 +15,7 @@ struct WebPageItem: Identifiable, Hashable { } var id: URL { metadata.url } - var title: String { metadata.title ?? "웹페이지를 찾을 수 없습니다" } + var title: String { metadata.title ?? String(localized: "web_page_missing_title") } var url: URL { metadata.url } var displayURL: String { metadata.displayURL.absoluteString } var imageURL: URL? { metadata.imageURL } diff --git a/DevLog/Presentation/ViewModel/AccountViewModel.swift b/DevLog/Presentation/ViewModel/AccountViewModel.swift index 71253167..edeee134 100644 --- a/DevLog/Presentation/ViewModel/AccountViewModel.swift +++ b/DevLog/Presentation/ViewModel/AccountViewModel.swift @@ -160,17 +160,17 @@ private extension AccountViewModel { func setAlert(_ state: inout State, isPresented: Bool, type: AlertType?) { switch type { case .linkEmailNotFound: - state.alertTitle = "이메일 확인 불가" - state.alertMessage = "선택한 계정의 이메일 정보를 확인할 수 없어 연결할 수 없어요. 계정 설정을 확인한 뒤 다시 시도해주세요." + state.alertTitle = String(localized: "account_alert_email_unavailable_title") + state.alertMessage = String(localized: "account_alert_email_unavailable_message") case .linkEmailMismatch: - state.alertTitle = "연결할 수 없음" - state.alertMessage = "현재 로그인한 계정과 선택한 계정의 이메일이 달라 연결할 수 없어요. 같은 이메일의 계정으로 다시 시도해주세요." + state.alertTitle = String(localized: "account_alert_cannot_link_title") + state.alertMessage = String(localized: "account_alert_cannot_link_message") case .linkCredentialAlreadyInUse: - state.alertTitle = "이미 연결된 계정" - state.alertMessage = "선택한 계정은 이미 다른 계정에 연결되어 있어요. 해당 계정으로 로그인한 뒤 이용해주세요." + state.alertTitle = String(localized: "account_alert_already_linked_title") + state.alertMessage = String(localized: "account_alert_already_linked_message") case .error: - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") case .none: state.alertTitle = "" state.alertMessage = "" @@ -182,9 +182,9 @@ private extension AccountViewModel { func setToast(_ state: inout State, isPresented: Bool, type: ToastType?) { switch type { case .linkSuccess: - state.toastMessage = "계정이 성공적으로 연결되었습니다." + state.toastMessage = String(localized: "account_toast_link_success") case .unlinkSuccess: - state.toastMessage = "계정 연결이 성공적으로 해제되었습니다." + state.toastMessage = String(localized: "account_toast_unlink_success") case .none: state.toastMessage = "" } diff --git a/DevLog/Presentation/ViewModel/HomeViewModel.swift b/DevLog/Presentation/ViewModel/HomeViewModel.swift index a906c21a..36c3a7e9 100644 --- a/DevLog/Presentation/ViewModel/HomeViewModel.swift +++ b/DevLog/Presentation/ViewModel/HomeViewModel.swift @@ -390,15 +390,15 @@ private extension HomeViewModel { ) { switch type { case .webPageInput: - state.alertTitle = "URL 추가" - state.alertMessage = "웹페이지 URL을 입력해주세요." + state.alertTitle = String(localized: "home_webpage_input_title") + state.alertMessage = String(localized: "home_webpage_input_message") state.webPageURLInput = "https://" case .invalidURL: - state.alertTitle = "URL 확인" - state.alertMessage = "올바른 URL을 입력해주세요." + state.alertTitle = String(localized: "home_invalid_url_title") + state.alertMessage = String(localized: "home_invalid_url_message") case .error: - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") case .none: state.alertTitle = "" state.alertMessage = "" @@ -414,7 +414,7 @@ private extension HomeViewModel { ) { switch type { case .deleteWebPage: - state.toastMessage = "실행 취소" + state.toastMessage = String(localized: "common_undo") case .none: state.toastMessage = "" } diff --git a/DevLog/Presentation/ViewModel/LoginViewModel.swift b/DevLog/Presentation/ViewModel/LoginViewModel.swift index bf92e3bc..4ed50ec2 100644 --- a/DevLog/Presentation/ViewModel/LoginViewModel.swift +++ b/DevLog/Presentation/ViewModel/LoginViewModel.swift @@ -75,8 +75,8 @@ private extension LoginViewModel { _ state: inout State, isPresented: Bool, ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } } diff --git a/DevLog/Presentation/ViewModel/MainViewModel.swift b/DevLog/Presentation/ViewModel/MainViewModel.swift index 80eb04f0..a8629738 100644 --- a/DevLog/Presentation/ViewModel/MainViewModel.swift +++ b/DevLog/Presentation/ViewModel/MainViewModel.swift @@ -77,8 +77,8 @@ private extension MainViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "알림 배지를 불러오는 중 문제가 발생했습니다." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "main_alert_badge_error_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/ProfileViewModel.swift b/DevLog/Presentation/ViewModel/ProfileViewModel.swift index aaa89eaa..647c2f4c 100644 --- a/DevLog/Presentation/ViewModel/ProfileViewModel.swift +++ b/DevLog/Presentation/ViewModel/ProfileViewModel.swift @@ -362,8 +362,8 @@ private extension ProfileViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift index db32d5de..f6386d4f 100644 --- a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift +++ b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift @@ -301,8 +301,8 @@ private extension PushNotificationListViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } @@ -310,7 +310,7 @@ private extension PushNotificationListViewModel { _ state: inout State, isPresented: Bool ) { - state.toastMessage = "실행 취소" + state.toastMessage = String(localized: "common_undo") state.showToast = isPresented } @@ -357,8 +357,8 @@ private extension PushNotificationListViewModel { extension PushNotificationQuery.SortOrder { var title: String { switch self { - case .latest: return "최신순" - case .oldest: return "예전순" + case .latest: return String(localized: "push_sort_latest") + case .oldest: return String(localized: "push_sort_oldest") } } } @@ -375,11 +375,17 @@ extension PushNotificationQuery.TimeFilter { var title: String { switch self { case .none: - return "전체" + return String(localized: "push_timefilter_all") case .hours(let value): - return "최근 \(value)시간" + return String.localizedStringWithFormat( + String(localized: "push_timefilter_hours_format"), + Int64(value) + ) case .days(let value): - return "최근 \(value)일" + return String.localizedStringWithFormat( + String(localized: "push_timefilter_days_format"), + Int64(value) + ) } } diff --git a/DevLog/Presentation/ViewModel/PushNotificationSettingsViewModel.swift b/DevLog/Presentation/ViewModel/PushNotificationSettingsViewModel.swift index 25acef32..f40e0cb3 100644 --- a/DevLog/Presentation/ViewModel/PushNotificationSettingsViewModel.swift +++ b/DevLog/Presentation/ViewModel/PushNotificationSettingsViewModel.swift @@ -150,8 +150,8 @@ extension PushNotificationSettingsViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/RootViewModel.swift b/DevLog/Presentation/ViewModel/RootViewModel.swift index d4f47503..14fb7121 100644 --- a/DevLog/Presentation/ViewModel/RootViewModel.swift +++ b/DevLog/Presentation/ViewModel/RootViewModel.swift @@ -92,8 +92,8 @@ private extension RootViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "네트워크 연결 끊김" - state.alertMessage = "인터넷 연결을 확인해주세요." + state.alertTitle = String(localized: "root_network_disconnected_title") + state.alertMessage = String(localized: "root_network_disconnected_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/SearchViewModel.swift b/DevLog/Presentation/ViewModel/SearchViewModel.swift index 2e56e10f..009b8785 100644 --- a/DevLog/Presentation/ViewModel/SearchViewModel.swift +++ b/DevLog/Presentation/ViewModel/SearchViewModel.swift @@ -155,8 +155,8 @@ private extension SearchViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/SettingViewModel.swift b/DevLog/Presentation/ViewModel/SettingViewModel.swift index 902118ae..482b47d5 100644 --- a/DevLog/Presentation/ViewModel/SettingViewModel.swift +++ b/DevLog/Presentation/ViewModel/SettingViewModel.swift @@ -143,17 +143,17 @@ private extension SettingViewModel { ) { switch type { case .signOut: - state.alertTitle = "로그아웃" - state.alertMessage = "로그아웃 하시겠습니까?" + state.alertTitle = String(localized: "settings_alert_sign_out_title") + state.alertMessage = String(localized: "settings_alert_sign_out_message") case .deleteAuth: - state.alertTitle = "정말 탈퇴하시겠습니까?" - state.alertMessage = "회원 탈퇴가 진행되면 모든 데이터가 지워지고 복구할 수 없습니다." + state.alertTitle = String(localized: "settings_alert_delete_account_title") + state.alertMessage = String(localized: "settings_alert_delete_account_message") case .error: - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") case .removeCache: - state.alertTitle = "임시 데이터 삭제" - state.alertMessage = "임시 데이터를 삭제하고 정리합니다.\n계속하시겠습니까?" + state.alertTitle = String(localized: "settings_alert_clear_temp_title") + state.alertMessage = String(localized: "settings_alert_clear_temp_message") case .none: state.alertTitle = "" state.alertMessage = "" diff --git a/DevLog/Presentation/ViewModel/TodayViewModel.swift b/DevLog/Presentation/ViewModel/TodayViewModel.swift index b339a74f..d3d08641 100644 --- a/DevLog/Presentation/ViewModel/TodayViewModel.swift +++ b/DevLog/Presentation/ViewModel/TodayViewModel.swift @@ -9,15 +9,26 @@ import Foundation @Observable final class TodayViewModel: Store { - enum SummaryScope: Hashable, CaseIterable { + // TodayView 상단에서 사용자가 선택하는 요약 탭 범위. + enum SectionScope: Hashable, CaseIterable { case all case focused case overdue case dueSoon } + // 요약 탭 아래 실제 리스트에 렌더링되는 섹션 분류. + enum SectionCategory: Hashable { + case later + case unscheduled + case focused + case overdue + case dueSoon + } + struct SectionContent: Identifiable, Equatable { - var id: String { title } + var id: SectionCategory { category } + let category: SectionCategory let title: String let items: [TodayTodoItem] } @@ -36,14 +47,14 @@ final class TodayViewModel: Store { var showAlert: Bool = false var alertTitle: String = "" var alertMessage: String = "" - var selectedSummaryScope: SummaryScope = .all + var selectedSectionScope: SectionScope = .all var displayOptions: TodayDisplayOptions = .default } enum Action { case refresh case setAlert(Bool) - case setSummaryScope(SummaryScope) + case setSectionScope(SectionScope) case setDueDateVisibility(TodayDisplayOptions.DueDateVisibility) case setFocusVisibility(TodayDisplayOptions.FocusVisibility) case resetDisplayOptions @@ -87,28 +98,64 @@ final class TodayViewModel: Store { } var sections: [SectionContent] { - let groupedItems = groupedSectionItems(from: displayedTodos) - let allSections: [SectionContent] = [ - SectionContent(title: "집중할 일", items: groupedItems.focused), - SectionContent(title: "지난 마감", items: groupedItems.overdue), - SectionContent(title: "\(upcomingWindowDays)일 내 일정", items: groupedItems.dueSoon), - SectionContent(title: "나중 일정", items: groupedItems.later), - SectionContent(title: "일정 미정", items: groupedItems.unscheduled) - ] - - switch state.selectedSummaryScope { + let items = groupedSectionItems(from: displayedTodos) + + switch state.selectedSectionScope { case .all: - return allSections.filter { !$0.items.isEmpty } + return + makeSection( + category: .focused, + title: String(localized: "today_section_focused"), + items: items.focused + ) + + makeSection( + category: .overdue, + title: String(localized: "today_section_overdue"), + items: items.overdue + ) + + makeSection( + category: .dueSoon, + title: String.localizedStringWithFormat( + String(localized: "today_section_due_soon_format"), + Int64(upcomingWindowDays) + ), + items: items.dueSoon + ) + + makeSection( + category: .later, + title: String(localized: "today_section_later"), + items: items.later + ) + + makeSection( + category: .unscheduled, + title: String(localized: "today_section_unscheduled"), + items: items.unscheduled + ) case .focused: - return allSections.filter { $0.title == "집중할 일" && !$0.items.isEmpty } + return makeSection( + category: .focused, + title: String(localized: "today_section_focused"), + items: items.focused + ) case .overdue: - return allSections.filter { $0.title == "지난 마감" && !$0.items.isEmpty } + return makeSection( + category: .overdue, + title: String(localized: "today_section_overdue"), + items: items.overdue + ) case .dueSoon: - return allSections.filter { $0.title == "\(upcomingWindowDays)일 내 일정" && !$0.items.isEmpty } + return makeSection( + category: .dueSoon, + title: String.localizedStringWithFormat( + String(localized: "today_section_due_soon_format"), + Int64(upcomingWindowDays) + ), + items: items.dueSoon + ) } } - func summaryValue(for scope: SummaryScope) -> Int { + func summaryValue(for scope: SectionScope) -> Int { switch scope { case .all: return displayedTodos.count @@ -126,7 +173,7 @@ final class TodayViewModel: Store { var effects: [SideEffect] = [] switch action { - case .refresh, .setAlert, .setSummaryScope, .setDueDateVisibility, .setFocusVisibility, + case .refresh, .setAlert, .setSectionScope, .setDueDateVisibility, .setFocusVisibility, .resetDisplayOptions, .completeTodo, .togglePinned: effects = reduceByUser(action, state: &state) case .onAppear: @@ -210,17 +257,26 @@ final class TodayViewModel: Store { } private extension TodayViewModel { + func makeSection( + category: SectionCategory, + title: String, + items: [TodayTodoItem] + ) -> [SectionContent] { + guard !items.isEmpty else { return [] } + return [SectionContent(category: category, title: title, items: items)] + } + func reduceByUser(_ action: Action, state: inout State) -> [SideEffect] { switch action { case .refresh: return [.fetchTodos] case .setAlert(let isPresented): setAlert(&state, isPresented: isPresented) - case .setSummaryScope(let scope): - if state.selectedSummaryScope == scope, scope != .all { - state.selectedSummaryScope = .all + case .setSectionScope(let scope): + if state.selectedSectionScope == scope, scope != .all { + state.selectedSectionScope = .all } else { - state.selectedSummaryScope = scope + state.selectedSectionScope = scope } case .setDueDateVisibility(let visibility): state.displayOptions.dueDateVisibility = visibility @@ -275,8 +331,8 @@ private extension TodayViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/TodoDetailViewModel.swift b/DevLog/Presentation/ViewModel/TodoDetailViewModel.swift index cfd9a71c..3f5e705b 100644 --- a/DevLog/Presentation/ViewModel/TodoDetailViewModel.swift +++ b/DevLog/Presentation/ViewModel/TodoDetailViewModel.swift @@ -141,8 +141,8 @@ private extension TodoDetailViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } diff --git a/DevLog/Presentation/ViewModel/TodoEditorViewModel.swift b/DevLog/Presentation/ViewModel/TodoEditorViewModel.swift index 26cca445..73c40819 100644 --- a/DevLog/Presentation/ViewModel/TodoEditorViewModel.swift +++ b/DevLog/Presentation/ViewModel/TodoEditorViewModel.swift @@ -104,10 +104,13 @@ final class TodoEditorViewModel: Store { var navigationTitle: String { if originalDraft == nil { - return "새 \(state.category.localizedName) 추가" + return String.localizedStringWithFormat( + String(localized: "todo_editor_new_format"), + state.category.localizedName + ) } - return "편집" + return String(localized: "todo_edit") } var hasChanges: Bool { diff --git a/DevLog/Presentation/ViewModel/TodoListViewModel.swift b/DevLog/Presentation/ViewModel/TodoListViewModel.swift index 11343d26..59452c0a 100644 --- a/DevLog/Presentation/ViewModel/TodoListViewModel.swift +++ b/DevLog/Presentation/ViewModel/TodoListViewModel.swift @@ -397,8 +397,8 @@ private extension TodoListViewModel { _ state: inout State, isPresented: Bool ) { - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." + state.alertTitle = String(localized: "common_error_title") + state.alertMessage = String(localized: "common_error_message") state.showAlert = isPresented } @@ -406,7 +406,7 @@ private extension TodoListViewModel { _ state: inout State, isPresented: Bool ) { - state.toastMessage = "실행 취소" + state.toastMessage = String(localized: "common_undo") state.showToast = isPresented } @@ -444,11 +444,11 @@ extension TodoQuery.SortTarget { var title: String { switch self { case .createdAt: - return "생성" + return String(localized: "todo_sort_created") case .updatedAt: - return "수정" + return String(localized: "todo_sort_updated") case .dueDate: - return "마감" + return String(localized: "todo_sort_due_date") } } } @@ -457,9 +457,9 @@ extension TodoQuery.SortOrder { var title: String { switch self { case .latest: - return "최신순" + return String(localized: "todo_sort_latest") case .oldest: - return "예전순" + return String(localized: "todo_sort_oldest") } } } @@ -468,11 +468,11 @@ extension TodoQuery.CompletionFilter { var title: String { switch self { case .all: - return "완료 + 미완료" + return String(localized: "todo_completion_all") case .incomplete: - return "미완료" + return String(localized: "todo_completion_incomplete") case .completed: - return "완료" + return String(localized: "todo_completion_completed") } } } diff --git a/DevLog/Presentation/ViewModel/TodoManageViewModel.swift b/DevLog/Presentation/ViewModel/TodoManageViewModel.swift index eea980c9..35669a73 100644 --- a/DevLog/Presentation/ViewModel/TodoManageViewModel.swift +++ b/DevLog/Presentation/ViewModel/TodoManageViewModel.swift @@ -44,11 +44,15 @@ final class TodoManageViewModel: Store { } var navigationTitle: String { - isEditing ? "카테고리 수정" : "카테고리 추가" + isEditing + ? String(localized: "todo_manage_edit_category_title") + : String(localized: "todo_manage_add_category_title") } var submitTitle: String { - isEditing ? "저장" : "추가" + isEditing + ? String(localized: "todo_manage_save") + : String(localized: "todo_add") } var placeholder: String { @@ -56,7 +60,7 @@ final class TodoManageViewModel: Store { let item = state.category, case .user(let category) = item.category else { - return "이름" + return String(localized: "todo_manage_name_placeholder") } return category.name diff --git a/DevLog/Resource/Localizable.xcstrings b/DevLog/Resource/Localizable.xcstrings index 0891522a..88bdc7b0 100644 --- a/DevLog/Resource/Localizable.xcstrings +++ b/DevLog/Resource/Localizable.xcstrings @@ -5,411 +5,4285 @@ }, "#%lld" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "#%1$lld" + } + } + } }, "%@ 검색" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Search %1$@" + } + } + } }, "%@의 제목이나 내용을 검색해 보세요." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Search titles or content in %1$@." + } + } + } }, "%lld" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld" + } + } + } }, "%lld개 필터가 적용됨" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld filters applied" + } + } + } }, "%lld주" : { - - }, - "https://" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Week %1$lld" + } + } + } }, - "lime_green" : { + "account_alert_already_linked_message" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The selected account is already linked to another account. Please sign in with that account and try again." + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "라임 그린" + "value" : "선택한 계정은 이미 다른 계정에 연결되어 있어요. 해당 계정으로 로그인한 뒤 이용해주세요." } } } }, - "Markdown 미리보기" : { - - }, - "Markdown 지원 · 예: # 제목, - 목록, **굵게**, - refs #번호" : { - - }, - "night_sky" : { + "account_alert_already_linked_title" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account Already Linked" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "밤하늘" + "value" : "이미 연결된 계정" } } } }, - "orange" : { + "account_alert_cannot_link_message" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The selected account uses a different email from the current account, so it cannot be linked. Please try again with an account that uses the same email." + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "오렌지" + "value" : "현재 로그인한 계정과 선택한 계정의 이메일이 달라 연결할 수 없어요. 같은 이메일의 계정으로 다시 시도해주세요." } } } }, - "pink" : { + "account_alert_cannot_link_title" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unable to Link" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "핑크" + "value" : "연결할 수 없음" } } } }, - "primary" : { + "account_alert_email_unavailable_message" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The selected account's email could not be verified, so it cannot be linked. Check the account settings and try again." + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "기본" + "value" : "선택한 계정의 이메일 정보를 확인할 수 없어 연결할 수 없어요. 계정 설정을 확인한 뒤 다시 시도해주세요." } } } }, - "Q%lld" : { - - }, - "rainbow" : { + "account_alert_email_unavailable_title" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Email Unavailable" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "무지개" + "value" : "이메일 확인 불가" } } } }, - "sky" : { + "account_connect" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Connect" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "하늘" + "value" : "연결" } } } }, - "sun" : { + "account_current_section" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Current Account" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "태양" + "value" : "현재 계정" } } } }, - "system_theme_automatic" : { + "account_disconnect" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disconnect" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "자동" + "value" : "연결 해제" } } } }, - "system_theme_dark" : { + "account_social_section" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Social Accounts" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "다크 모드" + "value" : "소셜 계정" } } } }, - "system_theme_light" : { + "account_title" : { "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "라이트 모드" + "value" : "계정 연동" } } } }, - "TODO" : { - + "account_toast_link_success" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account linked successfully." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "계정이 성공적으로 연결되었습니다." + } + } + } }, - "TODO 편집" : { - + "account_toast_unlink_success" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account disconnected successfully." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "계정 연결이 성공적으로 해제되었습니다." + } + } + } }, - "todo_category_doc" : { - "comment" : "Todo category: Documentation", + "common_cancel" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancel" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "문서화" + "value" : "취소" } } } }, - "todo_category_etc" : { - "comment" : "Todo category: Etc", + "common_close" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Close" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "기타" + "value" : "닫기" } } } }, - "todo_category_feature" : { - "comment" : "Todo category: Feature", + "common_confirm" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Confirm" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "신규 기능" + "value" : "확인" } } } }, - "todo_category_improvement" : { - "comment" : "Todo category: Improvement", + "common_delete" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "개선" + "value" : "삭제" } } } }, - "todo_category_issue" : { - "comment" : "Todo category: Issue", + "common_error_message" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Something went wrong. Please try again later." + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "이슈" + "value" : "문제가 발생했습니다. 잠시 후 다시 시도해주세요." } } } }, - "todo_category_research" : { - "comment" : "Todo category: Research", + "common_error_title" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Error" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "조사" + "value" : "오류" } } } }, - "todo_category_review" : { - "comment" : "Todo category: Review", + "common_undo" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Undo" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "리뷰" + "value" : "실행 취소" } } } }, - "todo_category_test" : { - "comment" : "Todo category: Test", + "home_add" : { + "extractionState" : "manual", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add" + } + }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "테스트" + "value" : "추가" } } } }, - "Todos" : { - + "home_content_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Content" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "컨텐츠" + } + } + } }, - "Web Page" : { - + "home_invalid_url_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Please enter a valid URL." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "올바른 URL을 입력해주세요." + } + } + } }, - "Web Pages" : { - + "home_invalid_url_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Check URL" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "URL 확인" + } + } + } }, - "개인정보 처리방침" : { - + "home_recent_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No recently updated todos." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최근 수정한 Todo가 없습니다." + } + } + } }, - "검색" : { - + "home_recent_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recently Updated" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최근 수정" + } + } + } + }, + "home_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Home" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "홈" + } + } + } + }, + "home_web_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saved web pages appear here." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "저장한 Web Page가 표시됩니다." + } + } + } + }, + "home_webpage_input_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter a web page URL." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "웹페이지 URL을 입력해주세요." + } + } + } + }, + "home_webpage_input_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add URL" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "URL 추가" + } + } + } + }, + "https://" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://" + } + } + } + }, + "lime_green" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lime Green" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "라임 그린" + } + } + } + }, + "login_apple_sign_in" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign in with Apple" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "애플 계정으로 로그인" + } + } + } + }, + "login_github_sign_in" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign in with GitHub" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "깃헙 계정으로 로그인" + } + } + } + }, + "login_google_sign_in" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign in with Google" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "구글 계정으로 로그인" + } + } + } + }, + "login_terms_notice" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "By signing in, you agree to the Terms of Service and Privacy Policy." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "로그인하면 사용 약관 및 개인 정보 취급 방침에 동의하게 됩니다." + } + } + } + }, + "main_alert_badge_error_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There was a problem loading the notification badge." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "알림 배지를 불러오는 중 문제가 발생했습니다." + } + } + } + }, + "Markdown 미리보기" : { + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markdown Preview" + } + } + } + }, + "Markdown 지원 · 예: # 제목, - 목록, **굵게**, - refs #번호" : { + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markdown supported, e.g. # Heading, - List, **Bold**, - refs #123" + } + } + } + }, + "nav_home" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Home" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "홈" + } + } + } + }, + "nav_notifications" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifications" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "알림" + } + } + } + }, + "nav_profile" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Profile" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "프로필" + } + } + } + }, + "nav_today" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Today" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "오늘" + } + } + } + }, + "night_sky" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Night Sky" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "밤하늘" + } + } + } + }, + "orange" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Orange" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "오렌지" + } + } + } + }, + "pink" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pink" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "핑크" + } + } + } + }, + "primary" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Default" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기본" + } + } + } + }, + "profile_activity_axis" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Activity" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "활동" + } + } + } + }, + "profile_activity_completed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completed" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + } + } + }, + "profile_activity_created" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Created" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "생성" + } + } + } + }, + "profile_activity_created_completed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Created/Completed" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "생성/완료" + } + } + } + }, + "profile_activity_heatmap" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Activity Heatmap" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "활동 히트맵" + } + } + } + }, + "profile_activity_none" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Activity" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "활동 없음" + } + } + } + }, + "profile_done" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Done" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + } + } + }, + "profile_quarter_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There is no selected activity in this quarter." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "이 분기에는 선택한 활동이 없어요" + } + } + } + }, + "profile_quarterly_activity" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quarterly Activity" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "분기별 활동" + } + } + } + }, + "profile_select_quarter" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select Quarter" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "분기 선택" + } + } + } + }, + "profile_status_placeholder" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set Status" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "상태 설정" + } + } + } + }, + "profile_week_axis" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Week" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "주차" + } + } + } + }, + "profile_week_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Week %1$lld" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld주" + } + } + } + }, + "profile_weekday_fri" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fri" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "금" + } + } + } + }, + "profile_weekday_mon" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mon" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "월" + } + } + } + }, + "profile_weekday_wed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wed" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "수" + } + } + } + }, + "profile_weekly_trend" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Weekly Trend" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "주간 추세" + } + } + } + }, + "profile_year" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Year" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "연도" + } + } + } + }, + "profile_year_option_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld년" + } + } + } + }, + "push_clear_all_filters" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear All Filters" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "모든 필터 지우기" + } + } + } + }, + "push_filters_applied_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld filters applied" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld개 필터가 적용됨" + } + } + } + }, + "push_notifications_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No notifications received." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "받은 알림이 없습니다." + } + } + } + }, + "push_notifications_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifications" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "받은 푸시 알람" + } + } + } + }, + "push_period" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Period" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기간" + } + } + } + }, + "push_settings_custom" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Custom" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "사용자 설정" + } + } + } + }, + "push_settings_enable" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enable Push Notifications" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "푸시 알람 활성화" + } + } + } + }, + "push_settings_footer" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Separate from your Settings app notification preference." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "설정에서의 푸시 알람 설정과 별개입니다." + } + } + } + }, + "push_settings_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alerts" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "알람" + } + } + } + }, + "push_sort_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort: %1$@" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "정렬: %1$@" + } + } + } + }, + "push_sort_latest" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Newest First" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최신순" + } + } + } + }, + "push_sort_oldest" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Oldest First" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "예전순" + } + } + } + }, + "push_time_days_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lldd ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld일 전" + } + } + } + }, + "push_time_hours_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lldh ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld시간 전" + } + } + } + }, + "push_time_minutes_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lldm ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld분 전" + } + } + } + }, + "push_time_seconds_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$llds ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld초 전" + } + } + } + }, + "push_timefilter_all" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "All" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "전체" + } + } + } + }, + "push_timefilter_days_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Last %1$lld days" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최근 %1$lld일" + } + } + } + }, + "push_timefilter_hours_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Last %1$lld hours" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최근 %1$lld시간" + } + } + } + }, + "push_unread" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unread" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "읽지 않음" + } + } + } + }, + "Q%lld" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Q%1$lld" + } + } + } + }, + "rainbow" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rainbow" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "무지개" + } + } + } + }, + "relative_time_days_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lldd ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld일 전" + } + } + } + }, + "relative_time_hours_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lldh ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld시간 전" + } + } + } + }, + "relative_time_minutes_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lldm ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld분 전" + } + } + } + }, + "relative_time_seconds_ago_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$llds ago" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld초 전" + } + } + } + }, + "relative_time_updated_suffix" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : " updated" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : " 업데이트" + } + } + } + }, + "relative_time_updated_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Updated %1$@" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ 업데이트" + } + } + } + }, + "root_network_disconnected_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Please check your internet connection." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "인터넷 연결을 확인해주세요." + } + } + } + }, + "root_network_disconnected_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Network Disconnected" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "네트워크 연결 끊김" + } + } + } + }, + "search_clear_all" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear All" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "전체 삭제" + } + } + } + }, + "search_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No results found." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "검색 결과가 없습니다." + } + } + } + }, + "search_instruction" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter a search term to find your saved content." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "검색어를 입력해 저장한 앱 컨텐츠를 찾아보세요." + } + } + } + }, + "search_prompt" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Search" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "검색" + } + } + } + }, + "search_recent" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recent Searches" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최근 검색" + } + } + } + }, + "search_show_more" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show More" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "더보기" + } + } + } + }, + "settings_account" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "계정 연동" + } + } + } + }, + "settings_alert_clear_temp_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "This will clear temporary data and free up space.\nDo you want to continue?" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "임시 데이터를 삭제하고 정리합니다.\n계속하시겠습니까?" + } + } + } + }, + "settings_alert_clear_temp_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear Temporary Data" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "임시 데이터 삭제" + } + } + } + }, + "settings_alert_delete_account_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deleting your account will erase all data and cannot be undone." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "회원 탈퇴가 진행되면 모든 데이터가 지워지고 복구할 수 없습니다." + } + } + } + }, + "settings_alert_delete_account_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Are you sure you want to delete your account?" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "정말 탈퇴하시겠습니까?" + } + } + } + }, + "settings_alert_sign_out_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Do you want to sign out?" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "로그아웃 하시겠습니까?" + } + } + } + }, + "settings_alert_sign_out_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign Out" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "로그아웃" + } + } + } + }, + "settings_clear_temp_data" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear Temporary Data" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "임시 데이터 삭제" + } + } + } + }, + "settings_delete_account" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Account" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "회원 탈퇴" + } + } + } + }, + "settings_delete_account_action" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "탈퇴" + } + } + } + }, + "settings_join_beta" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Join Beta Testing" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "베타 테스트 참여" + } + } + } + }, + "settings_join_beta_subtitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Get early access to new features." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "신규 기능을 빠르게 만나볼 수 있습니다" + } + } + } + }, + "settings_notifications" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifications" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "알림" + } + } + } + }, + "settings_privacy_policy" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Privacy Policy" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "개인정보 처리방침" + } + } + } + }, + "settings_sign_out" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign Out" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "로그아웃" + } + } + } + }, + "settings_theme" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Theme" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "테마" + } + } + } + }, + "settings_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Settings" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "설정" + } + } + } + }, + "settings_version" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "버전 정보" + } + } + } + }, + "sky" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sky" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "하늘" + } + } + } + }, + "sun" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sun" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "태양" + } + } + } + }, + "system_theme_automatic" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Automatic" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "자동" + } + } + } + }, + "system_theme_dark" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dark Mode" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "다크 모드" + } + } + } + }, + "system_theme_light" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Light Mode" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "라이트 모드" + } + } + } + }, + "theme_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Theme" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "테마" + } + } + } + }, + "today_complete_action" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Complete" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + } + } + }, + "today_due_overdue" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Overdue" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기한 지남" + } + } + } + }, + "today_due_visibility_all" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "All" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "전체" + } + } + } + }, + "today_due_visibility_label" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "View Range" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "보기 범위" + } + } + } + }, + "today_due_visibility_with_due" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "With Due Date Only" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기한 있는 Todo만" + } + } + } + }, + "today_due_visibility_without_due" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Without Due Date Only" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기한 없는 Todo만" + } + } + } + }, + "today_empty_all_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Incomplete work will appear here in priority order." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료되지 않은 일이 생기면 이곳에서 우선순위대로 볼 수 있습니다." + } + } + } + }, + "today_empty_all_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There are no remaining todos." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "남아 있는 Todo가 없습니다." + } + } + } + }, + "today_empty_due_soon_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Todos due soon will appear here first." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "곧 마감되는 Todo가 생기면 이곳에서 먼저 볼 수 있습니다." + } + } + } + }, + "today_empty_due_soon_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There is no schedule within 7 days." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "7일 내 일정이 없습니다." + } + } + } + }, + "today_empty_filtered_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Adjust the view range from the toolbar or return to the full view." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "툴바에서 보기 범위를 조정하거나 전체 보기로 돌아가세요." + } + } + } + }, + "today_empty_filtered_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There are no todos matching the selected view options." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "선택한 보기 옵션에 맞는 Todo가 없습니다." + } + } + } + }, + "today_empty_focused_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pinned todos will appear here right away." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "중요 표시한 Todo가 생기면 이곳에서 바로 볼 수 있습니다." + } + } + } + }, + "today_empty_focused_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There is nothing to focus on." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "집중할 일이 없습니다." + } + } + } + }, + "today_empty_overdue_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There are no overdue todos right now." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "지금은 기한이 지난 Todo가 없습니다." + } + } + } + }, + "today_empty_overdue_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There are no overdue todos." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "지난 마감 Todo가 없습니다." + } + } + } + }, + "today_pinned_only" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pinned Only" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "중요 표시만" + } + } + } + }, + "today_pinned_only_description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Only pinned todos are shown." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "중요 표시한 Todo만 표시됩니다." + } + } + } + }, + "today_section_due_soon_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due Within %1$lld Days" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld일 내 일정" + } + } + } + }, + "today_section_focused" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Focus" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "집중할 일" + } + } + } + }, + "today_section_later" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Later" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "나중 일정" + } + } + } + }, + "today_section_overdue" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Overdue" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "지난 마감" + } + } + } + }, + "today_section_unscheduled" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unscheduled" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "일정 미정" + } + } + } + }, + "today_summary_all" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Remaining" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "남은 일" + } + } + } + }, + "today_summary_due_soon" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Within 7 Days" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "7일 내" + } + } + } + }, + "today_summary_focused" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Focus" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "집중" + } + } + } + }, + "today_summary_overdue" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Overdue" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "지연" + } + } + } + }, + "today_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Today" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "오늘" + } + } + } + }, + "web_page_missing_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unable to find this web page" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "웹페이지를 찾을 수 없습니다" + } + } + } + }, + "TODO" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "TODO" + } + } + } + }, + "TODO 편집" : { + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit TODO" + } + } + } + }, + "todo_add" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "추가" + } + } + } + }, + "todo_category" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Category" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "카테고리" + } + } + } + }, + "todo_category_doc" : { + "comment" : "Todo category: Documentation", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Documentation" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "문서화" + } + } + } + }, + "todo_category_etc" : { + "comment" : "Todo category: Etc", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Other" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기타" + } + } + } + }, + "todo_category_feature" : { + "comment" : "Todo category: Feature", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Feature" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "신규 기능" + } + } + } + }, + "todo_category_improvement" : { + "comment" : "Todo category: Improvement", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Improvement" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "개선" + } + } + } + }, + "todo_category_issue" : { + "comment" : "Todo category: Issue", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Issue" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "이슈" + } + } + } + }, + "todo_category_research" : { + "comment" : "Todo category: Research", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Research" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "조사" + } + } + } + }, + "todo_category_review" : { + "comment" : "Todo category: Review", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Review" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "리뷰" + } + } + } + }, + "todo_category_test" : { + "comment" : "Todo category: Test", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Test" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "테스트" + } + } + } + }, + "todo_completed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completed" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + } + } + }, + "todo_completion_all" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completed + Incomplete" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료 + 미완료" + } + } + } + }, + "todo_completion_completed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completed" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + } + } + }, + "todo_completion_incomplete" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Incomplete" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "미완료" + } + } + } + }, + "todo_details" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Details" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "세부 정보" + } + } + } + }, + "todo_due_date" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due Date" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "마감일" + } + } + } + }, + "todo_edit" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "수정" + } + } + } + }, + "todo_editor_description_optional" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Description (Optional)" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "설명(선택)" + } + } + } + }, + "todo_editor_markdown_hint" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markdown supported, e.g. # Heading, - List, **Bold**, - refs #123" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markdown 지원 · 예: # 제목, - 목록, **굵게**, - refs #번호" + } + } + } + }, + "todo_editor_markdown_preview_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Write in Markdown on the Edit tab to preview formatted text here." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "편집 탭에서 Markdown으로 작성하면 여기에서 서식이 적용되어 보여요." + } + } + } + }, + "todo_editor_markdown_preview_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markdown Preview" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markdown 미리보기" + } + } + } + }, + "todo_editor_new_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "New %1$@" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "새 %1$@ 추가" + } + } + } + }, + "todo_editor_title_required" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Title (Required)" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "제목(필수)" + } + } + } + }, + "todo_info_completed_at" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completed At" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료일" + } + } + } + }, + "todo_info_created_at" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Created At" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "생성일" + } + } + } + }, + "todo_info_due_date" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due Date" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "마감일" + } + } + } + }, + "todo_info_no_due_date" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Due Date" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "마감일 없음" + } + } + } + }, + "todo_info_not_completed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Not Completed" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료하지 않음" + } + } + } + }, + "todo_list_clear_filters" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear All Filters" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "모든 필터 지우기" + } + } + } + }, + "todo_list_completion_status" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completion Status" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료 상태" + } + } + } + }, + "todo_list_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No content has been written." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "작성된 내용이 없습니다." + } + } + } + }, + "todo_list_filter_options" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Filter Options" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "필터 옵션" + } + } + } + }, + "todo_list_filters_applied_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld filters applied" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$lld개 필터가 적용됨" + } + } + } + }, + "todo_list_search_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No results found." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "검색 결과가 없습니다." + } + } + } + }, + "todo_list_search_instruction_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Search titles or content in %1$@." + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@의 제목이나 내용을 검색해 보세요." + } + } + } + }, + "todo_list_search_prompt_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Search %1$@" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ 검색" + } + } + } + }, + "todo_list_show_more" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show More" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "더보기" + } + } + } + }, + "todo_list_sort_by" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort By" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "정렬 기준" + } + } + } + }, + "todo_list_sort_format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort: %1$@ / %2$@" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "정렬: %1$@ / %2$@" + } + } + } + }, + "todo_list_sort_order" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort Order" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "정렬 순서" + } + } + } + }, + "todo_manage_add_category_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add Category" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "카테고리 추가" + } + } + } + }, + "todo_manage_delete_category_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deleting this category will move its TODOs to Other.\nAre you sure you want to delete it?" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "이 카테고리를 삭제하면 해당하던 TODO는 기타 카테고리로 처리됩니다.\n정말 삭제하시겠습니까?" + } + } + } + }, + "todo_manage_delete_category_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Category" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "카테고리 삭제" + } + } + } + }, + "todo_manage_edit_category_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit Category" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "카테고리 수정" + } + } + } + }, + "todo_manage_name_placeholder" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Name" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "이름" + } + } + } + }, + "todo_manage_save" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Save" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "저장" + } + } + } + }, + "todo_manage_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit TODO" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "TODO 편집" + } + } + } + }, + "todo_no_tags" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Tags" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "태그 없음" + } + } + } + }, + "todo_none" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "None" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "없음" + } + } + } + }, + "todo_options_section" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Options" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "옵션" + } + } + } + }, + "todo_pinned" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pinned" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "중요 표시" + } + } + } + }, + "todo_preview" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preview" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "미리보기" + } + } + } + }, + "todo_sort_created" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Created" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "생성" + } + } + } + }, + "todo_sort_due_date" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due Date" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "마감" + } + } + } + }, + "todo_sort_latest" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Newest First" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "최신순" + } + } + } + }, + "todo_sort_oldest" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Oldest First" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "예전순" + } + } + } + }, + "todo_sort_updated" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Updated" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "수정" + } + } + } + }, + "todo_tags" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tags" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "태그" + } + } + } + }, + "Todos" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Todos" + } + } + } + }, + "URL" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "URL" + } + } + } + }, + "Web Page" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Web Page" + } + } + } + }, + "Web Pages" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Web Pages" + } + } + } + }, + "개인정보 처리방침" : { + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Privacy Policy" + } + } + } + }, + "검색" : { + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Search" + } + } + } }, "검색 결과가 없습니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No results found." + } + } + } }, "검색어를 입력해 저장한 앱 컨텐츠를 찾아보세요." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter a search term to find your saved content." + } + } + } }, "계정 연동" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account" + } + } + } }, "기간" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Period" + } + } + } }, "더보기" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show More" + } + } + } }, "로그아웃" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign Out" + } + } + } }, "로그인하면 사용 약관 및 개인 정보 취급 방침에 동의하게 됩니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "By signing in, you agree to the Terms of Service and Privacy Policy." + } + } + } }, "마감일" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Due Date" + } + } + } }, "모든 필터 지우기" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear All Filters" + } + } + } }, "미리보기" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preview" + } + } + } }, "받은 알림이 없습니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No notifications received." + } + } + } }, "받은 푸시 알람" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifications" + } + } + } }, "버전 정보" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + } + } }, "베타 테스트 참여" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Join Beta Testing" + } + } + } }, "보기 범위" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Range" + } + } + } }, "분기 선택" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select Quarter" + } + } + } }, "분기별 활동" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quarterly Activity" + } + } + } }, "사용자 설정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "User Settings" + } + } + } }, "삭제" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete" + } + } + } }, "상태 설정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set Status" + } + } + } }, "생성일" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Created At" + } + } + } }, "설정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Settings" + } + } + } }, "설정에서의 푸시 알람 설정과 별개입니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Separate from your Settings app notification preference." + } + } + } }, "세부 정보" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Details" + } + } + } }, "소셜 계정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Social Accounts" + } + } + } }, "수정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit" + } + } + } }, "신규 기능을 빠르게 만나볼 수 있습니다" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Get early access to new features." + } + } + } }, "알람" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alerts" + } + } + } }, "알림" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifications" + } + } + } }, "없음" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "None" + } + } + } }, "연결" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Connect" + } + } + } }, "연결 해제" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disconnect" + } + } + } }, "연도" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Year" + } + } + } }, "오늘" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Today" + } + } + } }, "옵션" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Options" + } + } + } }, "완료" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Done" + } + } + } }, "완료 상태" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completion Status" + } + } + } }, "완료일" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completed At" + } + } + } }, "이 분기에는 선택한 활동이 없어요" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No selected activity this quarter." + } + } + } }, "이 카테고리를 삭제하면 해당하던 TODO는 기타 카테고리로 처리됩니다.\n정말 삭제하시겠습니까?" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deleting this category will move its TODOs to Other.\nAre you sure you want to delete it?" + } + } + } }, "읽지 않음" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unread" + } + } + } }, "임시 데이터 삭제" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear Temporary Data" + } + } + } }, "작성된 내용이 없습니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No content has been written." + } + } + } }, "저장한 Web Page가 표시됩니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saved web pages appear here." + } + } + } }, "전체 삭제" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear All" + } + } + } }, "정렬 기준" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort By" + } + } + } }, "정렬 순서" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort Order" + } + } + } }, "정렬: %@" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort: %1$@" + } + } + } }, "정렬: %@ / %@" : { + "extractionState" : "stale", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sort: %1$@ / %2$@" + } + }, "ko" : { "stringUnit" : { "state" : "new", @@ -419,95 +4293,313 @@ } }, "제목(필수)" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Title (Required)" + } + } + } }, "주간 추세" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Weekly Trend" + } + } + } }, "주차" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Week" + } + } + } }, "중요 표시" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pinned" + } + } + } }, "중요 표시만" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pinned Only" + } + } + } }, "중요 표시한 Todo만 표시됩니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Only pinned todos are shown." + } + } + } }, "최근 검색" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recent Searches" + } + } + } }, "최근 수정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recently Updated" + } + } + } }, "최근 수정한 Todo가 없습니다." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No recently updated todos." + } + } + } }, "추가" : { - - }, - "취소" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add" + } + } + } }, "카테고리" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Category" + } + } + } }, "카테고리 삭제" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Category" + } + } + } }, "컨텐츠" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Content" + } + } + } }, "탈퇴" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete" + } + } + } }, "태그" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tags" + } + } + } }, "태그 없음" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Tags" + } + } + } }, "테마" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Theme" + } + } + } }, "편집" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit" + } + } + } }, "편집 탭에서 Markdown으로 작성하면 여기에서 서식이 적용되어 보여요." : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Write in Markdown on the Edit tab to preview formatted text here." + } + } + } }, "푸시 알람 활성화" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enable Push Notifications" + } + } + } }, "프로필" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Profile" + } + } + } }, "필터 옵션" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Filter Options" + } + } + } }, "현재 계정" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Current Account" + } + } + } }, "홈" : { - - }, - "확인" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Home" + } + } + } }, "활동" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Activity" + } + } + } }, "활동 없음" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Activity" + } + } + } }, "활동 히트맵" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Activity Heatmap" + } + } + } }, "회원 탈퇴" : { - + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Account" + } + } + } } }, "version" : "1.0" -} \ No newline at end of file +} diff --git a/DevLog/UI/Common/Component/RelativeTimeText.swift b/DevLog/UI/Common/Component/RelativeTimeText.swift index 4f182462..7682c70f 100644 --- a/DevLog/UI/Common/Component/RelativeTimeText.swift +++ b/DevLog/UI/Common/Component/RelativeTimeText.swift @@ -14,7 +14,12 @@ struct RelativeTimeText: View { var body: some View { TimelineView(.periodic(from: .now, by: 1.0)) { context in - Text(relativeTimeText(from: date, now: context.date) + " 업데이트") + Text( + String.localizedStringWithFormat( + String(localized: "relative_time_updated_format"), + relativeTimeText(from: date, now: context.date) + ) + ) .font(bodyFont) .foregroundStyle(bodyColor) } @@ -24,16 +29,28 @@ struct RelativeTimeText: View { let seconds = Int(now.timeIntervalSince(date)) if seconds < 60 { - return "\(max(0, seconds))초 전" + return String.localizedStringWithFormat( + String(localized: "relative_time_seconds_ago_format"), + Int64(max(0, seconds)) + ) } else if seconds < 3600 { let minutes = seconds / 60 - return "\(minutes)분 전" + return String.localizedStringWithFormat( + String(localized: "relative_time_minutes_ago_format"), + Int64(minutes) + ) } else if seconds < 86400 { let hours = seconds / 3600 - return "\(hours)시간 전" + return String.localizedStringWithFormat( + String(localized: "relative_time_hours_ago_format"), + Int64(hours) + ) } else { let days = seconds / 86400 - return "\(days)일 전" + return String.localizedStringWithFormat( + String(localized: "relative_time_days_ago_format"), + Int64(days) + ) } } } diff --git a/DevLog/UI/Common/Component/ToolbarButton+.swift b/DevLog/UI/Common/Component/ToolbarButton+.swift index 00c89da9..64c0fe34 100644 --- a/DevLog/UI/Common/Component/ToolbarButton+.swift +++ b/DevLog/UI/Common/Component/ToolbarButton+.swift @@ -20,7 +20,7 @@ struct ToolbarLeadingButton: ToolbarContent { Button { action?() } label: { - Text("취소") + Text(String(localized: "common_cancel")) } } } @@ -52,7 +52,7 @@ struct ToolbarTrailingButton: ToolbarContent { Button { action?() } label: { - Text("확인") + Text(String(localized: "common_confirm")) .bold() } .disabled(isDisabled) diff --git a/DevLog/UI/Common/MainView.swift b/DevLog/UI/Common/MainView.swift index 089dab58..1acfeb9e 100644 --- a/DevLog/UI/Common/MainView.swift +++ b/DevLog/UI/Common/MainView.swift @@ -26,7 +26,7 @@ struct MainView: View { )) .tabItem { Image(systemName: "house.fill") - Text("홈") + Text(String(localized: "nav_home")) } TodayView(viewModel: TodayViewModel( fetchTodosUseCase: container.resolve(FetchTodosUseCase.self), @@ -37,7 +37,7 @@ struct MainView: View { )) .tabItem { Image(systemName: "sun.max.fill") - Text("오늘") + Text(String(localized: "nav_today")) } PushNotificationListView(viewModel: PushNotificationListViewModel( fetchUseCase: container.resolve(FetchPushNotificationsUseCase.self), @@ -49,7 +49,7 @@ struct MainView: View { )) .tabItem { Image(systemName: "bell.fill") - Text("알림") + Text(String(localized: "nav_notifications")) } .badge(viewModel.state.unreadPushCount) ProfileView(viewModel: ProfileViewModel( @@ -62,7 +62,7 @@ struct MainView: View { )) .tabItem { Image(systemName: "person.crop.circle.fill") - Text("프로필") + Text(String(localized: "nav_profile")) } } .onAppear { @@ -75,7 +75,7 @@ struct MainView: View { set: { viewModel.send(.setAlert($0)) } ) ) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } diff --git a/DevLog/UI/Common/TodoInfoSheetView.swift b/DevLog/UI/Common/TodoInfoSheetView.swift index 72f15eaa..32cdf7f0 100644 --- a/DevLog/UI/Common/TodoInfoSheetView.swift +++ b/DevLog/UI/Common/TodoInfoSheetView.swift @@ -19,7 +19,7 @@ struct TodoInfoSheetView: View { ScrollView { LazyVStack(spacing: 32) { VStack(alignment: .leading) { - Text("생성일") + Text(String(localized: "todo_info_created_at")) .font(.subheadline) .foregroundStyle(.white) HStack(spacing: 8) { @@ -37,7 +37,7 @@ struct TodoInfoSheetView: View { Divider() } VStack(alignment: .leading) { - Text("마감일") + Text(String(localized: "todo_info_due_date")) .font(.subheadline) .foregroundStyle(.secondary) HStack(spacing: 8) { @@ -46,7 +46,7 @@ struct TodoInfoSheetView: View { Text( dueDate? .formatted(date: .abbreviated, time: .omitted) - ?? "마감일 없음" + ?? String(localized: "todo_info_no_due_date") ) .foregroundStyle(dueDate == nil ? .secondary : .primary) Spacer() @@ -60,7 +60,7 @@ struct TodoInfoSheetView: View { Divider() } VStack(alignment: .leading) { - Text("완료일") + Text(String(localized: "todo_info_completed_at")) .font(.subheadline) .foregroundStyle(.secondary) HStack(spacing: 8) { @@ -69,7 +69,7 @@ struct TodoInfoSheetView: View { Text( completedAt? .formatted(date: .abbreviated, time: .omitted) - ?? "완료하지 않음" + ?? String(localized: "todo_info_not_completed") ) .foregroundStyle(.white) Spacer() @@ -83,7 +83,7 @@ struct TodoInfoSheetView: View { Divider() } VStack(alignment: .leading) { - Text("태그") + Text(String(localized: "todo_tags")) .font(.subheadline) .foregroundStyle(.secondary) Divider() diff --git a/DevLog/UI/Home/HomeView.swift b/DevLog/UI/Home/HomeView.swift index 968bbf37..c5da0939 100644 --- a/DevLog/UI/Home/HomeView.swift +++ b/DevLog/UI/Home/HomeView.swift @@ -21,7 +21,7 @@ struct HomeView: View { webPageSection } .listStyle(.insetGrouped) - .navigationTitle("홈") + .navigationTitle(String(localized: "home_title")) .navigationDestination(for: Path.self) { path in switch path { case .category(let item): @@ -148,14 +148,14 @@ struct HomeView: View { ) .textInputAutocapitalization(.never) .keyboardType(.URL) - Button("추가") { + Button(String(localized: "home_add")) { viewModel.send(.addWebPage) } - Button("취소", role: .cancel) { + Button(String(localized: "common_cancel"), role: .cancel) { viewModel.send(.setAlert(isPresented: false)) } case .invalidURL, .error, .none: - Button("확인", role: .cancel) { + Button(String(localized: "common_close"), role: .cancel) { viewModel.send(.setAlert(isPresented: false)) } } @@ -203,7 +203,7 @@ struct HomeView: View { } else if viewModel.state.recentTodos.isEmpty { HStack { Spacer() - Text("최근 수정한 Todo가 없습니다.") + Text(String(localized: "home_recent_empty")) .font(.callout) Spacer() } @@ -216,7 +216,7 @@ struct HomeView: View { } } header: { HStack { - Text("최근 수정") + Text(String(localized: "home_recent_title")) .foregroundStyle(Color.primary) .font(.title2.bold()) Spacer() @@ -233,7 +233,7 @@ struct HomeView: View { } else if viewModel.state.webPages.isEmpty { HStack { Spacer() - Text("저장한 Web Page가 표시됩니다.") + Text(String(localized: "home_web_empty")) .font(.callout) Spacer() } @@ -284,7 +284,7 @@ struct HomeView: View { Button(role: .destructive) { viewModel.send(.deleteWebPage(item)) } label: { - Label("삭제", systemImage: "trash") + Label(String(localized: "common_delete"), systemImage: "trash") } } } @@ -333,7 +333,7 @@ struct HomeView: View { .foregroundStyle(Color(.label)) } } - .navigationTitle("컨텐츠") + .navigationTitle(String(localized: "home_content_title")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .topBarLeading) { diff --git a/DevLog/UI/Home/TodoDetailView.swift b/DevLog/UI/Home/TodoDetailView.swift index 709eed2a..786b3d16 100644 --- a/DevLog/UI/Home/TodoDetailView.swift +++ b/DevLog/UI/Home/TodoDetailView.swift @@ -90,7 +90,7 @@ struct TodoDetailView: View { Button { viewModel.send(.setShowEditor(true)) } label: { - Text("수정") + Text(String(localized: "todo_edit")) } } } @@ -114,28 +114,28 @@ private struct TodoDetailInfoSheetView: View { var body: some View { NavigationStack { List { - Section("옵션") { + Section(String(localized: "todo_options_section")) { HStack { - Text("카테고리") + Text(String(localized: "todo_category")) Spacer() Text(TodoCategoryItem(from: todo.category).localizedName) .foregroundStyle(.secondary) } statusRow( - title: "완료", + title: String(localized: "todo_completed"), systemImage: todo.isCompleted ? "checkmark.circle.fill" : "circle", color: todo.isCompleted ? .green : .secondary ) statusRow( - title: "중요 표시", + title: String(localized: "todo_pinned"), systemImage: todo.isPinned ? "star.fill" : "star", color: todo.isPinned ? .orange : .secondary ) HStack { - Text("마감일") + Text(String(localized: "todo_due_date")) Spacer() @@ -143,15 +143,15 @@ private struct TodoDetailInfoSheetView: View { Tag(dueDateText(for: dueDate), isEditing: false) .padding(.vertical, -4) } else { - Text("없음") + Text(String(localized: "todo_none")) .foregroundStyle(.secondary) } } } - Section("태그") { + Section(String(localized: "todo_tags")) { if todo.tags.isEmpty { - Text("태그 없음") + Text(String(localized: "todo_no_tags")) .foregroundStyle(.secondary) .padding(.vertical, 4) } else { @@ -159,7 +159,7 @@ private struct TodoDetailInfoSheetView: View { } } } - .navigationTitle("세부 정보") + .navigationTitle(String(localized: "todo_details")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarLeadingButton { diff --git a/DevLog/UI/Home/TodoEditorView.swift b/DevLog/UI/Home/TodoEditorView.swift index 703341be..ee2f3bee 100644 --- a/DevLog/UI/Home/TodoEditorView.swift +++ b/DevLog/UI/Home/TodoEditorView.swift @@ -95,7 +95,7 @@ struct TodoEditorView: View { get: { viewModel.state.title }, set: { viewModel.send(.setTitle($0)) } ), - prompt: Text("제목(필수)").foregroundColor(Color.secondary), + prompt: Text(String(localized: "todo_editor_title_required")).foregroundColor(Color.secondary), ) .font(.title2) .frame(height: 30) @@ -110,7 +110,7 @@ struct TodoEditorView: View { viewModel.send(.setTabViewTag(.editor)) field = .content }) { - Text("편집") + Text(String(localized: "todo_edit")) .frame(maxWidth: .infinity) .foregroundStyle( viewModel.state.tabViewTag == .editor ? Color.primary : Color.secondary @@ -120,7 +120,7 @@ struct TodoEditorView: View { Button(action: { transitionToPreview() }) { - Text("미리보기") + Text(String(localized: "todo_preview")) .frame(maxWidth: .infinity) .foregroundStyle( viewModel.state.tabViewTag == .preview ? Color.primary : Color.gray @@ -142,7 +142,7 @@ struct TodoEditorView: View { get: { viewModel.state.content }, set: { viewModel.send(.setContent($0)) } ), - placeholder: "설명(선택)" + placeholder: String(localized: "todo_editor_description_optional") ) .focused($field, equals: .content) } @@ -163,16 +163,16 @@ struct TodoEditorView: View { } private var markdownHint: some View { - Text("Markdown 지원 · 예: # 제목, - 목록, **굵게**, - refs #번호") + Text(String(localized: "todo_editor_markdown_hint")) .font(.caption) .foregroundStyle(.secondary) } private var previewPlaceholder: some View { VStack(alignment: .leading, spacing: 6) { - Text("Markdown 미리보기") + Text(String(localized: "todo_editor_markdown_preview_title")) .font(.subheadline.weight(.semibold)) - Text("편집 탭에서 Markdown으로 작성하면 여기에서 서식이 적용되어 보여요.") + Text(String(localized: "todo_editor_markdown_preview_message")) .font(.footnote) .foregroundStyle(.secondary) } @@ -208,9 +208,9 @@ private struct TodoEditorInfoSheetView: View { var body: some View { NavigationStack { List { - Section("옵션") { + Section(String(localized: "todo_options_section")) { Picker( - "카테고리", + String(localized: "todo_category"), selection: Binding( get: { viewModel.state.category.id }, set: { categoryID in @@ -231,7 +231,7 @@ private struct TodoEditorInfoSheetView: View { } Toggle( - "완료", + String(localized: "todo_completed"), isOn: Binding( get: { viewModel.state.isCompleted }, set: { viewModel.send(.setCompleted($0)) } @@ -240,7 +240,7 @@ private struct TodoEditorInfoSheetView: View { .tint(.blue) Toggle( - "중요 표시", + String(localized: "todo_pinned"), isOn: Binding( get: { viewModel.state.isPinned }, set: { viewModel.send(.setPinned($0)) } @@ -251,10 +251,10 @@ private struct TodoEditorInfoSheetView: View { dueDateControl } - Section("태그") { + Section(String(localized: "todo_tags")) { HStack(spacing: 12) { TextField( - "추가", + String(localized: "todo_add"), text: Binding( get: { viewModel.state.tagText }, set: { viewModel.send(.setTagText($0)) } @@ -280,7 +280,7 @@ private struct TodoEditorInfoSheetView: View { } if viewModel.state.tags.isEmpty { - Text("태그 없음") + Text(String(localized: "todo_no_tags")) .foregroundStyle(.secondary) .padding(.vertical, 4) } else { @@ -292,7 +292,7 @@ private struct TodoEditorInfoSheetView: View { } } } - .navigationTitle("세부 정보") + .navigationTitle(String(localized: "todo_details")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarLeadingButton { @@ -308,7 +308,7 @@ private struct TodoEditorInfoSheetView: View { set: { viewModel.send(.setDueDate($0)) } )) { HStack { - Text("마감일") + Text(String(localized: "todo_due_date")) .foregroundStyle(.primary) Spacer() if let dueDate = viewModel.state.dueDate { @@ -317,7 +317,7 @@ private struct TodoEditorInfoSheetView: View { } .padding(.vertical, -4) } else { - Text("없음") + Text(String(localized: "todo_none")) .foregroundStyle(.secondary) } } diff --git a/DevLog/UI/Home/TodoListView.swift b/DevLog/UI/Home/TodoListView.swift index 7601b366..566eef3e 100644 --- a/DevLog/UI/Home/TodoListView.swift +++ b/DevLog/UI/Home/TodoListView.swift @@ -41,7 +41,12 @@ struct TodoListView: View { set: { viewModel.send(.setIsSearching($0)) } ), placement: .navigationBarDrawer(displayMode: .always), - prompt: "\(TodoCategoryItem(from: viewModel.state.category).localizedName) 검색" + prompt: Text( + String.localizedStringWithFormat( + String(localized: "todo_list_search_prompt_format"), + TodoCategoryItem(from: viewModel.state.category).localizedName + ) + ) ) } } @@ -62,7 +67,7 @@ struct TodoListView: View { get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert($0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } @@ -122,7 +127,7 @@ struct TodoListView: View { if viewModel.state.todos.isEmpty, !viewModel.state.isLoading { HStack { Spacer() - Text("작성된 내용이 없습니다.") + Text(String(localized: "todo_list_empty")) .foregroundStyle(Color.gray) Spacer() } @@ -222,7 +227,12 @@ struct TodoListView: View { set: { viewModel.send(.setIsSearching($0)) } ), placement: .navigationBarDrawer(displayMode: .always), - prompt: "\(TodoCategoryItem(from: viewModel.state.category).localizedName) 검색" + prompt: Text( + String.localizedStringWithFormat( + String(localized: "todo_list_search_prompt_format"), + TodoCategoryItem(from: viewModel.state.category).localizedName + ) + ) ) } @@ -235,14 +245,19 @@ struct TodoListView: View { : Array(searchResults.prefix(limit)) if viewModel.state.searchText.isEmpty { - Text("\(TodoCategoryItem(from: viewModel.state.category).localizedName)의 제목이나 내용을 검색해 보세요.") + Text( + String.localizedStringWithFormat( + String(localized: "todo_list_search_instruction_format"), + TodoCategoryItem(from: viewModel.state.category).localizedName + ) + ) .foregroundStyle(Color.gray) .frame(maxWidth: .infinity) } else if viewModel.state.isLoading { LoadingView() } else if searchResults.isEmpty { Spacer() - Text("검색 결과가 없습니다.") + Text(String(localized: "todo_list_search_empty")) .foregroundStyle(Color.gray) .frame(maxWidth: .infinity) Spacer() @@ -262,7 +277,7 @@ struct TodoListView: View { .padding(.horizontal, 16) if !viewModel.state.showAllSearchResults, limit < searchResults.count { - Button("더보기") { + Button(String(localized: "todo_list_show_more")) { viewModel.send(.setShowAllSearchResults(true)) } .font(.subheadline) @@ -280,11 +295,16 @@ struct TodoListView: View { HStack(spacing: 8) { if 0 < viewModel.appliedFilterCount { Menu { - Text("\(viewModel.appliedFilterCount)개 필터가 적용됨") + Text( + String.localizedStringWithFormat( + String(localized: "todo_list_filters_applied_format"), + Int64(viewModel.appliedFilterCount) + ) + ) Button(role: .destructive) { viewModel.send(.resetFilters) } label: { - Text("모든 필터 지우기") + Text(String(localized: "todo_list_clear_filters")) } } label: { HStack(spacing: 6) { @@ -322,7 +342,7 @@ struct TodoListView: View { Text(option.title).tag(option) } } label: { - Text("정렬 기준") + Text(String(localized: "todo_list_sort_by")) } Picker(selection: Binding( get: { viewModel.state.query.sortOrder }, @@ -332,12 +352,18 @@ struct TodoListView: View { Text(option.title).tag(option) } } label: { - Text("정렬 순서") + Text(String(localized: "todo_list_sort_order")) } } label: { let condition = viewModel.state.query.sortTarget == .createdAt && viewModel.state.query.sortOrder == .latest HStack { - Text("정렬: \(viewModel.state.query.sortTarget.title) / \(viewModel.state.query.sortOrder.title)") + Text( + String.localizedStringWithFormat( + String(localized: "todo_list_sort_format"), + viewModel.state.query.sortTarget.title, + viewModel.state.query.sortOrder.title + ) + ) Image(systemName: "chevron.down") } .foregroundStyle(condition ? Color(.label) : .white) @@ -351,7 +377,7 @@ struct TodoListView: View { get: { viewModel.state.query.isPinned == true }, set: { _ in viewModel.send(.togglePinnedOnly) } )) { - Text("중요 표시") + Text(String(localized: "todo_pinned")) } Picker(selection: Binding( @@ -362,12 +388,12 @@ struct TodoListView: View { Text(option.title).tag(option) } } label: { - Text("완료 상태") + Text(String(localized: "todo_list_completion_status")) } } label: { let condition = viewModel.state.query.isPinned == true || viewModel.state.query.completionFilter != .all HStack { - Text("필터 옵션") + Text(String(localized: "todo_list_filter_options")) Image(systemName: "chevron.down") } .foregroundStyle(condition ? .white : Color(.label)) diff --git a/DevLog/UI/Home/TodoManageView.swift b/DevLog/UI/Home/TodoManageView.swift index 99237bf3..0005e7a1 100644 --- a/DevLog/UI/Home/TodoManageView.swift +++ b/DevLog/UI/Home/TodoManageView.swift @@ -50,7 +50,7 @@ struct TodoManageView: View { .listRowInsets(EdgeInsets()) } .environment(\.editMode, .constant(.active)) - .navigationTitle("TODO 편집") + .navigationTitle(String(localized: "todo_manage_title")) .navigationBarTitleDisplayMode(.inline) .navigationBarBackButtonHidden() .sheet(isPresented: Binding( @@ -60,20 +60,20 @@ struct TodoManageView: View { categorySheet } .alert( - "카테고리 삭제", + String(localized: "todo_manage_delete_category_title"), isPresented: Binding( get: { viewModel.state.showAlert }, set: { viewModel.send(.setShowAlert($0)) } ) ) { - Button("취소", role: .cancel) { + Button(String(localized: "common_cancel"), role: .cancel) { viewModel.send(.setShowAlert(false)) } - Button("삭제", role: .destructive) { + Button(String(localized: "common_delete"), role: .destructive) { viewModel.send(.confirmDeleteUserCategory) } } message: { - Text("이 카테고리를 삭제하면 해당하던 TODO는 기타 카테고리로 처리됩니다.\n정말 삭제하시겠습니까?") + Text(String(localized: "todo_manage_delete_category_message")) .multilineTextAlignment(.leading) } .toolbar { @@ -89,7 +89,7 @@ struct TodoManageView: View { Button { onDismiss?(viewModel.state.preferences) } label: { - Text("완료") + Text(String(localized: "profile_done")) } } } @@ -147,7 +147,7 @@ struct TodoManageView: View { .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarLeading) { - Button("취소") { + Button(String(localized: "common_close")) { viewModel.send(.setShowSheet(false)) } } diff --git a/DevLog/UI/Login/LoginView.swift b/DevLog/UI/Login/LoginView.swift index 7943db7a..30fafdfd 100644 --- a/DevLog/UI/Login/LoginView.swift +++ b/DevLog/UI/Login/LoginView.swift @@ -22,23 +22,23 @@ struct LoginView: View { .frame(width: sceneWidth / 5) Spacer() VStack(spacing: 20) { - LoginButton(logo: Image("Google"), text: "구글 계정으로 로그인") { + LoginButton(logo: Image("Google"), text: String(localized: "login_google_sign_in")) { viewModel.send(.tapSignInButton(.google)) } .frame(width: sceneWidth * 3 / 4, height: sceneWidth / 10) - LoginButton(logo: Image("Github"), text: "깃헙 계정으로 로그인") { + LoginButton(logo: Image("Github"), text: String(localized: "login_github_sign_in")) { viewModel.send(.tapSignInButton(.github)) } .frame(width: sceneWidth * 3 / 4, height: sceneWidth / 10) - LoginButton(logo: Image("Apple"), text: "애플 계정으로 로그인") { + LoginButton(logo: Image("Apple"), text: String(localized: "login_apple_sign_in")) { viewModel.send(.tapSignInButton(.apple)) } .frame(width: sceneWidth * 3 / 4, height: sceneWidth / 10) } .padding(.bottom, 30) - Text("로그인하면 사용 약관 및 개인 정보 취급 방침에 동의하게 됩니다.") + Text(String(localized: "login_terms_notice")) .font(.caption2) .foregroundStyle(Color.gray) .multilineTextAlignment(.center) @@ -52,7 +52,7 @@ struct LoginView: View { get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert($0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } diff --git a/DevLog/UI/Profile/ProfileHeatmapView.swift b/DevLog/UI/Profile/ProfileHeatmapView.swift index 174d8021..9a264aa7 100644 --- a/DevLog/UI/Profile/ProfileHeatmapView.swift +++ b/DevLog/UI/Profile/ProfileHeatmapView.swift @@ -22,7 +22,7 @@ struct ProfileHeatmapView: View { ) VStack(alignment: .leading, spacing: 10) { - Text("활동 히트맵") + Text(String(localized: "profile_activity_heatmap")) .font(.subheadline) .bold() HStack(alignment: .top, spacing: 0) { @@ -47,9 +47,9 @@ struct ProfileHeatmapView: View { @ViewBuilder private func weekdayLabel(layout: ProfileHeatmapLayout) -> some View { let labels: [Int: String] = [ - 2: "월", - 4: "수", - 6: "금" + 2: String(localized: "profile_weekday_mon"), + 4: String(localized: "profile_weekday_wed"), + 6: String(localized: "profile_weekday_fri") ] let orderedWeekdays = Array(1...7) diff --git a/DevLog/UI/Profile/ProfileTrendChartView.swift b/DevLog/UI/Profile/ProfileTrendChartView.swift index 666339d2..5c5a0227 100644 --- a/DevLog/UI/Profile/ProfileTrendChartView.swift +++ b/DevLog/UI/Profile/ProfileTrendChartView.swift @@ -19,7 +19,7 @@ struct ProfileTrendChartView: View { var body: some View { VStack(alignment: .leading, spacing: 12) { HStack(alignment: .firstTextBaseline) { - Text("주간 추세") + Text(String(localized: "profile_weekly_trend")) .font(.subheadline) .bold() @@ -58,7 +58,12 @@ struct ProfileTrendChartView: View { .foregroundStyle(.quaternary) AxisValueLabel { if let weekIndex = value.as(Int.self) { - Text("\(weekIndex)주") + Text( + String.localizedStringWithFormat( + String(localized: "profile_week_format"), + Int64(weekIndex) + ) + ) .font(.caption2) .fixedSize() } @@ -86,7 +91,7 @@ struct ProfileTrendChartView: View { Image(systemName: "chart.line.uptrend.xyaxis") .font(.title3) .foregroundStyle(.secondary) - Text("이 분기에는 선택한 활동이 없어요") + Text(String(localized: "profile_quarter_empty")) .font(.caption) .foregroundStyle(.secondary) } @@ -161,15 +166,15 @@ struct ProfileTrendChartView: View { private var createdSeries: some ChartContent { ForEach(trendPoints) { point in LineMark( - x: .value("주차", point.weekIndex), + x: .value(String(localized: "profile_week_axis"), point.weekIndex), y: .value(ProfileActivityType.created.title, point.createdCount), - series: .value("활동", ProfileActivityType.created.title) + series: .value(String(localized: "profile_activity_axis"), ProfileActivityType.created.title) ) .foregroundStyle(createdColor) .lineStyle(StrokeStyle(lineWidth: 2.5)) PointMark( - x: .value("주차", point.weekIndex), + x: .value(String(localized: "profile_week_axis"), point.weekIndex), y: .value(ProfileActivityType.created.title, point.createdCount) ) .foregroundStyle(createdColor) @@ -180,15 +185,15 @@ struct ProfileTrendChartView: View { private var completedSeries: some ChartContent { ForEach(trendPoints) { point in LineMark( - x: .value("주차", point.weekIndex), + x: .value(String(localized: "profile_week_axis"), point.weekIndex), y: .value(ProfileActivityType.completed.title, point.completedCount), - series: .value("활동", ProfileActivityType.completed.title) + series: .value(String(localized: "profile_activity_axis"), ProfileActivityType.completed.title) ) .foregroundStyle(completedColor) .lineStyle(StrokeStyle(lineWidth: 2.5)) PointMark( - x: .value("주차", point.weekIndex), + x: .value(String(localized: "profile_week_axis"), point.weekIndex), y: .value(ProfileActivityType.completed.title, point.completedCount) ) .foregroundStyle(completedColor) diff --git a/DevLog/UI/Profile/ProfileView.swift b/DevLog/UI/Profile/ProfileView.swift index a7872ac6..6bca1d9b 100644 --- a/DevLog/UI/Profile/ProfileView.swift +++ b/DevLog/UI/Profile/ProfileView.swift @@ -45,7 +45,7 @@ struct ProfileView: View { get: { viewModel.state.statusMessage }, set: { viewModel.send(.updateStatusMessage($0)) }) ) { - Text("상태 설정") + Text(String(localized: "profile_status_placeholder")) } .frame(height: UIFont.preferredFont(forTextStyle: .body).lineHeight) .focused($focused) @@ -71,7 +71,7 @@ struct ProfileView: View { focused = false viewModel.send(.willUpdateStatusMessage) }) { - Text("완료") + Text(String(localized: "profile_done")) } .transition(.move(edge: .trailing).combined(with: .opacity)) } @@ -122,7 +122,7 @@ struct ProfileView: View { get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert($0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } @@ -138,7 +138,7 @@ struct ProfileView: View { private var activityHeatmapSection: some View { VStack(alignment: .leading, spacing: 16) { HStack { - Text("분기별 활동") + Text(String(localized: "profile_quarterly_activity")) .font(.headline) Spacer() quarterResetButton @@ -251,7 +251,7 @@ struct ProfileView: View { NavigationStack { VStack(alignment: .leading, spacing: 20) { HStack { - Text("연도") + Text(String(localized: "profile_year")) .font(.subheadline) .foregroundStyle(.secondary) Spacer() @@ -260,7 +260,13 @@ struct ProfileView: View { set: { viewModel.send(.setQuarterPickerYear($0)) } )) { ForEach(viewModel.availableQuarterYears, id: \.self) { year in - Text(year.formatted(.number.grouping(.never)) + "년").tag(year) + Text( + String.localizedStringWithFormat( + String(localized: "profile_year_option_format"), + Int64(year) + ) + ) + .tag(year) } } .pickerStyle(.menu) @@ -276,7 +282,7 @@ struct ProfileView: View { Spacer(minLength: 0) } .padding(20) - .navigationTitle("분기 선택") + .navigationTitle(String(localized: "profile_select_quarter")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarTrailingButton { @@ -322,7 +328,7 @@ struct ProfileView: View { .bold() if activities.isEmpty { - Text("활동 없음") + Text(String(localized: "profile_activity_none")) .font(.caption) .foregroundStyle(.secondary) .frame(maxWidth: .infinity, alignment: .center) diff --git a/DevLog/UI/PushNotification/PushNotificationListView.swift b/DevLog/UI/PushNotification/PushNotificationListView.swift index d83ed018..b2d89d72 100644 --- a/DevLog/UI/PushNotification/PushNotificationListView.swift +++ b/DevLog/UI/PushNotification/PushNotificationListView.swift @@ -36,14 +36,14 @@ struct PushNotificationListView: View { } } .refreshable { viewModel.send(.fetchNotifications) } - .navigationTitle("받은 푸시 알람") + .navigationTitle(String(localized: "push_notifications_title")) .alert( "", isPresented: Binding( get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert(isPresented: $0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } @@ -94,7 +94,7 @@ struct PushNotificationListView: View { if viewModel.state.notifications.isEmpty { HStack { Spacer() - Text("받은 알림이 없습니다.") + Text(String(localized: "push_notifications_empty")) .foregroundStyle(Color.gray) Spacer() } @@ -170,11 +170,16 @@ struct PushNotificationListView: View { HStack(spacing: 8) { if 0 < viewModel.appliedFilterCount { Menu { - Text("\(viewModel.appliedFilterCount)개 필터가 적용됨") + Text( + String.localizedStringWithFormat( + String(localized: "push_filters_applied_format"), + Int64(viewModel.appliedFilterCount) + ) + ) Button(role: .destructive) { viewModel.send(.resetFilters) } label: { - Text("모든 필터 지우기") + Text(String(localized: "push_clear_all_filters")) } } label: { HStack(spacing: 6) { @@ -189,7 +194,12 @@ struct PushNotificationListView: View { viewModel.send(.toggleSortOption) } label: { let condition = viewModel.state.query.sortOrder == .oldest - Text("정렬: \(viewModel.state.query.sortOrder.title)") + Text( + String.localizedStringWithFormat( + String(localized: "push_sort_format"), + viewModel.state.query.sortOrder.title + ) + ) .foregroundStyle(condition ? .white : Color(.label)) .adaptiveButtonStyle(color: condition ? .blue : .clear) } @@ -203,12 +213,12 @@ struct PushNotificationListView: View { Text(option.title).tag(option) } } label: { - Text("기간") + Text(String(localized: "push_period")) } } label: { let condition = viewModel.state.query.timeFilter == .none HStack { - Text("기간") + Text(String(localized: "push_period")) Image(systemName: "chevron.down") } .foregroundStyle(condition ? Color(.label) : .white) @@ -219,7 +229,7 @@ struct PushNotificationListView: View { viewModel.send(.toggleUnreadOnly) } label: { let condition = viewModel.state.query.unreadOnly - Text("읽지 않음") + Text(String(localized: "push_unread")) .foregroundStyle(condition ? .white : Color(.label)) .adaptiveButtonStyle(color: condition ? .blue : .clear) } @@ -306,16 +316,28 @@ struct PushNotificationListView: View { let seconds = Int(now.timeIntervalSince(date)) if seconds < 60 { - return "\(max(0, seconds))초 전" + return String.localizedStringWithFormat( + String(localized: "push_time_seconds_ago_format"), + Int64(max(0, seconds)) + ) } else if seconds < 3600 { let minutes = seconds / 60 - return "\(minutes)분 전" + return String.localizedStringWithFormat( + String(localized: "push_time_minutes_ago_format"), + Int64(minutes) + ) } else if seconds < 86400 { let hours = seconds / 3600 - return "\(hours)시간 전" + return String.localizedStringWithFormat( + String(localized: "push_time_hours_ago_format"), + Int64(hours) + ) } else { let days = seconds / 86400 - return "\(days)일 전" + return String.localizedStringWithFormat( + String(localized: "push_time_days_ago_format"), + Int64(days) + ) } } } diff --git a/DevLog/UI/Search/SearchView.swift b/DevLog/UI/Search/SearchView.swift index bb0ed3db..dec3802b 100644 --- a/DevLog/UI/Search/SearchView.swift +++ b/DevLog/UI/Search/SearchView.swift @@ -51,7 +51,7 @@ struct SearchView: View { get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert($0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } @@ -90,7 +90,7 @@ struct SearchView: View { set: { viewModel.send(.setSearching($0)) } ), placement: .navigationBarDrawer(displayMode: .always), - prompt: "검색" + prompt: Text(String(localized: "search_prompt")) ) .onSubmit(of: .search) { viewModel.send(.addRecentQuery(viewModel.state.searchQuery)) @@ -100,7 +100,7 @@ struct SearchView: View { private var searchInstruction: some View { VStack { Spacer() - Text("검색어를 입력해 저장한 앱 컨텐츠를 찾아보세요.") + Text(String(localized: "search_instruction")) .foregroundStyle(Color.gray) Spacer() } @@ -110,7 +110,7 @@ struct SearchView: View { private var emptySearchResult: some View { VStack { Spacer() - Text("검색 결과가 없습니다.") + Text(String(localized: "search_empty")) .foregroundStyle(Color.gray) Spacer() } @@ -147,7 +147,7 @@ struct SearchView: View { } .padding(.top, -12) if !viewModel.state.showAllTodos && limit < viewModel.state.todos.count { - Button("더보기") { + Button(String(localized: "search_show_more")) { viewModel.send(.setShowAllTodos(true)) } .font(.subheadline) @@ -177,7 +177,7 @@ struct SearchView: View { } .padding(.top, -12) if !viewModel.state.showAllWebPages && limit < viewModel.state.webPages.count { - Button("더보기") { + Button(String(localized: "search_show_more")) { viewModel.send(.setShowAllWebPages(true)) } .font(.subheadline) @@ -212,11 +212,11 @@ struct SearchView: View { private var recentQueries: some View { VStack(alignment: .leading, spacing: 12) { HStack { - Text("최근 검색") + Text(String(localized: "search_recent")) .font(.headline) .foregroundStyle(Color(.label)) Spacer() - Button("전체 삭제") { + Button(String(localized: "search_clear_all")) { viewModel.send(.clearRecentQueries) } .font(.subheadline) diff --git a/DevLog/UI/Setting/AccountView.swift b/DevLog/UI/Setting/AccountView.swift index fc826420..92e9dedc 100644 --- a/DevLog/UI/Setting/AccountView.swift +++ b/DevLog/UI/Setting/AccountView.swift @@ -13,14 +13,14 @@ struct AccountView: View { var body: some View { List { - Section("현재 계정") { + Section(String(localized: "account_current_section")) { HStack { if let provider = viewModel.state.currentProvider { providerContent(provider) } } } - Section("소셜 계정") { + Section(String(localized: "account_social_section")) { let providers = AuthProvider.allCases.filter { $0 != viewModel.state.currentProvider } ForEach(providers, id: \.self) { provider in let isConnected = viewModel.state.connectedProviders.contains(provider) @@ -34,7 +34,9 @@ struct AccountView: View { viewModel.send(.linkWithProvider(provider)) } } label: { - Text(isConnected ? "연결 해제" : "연결") + Text(isConnected + ? String(localized: "account_disconnect") + : String(localized: "account_connect")) .font(.caption.weight(.semibold)) .foregroundStyle(.white) .padding(.horizontal, 12) @@ -49,7 +51,7 @@ struct AccountView: View { } .scrollDisabled(true) .listStyle(.insetGrouped) - .navigationTitle("계정 연동") + .navigationTitle(String(localized: "account_title")) .onAppear { viewModel.send(.onAppear) } @@ -57,7 +59,7 @@ struct AccountView: View { get: { viewModel.state.showAlert }, set: { viewModel.send(.setAlert(isPresented: $0)) } )) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } diff --git a/DevLog/UI/Setting/PushNotificationSettingsView.swift b/DevLog/UI/Setting/PushNotificationSettingsView.swift index f3bfb62e..de33514d 100644 --- a/DevLog/UI/Setting/PushNotificationSettingsView.swift +++ b/DevLog/UI/Setting/PushNotificationSettingsView.swift @@ -18,11 +18,11 @@ struct PushNotificationSettingsView: View { get: { viewModel.state.pushNotificationEnable }, set: { viewModel.send(.setPushNotificationEnable($0)) } )) { - Text("푸시 알람 활성화") + Text(String(localized: "push_settings_enable")) } .tint(.blue) }, footer: { - Text("설정에서의 푸시 알람 설정과 별개입니다.") + Text(String(localized: "push_settings_footer")) }) Section { ForEach([9, 15, 18, 21], id: \.self) { hour in @@ -43,7 +43,7 @@ struct PushNotificationSettingsView: View { } } HStack { - Text("사용자 설정") + Text(String(localized: "push_settings_custom")) Spacer() Text(formattedTimeString(viewModel.state.viewPushNotificationTime)) .foregroundStyle(.secondary) @@ -61,7 +61,7 @@ struct PushNotificationSettingsView: View { .opacity(viewModel.state.pushNotificationEnable ? 1.0 : 0.2) } .listStyle(.insetGrouped) - .navigationTitle("알람") + .navigationTitle(String(localized: "push_settings_title")) .overlay { if viewModel.state.isLoading { LoadingView() @@ -109,15 +109,6 @@ struct PushNotificationSettingsView: View { } private func formattedTimeString(_ date: Date) -> String { - let minuteValue = Calendar.current.component(.minute, from: date) - let formatStyle: Date.FormatStyle = .dateTime.hour(.twoDigits(amPM: .wide)) - - if minuteValue == 0 { - return "\(date.formatted(formatStyle))" - } - - let hourText = date.formatted(formatStyle) - let minuteText = date.formatted(.dateTime.minute(.twoDigits)) - return "\(hourText) \(minuteText)분" + date.formatted(.dateTime.hour().minute()) } } diff --git a/DevLog/UI/Setting/SettingView.swift b/DevLog/UI/Setting/SettingView.swift index d9388ec9..9ad4cf9d 100644 --- a/DevLog/UI/Setting/SettingView.swift +++ b/DevLog/UI/Setting/SettingView.swift @@ -20,7 +20,7 @@ struct SettingView: View { router.push(Path.theme) } label: { HStack { - Text("테마") + Text(String(localized: "settings_theme")) .foregroundStyle(Color.primary) Spacer() Text(viewModel.state.theme.localizedName) @@ -31,7 +31,7 @@ struct SettingView: View { Button { router.push(Path.pushNotification) } label: { - Text("알림") + Text(String(localized: "settings_notifications")) .foregroundStyle(connected ? Color.primary : Color.secondary) } .disabled(!connected) @@ -41,7 +41,7 @@ struct SettingView: View { viewModel.send(.tapRemoveCacheButton) } label: { HStack { - Text("임시 데이터 삭제") + Text(String(localized: "settings_clear_temp_data")) .foregroundStyle(dirSize == 0 ? Color.secondary : .primary) Spacer() Text(formatFileSize(bytes: dirSize)) @@ -54,7 +54,7 @@ struct SettingView: View { Section { if let appVersion = viewModel.appVersion { HStack { - Text("버전 정보") + Text(String(localized: "settings_version")) Spacer() Text(appVersion) } @@ -62,7 +62,7 @@ struct SettingView: View { if let policyString = viewModel.policyURL, let url = URL(string: policyString) { Link(destination: url) { - Text("개인정보 처리방침") + Text(String(localized: "settings_privacy_policy")) .foregroundColor(Color.blue) } } @@ -73,8 +73,8 @@ struct SettingView: View { } }) { VStack(alignment: .leading) { - Text("베타 테스트 참여") - Text("신규 기능을 빠르게 만나볼 수 있습니다") + Text(String(localized: "settings_join_beta")) + Text(String(localized: "settings_join_beta_subtitle")) .foregroundStyle(Color.gray) .font(.caption) } @@ -85,13 +85,13 @@ struct SettingView: View { Button { router.push(Path.account) } label: { - Text("계정 연동") + Text(String(localized: "settings_account")) } .disabled(!connected) Button(role: .destructive, action: { viewModel.send(.setAlert(isPresented: true, type: .signOut)) }) { - Text("로그아웃") + Text(String(localized: "settings_sign_out")) } .disabled(!connected) } @@ -101,14 +101,14 @@ struct SettingView: View { Button(role: .destructive, action: { viewModel.send(.setAlert(isPresented: true, type: .deleteAuth)) }) { - Text("회원 탈퇴") + Text(String(localized: "settings_delete_account")) .font(.headline) } .disabled(!connected) Spacer() } } - .navigationTitle("설정") + .navigationTitle(String(localized: "settings_title")) .navigationBarTitleDisplayMode(.inline) .navigationDestination(for: Path.self) { path in switch path { @@ -164,28 +164,28 @@ struct SettingView: View { private var alertButtons: some View { switch viewModel.state.alertType { case .signOut: - Button("취소", role: .cancel) { + Button(String(localized: "common_cancel"), role: .cancel) { viewModel.send(.setAlert(isPresented: false)) } - Button("확인", role: .destructive) { + Button(String(localized: "common_confirm"), role: .destructive) { viewModel.send(.tapSignOutButton) } case .deleteAuth: - Button("취소", role: .cancel) { + Button(String(localized: "common_cancel"), role: .cancel) { viewModel.send(.setAlert(isPresented: false)) } - Button("탈퇴", role: .destructive) { + Button(String(localized: "settings_delete_account_action"), role: .destructive) { viewModel.send(.tapDeleteAuthButton) } case .removeCache: - Button("취소", role: .cancel) { + Button(String(localized: "common_cancel"), role: .cancel) { viewModel.send(.setAlert(isPresented: false)) } - Button("확인", role: .destructive) { + Button(String(localized: "common_confirm"), role: .destructive) { viewModel.send(.confirmRemoveCache) } case .error, .none: - Button("확인", role: .cancel) { + Button(String(localized: "common_close"), role: .cancel) { viewModel.send(.setAlert(isPresented: false)) } } diff --git a/DevLog/UI/Setting/ThemeView.swift b/DevLog/UI/Setting/ThemeView.swift index 2f7595b6..b7ac0e19 100644 --- a/DevLog/UI/Setting/ThemeView.swift +++ b/DevLog/UI/Setting/ThemeView.swift @@ -52,7 +52,7 @@ struct ThemeView: View { .listStyle(.insetGrouped) .toolbar { ToolbarItem(placement: .principal) { - Text("테마") + Text(String(localized: "theme_title")) .bold() } } diff --git a/DevLog/UI/Today/TodayView.swift b/DevLog/UI/Today/TodayView.swift index 1765db8b..f434f10d 100644 --- a/DevLog/UI/Today/TodayView.swift +++ b/DevLog/UI/Today/TodayView.swift @@ -25,7 +25,7 @@ struct TodayView: View { } } .listStyle(.insetGrouped) - .navigationTitle("오늘") + .navigationTitle(String(localized: "today_title")) .toolbar { toolbarContent } .navigationDestination(for: Path.self) { path in switch path { @@ -48,7 +48,7 @@ struct TodayView: View { set: { viewModel.send(.setAlert($0)) } ) ) { - Button("확인", role: .cancel) { } + Button(String(localized: "common_close"), role: .cancel) { } } message: { Text(viewModel.state.alertMessage) } @@ -64,17 +64,17 @@ struct TodayView: View { Section { ScrollView(.horizontal) { HStack(spacing: 12) { - ForEach(TodayViewModel.SummaryScope.allCases, id: \.self) { scope in + ForEach(TodayViewModel.SectionScope.allCases, id: \.self) { scope in Button { withAnimation(.easeInOut) { - viewModel.send(.setSummaryScope(scope)) + viewModel.send(.setSectionScope(scope)) } } label: { SummaryCard( title: scope.title, value: viewModel.summaryValue(for: scope), accentColor: scope.accentColor, - isSelected: viewModel.state.selectedSummaryScope == scope + isSelected: viewModel.state.selectedSectionScope == scope ) } .buttonStyle(.plain) @@ -92,7 +92,7 @@ struct TodayView: View { ToolbarItem(placement: .topBarTrailing) { Menu { Picker( - "보기 범위", + String(localized: "today_due_visibility_label"), selection: Binding( get: { viewModel.state.displayOptions.dueDateVisibility }, set: { viewModel.send(.setDueDateVisibility($0)) } @@ -104,7 +104,7 @@ struct TodayView: View { } Toggle( - "중요 표시만", + String(localized: "today_pinned_only"), isOn: Binding( get: { viewModel.state.displayOptions.focusVisibility == .focusedOnly }, set: { @@ -115,7 +115,7 @@ struct TodayView: View { .tint(.orange) if viewModel.state.displayOptions.focusVisibility == .focusedOnly { - Text("중요 표시한 Todo만 표시됩니다.") + Text(String(localized: "today_pinned_only_description")) .font(.caption) } } label: { @@ -161,7 +161,7 @@ struct TodayView: View { Button { viewModel.send(.completeTodo(item)) } label: { - Label("완료", systemImage: "checkmark") + Label(String(localized: "today_complete_action"), systemImage: "checkmark") } .tint(.green) } @@ -174,32 +174,32 @@ struct TodayView: View { } private var emptyStateContent: EmptyStateContent { - switch viewModel.state.selectedSummaryScope { + switch viewModel.state.selectedSectionScope { case .all: if viewModel.state.todos.isEmpty { return EmptyStateContent( - title: "남아 있는 Todo가 없습니다.", - message: "완료되지 않은 일이 생기면 이곳에서 우선순위대로 볼 수 있습니다." + title: String(localized: "today_empty_all_title"), + message: String(localized: "today_empty_all_message") ) } return EmptyStateContent( - title: "선택한 보기 옵션에 맞는 Todo가 없습니다.", - message: "툴바에서 보기 범위를 조정하거나 전체 보기로 돌아가세요." + title: String(localized: "today_empty_filtered_title"), + message: String(localized: "today_empty_filtered_message") ) case .focused: return EmptyStateContent( - title: "집중할 일이 없습니다.", - message: "중요 표시한 Todo가 생기면 이곳에서 바로 볼 수 있습니다." + title: String(localized: "today_empty_focused_title"), + message: String(localized: "today_empty_focused_message") ) case .overdue: return EmptyStateContent( - title: "지난 마감 Todo가 없습니다.", - message: "지금은 기한이 지난 Todo가 없습니다." + title: String(localized: "today_empty_overdue_title"), + message: String(localized: "today_empty_overdue_message") ) case .dueSoon: return EmptyStateContent( - title: "7일 내 일정이 없습니다.", - message: "곧 마감되는 Todo가 생기면 이곳에서 먼저 볼 수 있습니다." + title: String(localized: "today_empty_due_soon_title"), + message: String(localized: "today_empty_due_soon_message") ) } } @@ -218,26 +218,26 @@ private extension TodayDisplayOptions.DueDateVisibility { var title: String { switch self { case .all: - return "전체" + return String(localized: "today_due_visibility_all") case .withDueDateOnly: - return "기한 있는 Todo만" + return String(localized: "today_due_visibility_with_due") case .withoutDueDateOnly: - return "기한 없는 Todo만" + return String(localized: "today_due_visibility_without_due") } } } -private extension TodayViewModel.SummaryScope { +private extension TodayViewModel.SectionScope { var title: String { switch self { case .all: - return "남은 일" + return String(localized: "today_summary_all") case .focused: - return "집중" + return String(localized: "today_summary_focused") case .overdue: - return "지연" + return String(localized: "today_summary_overdue") case .dueSoon: - return "7일 내" + return String(localized: "today_summary_due_soon") } } @@ -339,7 +339,7 @@ private struct TodayTodoRow: View { if dueDay < today { return DueDateBadge( - text: "기한 지남", + text: String(localized: "today_due_overdue"), textColor: .red, backgroundColor: Color.red.opacity(0.12) ) diff --git a/Firebase/functions/package-lock.json b/Firebase/functions/package-lock.json index 5f839b66..6b3f2d2e 100644 --- a/Firebase/functions/package-lock.json +++ b/Firebase/functions/package-lock.json @@ -6,17 +6,17 @@ "": { "name": "functions", "dependencies": { - "@google-cloud/tasks": "^6.2.0", - "axios": "^1.9.0", - "dotenv": "^16.5.0", - "firebase-admin": "^12.6.0", + "@google-cloud/tasks": "^6.2.1", + "axios": "^1.13.6", + "dotenv": "^16.6.1", + "firebase-admin": "^12.7.0", "firebase-functions": "^7.2.2", - "jsonwebtoken": "^9.0.2" + "jsonwebtoken": "^9.0.3" }, "devDependencies": { - "@types/node": "^25.2.3", + "@types/node": "^25.5.0", "firebase-functions-test": "^3.1.0", - "typescript": "^4.9.0" + "typescript": "^4.9.5" }, "engines": { "node": "22" @@ -791,9 +791,9 @@ } }, "node_modules/@google-cloud/tasks": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@google-cloud/tasks/-/tasks-6.2.0.tgz", - "integrity": "sha512-LHnmkhaMWoVTU7mYMtlNy++Gva2273vATiHYbmxN4QJ8cHXcFHynYByZvCxUqW/ehANheQZ5d/JVS8Q21Gui8w==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@google-cloud/tasks/-/tasks-6.2.1.tgz", + "integrity": "sha512-Y21jNAdaUwZvYQijJSE9E27NA87c/Wl9fZxNDGx6WsWFFGEBmJmc1zg2fXLXTW0kPvKIxHQC+IcKa9SNgvIEsQ==", "license": "Apache-2.0", "dependencies": { "google-gax": "^5.0.0" @@ -1737,12 +1737,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", - "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/qs": { @@ -1973,13 +1973,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -2651,9 +2651,9 @@ } }, "node_modules/dotenv": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", - "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -3201,9 +3201,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -3221,14 +3221,15 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -4729,12 +4730,12 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", "license": "MIT", "dependencies": { - "jws": "^3.2.2", + "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -4750,27 +4751,6 @@ "npm": ">=6" } }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/jsonwebtoken/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4841,12 +4821,12 @@ "license": "MIT" }, "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "license": "MIT", "dependencies": { - "jwa": "^2.0.0", + "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, @@ -6438,9 +6418,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "license": "MIT" }, "node_modules/unpipe": { diff --git a/Firebase/functions/package.json b/Firebase/functions/package.json index f5fe7f8e..2de1887b 100644 --- a/Firebase/functions/package.json +++ b/Firebase/functions/package.json @@ -14,17 +14,17 @@ }, "main": "lib/index.js", "dependencies": { - "@google-cloud/tasks": "^6.2.0", - "axios": "^1.9.0", - "dotenv": "^16.5.0", - "firebase-admin": "^12.6.0", + "@google-cloud/tasks": "^6.2.1", + "axios": "^1.13.6", + "dotenv": "^16.6.1", + "firebase-admin": "^12.7.0", "firebase-functions": "^7.2.2", - "jsonwebtoken": "^9.0.2" + "jsonwebtoken": "^9.0.3" }, "devDependencies": { - "@types/node": "^25.2.3", + "@types/node": "^25.5.0", "firebase-functions-test": "^3.1.0", - "typescript": "^4.9.0" + "typescript": "^4.9.5" }, "private": true } diff --git a/Firebase/package-lock.json b/Firebase/package-lock.json deleted file mode 100644 index 931089a8..00000000 --- a/Firebase/package-lock.json +++ /dev/null @@ -1,3129 +0,0 @@ -{ - "name": "Firebase", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "firebase-functions": "^7.2.2" - } - }, - "node_modules/@fastify/busboy": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", - "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", - "license": "MIT", - "peer": true - }, - "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", - "license": "Apache-2.0", - "peer": true - }, - "node_modules/@firebase/app-types": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", - "license": "Apache-2.0", - "peer": true - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", - "license": "Apache-2.0", - "peer": true - }, - "node_modules/@firebase/component": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.2.tgz", - "integrity": "sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@firebase/util": "1.15.0", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@firebase/database": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.2.tgz", - "integrity": "sha512-lP96CMjMPy/+d1d9qaaHjHHdzdwvEOuyyLq9ehX89e2XMKwS1jHNzYBO+42bdSumuj5ukPbmnFtViZu8YOMT+w==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.7.2", - "@firebase/logger": "0.5.0", - "@firebase/util": "1.15.0", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.2.tgz", - "integrity": "sha512-j4A6IhVZbgxAzT6gJJC2PfOxYCK9SrDrUO7nTM4EscTYtKkAkzsbKoCnDdjFapQfnsncvPWjqVTr/0PffUwg3g==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@firebase/component": "0.7.2", - "@firebase/database": "1.1.2", - "@firebase/database-types": "1.0.18", - "@firebase/logger": "0.5.0", - "@firebase/util": "1.15.0", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.18.tgz", - "integrity": "sha512-yOY8IC2go9lfbVDMiy2ATun4EB2AFwocPaQADwMN/RHRUAZSM4rlAV7PGbWPSG/YhkJ2A9xQAiAENgSua9G5Fg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@firebase/app-types": "0.9.3", - "@firebase/util": "1.15.0" - } - }, - "node_modules/@firebase/logger": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", - "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@firebase/util": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.15.0.tgz", - "integrity": "sha512-AmWf3cHAOMbrCPG4xdPKQaj5iHnyYfyLKZxwz+Xf55bqKbpAmcYifB4jQinT2W9XhDRHISOoPyBOariJpCG6FA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@google-cloud/firestore": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.6.tgz", - "integrity": "sha512-EW/O8ktzwLfyWBOsNuhRoMi8lrC3clHM5LVFhGvO1HCsLozCOOXRAlHrYBoE6HL42Sc8yYMuCb2XqcnJ4OOEpw==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@opentelemetry/api": "^1.3.0", - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.3.3", - "protobufjs": "^7.2.6" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.19.0.tgz", - "integrity": "sha512-n2FjE7NAOYyshogdc7KQOl/VZb4sneqPjWouSyia9CMDdMhRX5+RIbqalNmC7LOLzuLAN89VlF2HvG8na9G+zQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@google-cloud/paginator": "^5.0.0", - "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "<4.1.0", - "abort-controller": "^3.0.0", - "async-retry": "^1.3.3", - "duplexify": "^4.1.3", - "fast-xml-parser": "^5.3.4", - "gaxios": "^6.0.2", - "google-auth-library": "^9.6.3", - "html-entities": "^2.5.2", - "mime": "^3.0.0", - "p-limit": "^3.0.1", - "retry-request": "^7.0.0", - "teeny-request": "^9.0.0", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage/node_modules/gcp-metadata": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "gaxios": "^6.1.1", - "google-logging-utils": "^0.0.2", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage/node_modules/google-auth-library": { - "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage/node_modules/google-logging-utils": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", - "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@grpc/proto-loader": "^0.8.0", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", - "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.5.3", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "license": "MIT", - "optional": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", - "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "^1" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.8", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", - "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "license": "MIT" - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/ms": "*", - "@types/node": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT", - "peer": true - }, - "node_modules/@types/node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@types/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/request": { - "version": "2.48.13", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz", - "integrity": "sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.5" - } - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - } - }, - "node_modules/@types/serve-static/node_modules/@types/send": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "retry": "0.13.1" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peer": true - }, - "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.14.0", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause", - "peer": true - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", - "license": "MIT" - }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", - "proxy-addr": "~2.0.7", - "qs": "~6.14.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", - "setprototypeof": "1.2.0", - "statuses": "~2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT", - "peer": true - }, - "node_modules/farmhash-modern": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", - "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT", - "peer": true - }, - "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "path-expression-matcher": "^1.1.3" - } - }, - "node_modules/fast-xml-parser": { - "version": "5.5.9", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.9.tgz", - "integrity": "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.0", - "strnum": "^2.2.2" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/firebase-admin": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.7.0.tgz", - "integrity": "sha512-o3qS8zCJbApe7aKzkO2Pa380t9cHISqeSd3blqYTtOuUUUua3qZTLwNWgGUOss3td6wbzrZhiHIj3c8+fC046Q==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@fastify/busboy": "^3.0.0", - "@firebase/database-compat": "^2.0.0", - "@firebase/database-types": "^1.0.6", - "farmhash-modern": "^1.1.0", - "fast-deep-equal": "^3.1.1", - "google-auth-library": "^10.6.1", - "jsonwebtoken": "^9.0.0", - "jwks-rsa": "^3.1.0", - "node-forge": "^1.3.1", - "uuid": "^11.0.2" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@google-cloud/firestore": "^7.11.0", - "@google-cloud/storage": "^7.19.0" - } - }, - "node_modules/firebase-functions": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-7.2.2.tgz", - "integrity": "sha512-fWFVI+4weuaat+Fp+4xYY1T+omiTvya8fW79+edgLWCOaDEBSBNlfhstnt+K1esblscZlJf8v+IA0LsCG8Uf1Q==", - "license": "MIT", - "dependencies": { - "@types/cors": "^2.8.5", - "@types/express": "^4.17.21", - "cors": "^2.8.5", - "express": "^4.21.0", - "protobufjs": "^7.2.2" - }, - "bin": { - "firebase-functions": "lib/bin/firebase-functions.js" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@apollo/server": "^5.2.0", - "@as-integrations/express4": "^1.1.2", - "firebase-admin": "^11.10.0 || ^12.0.0 || ^13.0.0", - "graphql": "^16.12.0" - }, - "peerDependenciesMeta": { - "@apollo/server": { - "optional": true - }, - "@as-integrations/express4": { - "optional": true - }, - "graphql": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", - "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.35", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "peer": true, - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/gaxios": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/gaxios/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/gcp-metadata": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", - "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "gaxios": "^7.0.0", - "google-logging-utils": "^1.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/gcp-metadata/node_modules/gaxios": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", - "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/gcp-metadata/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "peer": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "optional": true, - "peer": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/google-auth-library": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", - "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.1.4", - "gcp-metadata": "8.1.2", - "google-logging-utils": "1.1.3", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/google-auth-library/node_modules/gaxios": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", - "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/google-auth-library/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "peer": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/google-gax": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", - "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@grpc/grpc-js": "^1.10.9", - "@grpc/proto-loader": "^0.7.13", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.3.0", - "node-fetch": "^2.7.0", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.2", - "protobufjs": "^7.3.2", - "retry-request": "^7.0.0", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax/node_modules/gcp-metadata": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "gaxios": "^6.1.1", - "google-logging-utils": "^0.0.2", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax/node_modules/google-auth-library": { - "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax/node_modules/google-logging-utils": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/google-logging-utils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", - "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gtoken": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "gaxios": "^6.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "license": "MIT", - "peer": true - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-agent/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "peer": true, - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "peer": true - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", - "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", - "license": "MIT", - "peer": true, - "dependencies": { - "jws": "^4.0.1", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "peer": true - }, - "node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", - "license": "MIT", - "peer": true, - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jwks-rsa": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.2.tgz", - "integrity": "sha512-BqTyEDV+lS8F2trk3A+qJnxV5Q9EqKCBJOPti3W97r7qTympCZjb7h2X6f2kc+0K3rsSTY1/6YG2eaXKoj497w==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/jsonwebtoken": "^9.0.4", - "debug": "^4.3.4", - "jose": "^4.15.4", - "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/jwks-rsa/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/jwks-rsa/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "peer": true - }, - "node_modules/jws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", - "license": "MIT", - "peer": true, - "dependencies": { - "jwa": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==", - "peer": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "license": "MIT", - "peer": true - }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-memoizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", - "license": "MIT", - "peer": true, - "dependencies": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-forge": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", - "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "peer": true, - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-expression-matcher": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz", - "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", - "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", - "license": "MIT" - }, - "node_modules/proto3-json-serializer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "protobufjs": "^7.2.5" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/protobufjs": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/retry-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/request": "^2.48.8", - "extend": "^3.0.2", - "teeny-request": "^9.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.4.1", - "range-parser": "~1.2.1", - "statuses": "~2.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "~0.19.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strnum": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz", - "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/teeny-request": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.9", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/teeny-request/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/teeny-request/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/teeny-request/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", - "license": "MIT" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "peer": true, - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause", - "optional": true, - "peer": true - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC", - "optional": true, - "peer": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "optional": true, - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC", - "peer": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/Firebase/package.json b/Firebase/package.json deleted file mode 100644 index 7bea15f5..00000000 --- a/Firebase/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "firebase-functions": "^7.2.2" - } -}