diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..81570a5 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "Bash(git commit:*)" + ] + } +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8f466bd --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,109 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +POWERFUN Settings App - A React Native application for managing POWERFUN fitness devices (power meters, paddle sensors, T5 trainers) via Bluetooth LE. Supports device scanning, information reading, calibration, firmware updates (DFU), and spindown calibration. + +## Build Commands + +```sh +yarn start # Start Metro bundler +yarn android # Run on Android +yarn ios # Run on iOS +yarn build-a # Android release build (set NODE_OPTIONS=--openssl-legacy-provider) +yarn lint # Run ESLint +yarn test # Run Jest tests +yarn clean-a # Clean Android build (cd android && gradlew clean) +``` + +## Architecture + +### Navigation Structure +- React Navigation Native Stack Navigator +- Entry: SplashScreen → HomeScreen +- Three device paths from HomeScreen: Power Meter, Paddle, T5 Trainer +- Each path: ScanScreen → InfoScreen → DfuScreen +- T5 has additional: SpindownScreen +- Global: SettingScreen, PrivacyScreen + +### Screen to File Mapping +| Screen | File | Purpose | +|--------|------|---------| +| HomeScreen | src/HomeScreen.tsx | Device type selection (3 buttons) | +| ScanScreen | src/ScanScreen.tsx | Power meter BLE scanning | +| ScanScreen2 | src/ScanScreen2.tsx | Paddle BLE scanning | +| ScanScreen3 | src/ScanScreen3.tsx | T5 trainer BLE scanning | +| InfoScreen | src/InfoScreen.tsx | Power meter info, real-time data, calibration, power trim | +| InfoScreen2 | src/InfoScreen2.tsx | Paddle boat type settings | +| InfoScreen3 | src/InfoScreen3.tsx | T5 trainer weight, bike type, ERG smoothing | +| DfuScreen | src/DfuScreen.tsx | Nordic DFU firmware upgrade | +| SpindownScreen | src/SpindownScreen.tsx | T5 trainer spindown calibration | +| SettingScreen | src/SettingScreen.tsx | Language, privacy policy | +| PrivacyScreen | src/PrivacyScreen.tsx | Privacy policy content | + +### Bluetooth LE Architecture +- Library: `@systemic-games/react-native-bluetooth-le` +- Central API for scanning, connecting, reading/writing characteristics, subscribing to notifications +- Device name prefixes for filtering: + - Power meters: `PF-PM5-` or `POWERFUN-` + - Paddles: `PF-STK-` or `POWERFUN-` + - T5 trainers: `PF-T5-` or `POWERFUN-` +- RSSI filtering: devices below -90 dBm are filtered out + +### BLE Service/Characteristic UUIDs +| Service | Characteristic | Purpose | +|---------|----------------|---------| +| fff1 | fff2 (write) | Custom power meter commands | +| fff1 | fff3 (notify) | Custom power meter responses | +| 180a | 2a25 | Serial number | +| 180a | 2a28 | Firmware version | +| 180a | 2a27 | Hardware version | +| 180f | 2a19 | Battery level | +| 1818 | 2a63 | Cycling power measurement (real-time) | + +### DFU Architecture +- Library: `@systemic-games/react-native-nordic-nrf5-dfu` +- Firmware manifest: `https://powerfun.oss-cn-shanghai.aliyuncs.com/yecongdfu/latest.json` +- Firmware versions parsed as `hardware.iteration.build` (e.g., "1.23.456") +- Upgrade only allowed when server iteration > device iteration +- Downloads firmware zip to cache, then initiates DFU + +### i18n Architecture +- Library: i18next with react-i18next +- Languages: Chinese (zh) and English (en) +- Storage key: `@app_language` in AsyncStorage +- Translation files: `src/i18n/locales/zh.json`, `src/i18n/locales/en.json` + +## Key Implementation Notes + +### Bluetooth Connection Lifecycle +- InfoScreens connect to device on mount, disconnect on navigation away (except when going to DfuScreen) +- Connection status listener: `Central.addListener("peripheralConnectionStatus", handler)` +- Device ready state: `connectionStatus === "ready"` + +### Real-time Data Parsing (Power Meter - 2A63) +- Byte 2-3: Power value (little-endian) +- Byte 4: Left balance (0.5% units) +- Byte 5-6: Cadence revolution count (little-endian) +- Byte 7-8: Cadence timestamp (1/1024 second units) +- Cadence RPM = (revolution_diff / time_in_seconds) * 60 + +### Power Trim +- Range: 50-200 (represents 50%-200%) +- Stored as: value * 100, sent as 2-byte little-endian +- Protocol: Write [0x02, low, high] to FFF2, then write [0x04] to trigger update + +### Calibration +- Command: Write 0x05 to FFF2 +- Response: Read from FFF3 notify (0x05 + 2-byte value in 0.1 units) +- Timeout: 5 seconds + +### Firmware Version Comparison +```typescript +// Version format: "hardware.iteration.build" (e.g., "1.23.456") +// Only iteration is compared for upgrade decision +// hardware mismatch → cannot upgrade +// server iteration <= device iteration → no upgrade needed +``` diff --git a/android/app/build.gradle b/android/app/build.gradle index 11fda38..2b7bd43 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -83,7 +83,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "1.0.1" + versionName "1.0.2" } signingConfigs { debug { diff --git a/android/gradle.properties b/android/gradle.properties index 05ee00f..47d6d85 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -45,4 +45,4 @@ edgeToEdgeEnabled=false - +org.gradle.java.home=E:\\jdk\\jdk-17.0.12 \ No newline at end of file diff --git a/ios/dfuapp.xcodeproj/project.pbxproj b/ios/dfuapp.xcodeproj/project.pbxproj index f88094a..50cfe86 100644 --- a/ios/dfuapp.xcodeproj/project.pbxproj +++ b/ios/dfuapp.xcodeproj/project.pbxproj @@ -296,7 +296,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = PXHWD6972V; + DEVELOPMENT_TEAM = B7ZA544T59; ENABLE_BITCODE = NO; INFOPLIST_FILE = dfuapp/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "POWERFUN设置"; @@ -305,13 +305,13 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.2; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = com.zhixingpai.powerfundfuapp123; + PRODUCT_BUNDLE_IDENTIFIER = com.zhixingpai.powerfundfuapp; PRODUCT_NAME = dfuapp; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -326,7 +326,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = PXHWD6972V; + DEVELOPMENT_TEAM = B7ZA544T59; INFOPLIST_FILE = dfuapp/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "POWERFUN设置"; IPHONEOS_DEPLOYMENT_TARGET = 15.1; @@ -334,13 +334,13 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.2; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = com.zhixingpai.powerfundfuapp123; + PRODUCT_BUNDLE_IDENTIFIER = com.zhixingpai.powerfundfuapp; PRODUCT_NAME = dfuapp; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/package.json b/package.json index 149cc7c..8e77eb5 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "base-64": "^1.0.0", "i18next": "^25.7.3", "react": "19.1.0", - "react-i18next": "^16.5.0", + "react-i18next": "16.5.0", "react-native": "0.81.4", "react-native-device-info": "^15.0.1", "react-native-fs": "^2.20.0", @@ -53,10 +53,7 @@ "prettier": "2.8.8", "react-test-renderer": "19.1.0", "typescript": "^5.8.3" - }, - - "engines": { "node": ">=20" } diff --git a/src/HomeScreen.tsx b/src/HomeScreen.tsx index 92d9dc6..71e5f1d 100644 --- a/src/HomeScreen.tsx +++ b/src/HomeScreen.tsx @@ -1,48 +1,111 @@ -import React from "react"; -import { View, Text, TouchableOpacity, StyleSheet, StatusBar, Image } from "react-native"; -import { NativeStackScreenProps,NativeStackNavigationProp } from "@react-navigation/native-stack"; +import React, { useEffect, useState } from "react"; +import { View, Text, TouchableOpacity, StyleSheet, Image, Platform } from "react-native"; +import { NativeStackScreenProps } from "@react-navigation/native-stack"; import { RootStackParamList } from "../App"; import MyStatusbar from "./component/MyStatusbar"; import MyHeader from "./component/MyHeader"; +import UpdateModal from "./component/UpdateModal"; import pxToDp from "./helper/pxToDp"; import DeviceInfo from "react-native-device-info"; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from "react-i18next"; type Props = NativeStackScreenProps; +interface UpdateInfo { + latestVersion: string; + downloadUrl: string; + updateLogs: string[]; +} + +const UPDATE_JSON_URL = "https://powerfun.oss-cn-shanghai.aliyuncs.com/yecongdfu/apks/update.json"; + +const compareVersions = (latest: string, current: string): boolean => { + const latestParts = latest.split(".").map(Number); + const currentParts = current.split(".").map(Number); + + for (let i = 0; i < Math.max(latestParts.length, currentParts.length); i++) { + const latestNum = latestParts[i] || 0; + const currentNum = currentParts[i] || 0; + if (latestNum > currentNum) return true; + if (latestNum < currentNum) return false; + } + return false; +}; + export default function HomeScreen({ navigation }: Props) { const { t } = useTranslation(); + const [updateModalVisible, setUpdateModalVisible] = useState(false); + const [updateInfo, setUpdateInfo] = useState(null); + const [currentVersion, setCurrentVersion] = useState(""); + + useEffect(() => { + const checkUpdate = async () => { + try { + const version = DeviceInfo.getVersion(); + setCurrentVersion(version); + + const resp = await fetch(UPDATE_JSON_URL); + if (!resp.ok) return; + + const data = await resp.json(); + const platform = Platform.OS === "ios" ? "ios" : "android"; + const platformUpdate = data[platform]; + if (!platformUpdate) return; + + if (compareVersions(platformUpdate.latestVersion, version)) { + setUpdateInfo({ + latestVersion: platformUpdate.latestVersion, + downloadUrl: platformUpdate.downloadUrl, + updateLogs: platformUpdate.updateLogs || [], + }); + setUpdateModalVisible(true); + } + } catch (e) { + console.log("检查更新失败:", e); + } + }; + + checkUpdate(); + }, []); + return ( - {/* 设置状态栏颜色 */} - navigation.navigate("Setting")}> - - }> - {/* 中间按钮 */} + navigation.navigate("Setting")} + > + + + } + > + - - navigation.navigate("Scan")} - > + + navigation.navigate("Scan")}> {t("home.powerMeter")} - navigation.navigate("ScanScreen2")} - > + navigation.navigate("ScanScreen2")}> {t("home.paddle")} - navigation.navigate("ScanScreen3")} - > + {/* navigation.navigate("ScanScreen3")}> {t("home.T5trainer")} - + */} + + setUpdateModalVisible(false)} + /> ); } @@ -54,18 +117,17 @@ const styles = StyleSheet.create({ }, centerBox: { flex: 1, - // justifyContent: "center", alignItems: "center", - backgroundColor:'#fff', - paddingTop:pxToDp(250) + backgroundColor: "#fff", + paddingTop: pxToDp(250), }, button: { backgroundColor: "#E7141E", borderRadius: pxToDp(24), - width:pxToDp(300), - height:pxToDp(96), - alignItems:'center', - justifyContent:'center' + width: pxToDp(300), + height: pxToDp(96), + alignItems: "center", + justifyContent: "center", }, buttonText: { color: "#fff", @@ -78,7 +140,7 @@ const styles = StyleSheet.create({ }, privacyText: { fontSize: 16, - color: "#E7141E", // 红色字体 + color: "#E7141E", marginBottom: 8, }, version: { diff --git a/src/component/LanguageModal.tsx b/src/component/LanguageModal.tsx index 84b69d2..76534a9 100644 --- a/src/component/LanguageModal.tsx +++ b/src/component/LanguageModal.tsx @@ -33,6 +33,7 @@ const LanguageModal: React.FC = ({ visible, onClose }) => { transparent animationType="fade" onRequestClose={onClose} + statusBarTranslucent > void; +} + +export default function UpdateModal({ visible, updateInfo, currentVersion, onClose }: UpdateModalProps) { + const { t } = useTranslation(); + + const handleUpdatePress = () => { + if (updateInfo?.downloadUrl) { + Linking.openURL(updateInfo.downloadUrl); + } + }; + + if (!updateInfo) return null; + + return ( + + + + {t("home.updateTitle")} + + {t("home.latestVersion")}: {updateInfo.latestVersion} + + + {t("home.currentVersion")}: {currentVersion} + + + + {t("home.updateLogs")} + {updateInfo.updateLogs.map((log, index) => ( + • {log} + ))} + + + + {t("home.updateNow")} + + + {/* + {t("home.updateLater")} + */} + + + + ); +} + +const styles = StyleSheet.create({ + modalOverlay: { + flex: 1, + backgroundColor: "rgba(0, 0, 0, 0.5)", + justifyContent: "center", + alignItems: "center", + }, + modalContent: { + width: pxToDp(600), + backgroundColor: "#fff", + borderRadius: pxToDp(20), + padding: pxToDp(40), + alignItems: "center", + }, + modalTitle: { + fontSize: pxToDp(36), + fontWeight: "bold", + color: "#333", + marginBottom: pxToDp(20), + }, + modalVersion: { + fontSize: pxToDp(28), + color: "#666", + marginBottom: pxToDp(10), + }, + updateLogsContainer: { + width: "100%", + marginTop: pxToDp(20), + marginBottom: pxToDp(20), + paddingHorizontal: pxToDp(10), + maxHeight: pxToDp(300), + }, + updateLogsTitle: { + fontSize: pxToDp(28), + fontWeight: "bold", + color: "#333", + marginBottom: pxToDp(10), + }, + updateLogItem: { + fontSize: pxToDp(24), + color: "#666", + lineHeight: pxToDp(40), + }, + updateButton: { + width: "100%", + backgroundColor: "#E7141E", + borderRadius: pxToDp(12), + padding: pxToDp(24), + alignItems: "center", + // marginBottom: pxToDp(20), + }, + updateButtonText: { + fontSize: pxToDp(32), + fontWeight: "bold", + color: "#fff", + }, + laterButton: { + padding: pxToDp(20), + }, + laterButtonText: { + fontSize: pxToDp(28), + color: "#999", + }, +}); diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index e4ef065..af137b3 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1,258 +1,263 @@ { - "nav": { - "scan": "Scan", - "info": "Device Info", - "dfu": "Firmware Update", - "privacy": "Privacy Policy" - }, - "home": { - "title": "POWERFUN Settings", - "scan": "Scan Devices", - "privacy": "Privacy Policy", - "version": "Version v0.0.1", - "powerMeter": "Power Meter", - "paddle": "Paddle", - "T5trainer": "T5 Trainer" - }, - "scan": { - "title": "Scan Devices", - "scanning": "Scanning...", - "noDevice": "No Devices Found", - "tipScanning": "(Make sure the device is powered on and awake)", - "tipBluetooth": "(Please enable Bluetooth in settings)", - "noName": "[No Name]", - "rssiUnit": "dBm" + "nav": { + "scan": "Scan", + "info": "Device Info", + "dfu": "Firmware Update", + "privacy": "Privacy Policy" + }, + "home": { + "title": "POWERFUN Settings", + "scan": "Scan Devices", + "privacy": "Privacy Policy", + "version": "Version v0.0.1", + "powerMeter": "Power Meter", + "paddle": "Paddle", + "T5trainer": "T5 Trainer", + "updateTitle": "Update Available", + "latestVersion": "Latest Version", + "currentVersion": "Current Version", + "updateLogs": "Update Logs", + "updateNow": "Update Now", + "updateLater": "Later" + }, + "scan": { + "title": "Scan Devices", + "scanning": "Scanning...", + "noDevice": "No Devices Found", + "tipScanning": "(Make sure the device is powered on and awake)", + "tipBluetooth": "(Please enable Bluetooth in settings)", + "noName": "[No Name]", + "rssiUnit": "dBm" + }, + "t5Scan": { + "title": "Scan T5 Trainer", + "scanning": "Scanning...", + "noDevice": "No T5 trainers found", + "tipScanning": "(Make sure the trainer is powered on and awake)", + "tipBluetooth": "(Please enable Bluetooth in settings)" + }, + "paddleScan": { + "title": "Scan Paddle", + "scanning": "Scanning...", + "noDevice": "No paddle devices found", + "tipScanning": "(Make sure the paddle device is powered on and awake)", + "tipBluetooth": "(Please enable Bluetooth in settings)", + "noName": "[No Name]", + "rssiUnit": "dBm" + }, + "common": { + "notice": "Notice", + "unknown": "Unknown", + "unknownDevice": "Unknown Device", + "yes": "Yes", + "no": "No" + }, + "info2": { + "waitingAction": "Waiting", + "notMatched": "Not Matched", + "checkFailed": "Check Failed", + "unknownBoatType": "Unknown boat type", + "readAbnormal": "Unexpected response: {{hex}}", + "writingBoat": "Writing {{boatName}}...", + "writtenWaitRead": "Written {{boatName}}, reading back in 200ms...", + "requestingBoatRead": "Requesting boat type...", + "setSuccess": "Set success: {{boatName}}", + "notMatch": "Mismatch: expected {{expected}}, actual {{actual}}", + "readResult": "Read result: {{hex}}", + "actionFailed": "Action failed: {{message}}", + "failed": "Failed", + "waitFff3Timeout": "Timeout waiting for FFF3 response", + "currentBoat": "✅ Current boat type: {{boatName}}", + "readCurrentBoat": "Current boat type read: {{boatName}}", + "disconnectedNeedReconnect": "Device disconnected. Reconnect before upgrading.", + "defaultReadFailed": "Connected, but initial boat type read failed", + "connectOrReadFailed": "Connection or read failed", + "connectOrReadFailedAlert": "Bluetooth connection failed or device info read failed", + "cadence": "Cadence", + "cadenceUnit": "RPM (strokes/min)", + "boatSelect": "Boat Type", + "boatSwitching": "Switching boat type...", + "retry": "Please retry", + "boatKayak": "Kayak", + "boatRowing": "Rowing", + "boatRacing": "Racing", + "latestFirmware": "Latest Firmware", + "checking": "Checking..." + }, + "info3": { + "bikeTypeFollow": "Follow Software", + "bikeTypeRoad": "Road Bike", + "bikeTypeMtb26": "Mountain Bike 26\"", + "bikeTypeMtb275": "Mountain Bike 27.5\"", + "bikeTypeMtb29": "Mountain Bike 29\"", + "bikeTypeSmallWheel": "Small Wheel Bike", + "ergOn": "On", + "ergOff": "Off", + "readUsedHoursTimeout": "Timeout reading usage hours", + "readUsedMileageTimeout": "Timeout reading usage mileage", + "powerTrimRangeError": "Please enter a value between 50.00 and 200.00 with up to 2 decimals", + "deviceNotReady": "Device is not ready yet. Please try again later", + "invalidWeight": "Please enter a valid weight", + "waitFff3Timeout": "Timeout waiting for FFF3 response", + "readPowerTrimTimeout": "Timeout reading current power trim", + "waitWeightAckTimeout": "Timeout waiting for weight setting confirmation", + "readWeightTimeout": "Timeout reading current weight", + "readBikeTypeTimeout": "Timeout reading bike type", + "waitBikeTypeAckTimeout": "Timeout waiting for bike type confirmation", + "readErgTimeout": "Timeout reading ERG smoothing", + "waitErgAckTimeout": "Timeout waiting for ERG smoothing confirmation", + "connectReadFailed": "Device connection or read failed", + "readFailed": "Read failed", + "connecting": "Connecting", + "pendingTag": "Pending", + "settingTag": "Applying", + "currentWeightValue": "Current: {{value}} kg", + "currentPowerTrimValue": "Current: {{value}} %", + "currentTextValue": "Current: {{value}}", + "usedMileage": "Usage Mileage", + "speedKph": "Speed/km/h", + "weightSetting": "Weight Setting", + "powerTrim": "Power Trim", + "bikeType": "Bike Type", + "ergSmooth": "ERG Smoothing", + "settingWeight": "Setting weight...", + "weightSetDone": "Weight set successfully", + "weightSetFailed": "Weight setting failed", + "settingPowerTrim": "Setting power trim...", + "powerTrimSetDone": "Power trim set successfully", + "powerTrimSetFailed": "Power trim setting failed", + "settingBikeType": "Setting bike type...", + "bikeTypeSetDone": "Bike type set successfully", + "bikeTypeSetFailed": "Bike type setting failed", + "settingErgSmooth": "Setting ERG smoothing...", + "ergSmoothSetDone": "ERG smoothing set successfully", + "ergSmoothSetFailed": "ERG smoothing setting failed", + "confirmWeightChange": "Set weight to {{value}}kg?", + "confirmPowerTrimChange": "Set power trim to {{value}}%?", + "helpText": "Hold to view help" + }, + "spindown": { + "title": "Spindown", + "headerTitle": "Trainer Spindown", + "connecting": "Connecting", + "connected": "Connected", + "targetLabel": "Target Speed", + "targetHint": "Ride to reach the target speed first", + "currentSpeed": "Current Speed", + "statusReach36": "Ride to reach {{speed}} km/h", + "statusReached36": "Reached {{high}} km/h. Stop pedaling and wait until speed drops to {{low}} km/h", + "statusCalibrating": "Spindown in progress, please wait", + "statusCompleted": "Spindown completed", + "deviceNotReady": "Device not ready, please try again", + "connectFailed": "Failed to connect. Please go back and try again", + "timeout": "Timed out waiting for spindown time", + "failedRetry": "Spindown failed, please try again", + "step1Title": "Ride to {{speed}} km/h", + "step1Desc": "Automatically proceeds after reaching the target speed", + "step2Title": "Stop pedaling and coast", + "step2Desc": "Starts spindown automatically when speed drops to {{speed}} km/h", + "step3Title": "Spindown Completed", + "step3Loading": "Reading spindown time...", + "step3Pending": "Will appear here after completion", + "loading": "Connecting and preparing spindown...", + "result": "Spindown completed, time {{seconds}}s", + "retry": "Restart Spindown" + }, + "dfu": { + "title": "Firmware Update", + "preparing": "Preparing...", + "reading": "Reading...", - }, - "t5Scan": { - "title": "Scan T5 Trainer", - "scanning": "Scanning...", - "noDevice": "No T5 trainers found", - "tipScanning": "(Make sure the trainer is powered on and awake)", - "tipBluetooth": "(Please enable Bluetooth in settings)" - }, - "paddleScan": { - "title": "Scan Paddle", - "scanning": "Scanning...", - "noDevice": "No paddle devices found", - "tipScanning": "(Make sure the paddle device is powered on and awake)", - "tipBluetooth": "(Please enable Bluetooth in settings)", - "noName": "[No Name]", - "rssiUnit": "dBm" - }, - "common": { - "notice": "Notice", - "unknown": "Unknown", - "unknownDevice": "Unknown Device", - "yes": "Yes", - "no": "No" - }, - "info2": { - "waitingAction": "Waiting", - "notMatched": "Not Matched", - "checkFailed": "Check Failed", - "unknownBoatType": "Unknown boat type", - "readAbnormal": "Unexpected response: {{hex}}", - "writingBoat": "Writing {{boatName}}...", - "writtenWaitRead": "Written {{boatName}}, reading back in 200ms...", - "requestingBoatRead": "Requesting boat type...", - "setSuccess": "Set success: {{boatName}}", - "notMatch": "Mismatch: expected {{expected}}, actual {{actual}}", - "readResult": "Read result: {{hex}}", - "actionFailed": "Action failed: {{message}}", - "failed": "Failed", - "waitFff3Timeout": "Timeout waiting for FFF3 response", - "currentBoat": "✅ Current boat type: {{boatName}}", - "readCurrentBoat": "Current boat type read: {{boatName}}", - "disconnectedNeedReconnect": "Device disconnected. Reconnect before upgrading.", - "defaultReadFailed": "Connected, but initial boat type read failed", - "connectOrReadFailed": "Connection or read failed", - "connectOrReadFailedAlert": "Bluetooth connection failed or device info read failed", - "cadence": "Cadence", - "cadenceUnit": "RPM (strokes/min)", - "boatSelect": "Boat Type", - "boatSwitching": "Switching boat type...", - "retry": "Please retry", - "boatKayak": "Kayak", - "boatRowing": "Rowing", - "boatRacing": "Racing", - "latestFirmware": "Latest Firmware", - "checking": "Checking..." - }, - "info3": { - "bikeTypeFollow": "Follow Software", - "bikeTypeRoad": "Road Bike", - "bikeTypeMtb26": "Mountain Bike 26\"", - "bikeTypeMtb275": "Mountain Bike 27.5\"", - "bikeTypeMtb29": "Mountain Bike 29\"", - "bikeTypeSmallWheel": "Small Wheel Bike", - "ergOn": "On", - "ergOff": "Off", - "readUsedHoursTimeout": "Timeout reading usage hours", - "readUsedMileageTimeout": "Timeout reading usage mileage", - "powerTrimRangeError": "Please enter a value between 50.00 and 200.00 with up to 2 decimals", - "deviceNotReady": "Device is not ready yet. Please try again later", - "invalidWeight": "Please enter a valid weight", - "waitFff3Timeout": "Timeout waiting for FFF3 response", - "readPowerTrimTimeout": "Timeout reading current power trim", - "waitWeightAckTimeout": "Timeout waiting for weight setting confirmation", - "readWeightTimeout": "Timeout reading current weight", - "readBikeTypeTimeout": "Timeout reading bike type", - "waitBikeTypeAckTimeout": "Timeout waiting for bike type confirmation", - "readErgTimeout": "Timeout reading ERG smoothing", - "waitErgAckTimeout": "Timeout waiting for ERG smoothing confirmation", - "connectReadFailed": "Device connection or read failed", - "readFailed": "Read failed", - "connecting": "Connecting", - "pendingTag": "Pending", - "settingTag": "Applying", - "currentWeightValue": "Current: {{value}} kg", - "currentPowerTrimValue": "Current: {{value}} %", - "currentTextValue": "Current: {{value}}", - "usedMileage": "Usage Mileage", - "speedKph": "Speed/km/h", - "weightSetting": "Weight Setting", - "powerTrim": "Power Trim", - "bikeType": "Bike Type", - "ergSmooth": "ERG Smoothing", - "settingWeight": "Setting weight...", - "weightSetDone": "Weight set successfully", - "weightSetFailed": "Weight setting failed", - "settingPowerTrim": "Setting power trim...", - "powerTrimSetDone": "Power trim set successfully", - "powerTrimSetFailed": "Power trim setting failed", - "settingBikeType": "Setting bike type...", - "bikeTypeSetDone": "Bike type set successfully", - "bikeTypeSetFailed": "Bike type setting failed", - "settingErgSmooth": "Setting ERG smoothing...", - "ergSmoothSetDone": "ERG smoothing set successfully", - "ergSmoothSetFailed": "ERG smoothing setting failed", - "confirmWeightChange": "Set weight to {{value}}kg?", - "confirmPowerTrimChange": "Set power trim to {{value}}%?", - "helpText": "Hold to view help" - }, - "spindown": { - "title": "Spindown", - "headerTitle": "Trainer Spindown", - "connecting": "Connecting", - "connected": "Connected", - "targetLabel": "Target Speed", - "targetHint": "Ride to reach the target speed first", - "currentSpeed": "Current Speed", - "statusReach36": "Ride to reach {{speed}} km/h", - "statusReached36": "Reached {{high}} km/h. Stop pedaling and wait until speed drops to {{low}} km/h", - "statusCalibrating": "Spindown in progress, please wait", - "statusCompleted": "Spindown completed", - "deviceNotReady": "Device not ready, please try again", - "connectFailed": "Failed to connect. Please go back and try again", - "timeout": "Timed out waiting for spindown time", - "failedRetry": "Spindown failed, please try again", - "step1Title": "Ride to {{speed}} km/h", - "step1Desc": "Automatically proceeds after reaching the target speed", - "step2Title": "Stop pedaling and coast", - "step2Desc": "Starts spindown automatically when speed drops to {{speed}} km/h", - "step3Title": "Spindown Completed", - "step3Loading": "Reading spindown time...", - "step3Pending": "Will appear here after completion", - "loading": "Connecting and preparing spindown...", - "result": "Spindown completed, time {{seconds}}s", - "retry": "Restart Spindown" - }, - "dfu": { - "title": "Firmware Update", - "preparing": "Preparing...", - "reading": "Reading...", - - "bluetoothName": "Bluetooth Name", - "latestVersion": "Latest Version", - "currentVersion": "Current Version", - "upgradeStatus": "Update Status", - - "stateConnecting": "Connecting…", - "stateStarting": "Initializing…", - "stateEnablingDfuMode": "Enabling DFU Mode…", - "stateUploading": "Uploading Firmware…", - "stateValidating": "Validating Firmware…", - "stateDisconnecting": "Disconnecting…", - "stateCompleted": "Update Completed", - "stateAborted": "Aborted", - "stateFailed": "Update Failed", - "stateInitializing": "Starting…", - "stateErrored": "Update Error!", - - "pleaseWait": "Please Wait", - "doNotReturn": "Updating in progress, do not go back or close the app!", - - "cannotUpgrade": "Cannot Update", - "hardwareNotFound": "Firmware not found for hardware version {hardware}", - "noNeedUpgrade": "No Update Needed", - "alreadyLatest": "Already the latest firmware, no update needed", - - "upgradeSuccess": "Update Successful", - "upgradeSuccessMessage": "Update successful, please reconnect the device", - "upgradeFailed": "Update Failed", - "dfuFailed": "DFU Failed", - - "confirm": "OK" - }, - "privacy": { - "title": "Privacy Policy", - "content": "This application respects and protects the personal privacy of all users. This Privacy Policy applies only to the POWERFUN Settings App products or services provided by Wuxi Zhixingpai Sports Culture Development Co., Ltd. Please read and fully understand this policy before using our products or services.\n\n1. How We Collect and Use Your Information\n\n1. The POWERFUN Settings App does not require registration or login and does not collect any personal information.\n\n2. During your use of our products or services, we may use the following permissions:\n- Android ID\n- Storage\n- Location\n- Bluetooth\n\n3. Third-party SDK usage:\n\n(1) Tencent Bugly \nProvider: Tencent Computer Systems Company Limited \nPurpose: crash reporting and performance monitoring.\n\n(2) Aliyun OSS \nProvider: Alibaba Cloud Computing Co., Ltd. \nPurpose: storage of configuration and firmware update files.\n\n2. Updates to This Policy\n\nWe may update this policy from time to time. Changes will be published on this page.\n\n3. Contact Us\n\nEmail: bike99@qq.com\n\nWuxi Zhixingpai Sports Culture Development Co., Ltd. \nEffective date: July 1, 2019" - }, - "settings": { - "title": "Settings", - "language": "Language", - "privacy": "Privacy Policy", - "version": "Version" - }, - "languageModal": { - "title": "Language" - }, - "info": { - "title": "Device Info", - "bluetoothName": "Bluetooth Name", - "idNumber": "ID Number", - "firmwareVersion": "Firmware Version", - "battery": "Battery", - "connectionStatus": "Connection Status", - "connected": "Connected", - "disconnected": "Disconnected", - "reading": "Reading...", - - "power": "Power/W", - "cadence": "Cadence/RPM", - "balance": "L/R Balance/%", - "balanceHeader": "L / R", - - "powerTrimTitle": "Power Trim Settings", - "currentTrim": "Current Trim", - "trimPlaceholder": "Enter 50-200", - "updateValue": "Update Value", - - "calibrateButton": "Calibrate Zero", - "calibrating": "Calibrating... Waiting for device", - "firmwareUpgrade": "Firmware Update", - - "readingInfo": "Reading information...", - "readSuccess": "Read successfully!", - "writingTrim": "Writing power trim...", - "trimUpdateSuccess": "Power trim updated successfully!", - - "disconnectTitle": "Notice", - "disconnectMessage": "Device disconnected, please reconnect", - "reconnectMessage": "Please reconnect the device", - "confirm": "OK", - - "trimRangeAlert": "Power trim adjusts the power meter's high and low deviation. Default value is 100%. Adjustable range is 50%-200%. Please enter a number between 50 and 200 without the % symbol. Click the button below to update the power meter after entering.", - "deviceNotConnected": "Device not connected", - "writeFailed": "Write failed", - - "calibrationSuccess": "Calibration Successful", - "calibrationValue": "Calibration Value", - "calibrationError": "Calibration Error", - "calibrationTimeout": "Device not responding, please try again", - "calibrationFormatError": "Invalid response format from device", - "calibrationSendError": "Failed to send calibration command", - "error": "Error" - } + "bluetoothName": "Bluetooth Name", + "latestVersion": "Latest Version", + "currentVersion": "Current Version", + "upgradeStatus": "Update Status", + + "stateConnecting": "Connecting…", + "stateStarting": "Initializing…", + "stateEnablingDfuMode": "Enabling DFU Mode…", + "stateUploading": "Uploading Firmware…", + "stateValidating": "Validating Firmware…", + "stateDisconnecting": "Disconnecting…", + "stateCompleted": "Update Completed", + "stateAborted": "Aborted", + "stateFailed": "Update Failed", + "stateInitializing": "Starting…", + "stateErrored": "Update Error!", + + "pleaseWait": "Please Wait", + "doNotReturn": "Updating in progress, do not go back or close the app!", + + "cannotUpgrade": "Cannot Update", + "hardwareNotFound": "Firmware not found for hardware version {hardware}", + "noNeedUpgrade": "No Update Needed", + "alreadyLatest": "Already the latest firmware, no update needed", + + "upgradeSuccess": "Update Successful", + "upgradeSuccessMessage": "Update successful, please reconnect the device", + "upgradeFailed": "Update Failed", + "dfuFailed": "DFU Failed", + + "confirm": "OK" + }, + "privacy": { + "title": "Privacy Policy", + "content": "This application respects and protects the personal privacy of all users. This Privacy Policy applies only to the POWERFUN Settings App products or services provided by Wuxi Zhixingpai Sports Culture Development Co., Ltd. Please read and fully understand this policy before using our products or services.\n\n1. How We Collect and Use Your Information\n\n1. The POWERFUN Settings App does not require registration or login and does not collect any personal information.\n\n2. During your use of our products or services, we may use the following permissions:\n- Android ID\n- Storage\n- Location\n- Bluetooth\n\n3. Third-party SDK usage:\n\n(1) Tencent Bugly \nProvider: Tencent Computer Systems Company Limited \nPurpose: crash reporting and performance monitoring.\n\n(2) Aliyun OSS \nProvider: Alibaba Cloud Computing Co., Ltd. \nPurpose: storage of configuration and firmware update files.\n\n2. Updates to This Policy\n\nWe may update this policy from time to time. Changes will be published on this page.\n\n3. Contact Us\n\nEmail: bike99@qq.com\n\nWuxi Zhixingpai Sports Culture Development Co., Ltd. \nEffective date: July 1, 2019" + }, + "settings": { + "title": "Settings", + "language": "Language", + "privacy": "Privacy Policy", + "version": "Version" + }, + "languageModal": { + "title": "Language" + }, + "info": { + "title": "Device Info", + "bluetoothName": "Bluetooth Name", + "idNumber": "ID Number", + "firmwareVersion": "Firmware Version", + "battery": "Battery", + "connectionStatus": "Connection Status", + "connected": "Connected", + "disconnected": "Disconnected", + "reading": "Reading...", + + "power": "Power/W", + "cadence": "Cadence/RPM", + "balance": "L/R Balance/%", + "balanceHeader": "L / R", + + "powerTrimTitle": "Power Trim Settings", + "currentTrim": "Current Trim", + "trimPlaceholder": "Enter 50-200", + "updateValue": "Update Value", + + "calibrateButton": "Calibrate Zero", + "calibrating": "Calibrating... Waiting for device", + "firmwareUpgrade": "Firmware Update", + + "readingInfo": "Reading information...", + "readSuccess": "Read successfully!", + "writingTrim": "Writing power trim...", + "trimUpdateSuccess": "Power trim updated successfully!", + + "disconnectTitle": "Notice", + "disconnectMessage": "Device disconnected, please reconnect", + "reconnectMessage": "Please reconnect the device", + "confirm": "OK", + + "trimRangeAlert": "Power trim adjusts the power meter's high and low deviation. Default value is 100%. Adjustable range is 50%-200%. Please enter a number between 50 and 200 without the % symbol. Click the button below to update the power meter after entering.", + "deviceNotConnected": "Device not connected", + "writeFailed": "Write failed", + + "calibrationSuccess": "Calibration Successful", + "calibrationValue": "Calibration Value", + "calibrationError": "Calibration Error", + "calibrationTimeout": "Device not responding, please try again", + "calibrationFormatError": "Invalid response format from device", + "calibrationSendError": "Failed to send calibration command", + "error": "Error" } +} diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json index a52b4e1..df27188 100644 --- a/src/i18n/locales/zh.json +++ b/src/i18n/locales/zh.json @@ -1,257 +1,263 @@ { - "nav": { - "scan": "搜索", - "info": "设备信息", - "dfu": "固件升级", - "privacy": "隐私协议" - }, - "home": { - "title": "POWERFUN设置", - "scan": "搜索设备", - "privacy": "隐私协议", - "version": "版本号 v0.0.1", - "powerMeter": "功率计", - "paddle": "桨频器", - "T5trainer": "T5骑行台" - }, - "scan": { - "title": "搜索设备", - "scanning": "搜索中...", - "noDevice": "暂无设备", - "tipScanning": "(请确保设备有电且被唤醒)", - "tipBluetooth": "(请在设置中打开蓝牙)", - "noName": "[无名称]", - "rssiUnit": "dBm" - }, - "t5Scan": { - "title": "搜索T5骑行台", - "scanning": "搜索中...", - "noDevice": "暂无T5骑行台设备", - "tipScanning": "(请确保骑行台有电且被唤醒)", - "tipBluetooth": "(请在设置中打开蓝牙)" - }, - "paddleScan": { - "title": "搜索桨频器", - "scanning": "搜索中...", - "noDevice": "暂无桨频器设备", - "tipScanning": "(请确保桨频器设备有电且被唤醒)", - "tipBluetooth": "(请在设置中打开蓝牙)", - "noName": "[无名称]", - "rssiUnit": "dBm" - }, - "common": { - "notice": "提示", - "unknown": "未知", - "unknownDevice": "未知设备", - "yes": "是", - "no": "否" - }, - "info2": { - "waitingAction": "等待操作", - "notMatched": "未匹配", - "checkFailed": "检查失败", - "unknownBoatType": "读取到未知船型", - "readAbnormal": "读取返回异常:{{hex}}", - "writingBoat": "正在写入{{boatName}}...", - "writtenWaitRead": "已写入{{boatName}},200ms后读取确认...", - "requestingBoatRead": "正在请求读取船型...", - "setSuccess": "设置成功:{{boatName}}", - "notMatch": "不一致:期望 {{expected}},实际 {{actual}}", - "readResult": "读取返回:{{hex}}", - "actionFailed": "操作失败:{{message}}", - "failed": "失败", - "waitFff3Timeout": "等待 FFF3 返回超时", - "currentBoat": "✅ 当前船型:{{boatName}}", - "readCurrentBoat": "已读取当前船型:{{boatName}}", - "disconnectedNeedReconnect": "设备已断开,请重新连接", - "defaultReadFailed": "已连接,但默认读取船型失败", - "connectOrReadFailed": "连接或读取失败", - "connectOrReadFailedAlert": "蓝牙连接失败或设备信息读取失败", - "cadence": "桨频", - "cadenceUnit": "RPM(次/分钟)", - "boatSelect": "船型选择", - "boatSwitching": "船型切换中...", - "retry": "请重试", - "boatKayak": "皮艇", - "boatRowing": "划艇", - "boatRacing": "赛艇", - "latestFirmware": "最新固件", - "checking": "检查中..." - }, - "info3": { - "bikeTypeFollow": "跟随软件", - "bikeTypeRoad": "公路车", - "bikeTypeMtb26": "山地车26寸", - "bikeTypeMtb275": "山地车27.5寸", - "bikeTypeMtb29": "山地车29寸", - "bikeTypeSmallWheel": "小轮车", - "ergOn": "开启", - "ergOff": "关闭", - "readUsedMileageTimeout": "读取使用里程超时", - "powerTrimRangeError": "请输入50.00-200.00之间的数,最多保留两位小数", - "deviceNotReady": "设备尚未准备完成,请稍后再试", - "invalidWeight": "请输入正确的体重", - "waitFff3Timeout": "等待FFF3返回超时", - "readPowerTrimTimeout": "读取当前功率微调超时", - "waitWeightAckTimeout": "等待体重设定确认超时", - "readWeightTimeout": "读取当前体重超时", - "readBikeTypeTimeout": "读取当前车型超时", - "waitBikeTypeAckTimeout": "等待车型设定确认超时", - "readErgTimeout": "读取ERG功率平滑超时", - "waitErgAckTimeout": "等待ERG功率平滑确认超时", - "connectReadFailed": "设备连接或读取失败", - "readFailed": "读取失败", - "connecting": "连接中", - "pendingTag": "待保存", - "settingTag": "设置中", - "currentWeightValue": "当前:{{value}} kg", - "currentPowerTrimValue": "当前:{{value}} %", - "currentTextValue": "当前:{{value}}", - "usedMileage": "使用里程", - "speedKph": "速度/km/h", - "weightSetting": "体重设定", - "powerTrim": "功率微调", - "bikeType": "车型选择", - "ergSmooth": "ERG功率平滑", - "settingWeight": "正在设置体重…", - "weightSetDone": "体重设定完成", - "weightSetFailed": "体重设定失败", - "settingPowerTrim": "正在设置功率微调…", - "powerTrimSetDone": "功率微调设定完成", - "powerTrimSetFailed": "功率微调设定失败", - "settingBikeType": "车型设定中", - "bikeTypeSetDone": "车型设定完成", - "bikeTypeSetFailed": "车型设定失败", - "settingErgSmooth": "ERG功率平滑设定中", - "ergSmoothSetDone": "ERG功率平滑设定完成", - "ergSmoothSetFailed": "ERG功率平滑设定失败", - "confirmWeightChange": "是否将体重改为{{value}}kg", - "confirmPowerTrimChange": "是否将功率微调改为{{value}}%", - "helpText": "按住查看说明" - }, - "spindown": { - "title": "消旋", - "headerTitle": "骑行台消旋", - "connecting": "设备连接中", - "connected": "设备已连接", - "targetLabel": "目标速度", - "targetHint": "请先骑行加速到目标速度", - "currentSpeed": "当前速度", - "statusReach36": "请骑行加速到 {{speed}} km/h", - "statusReached36": "已达到 {{high}} km/h,请停止踩踏并等待速度下降到 {{low}} km/h", - "statusCalibrating": "正在消旋,请等待", - "statusCompleted": "消旋完成", - "deviceNotReady": "设备未准备好,请稍后重试", - "connectFailed": "设备连接失败,请返回重试", - "timeout": "等待消旋时间返回超时", - "failedRetry": "消旋失败,请重试", - "step1Title": "请骑行到 {{speed}} km/h", - "step1Desc": "达到目标速度后自动进入下一步", - "step2Title": "停止踩踏并等待减速", - "step2Desc": "速度下降到 {{speed}} km/h 后自动开始消旋", - "step3Title": "消旋完成", - "step3Loading": "正在读取消旋时间...", - "step3Pending": "完成前会显示在这里", - "loading": "正在连接设备并准备消旋...", - "result": "消旋完成,时间 {{seconds}}s", - "retry": "重新开始消旋" - }, + "nav": { + "scan": "搜索", + "info": "设备信息", + "dfu": "固件升级", + "privacy": "隐私协议" + }, + "home": { + "title": "POWERFUN设置", + "scan": "搜索设备", + "privacy": "隐私协议", + "version": "版本号 v0.0.1", + "powerMeter": "功率计", + "paddle": "桨频器", + "T5trainer": "T5骑行台", + "updateTitle": "发现新版本", + "latestVersion": "最新版本", + "currentVersion": "当前版本", + "updateLogs": "更新日志", + "updateNow": "立即更新", + "updateLater": "稍后再说" + }, + "scan": { + "title": "搜索设备", + "scanning": "搜索中...", + "noDevice": "暂无设备", + "tipScanning": "(请确保设备有电且被唤醒)", + "tipBluetooth": "(请在设置中打开蓝牙)", + "noName": "[无名称]", + "rssiUnit": "dBm" + }, + "t5Scan": { + "title": "搜索T5骑行台", + "scanning": "搜索中...", + "noDevice": "暂无T5骑行台设备", + "tipScanning": "(请确保骑行台有电且被唤醒)", + "tipBluetooth": "(请在设置中打开蓝牙)" + }, + "paddleScan": { + "title": "搜索桨频器", + "scanning": "搜索中...", + "noDevice": "暂无桨频器设备", + "tipScanning": "(请确保桨频器设备有电且被唤醒)", + "tipBluetooth": "(请在设置中打开蓝牙)", + "noName": "[无名称]", + "rssiUnit": "dBm" + }, + "common": { + "notice": "提示", + "unknown": "未知", + "unknownDevice": "未知设备", + "yes": "是", + "no": "否" + }, + "info2": { + "waitingAction": "等待操作", + "notMatched": "未匹配", + "checkFailed": "检查失败", + "unknownBoatType": "读取到未知船型", + "readAbnormal": "读取返回异常:{{hex}}", + "writingBoat": "正在写入{{boatName}}...", + "writtenWaitRead": "已写入{{boatName}},200ms后读取确认...", + "requestingBoatRead": "正在请求读取船型...", + "setSuccess": "设置成功:{{boatName}}", + "notMatch": "不一致:期望 {{expected}},实际 {{actual}}", + "readResult": "读取返回:{{hex}}", + "actionFailed": "操作失败:{{message}}", + "failed": "失败", + "waitFff3Timeout": "等待 FFF3 返回超时", + "currentBoat": "✅ 当前船型:{{boatName}}", + "readCurrentBoat": "已读取当前船型:{{boatName}}", + "disconnectedNeedReconnect": "设备已断开,请重新连接", + "defaultReadFailed": "已连接,但默认读取船型失败", + "connectOrReadFailed": "连接或读取失败", + "connectOrReadFailedAlert": "蓝牙连接失败或设备信息读取失败", + "cadence": "桨频", + "cadenceUnit": "RPM(次/分钟)", + "boatSelect": "船型选择", + "boatSwitching": "船型切换中...", + "retry": "请重试", + "boatKayak": "皮艇", + "boatRowing": "划艇", + "boatRacing": "赛艇", + "latestFirmware": "最新固件", + "checking": "检查中..." + }, + "info3": { + "bikeTypeFollow": "跟随软件", + "bikeTypeRoad": "公路车", + "bikeTypeMtb26": "山地车26寸", + "bikeTypeMtb275": "山地车27.5寸", + "bikeTypeMtb29": "山地车29寸", + "bikeTypeSmallWheel": "小轮车", + "ergOn": "开启", + "ergOff": "关闭", + "readUsedMileageTimeout": "读取使用里程超时", + "powerTrimRangeError": "请输入50.00-200.00之间的数,最多保留两位小数", + "deviceNotReady": "设备尚未准备完成,请稍后再试", + "invalidWeight": "请输入正确的体重", + "waitFff3Timeout": "等待FFF3返回超时", + "readPowerTrimTimeout": "读取当前功率微调超时", + "waitWeightAckTimeout": "等待体重设定确认超时", + "readWeightTimeout": "读取当前体重超时", + "readBikeTypeTimeout": "读取当前车型超时", + "waitBikeTypeAckTimeout": "等待车型设定确认超时", + "readErgTimeout": "读取ERG功率平滑超时", + "waitErgAckTimeout": "等待ERG功率平滑确认超时", + "connectReadFailed": "设备连接或读取失败", + "readFailed": "读取失败", + "connecting": "连接中", + "pendingTag": "待保存", + "settingTag": "设置中", + "currentWeightValue": "当前:{{value}} kg", + "currentPowerTrimValue": "当前:{{value}} %", + "currentTextValue": "当前:{{value}}", + "usedMileage": "使用里程", + "speedKph": "速度/km/h", + "weightSetting": "体重设定", + "powerTrim": "功率微调", + "bikeType": "车型选择", + "ergSmooth": "ERG功率平滑", + "settingWeight": "正在设置体重…", + "weightSetDone": "体重设定完成", + "weightSetFailed": "体重设定失败", + "settingPowerTrim": "正在设置功率微调…", + "powerTrimSetDone": "功率微调设定完成", + "powerTrimSetFailed": "功率微调设定失败", + "settingBikeType": "车型设定中", + "bikeTypeSetDone": "车型设定完成", + "bikeTypeSetFailed": "车型设定失败", + "settingErgSmooth": "ERG功率平滑设定中", + "ergSmoothSetDone": "ERG功率平滑设定完成", + "ergSmoothSetFailed": "ERG功率平滑设定失败", + "confirmWeightChange": "是否将体重改为{{value}}kg", + "confirmPowerTrimChange": "是否将功率微调改为{{value}}%", + "helpText": "按住查看说明" + }, + "spindown": { + "title": "消旋", + "headerTitle": "骑行台消旋", + "connecting": "设备连接中", + "connected": "设备已连接", + "targetLabel": "目标速度", + "targetHint": "请先骑行加速到目标速度", + "currentSpeed": "当前速度", + "statusReach36": "请骑行加速到 {{speed}} km/h", + "statusReached36": "已达到 {{high}} km/h,请停止踩踏并等待速度下降到 {{low}} km/h", + "statusCalibrating": "正在消旋,请等待", + "statusCompleted": "消旋完成", + "deviceNotReady": "设备未准备好,请稍后重试", + "connectFailed": "设备连接失败,请返回重试", + "timeout": "等待消旋时间返回超时", + "failedRetry": "消旋失败,请重试", + "step1Title": "请骑行到 {{speed}} km/h", + "step1Desc": "达到目标速度后自动进入下一步", + "step2Title": "停止踩踏并等待减速", + "step2Desc": "速度下降到 {{speed}} km/h 后自动开始消旋", + "step3Title": "消旋完成", + "step3Loading": "正在读取消旋时间...", + "step3Pending": "完成前会显示在这里", + "loading": "正在连接设备并准备消旋...", + "result": "消旋完成,时间 {{seconds}}s", + "retry": "重新开始消旋" + }, - "dfu": { - "title": "固件升级", - "preparing": "准备中...", - "reading": "读取中...", - - "bluetoothName": "蓝牙名称", - "latestVersion": "最新版本", - "currentVersion": "当前版本", - "upgradeStatus": "升级状态", - - "stateConnecting": "连接中…", - "stateStarting": "初始化中…", - "stateEnablingDfuMode": "启用 DFU 模式…", - "stateUploading": "上传固件中…", - "stateValidating": "校验固件…", - "stateDisconnecting": "断开连接…", - "stateCompleted": "升级完成", - "stateAborted": "已取消", - "stateFailed": "升级失败", - "stateInitializing": "启动中…", - "stateErrored": "升级出错!", - - "pleaseWait": "请稍候", - "doNotReturn": "正在升级,请勿返回或关闭应用!", - - "cannotUpgrade": "无法升级", - "hardwareNotFound": "未找到硬件版本 {hardware} 的固件", - "noNeedUpgrade": "无需升级", - "alreadyLatest": "已是最新固件,无需升级", - - "upgradeSuccess": "升级成功", - "upgradeSuccessMessage": "升级成功,请重连设备", - "upgradeFailed": "升级失败", - "dfuFailed": "DFU失败", - - "confirm": "确认" - }, - "privacy": { - "title": "隐私协议", - "content": "本应用尊重并保护所有使用服务用户的个人隐私权。本隐私政策仅适用于无锡执行派体育文化发展有限公司的 POWERFUN 设置 APP 产品或服务。请在使用我们的产品或服务前,仔细阅读并了解本隐私政策。\n\n一、我们如何收集和使用您的信息\n\n1. POWERFUN 设置 APP 不需要注册和登录,也不会收集任何关于个人的信息。\n\n2. 在您使用我司产品或服务过程中,我们可能会使用以下权限和信息:\n- Android ID:用于第三方或我们分析错误信息。\n- 存储权限:用于管理本地缓存。\n- 位置权限:用于设备产品与 APP 蓝牙连接。\n- 蓝牙权限:用于设备产品与 APP 蓝牙连接。\n\n3. 关于第三方 SDK 使用说明:\n\n(1)第三方 SDK 名称:腾讯 Bugly \n提供方:深圳市腾讯计算机系统有限公司 \n收集类型:系统版本、设备 ID、手机型号、网络状态、系统设置、网络与 WiFi 信息、手机状态、系统日志等。 \n使用目的:用于监控应用性能与稳定性,收集崩溃报告和使用数据以帮助我们识别并修复问题。\n\n(2)第三方 SDK 名称:Aliyun OSS \n提供方:阿里云计算有限公司 \n使用目的:用于存储应用运行必要的配置和固件升级文件,确保数据可靠存储。\n\n二、本政策如何更新\n\n我们的隐私政策可能会根据需求进行变更。未经您明确同意,我们不会削减您依据隐私政策应享有的权利。任何变更我们将在本页面公布。对于重大变更,我们会提供更为显著的通知。\n\n重大变更包括但不限于:\n- 服务模式发生重大变化(如用户信息处理目的、类型、方式等)。\n- 在所有权或组织架构方面发生变更(如业务调整、破产并购等)。\n- 用户信息安全影响评估报告显示存在高风险。\n\n三、如何联系我们\n\n如果您对本隐私政策有任何疑问、意见或建议,可通过以下方式与我们联系:\n电子邮件:bike99@qq.com\n\n一般情况下,我们将在三十天内回复。\n\n无锡执行派体育文化发展有限公司 \n本政策自 2019 年 7 月 1 日起生效" - }, - "settings": { - "title": "设置", - "language": "软件语言", - "privacy": "隐私协议", - "version": "版本号" - }, - "languageModal": { - "title": "软件语言" - }, - "info": { - "title": "设备信息", - "bluetoothName": "蓝牙名称", - "idNumber": "ID号", - "firmwareVersion": "固件版本", - "battery": "电量", - "connectionStatus": "连接状态", - "connected": "已连接", - "disconnected": "未连接", - "reading": "读取中...", - - "power": "功率/W", - "cadence": "踏频/RPM", - "balance": "左右平衡/%", - "balanceHeader": "L / R", - - "powerTrimTitle": "功率微调设置", - "currentTrim": "当前微调", - "trimPlaceholder": "输入50-200", - "updateValue": "更新数值", - - "calibrateButton": "校准归零", - "calibrating": "校准中...等待设备反应", - "firmwareUpgrade": "固件升级", - - "readingInfo": "正在读取信息...", - "readSuccess": "读取成功!", - "writingTrim": "正在写入功率微调...", - "trimUpdateSuccess": "功率微调更新成功!", - - "disconnectTitle": "提示", - "disconnectMessage": "设备已断开,请重新连接设备", - "reconnectMessage": "请重新连接设备", - "confirm": "确定", - - "trimRangeAlert": "功率微调可调整功率计的高低偏差,默认值100%。可调整的范围是50%-200%。请输入50至200的纯数字,不需要包含%符号。输入后点击下方按钮更新进功率计设备。", - "deviceNotConnected": "设备未连接", - "writeFailed": "写入失败", - - "calibrationSuccess": "校准成功", - "calibrationValue": "校准值", - "calibrationError": "校准错误", - "calibrationTimeout": "设备未响应,请重试", - "calibrationFormatError": "设备返回数据格式错误", - "calibrationSendError": "发送校准命令失败", - "error": "错误" - } + "dfu": { + "title": "固件升级", + "preparing": "准备中...", + "reading": "读取中...", + + "bluetoothName": "蓝牙名称", + "latestVersion": "最新版本", + "currentVersion": "当前版本", + "upgradeStatus": "升级状态", + + "stateConnecting": "连接中…", + "stateStarting": "初始化中…", + "stateEnablingDfuMode": "启用 DFU 模式…", + "stateUploading": "上传固件中…", + "stateValidating": "校验固件…", + "stateDisconnecting": "断开连接…", + "stateCompleted": "升级完成", + "stateAborted": "已取消", + "stateFailed": "升级失败", + "stateInitializing": "启动中…", + "stateErrored": "升级出错!", + + "pleaseWait": "请稍候", + "doNotReturn": "正在升级,请勿返回或关闭应用!", + + "cannotUpgrade": "无法升级", + "hardwareNotFound": "未找到硬件版本 {hardware} 的固件", + "noNeedUpgrade": "无需升级", + "alreadyLatest": "已是最新固件,无需升级", + + "upgradeSuccess": "升级成功", + "upgradeSuccessMessage": "升级成功,请重连设备", + "upgradeFailed": "升级失败", + "dfuFailed": "DFU失败", + + "confirm": "确认" + }, + "privacy": { + "title": "隐私协议", + "content": "本应用尊重并保护所有使用服务用户的个人隐私权。本隐私政策仅适用于无锡执行派体育文化发展有限公司的 POWERFUN 设置 APP 产品或服务。请在使用我们的产品或服务前,仔细阅读并了解本隐私政策。\n\n一、我们如何收集和使用您的信息\n\n1. POWERFUN 设置 APP 不需要注册和登录,也不会收集任何关于个人的信息。\n\n2. 在您使用我司产品或服务过程中,我们可能会使用以下权限和信息:\n- Android ID:用于第三方或我们分析错误信息。\n- 存储权限:用于管理本地缓存。\n- 位置权限:用于设备产品与 APP 蓝牙连接。\n- 蓝牙权限:用于设备产品与 APP 蓝牙连接。\n\n3. 关于第三方 SDK 使用说明:\n\n(1)第三方 SDK 名称:腾讯 Bugly \n提供方:深圳市腾讯计算机系统有限公司 \n收集类型:系统版本、设备 ID、手机型号、网络状态、系统设置、网络与 WiFi 信息、手机状态、系统日志等。 \n使用目的:用于监控应用性能与稳定性,收集崩溃报告和使用数据以帮助我们识别并修复问题。\n\n(2)第三方 SDK 名称:Aliyun OSS \n提供方:阿里云计算有限公司 \n使用目的:用于存储应用运行必要的配置和固件升级文件,确保数据可靠存储。\n\n二、本政策如何更新\n\n我们的隐私政策可能会根据需求进行变更。未经您明确同意,我们不会削减您依据隐私政策应享有的权利。任何变更我们将在本页面公布。对于重大变更,我们会提供更为显著的通知。\n\n重大变更包括但不限于:\n- 服务模式发生重大变化(如用户信息处理目的、类型、方式等)。\n- 在所有权或组织架构方面发生变更(如业务调整、破产并购等)。\n- 用户信息安全影响评估报告显示存在高风险。\n\n三、如何联系我们\n\n如果您对本隐私政策有任何疑问、意见或建议,可通过以下方式与我们联系:\n电子邮件:bike99@qq.com\n\n一般情况下,我们将在三十天内回复。\n\n无锡执行派体育文化发展有限公司 \n本政策自 2019 年 7 月 1 日起生效" + }, + "settings": { + "title": "设置", + "language": "软件语言", + "privacy": "隐私协议", + "version": "版本号" + }, + "languageModal": { + "title": "软件语言" + }, + "info": { + "title": "设备信息", + "bluetoothName": "蓝牙名称", + "idNumber": "ID号", + "firmwareVersion": "固件版本", + "battery": "电量", + "connectionStatus": "连接状态", + "connected": "已连接", + "disconnected": "未连接", + "reading": "读取中...", + + "power": "功率/W", + "cadence": "踏频/RPM", + "balance": "左右平衡/%", + "balanceHeader": "L / R", + + "powerTrimTitle": "功率微调设置", + "currentTrim": "当前微调", + "trimPlaceholder": "输入50-200", + "updateValue": "更新数值", + + "calibrateButton": "校准归零", + "calibrating": "校准中...等待设备反应", + "firmwareUpgrade": "固件升级", + + "readingInfo": "正在读取信息...", + "readSuccess": "读取成功!", + "writingTrim": "正在写入功率微调...", + "trimUpdateSuccess": "功率微调更新成功!", + + "disconnectTitle": "提示", + "disconnectMessage": "设备已断开,请重新连接设备", + "reconnectMessage": "请重新连接设备", + "confirm": "确定", + + "trimRangeAlert": "功率微调可调整功率计的高低偏差,默认值100%。可调整的范围是50%-200%。请输入50至200的纯数字,不需要包含%符号。输入后点击下方按钮更新进功率计设备。", + "deviceNotConnected": "设备未连接", + "writeFailed": "写入失败", + + "calibrationSuccess": "校准成功", + "calibrationValue": "校准值", + "calibrationError": "校准错误", + "calibrationTimeout": "设备未响应,请重试", + "calibrationFormatError": "设备返回数据格式错误", + "calibrationSendError": "发送校准命令失败", + "error": "错误" } +} diff --git a/yarn.lock b/yarn.lock index a2b7673..5819b0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,7 +16,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz" integrity sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw== -"@babel/core@^7.0.0", "@babel/core@^7.0.0 || ^8.0.0-0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.23.9", "@babel/core@^7.25.2", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.8.0": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2": version "7.28.4" resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz" integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== @@ -37,7 +37,7 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@^7.12.0", "@babel/eslint-parser@^7.25.1": +"@babel/eslint-parser@^7.25.1": version "7.28.4" resolved "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.4.tgz" integrity sha512-Aa+yDiH87980jR6zvRfFuCR1+dLb00vBydhTL+zI992Rz/wQhSvuxjmOOuJOgO3XmakO6RykRGD2S1mq1AtgHA== @@ -971,6 +971,11 @@ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz" integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== +"@babel/runtime@^7.27.6": + version "7.29.7" + resolved "https://repo.huaweicloud.com/repository/npm/@babel/runtime/-/runtime-7.29.7.tgz#12022450c45a4da6d8d8287b18a4ff2ddb23f768" + integrity sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw== + "@babel/template@^7.25.0", "@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3": version "7.27.2" resolved "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz" @@ -1370,7 +1375,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1511,7 +1516,7 @@ dependencies: joi "^17.2.1" -"@react-native-community/cli@*", "@react-native-community/cli@15.0.0": +"@react-native-community/cli@15.0.0": version "15.0.0" resolved "https://registry.npmmirror.com/@react-native-community/cli/-/cli-15.0.0.tgz" integrity sha512-IzDIFCoWZsoOHLSKcd8OX9gAXnbH83vsyBIFaj/X6praDUA4VCnDf41mGGSOT/VEarGlarTa3tvRcqZ8aE5l/A== @@ -1688,7 +1693,7 @@ hermes-parser "0.29.1" nullthrows "^1.1.1" -"@react-native/metro-config@*", "@react-native/metro-config@0.81.4": +"@react-native/metro-config@0.81.4": version "0.81.4" resolved "https://registry.npmjs.org/@react-native/metro-config/-/metro-config-0.81.4.tgz" integrity sha512-aEXhRMsz6yN5X63Zk+cdKByQ0j3dsKv+ETRP9lLARdZ82fBOCMuK6IfmZMwK3A/3bI7gSvt2MFPn3QHy3WnByw== @@ -1957,7 +1962,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.0.0 || ^6.0.0 || ^7.0.0", "@typescript-eslint/eslint-plugin@^7.1.1": +"@typescript-eslint/eslint-plugin@^7.1.1": version "7.18.0" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz" integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== @@ -1972,7 +1977,7 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^7.0.0", "@typescript-eslint/parser@^7.1.1": +"@typescript-eslint/parser@^7.1.1": version "7.18.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz" integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== @@ -2046,6 +2051,16 @@ semver "^7.6.0" ts-api-utils "^1.3.0" +"@typescript-eslint/utils@7.18.0": + version "7.18.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz" + integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/utils@^5.10.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz" @@ -2060,16 +2075,6 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/utils@7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz" - integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz" @@ -2111,7 +2116,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.15.0, acorn@^8.9.0: +acorn@^8.15.0, acorn@^8.9.0: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -2473,7 +2478,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0, browserslist@^4.25.3, "browserslist@>= 4.21.0": +browserslist@^4.24.0, browserslist@^4.25.3: version "4.26.2" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz" integrity sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A== @@ -2673,16 +2678,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-string@^1.9.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -2840,27 +2845,20 @@ dayjs@^1.8.15: resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz" integrity sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ== -debug@^2.6.9: +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1, debug@4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1: version "4.4.3" resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: ms "^2.1.3" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - decamelize@^1.2.0: version "1.2.0" resolved "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz" @@ -3242,7 +3240,7 @@ eslint-plugin-react@^7.30.1: string.prototype.matchall "^4.0.12" string.prototype.repeat "^1.0.0" -eslint-scope@^5.1.1, eslint-scope@5.1.1: +eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -3263,22 +3261,12 @@ eslint-visitor-keys@^2.1.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.3.0: +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint-visitor-keys@^3.4.1: - version "3.4.3" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", "eslint@^7.5.0 || ^8.0.0 || ^9.0.0", eslint@^8.1.0, eslint@^8.19.0, eslint@^8.56.0, eslint@>=4.19.1, eslint@>=7.0.0, eslint@>=8: +eslint@^8.19.0: version "8.57.1" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz" integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== @@ -3495,15 +3483,7 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^4.1.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3815,7 +3795,7 @@ human-signals@^2.1.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -i18next@^25.7.3, "i18next@>= 25.6.2": +i18next@^25.7.3: version "25.8.14" resolved "https://registry.npmmirror.com/i18next/-/i18next-25.8.14.tgz" integrity sha512-paMUYkfWJMsWPeE/Hejcw+XLhHrQPehem+4wMo+uELnvIwvCG019L9sAIljwjCmEMtFQQO3YeitJY8Kctei3iA== @@ -3868,7 +3848,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4131,14 +4111,7 @@ is-wsl@^1.1.0: resolved "https://registry.npmmirror.com/is-wsl/-/is-wsl-1.1.0.tgz" integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== -is-wsl@^2.1.1: - version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -is-wsl@^2.2.0: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -4424,7 +4397,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.7.0: +jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -4568,7 +4541,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@*, jest@^29.6.3: +jest@^29.6.3: version "29.7.0" resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -4842,7 +4815,7 @@ metro-cache@0.83.2: https-proxy-agent "^7.0.5" metro-core "0.83.2" -metro-config@^0.83.1, metro-config@0.83.2: +metro-config@0.83.2, metro-config@^0.83.1: version "0.83.2" resolved "https://registry.npmjs.org/metro-config/-/metro-config-0.83.2.tgz" integrity sha512-1FjCcdBe3e3D08gSSiU9u3Vtxd7alGH3x/DNFqWDFf5NouX4kLgbVloDDClr1UrLz62c0fHh2Vfr9ecmrOZp+g== @@ -4856,7 +4829,7 @@ metro-config@^0.83.1, metro-config@0.83.2: metro-runtime "0.83.2" yaml "^2.6.1" -metro-core@^0.83.1, metro-core@0.83.2: +metro-core@0.83.2, metro-core@^0.83.1: version "0.83.2" resolved "https://registry.npmjs.org/metro-core/-/metro-core-0.83.2.tgz" integrity sha512-8DRb0O82Br0IW77cNgKMLYWUkx48lWxUkvNUxVISyMkcNwE/9ywf1MYQUE88HaKwSrqne6kFgCSA/UWZoUT0Iw== @@ -4895,7 +4868,7 @@ metro-resolver@0.83.2: dependencies: flow-enums-runtime "^0.0.6" -metro-runtime@^0.83.1, metro-runtime@0.83.2: +metro-runtime@0.83.2, metro-runtime@^0.83.1: version "0.83.2" resolved "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.2.tgz" integrity sha512-nnsPtgRvFbNKwemqs0FuyFDzXLl+ezuFsUXDbX8o0SXOfsOPijqiQrf3kuafO1Zx1aUWf4NOrKJMAQP5EEHg9A== @@ -4903,7 +4876,7 @@ metro-runtime@^0.83.1, metro-runtime@0.83.2: "@babel/runtime" "^7.25.0" flow-enums-runtime "^0.0.6" -metro-source-map@^0.83.1, metro-source-map@0.83.2: +metro-source-map@0.83.2, metro-source-map@^0.83.1: version "0.83.2" resolved "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.2.tgz" integrity sha512-5FL/6BSQvshIKjXOennt9upFngq2lFvDakZn5LfauIVq8+L4sxXewIlSTcxAtzbtjAIaXeOSVMtCJ5DdfCt9AA== @@ -4962,7 +4935,7 @@ metro-transform-worker@0.83.2: metro-transform-plugins "0.83.2" nullthrows "^1.1.1" -metro@^0.83.1, metro@0.83.2: +metro@0.83.2, metro@^0.83.1: version "0.83.2" resolved "https://registry.npmjs.org/metro/-/metro-0.83.2.tgz" integrity sha512-HQgs9H1FyVbRptNSMy/ImchTTE5vS2MSqLoOo7hbDoBq6hPPZokwJvBMwrYSxdjQZmLXz2JFZtdvS+ZfgTc9yw== @@ -5016,16 +4989,16 @@ micromatch@^4.0.4, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" -"mime-db@>= 1.43.0 < 2": - version "1.54.0" - resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - mime-db@1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +"mime-db@>= 1.43.0 < 2": + version "1.54.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + mime-types@^2.1.27, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" @@ -5033,43 +5006,22 @@ mime-types@^2.1.27, mime-types@~2.1.34: dependencies: mime-db "1.52.0" -mime@^2.4.1: - version "2.6.0" - resolved "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - mime@1.6.0: version "1.6.0" resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.4.1: + version "2.6.0" + resolved "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.5: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -5088,16 +5040,16 @@ mkdirp@^1.0.4: resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -ms@^2.1.3, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== +ms@2.1.3, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + nanoid@^3.3.11: version "3.3.11" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" @@ -5108,16 +5060,16 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@~0.6.4: - version "0.6.4" - resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== - negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@~0.6.4: + version "0.6.4" + resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + nocache@^3.0.1: version "3.0.4" resolved "https://registry.npmmirror.com/nocache/-/nocache-3.0.4.tgz" @@ -5219,13 +5171,6 @@ object.values@^1.1.6, object.values@^1.2.1: define-properties "^1.2.1" es-object-atoms "^1.0.0" -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -5233,6 +5178,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + on-headers@~1.1.0: version "1.1.0" resolved "https://registry.npmmirror.com/on-headers/-/on-headers-1.1.0.tgz" @@ -5415,7 +5367,7 @@ prelude-ls@^1.2.1: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@>=2, prettier@2.8.8: +prettier@2.8.8: version "2.8.8" resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== @@ -5513,12 +5465,12 @@ react-freeze@^1.0.0: resolved "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz" integrity sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA== -react-i18next@^16.5.0: - version "16.5.6" - resolved "https://registry.npmmirror.com/react-i18next/-/react-i18next-16.5.6.tgz" - integrity sha512-Ua7V2/efA88ido7KyK51fb8Ki8M/sRfW8LR/rZ/9ZKr2luhuTI7kwYZN5agT1rWG7aYm5G0RYE/6JR8KJoCMDw== +react-i18next@16.5.0: + version "16.5.0" + resolved "https://repo.huaweicloud.com/repository/npm/react-i18next/-/react-i18next-16.5.0.tgz#107e4323742344a2f8792feb905cea551da6fd2c" + integrity sha512-IMpPTyCTKxEj8klCrLKUTIUa8uYTd851+jcu2fJuUB9Agkk9Qq8asw4omyeHVnOXHrLgQJGTm5zTvn8HpaPiqw== dependencies: - "@babel/runtime" "^7.28.4" + "@babel/runtime" "^7.27.6" html-parse-stringify "^3.0.1" use-sync-external-store "^1.6.0" @@ -5560,7 +5512,7 @@ react-native-is-edge-to-edge@^1.2.1: resolved "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz" integrity sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q== -react-native-safe-area-context@^5.6.1, "react-native-safe-area-context@>= 4.0.0": +react-native-safe-area-context@^5.6.1: version "5.6.1" resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.1.tgz" integrity sha512-/wJE58HLEAkATzhhX1xSr+fostLsK8Q97EfpfMDKo8jlOc1QKESSX/FQrhk7HhQH/2uSaox4Y86sNaI02kteiA== @@ -5570,7 +5522,7 @@ react-native-safearea-height@^1.0.8: resolved "https://registry.npmmirror.com/react-native-safearea-height/-/react-native-safearea-height-1.0.8.tgz" integrity sha512-nAACsA6HwbMI5zUKHUy4IOvqrohA2AFYB31Yhv6JOXbok6S7VOjOWJZNJx4dllECREon254Y2ZlqeVGUb2eqgQ== -react-native-screens@^4.16.0, "react-native-screens@>= 4.0.0": +react-native-screens@^4.16.0: version "4.16.0" resolved "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz" integrity sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q== @@ -5592,7 +5544,7 @@ react-native-vector-icons@^10.3.0: prop-types "^15.7.2" yargs "^16.1.1" -react-native@*, "react-native@^0.0.0-0 || >=0.65 <1.0", react-native@0.81.4: +react-native@0.81.4: version "0.81.4" resolved "https://registry.npmjs.org/react-native/-/react-native-0.81.4.tgz" integrity sha512-bt5bz3A/+Cv46KcjV0VQa+fo7MKxs17RCcpzjftINlen4ZDUl0I6Ut+brQ2FToa5oD0IB0xvQHfmsg2EDqsZdQ== @@ -5645,7 +5597,7 @@ react-test-renderer@19.1.0: react-is "^19.1.0" scheduler "^0.26.0" -react@*, "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", react@^19.1.0, "react@>= 16.8.0", "react@>= 18.2.0", react@>=16.8, react@>=17.0.0, react@19.1.0: +react@19.1.0: version "19.1.0" resolved "https://registry.npmjs.org/react/-/react-19.1.0.tgz" integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg== @@ -5819,7 +5771,7 @@ safe-array-concat@^1.1.3: has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@~5.2.0, safe-buffer@5.2.1: +safe-buffer@5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -5841,7 +5793,7 @@ safe-regex-test@^1.1.0: es-errors "^1.3.0" is-regex "^1.2.1" -scheduler@^0.26.0, scheduler@0.26.0: +scheduler@0.26.0, scheduler@^0.26.0: version "0.26.0" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz" integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== @@ -5851,32 +5803,7 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.3: - version "7.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -semver@^7.3.7: - version "7.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -semver@^7.5.2: - version "7.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -semver@^7.5.3: - version "7.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -semver@^7.5.4: - version "7.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -semver@^7.6.0: +semver@^7.1.3, semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: version "7.7.2" resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== @@ -6044,14 +5971,6 @@ slice-ansi@^2.0.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@0.5.13: version "0.5.13" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" @@ -6060,6 +5979,14 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map@^0.5.6: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" @@ -6099,16 +6026,16 @@ stacktrace-parser@^0.1.10: dependencies: type-fest "^0.7.1" -statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - statuses@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + stop-iteration-iterator@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz" @@ -6122,13 +6049,6 @@ strict-uri-encode@^2.0.0: resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz" integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - string-length@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -6210,14 +6130,14 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -strip-ansi@^5.0.0: - version "5.2.0" - resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-5.2.0.tgz" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - ansi-regex "^4.1.0" + safe-buffer "~5.2.0" -strip-ansi@^5.2.0: +strip-ansi@^5.0.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-5.2.0.tgz" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -6410,7 +6330,7 @@ typed-array-length@^1.0.7: possible-typed-array-names "^1.0.0" reflect.getprototypeof "^1.0.6" -typescript@^5, typescript@^5.8.3, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=4.2.0, typescript@>=4.9.5: +typescript@^5.8.3: version "5.9.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz" integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== @@ -6659,12 +6579,7 @@ ws@^6.2.3: dependencies: async-limiter "~1.0.0" -ws@^7: - version "7.5.10" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" - integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== - -ws@^7.5.10: +ws@^7, ws@^7.5.10: version "7.5.10" resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==